我想创建一个函数:
CREATE OR REPLACE FUNCTION medibv.delAuto(tableName nvarchar(50), columnName nvarchar(100),value
nvarchar(100))
RETURNS void AS
$BODY$
begin
DELETE from tableName where columnName=value
end;
$BODY$
LANGUAGE plpgsql VOLATILE;
我有以下参数:tableName, columnName, value
。
我希望tableName
作为PostgreSQL中的表。
答案 0 :(得分:3)
CREATE OR REPLACE FUNCTION medibv.delauto(tbl regclass, col text, val text
,OUT success bool)
RETURNS bool AS
$func$
BEGIN
EXECUTE format('
DELETE FROM %s
WHERE %I = $1
RETURNING TRUE', tbl, col)
USING val
INTO success;
RETURN; -- optional in this case
END
$func$ LANGUAGE plpgsql;
呼叫:
SELECT medibv.delauto('myschema.mytbl', 'my_txt_col', 'foo');
返回TRUE
或NULL
。
Postgres中没有nvarchar
类型。你可能会想到SQL Server。相当于varchar
,但大多数时候您只需使用text
。
regclass
是注册表名的专用类型。它非常适用于自动且最有效地阻止表名的 SQL注入的情况。更多在下面的相关答案中。
列名仍然易于SQL注入。我使用format(%I)
清理函数。
format()
需要PostgreSQL 9.1 +。
您的功能未报告发生了什么。可以找到并删除一行或多行。或者根本没有。作为最低限度,我添加了boolean OUT
列,如果删除了一行或多行,则会TRUE
。因为(quoting the manual here):
如果返回多行,则只会将第一行分配给
INTO
变量。
最后,使用 USING
和EXECUTE
传递值。不要来回投掷。这是低效的,容易出错,再次出现在SQLi上。
在这个密切相关的答案中找到更多解释和链接:
Table name as a PostgreSQL function parameter
答案 1 :(得分:1)
使用EXECUTE运行动态命令:
CREATE OR REPLACE FUNCTION medibv.delAuto(tableName nvarchar(50), columnName nvarchar(100),value
nvarchar(100))
RETURNS void AS
$BODY$
begin
EXECUTE 'DELETE FROM ' || tableName || ' WHERE ' || columnName || '=' || value;
end;
$BODY$
LANGUAGE plpgsql VOLATILE;