postgresql 如何在存储过程中调用数组?

dphi5xsq  于 2022-11-29  发布在  PostgreSQL
关注(0)|答案(2)|浏览(688)

我可以知道如何在存储过程中调用数组吗?我试着用括号把它括起来,把需要插入到新表中的column_name放在里面。

CREATE OR REPLACE PROCEDURE data_versioning_nonull(new_table_name VARCHAR(100),column_name VARCHAR(100)[], current_table_name VARCHAR(100))
language plpgsql
as $$
BEGIN
    EXECUTE ('CREATE TABLE ' || quote_ident(new_table_name) || ' AS SELECT ' || quote_ident(column_name) || ' FROM ' || quote_ident(current_table_name));
END $$;

CALL data_versioning_nonull('sales_2019_sample', ['orderid', 'product', 'address'], 'sales_2019');
rta7y2nd

rta7y2nd1#

1.使用execute format()可让您将单一文字中的所有quote_ident()取代为%I预留位置,而非一系列串连的片段。%1$I可让您重复使用第一个参数。
1.最好是使用ARRAY['a','b','c']::VARCHAR(100)[]显式地将其设置为所需类型的数组。'{"a","b","c"}'::VARCHAR(100)[]也可以。
1.您需要用其他方法将数组转换为列列表,因为当转换为文本时,它会得到列列表语法中不允许的大括号。Demo
1.引入随机限制并不是一个好的做法- PostgreSQL没有将标识符长度限制在100个字符以内,所以你也不必这样做。默认限制是63 bytes,所以你可以选择比100个字符更长的长度(demo)。您可以将该数据类型切换为常规的text。有趣的是,超过指定的varchar长度would just convert it to unlimited varchar,使其成为语法噪音。
DBFiddle online demo

CREATE TABLE sales_2019(orderid INT,product INT,address INT);

CREATE OR REPLACE PROCEDURE data_versioning_nonull(
  new_table_name     TEXT,
  column_names       TEXT[], 
  current_table_name TEXT)
LANGUAGE plpgsql AS $$
DECLARE
  list_of_columns_as_quoted_identifiers TEXT;
BEGIN
  SELECT string_agg(quote_ident(name),',')
  INTO list_of_columns_as_quoted_identifiers
  FROM unnest(column_names) name;
  
  EXECUTE format('CREATE TABLE %1$I.%2$I AS SELECT %3$s FROM %1$I.%4$I',
                   current_schema(),
                   new_table_name,
                   list_of_columns_as_quoted_identifiers,
                   current_table_name);
END $$;

CALL data_versioning_nonull(
  'sales_2019_sample', 
  ARRAY['orderid', 'product', 'address']::text[], 
  'sales_2019');

1.架构感知:当前,该过程在默认模式中创建新表,基于同一默认模式中的表--上面我将其显式化,但这是它在没有current_schema()调用的情况下所做的。您可以添加new_table_schemacurrent_table_schema参数,如果大多数情况下您不希望使用它们,则可以将它们隐藏在过程重载后面以方便使用。使用current_schema()来保持隐式行为。Demo

yzuktlbb

yzuktlbb2#

首先,更改存储过程,将选定列从数组转换为csv,如下所示。

CREATE OR REPLACE PROCEDURE data_versioning_nonull(new_table_name VARCHAR(100),column_name VARCHAR(100)[], current_table_name VARCHAR(100))
language plpgsql
as $$
BEGIN
    EXECUTE ('CREATE TABLE ' || quote_ident(new_table_name) || ' AS SELECT ' || array_to_string(column_name, ',') || ' FROM ' || quote_ident(current_table_name));
END $$;

便叫它为:

CALL data_versioning_nonull('sales_2019_sample', '{"orderid", "product", "address"}', 'sales_2019');

相关问题