PostgreSQL - 不能在函数中使用args

时间:2016-06-17 14:34:29

标签: postgresql

我想在postgresql中编写一个简单的函数,它检查我的表是否存在,如果存在,则清除其所有行。在postgresql文档中,我看到我可以通过$加上arg数来引用我的参数,但它在函数创建过程中给出了一个错误。

这是我的功能:

CREATE OR REPLACE FUNCTION delete_if_exists(table_name text) RETURNS void
AS $$
BEGIN

IF EXISTS(SELECT * FROM $1)
THEN 
delete from $1;
END IF;
RETURN;

END;
$$ LANGUAGE plpgsql;

enter image description here

2 个答案:

答案 0 :(得分:0)

函数中的变量不是简单地插入到字符串中,而是作为参数传递给准备好的查询。因此,您无法直接在可能会更改计划的部分查询中使用它们,例如表名和列名。

为了做到这一点,你需要改为使用动态SQL ,即以编程方式构建一个字符串,并执行它。请参阅Executing Dynamic SQL in the manual

创建动态SQL时应始终非常小心,因为很容易意外地产生安全问题。至少,您应该使用正确的转义机制,但您可能还希望将函数所期望的表名称列入白名单或模式匹配。

使用the format() function %I占位符正确引用的示例:

EXECUTE format('delete from %I;', $1);

请注意,您还可以使用变量的名称,而不是位置标识符,这在较长的函数中更容易阅读:

EXECUTE format('delete from %I;', table_name);

我不会尝试调整你的完整例子,因为我认为它无论如何都是一个过于简化的例子,因为它实际上并没有写成。

答案 1 :(得分:0)

如果将标识符(表名,列名)传递给函数,则需要execute the query dynamically。此外,如果没有过滤器DELETE FROM,您应该使用TRUNCATE,因为这样会更快并且会清理您的硬盘(在不利方面,更改无法撤消)。

CREATE FUNCTION delete_if_exists(table_name text) RETURNS void AS $$
BEGIN
    -- Just try to TRUNCATE
    EXECUTE format('TRUNCATE %I', table_name);
EXCEPTION
    WHEN OTHERS THEN
        NULL;  -- If the table does not exist, an error is thrown, just ignore it
END;
$$ LANGUAGE plpgsql;