我在Postgres中有一个功能:
CREATE OR REPLACE FUNCTION upsert(sql_insert text, sql_update text)
RETURNS integer AS
$BODY$
BEGIN
EXECUTE sql_insert;
RETURN 1;
EXCEPTION WHEN unique_violation THEN
EXECUTE sql_update;
RETURN 2;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE
COST 100;
ALTER FUNCTION upsert(text, text) OWNER TO dce;
我通常使用此查询来调用该函数:
select upsert(
$$INSERT INTO zz(a, b) VALUES (66, 'hahahaha')$$,
$$UPDATE zz SET a=66, b='hahahaha' WHERE a=66$$
)
有效。不幸的是,我的查询字符串不能包含$$
,如下所示:
select upsert(
$$INSERT INTO zz(a, b) VALUES (66, 'ha$$hahaha')$$,
$$UPDATE zz SET a=66, b='hahahaha' WHERE a=66$$
)
我已阅读this Postgres文档,但仍需要协助如何操作。
答案 0 :(得分:6)
因此请改用其他dollar-quote:
select upsert( $weird_string$INSERT INTO zz(a, b) VALUES (66, 'ha$$hahaha')$weird_string$, $weird_string$UPDATE zz SET a=66, b='hahahaha' WHERE a=66$weird_string$ )
这仍然存在理论上的机会,即美元报价可能在字符串内匹配。
如果您手动构建查询,只需检查字符串中的$
即可。
如果要从变量构建查询,则可以改为使用quote_literal(querystring)
。
自Postgres 9.1以来,还有方便的format()
功能。
顺便说一下:我假设你知道这种形式的动态SQL极易受到SQL注入的影响吗?任何类型的东西都应该是非常私密或非常安全的使用。