2015-07-21 236 views
4

我刚刚创建了plpgsql函数。我需要一些关于在函数内部执行的动态命令上使用quote_ident()(甚至是quote_literal())的说明。希望任何人都能给我一个关于他们如何在函数内部工作的具体解释。 TIA在plpgsql函数中使用quote_ident()

下面是它的一个例子:

EXECUTE 'UPDATE tbl SET ' || quote_ident(colname) || ' = ' || quote_literal(newvalue) || ' WHERE key = ' || quote_literal(keyvalue); 
+1

[文档](http://www.postgresql.org/docs/current/interactive/functions-string.html)不够清楚? –

回答

11

quote_ident用于标识符引用。 quote_literal用于字符串的引用。

postgres=# select quote_ident('tablename'); 
┌─────────────┐ 
│ quote_ident │ 
╞═════════════╡ 
│ tablename │ 
└─────────────┘ 
(1 row) 

postgres=# select quote_ident('special name'); 
┌────────────────┐ 
│ quote_ident │ 
╞════════════════╡ 
│ "special name" │ 
└────────────────┘ 
(1 row) 

postgres=# select quote_literal(e'some text with special char"\'"'); 
┌───────────────────────────────────┐ 
│   quote_literal   │ 
╞═══════════════════════════════════╡ 
│ 'some text with special char"''"' │ 
└───────────────────────────────────┘ 
(1 row) 

什么是标识符?表,列,模式,序列的名称......字面意思是什么? - 通常是一些文本值(但可以是任何类型的值)。这两个函数都会搜索并替换一些特殊的字符,但使用不同的规则 - SQL中的标识符和字符串是不同的。

现在 - 这些功能已经过时了。 quote_literal应该by子句USING(更好的性能)来代替,quote_ident应该通过格式化功能format(由于更好的可读性)来代替:

EXECUTE format('UPDATE tbl SET %I=$1 WHERE key=$2', colname) 
    USING newvalue, keyvalue; 

或仅与格式功能

EXECUTE format('UPDATE tbls SET %I=%L WHERE key=%L', colname, newvalue, keyvalue); 

无报价动态SQL a)不应该工作(语法错误失败),b)对sql注入不安全

+0

参考:https://www.postgresql.org/docs/current/static/plpgsql-statements.html#PLPGSQL-QUOTE-LITERAL-EXAMPLE。还应该使用格式,因为:“这种形式更好,因为变量是以其原生数据类型格式处理的,而不是无条件地将它们转换为文本并通过%L引用它们,它也更有效” – raphael