将$$放入PostgreSQL中的美元引号字符串中

z31licg0  于 2023-02-08  发布在  PostgreSQL
关注(0)|答案(1)|浏览(201)

我在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文档,但仍然需要如何操作的帮助。

shstlldc

shstlldc1#

请改用不同的美元引号:

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()函数。
参见:

  • 在PostgreSQL中插入带单引号的文本

旁白:这种形式的动态SQL极易受到SQL注入的攻击。任何这类东西都应该只用于非常私密或非常安全的用途。

相关问题