0

我试图弄清楚如何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;

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

查询成功,0 行受影响(执行时间:296 毫秒;总时间:296 毫秒)

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

4

1 回答 1

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

还有其他方法:

于 2015-04-13T23:03:43.420 回答