从存储过程更新

时间:2014-04-10 14:05:26

标签: postgresql sql-injection plpgsql dynamic-sql

我需要创建一个存储过程,它可以将模式名称和表名作为参数,并在同一个表上进行更新。

CREATE OR REPLACE FUNCTION garscratch.update_table(schema_name text, table_name text ) RETURNS void as $$
DECLARE
 table TEXT;
BEGIN
execute 'update '||schema||'.'||table_name|| 'set id = substring(id from 1 for 2) where name = "test"';
END;
$$ LANGUAGE plpgsql;

当我执行上述程序时:

select update_table(my,my_table);

我收到错误:

  

列“我的”不存在。

它不会将“my”视为架构名称。

3 个答案:

答案 0 :(得分:2)

  • 您需要tablenameset之间的空格。
  • 你需要围绕值'test'的sinlge引号 或者,如果它应该是列名,那么根本不需要引号。
  • 您需要清理标识符以避免SQL注入。

改为使用(完全重写):

CREATE OR REPLACE FUNCTION garscratch.update_table(_tbl regclass)
  RETURNS void AS
$func$
BEGIN
EXECUTE 'UPDATE ' || _tbl || $$ SET id = left(id, 2) WHERE name = 'test'$$;
END
$func$ LANGUAGE plpgsql;

呼叫:

SELECT garscratch.update_table('myschema.my_table');

详细说明:
Table name as a PostgreSQL function parameter

答案 1 :(得分:1)

在我看来,您可能会遇到table_name|| 'set id=部分的问题 - 具体来说,我认为您应该在'set之间添加空格。尝试打印您正在执行的内容,您可能会发现问题所在。

答案 2 :(得分:0)

执行程序如下:

select update_table('my','my_table');

同时更改行

execute 'update '||schema||'.'||table_name|| 'set id = substring(id from 1 for 2) where name = "test"';

execute 'update '||schema_name||'.'||table_name|| 'set id = substring(id from 1 for 2) where name = "test"';