PLPGSQL: передача аргумента в функцию разбивает мои кавычки - PullRequest
0 голосов
/ 16 ноября 2011

Без функций я могу сделать:

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 Ответ

1 голос
/ 16 ноября 2011

Это поведение основано на неявном использовании операторов подготовки. Когда используются подготовленные операторы, запрос и параметры передаются на сервер базы данных отдельно. Не указывайте значения в этом сценарии. 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;
...