【问题标题】:Dynamic table name for INSERT INTO queryINSERT INTO 查询的动态表名
【发布时间】:2014-11-05 07:25:28
【问题描述】:

我正在尝试弄清楚如何编写一个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 毫秒)

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

【问题讨论】:

  • 如果您有多个具有相同架构的表,因此它们包含相同“排序”的数据,这通常表明它们应该是一个带有附加列来包含数据的表这可能是,目前,作为表 names 的一部分嵌入。 IE。如果你在为一个组织建模,你几乎肯定不应该有 maleEmployeesfemaleEmployees 表。
  • "schemaname"."Table_1" 有可能有零行吗?输出是什么:SELECT count("Col_A") FROM "schemaname"."Table_1";

标签: postgresql function insert plpgsql dynamic-queries


【解决方案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

还有其他方法:

【讨论】:

    猜你喜欢
    • 2016-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    • 2012-07-06
    相关资源
    最近更新 更多