INSERT具有动态列名称

时间:2016-06-19 00:25:14

标签: sql postgresql plpgsql dynamic-sql names

我将列名存储在变量colls中,然后执行代码:

DO $$
DECLARE
v_name text :=  quote_ident('colls');
BEGIN
EXECUTE 'insert into table1 select '|| colls ||' from table2 ';
-- EXECUTE 'insert into table1 select '|| v_name ||' from table2 ';
END$$;

我收到了错误: column" colls"不存在。程序使用colls作为名称而不是变量。我做错了什么?

我在文档中找到了类似的例子:
https://www.postgresql.org/docs/8.1/static/plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN

1 个答案:

答案 0 :(得分:1)

  

我的列名存储在变量colls

不,你没有。您有一个变量v_name - 其中包含单个字:'colls'。关于SQL中的变量:

阅读手册中的章节Identifiers and Key WordsConstants

如果您在单个变量中有多个列名称,则无法使用quote_ident()。它会将整个字符串作为单个标识符进行转义。

我想基本的误解是这样的:'colls'字符串常量,而不是变量DO语句中没有其他变量,而不是DECLARE部分中声明的变量。您可能正在寻找 一个函数,该函数将可变数量的列名称作为参数 ......

CREATE OR REPLACE FUNCTION f_insert_these_columns(VARIADIC _cols text[])
  RETURNS void AS
$func$
BEGIN
   EXECUTE (
      SELECT 'INSERT INTO table1 SELECT '
          || string_agg(quote_ident(col), ', ')
          || ' FROM table2'
      FROM   unnest(_cols) col
      );
END
$func$  LANGUAGE plpgsql;

呼叫:

SELECT f_insert_these_columns('abd', 'NeW Deal');          -- column names case sensitive!
SELECT f_insert_these_columns(VARIADIC '{abd, NeW Deal}'); -- column names case sensitive!

请注意我如何删除列名称数组并逐个转义 VARIADIC参数应该适合您的用例。您可以传递列名列表或数组 无论哪种方式,都可以使用不同的SQL注入 相关,有更多解释: