Postgresql - 在动态查询中转义单引号

Postgresql - Escape single qoutes in dynamic queries

Version: PG-13.3 with pgAdmin4

如何在函数的动态 SQL 中转义单引号?

这是我的代码

DO $$
DECLARE
    uuid text;
BEGIN
        uuid := 'X-2132135671';
        -- Create a function using above id
        EXECUTE format(E'CREATE FUNCTION system_uid() RETURNS text AS \'SELECT %L\' LANGUAGE SQL IMMUTABLE;', uuid);
END;
$$ LANGUAGE plpgsql;

这里当我尝试执行代码时出现如下错误

ERROR:  syntax error at or near "X"
LINE 1: ...UNCTION system_uid() RETURNS text AS 'SELECT 'X-21321356...
                                                             ^
QUERY:  CREATE FUNCTION system_uid() RETURNS text AS 'SELECT 'X-2132135671'' LANGUAGE SQL IMMUTABLE;
CONTEXT:  PL/pgSQL function inline_code_block line 7 at EXECUTE
SQL state: 42601

请建议正确的方法。

使用多个"dollar quotes":

DO $$
DECLARE
    uuid text;
BEGIN
  uuid := 'X-2132135671';
  -- Create a function using above id
  EXECUTE format($f$CREATE FUNCTION system_uid() RETURNS text AS $s$SELECT %L$s$ LANGUAGE SQL IMMUTABLE;$f$, uuid);
END;
$$ LANGUAGE plpgsql;

演示:db<>fiddle

除了嵌套的“美元引号”之外,我建议在执行语句本身之前构建您想要的 SQL 语句,并对该语句执行“加注 notice/log”。这样做可以让您看到实际的陈述 运行。这样,当发生错误时,您可以看到您 运行 的确切语句。类似于:

do $do$
declare
    k_base constant text :=
           $stmt$
               create function system_uid() 
                 returns text 
                 language sql immutable                      
               as $$ select %L; $$;
           $stmt$;
     
    l_uuid text;
    l_stmt text; 

begin
        l_uuid := 'X-2132135671';
        -- create a function using above id
        l_stmt = format (k_base, l_uuid);
        raise notice e'Running Statement:\n%',l_stmt; 
        execute l_stmt;  
end;
$do$;

注意:UUID 是 Postgres 中定义的数据类型,因此您应避免将其用作 column/variable 名称。它有一个预定义的结构(32 位十六进制数字)。小心不要引起混淆。