joh*_*eel 6 sql postgresql function plpgsql
我只是创建plpgsql函数的新手.我需要一些关于在函数内部执行的动态命令中使用quote_ident()(甚至是quote_lite())的说明.希望任何人都可以给我一个关于它们如何在函数内工作的具体解释.TIA
这是一个例子:
EXECUTE 'UPDATE tbl SET ' || quote_ident(colname) || ' = ' || quote_literal(newvalue) || ' WHERE key = ' || quote_literal(keyvalue);
Run Code Online (Sandbox Code Playgroud)
Pav*_*ule 16
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)
Run Code Online (Sandbox Code Playgroud)
什么是标识符?表,列,模式,序列的名称......什么是字面值? - 通常是一些文本值(但可以是任何类型的值).函数搜索和替换一些特殊字符,但具有不同的规则 - 标识符和字符串在SQL中是不同的.
现在 - 这些功能有点过时了.quote_literal应该用子句替换USING(性能更好),quote_ident应该用格式化函数替换format(由于更好的可读性):
EXECUTE format('UPDATE tbl SET %I=$1 WHERE key=$2', colname)
USING newvalue, keyvalue;
Run Code Online (Sandbox Code Playgroud)
或仅与格式功能
EXECUTE format('UPDATE tbls SET %I=%L WHERE key=%L', colname, newvalue, keyvalue);
Run Code Online (Sandbox Code Playgroud)
不引用动态SQL a)不应该工作(语法错误失败),b)对sql注入不安全.