将$$放在PostgreSQL中以美元引用的字符串中

ily*_*als 3 postgresql syntax escaping dynamic-sql quoting

我在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;
Run Code Online (Sandbox Code Playgroud)

我通常使用此查询来调用该函数:

select upsert(
  $$INSERT INTO zz(a, b) VALUES (66, 'hahahaha')$$,
  $$UPDATE zz SET a=66, b='hahahaha' WHERE a=66$$
)
Run Code Online (Sandbox Code Playgroud)

有用.不幸的是,我的查询字符串不能包含$$,如下所示:

select upsert(
  $$INSERT INTO zz(a, b) VALUES (66, 'ha$$hahaha')$$,
  $$UPDATE zz SET a=66, b='hahahaha' WHERE a=66$$
)
Run Code Online (Sandbox Code Playgroud)

我已阅读 Postgres文档但仍需要协助如何执行此操作.

Erw*_*ter 9

所以请使用不同的美元报价代替:

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注入的攻击吗?任何类型的东西都应该是非常私密或非常安全的使用.