转义 PostgreSQL 插入语句中的特殊字符

Escaping Special Characters in PostgreSQL Insert Statement

我正在编写一个函数,需要我在 PostgreSQL 数据库 table 中存储一些 JavaScript 代码(这是必需的)。我正在寻找一种 "Lazy" 方法来执行此操作,而无需修改我的 PostgreSQL 插入语句以在 JavaScript 代码中可能出现的每个实例中转义特殊字符。我主要是想避免在 JavaScript 代码变长的情况下进行转义。因为这可能很快就会变得有点混乱。 PostgreSQL 似乎提供以下功能:

  1. quote_literal()
  2. quote_ident()

参考:PostgreSQL String Formatting Functions

测试了这两个常见错误后,我 运行 遇到以下错误:

错误:“”处或附近未终止的引号标识符:真

乍一看,我的问题似乎出在格式化的 JavaScript 文本本身。

有没有一种 "Lazy" 方法可以让我避免转义所有这些特殊字符而无需手动执行此操作?本质上,我想将这段代码转储到一个变量中,并使用存储的变量执行插入,而无需(理想情况下)或对存储的 JScript 文本进行最少的修改。

下面是我的代码的示例:

CREATE OR REPLACE FUNCTION abc.my_function(text, text, text, text, text[])
     RETURNS void AS $body$
DECLARE
     -- Variable Declarations here
     jscript TEXT := quote_ident('/* JScript Comments Here*/ $(document).ready(function(){
     // Initialize Datatable ...
     $('#Index').Datatable({
     "paging": true, // comment here
     "responsive": true, // comment here 
     "pageLength": 25, // comment here
     "columnDefs": [ {
     ...
     ...
     ...
          }]
     });
'); 


BEGIN
     ...
     ...
     ...
     -- Insert static HTML
     execute 'Insert into abc.my_table(file, data, gen_flag) values('||'''main.js||','||jscript||','|| '''N''' || ')';
     ...
     ...
     ...


END; 
$body$
     LANGUAGE 'plpgsql' VOLATILE;

主要问题是,您使用的 quote_ident 用于引用 标识符 (列名,table 名称,...),其中您应该使用 quote_literal 用于正确引用文字值。

要声明您的变量并分配值,您可以使用第二级美元引用,这样您就不必担心值中的单引号:

declare 
  jscript TEXT := $js$
     /* JScript Comments Here*/
     $(document).ready(function(){
       // Initialize Datatable ...
       $(#Index').Datatable({
       "paging": true, // comment here
       "responsive": true, // comment here 
       "pageLength": 25, // comment here
       "columnDefs": [ {
       ...
       ...
       ...}]
     });
  $js$;

动态 SQL 最好使用 format() 函数创建,该函数负责正确引用:

execute format('Insert into abc.my_table(file, data, gen_flag) values(%L, %L, %L), 'main.js',jscript, 'N')';

但是你根本不需要动态SQL,你可以这样写:

insert into abc.my_table(file, data, gen_flag) values('main.js', jscript, 'N');

在线演示:https://dbfiddle.uk/?rdbms=postgres_10&fiddle=81b36bb1d3f246637186a419a9b337d4