INSERT INTO查询的动态表名称

时间:2014-11-05 07:25:29

标签: postgresql function insert plpgsql dynamic-queries

我试图找出如何使用源名称和源列名作为参数编写INSERT INTO查询。

对于初学者,我只是试图参数化源表名。我写了以下查询。现在我直接声明并赋值变量tablename的值,但在实际例子中,它将来自其他一些源/列表。目标表只有一列。

CREATE OR REPLACE FUNCTION foo()
RETURNS void AS
$$
DECLARE
    tablename text;
BEGIN
   tablename := 'Table_1';
   EXECUTE 'INSERT INTO "Schemaname"."targettable"
   SELECT "Col_A"
   FROM "schemaname".'
   ||quote_ident(tablename);
END
$$ LANGUAGE PLPGSQL;

虽然查询运行时没有任何错误,但目标表中没有反映任何更改。在运行查询时,我得到以下输出。

  

查询OK,0行受影响(执行时间:296 ms;总时间:296 ms)

我希望更改能够反映在目标表中。我不知道如何解决问题。

1 个答案:

答案 0 :(得分:1)

审核代码

CREATE OR REPLACE FUNCTION foo()
   RETURNS void AS
$func$
DECLARE
   _tbl text := 'Table_1';  -- or 'table_1'?
BEGIN       
   EXECUTE 'INSERT INTO schemaname.targettable(column_name)
   SELECT  "Col_A"
   FROM    schemaname.' || quote_ident(_tbl);  -- or "Schemaname"?
END
$func$  LANGUAGE plpgsql;
  • 始终对持久性INSERT语句使用显式目标列表。

  • 您可以在申报时分配变量。

  • 使用双引号标识符来保护非法拼写是一种广泛的愚蠢行为。您必须为其余的存在重复引用该名称。这些错误中的一个或多个似乎已经悄悄进入您的代码:"Schemaname""schemaname"Table_1"Table_1"

  • 当您提供表格名称为text参数的标识符并使​​用quote_ident()转义时, 区分大小写
    除非双引号,否则SQL代码中的标识符将转换为小写。但quote-ident()(您必须用来防御SQL注入)会在必要时保留您提供的双引号拼写。

带参数

的功能
CREATE OR REPLACE FUNCTION foo(_tbl text)
   RETURNS void AS
$func$
BEGIN       
   EXECUTE 'INSERT INTO schemaname.targettable(column_name)
   SELECT  "Col_A"
   FROM    schemaname.' || quote_ident(_tbl);
END
$func$  LANGUAGE plpgsql;

呼叫:

SELECT foo('tablename');  -- tablename is case sensitive

还有其他方法: