我试图找出如何使用源名称和源列名作为参数编写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)
我希望更改能够反映在目标表中。我不知道如何解决问题。
答案 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
还有其他方法: