2012-02-14 28 views
3

美元引号的字符串我有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

[那么你有你的答案吗?](http://meta.stackexchange.com/a/5235/169168) – 2015-07-28 12:49:59

回答

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注入攻击?任何类型的应该只用于非常私密或非常安全的使用。

+0

非常感谢Erwin。 – ilyasfals 2012-02-14 06:19:02

+0

它的工作原理!我以前不知道那个标签。 – ilyasfals 2012-02-14 06:35:08

+0

我构建查询的变量。所以,我想我会用quote_literal()。这非常有用。 – ilyasfals 2012-02-14 06:48:54