如何使用execute
和if exists
语句在postgresql中编写函数?
CREATE FUNCTION replace_value(var_id char, var_data text, table_name char) RETURNS void AS $$
BEGIN
IF EXISTS EXECUTE'(SELECT id FROM ' ||table_name|| ' WHERE id = '||var_id||')'
THEN EXECUTE 'UPDATE ' ||table_name||'
SET (id, data) = '||(var_id, var_data)||';'
ELSE EXECUTE 'INSERT INTO ' ||table_name||' (id, data)
VALUES '||(var_id, var_data)||';'
END IF;
RETURN;
END;
$$ LANGUAGE plpgsql;
我还会使用table_name
作为传递给函数的参数以及此示例中的一些变量'var_id'
和'var_data'
。我知道只有在使用execute语句时才能在postgresql函数中使用表名。
答案 0 :(得分:1)
EXECUTE是plpgsql语句,你不能将两个语句合并在一起。您的代码还有其他两个问题 - SQL注入漏洞和竞争条件。
一个变体(当更多客户端尝试插入相同数据时应该失败)
DECLARE rc int;
BEGIN
EXECUTE format('UPDATE %I SET data=$1 WHERE id=$2', table_name)
USING data, var_id;
GET DIAGNOSTICS rc = ROW_COUNT;
IF rc = 0 THEN
EXECUTE format('INSERT INTO %I(id, data) VALUES($1,$2)', table_name)
USING var_id, data;
END IF;
END;
或者,有些人喜欢你这样做:
DECLARE rc int;
BEGIN
EXECUTE format('SELECT id FROM %I WHERE id=$1 FOR UPDATE', table_name)
USING var_id;
GET DIAGNOSTICS rc = ROW_COUNT;
if rc = 0 THEN
EXECUTE format('INSERT INTO %I(id, data) VALUES($1,$2)', table_name)
USING var_id, data;
ELSE
EXECUTE format('UPDATE %I SET data=$1 WHERE id=$2', table_name)
USING data, var_id;
END IF;
END