我在 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 文档,但仍需要有关如何操作的帮助。
最佳答案
使用不同的dollar-quotes相反:
select upsert( $unique_token$INSERT INTO zz(a, b) VALUES (66, 'ha$$hahaha')$unique_token$, $unique_token2$UPDATE zz SET a=66, b='hahahaha' WHERE a=66$unique_token2$ )
每个结束点都必须与每个开始点相匹配。这两对不必截然不同,但这样做是最安全的。
这仍然留下了美元引号可能在字符串中匹配的理论上的可能性。
如果您手动构建查询,只需检查字符串中的 $
。
如果您从变量构建查询,请使用 quote_literal(string)
或 quote_nullable(string)
相反。
还有方便的format()
功能。
参见:
旁白:这种形式的动态 SQL 极易受到 SQL 注入(inject)的攻击。任何此类内容都应仅用于非常私密或非常安全的用途。
关于postgresql - 在 PostgreSQL 中将 $$ 放入美元引用的字符串中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9272007/