0

我想创建一个函数:

 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 中作为表。

4

2 回答 2

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');

返回TRUENULL

  • Postgres中没有nvarchar类型。您可能正在考虑 SQL Server。相当于是varchar,但大多数时候你可以简单地使用text.

  • regclass是注册表名的特殊类型。它非常适合自动和最有效地防止对表名进行SQL 注入的情况。更多在下面的相关答案中。

  • 列名仍然容易被 SQL 注入。我用format(%I).

  • format()需要 PostgreSQL 9.1+。

  • 你的函数没有报告发生了什么。可以找到并删除一行或多行。或者根本没有。作为最低限度,我添加了一个boolean OUT列,TRUE如果一个或多个行被删除。因为(在这里引用手册):

    如果返回多行,则仅将第一行分配给INTO变量。

  • 最后,使用USINGwithEXECUTE传递。不要来回投掷。这是低效的并且容易出错并且再次出现 SQLi。

  • 在这个密切相关的答案中找到更多解释和链接:
    Table name as a PostgreSQL function parameter

于 2013-04-22T00:50:19.367 回答
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;
于 2013-04-16T05:21:38.947 回答