PLPGSQL:将参数传递给函数会破坏我的引号

时间:2011-11-16 07:47:18

标签: plpgsql

没有功能,我可以这样做:

DELETE FROM table1
WHERE something='hello'

我的行='hello'的值被删除了,但是一旦我实现了函数,我开始遇到引号问题。

CREATE OR REPLACE FUNCTION somefunc(varchar)
RETURNS varchar AS $$
BEGIN

  DELETE FROM table1
  WHERE something='$1';

  DELETE FROM table2
  WHERE something='$1';

  RETURN $1;

END;
$$ LANGUAGE plpgsql;`

似乎没什么用。我试过了(我在SO或其他地方看到的所有变化):

something=$1   <-- says column "hello" doesn't exist (because no quotes are given)
something=''$1''
something='''$1'''
something=''''$1''''
something='''||$1||'''
something=$Q$$1$Q1$   <--- gives syntax error
something=$Q1$ $1 $Q1$
something=$$ $1 $$
something=quote_literal($1)

还有很多其他变种。我该如何解决这个问题?

顺便说一句,我正在使用python脚本来运行该函数。这是运行它的线。我也试过在这一行添加引号也无济于事:

cur.execute("SELECT somefunc(%s);" % (sys.argv[2]))

谢谢!

1 个答案:

答案 0 :(得分:1)

此行为基于对prepare语句的隐式使用。使用预准备语句时,查询和参数将分别传递给数据库服务器。不要在该场景中引用值。 PL / pgSQL使用预处理语句,psycopg2也使用预处理语句:

...
DECLARE myvar int;
BEGIN
   DELETE FROM mytab WHERE column = myvar; -- quietly using prepared statement

DECLARE myvar int;
BEGIN
   -- using dynamic SQL is similar to classic languages, quoting is necessary
   -- but use the quote_literal() function to protect against SQL injection
   EXECUTE 'DELETE FROM mytab WHERE column = ' || quote_literal(myvar);

   -- or dynamic SQL with "USING" clause 
   EXECUTE 'DELETE FROM mytab WHERE column = $1' USING myvar;