字符串需要用作列

时间:2019-03-26 09:27:17

标签: postgresql

动态查询无法正常工作。它抛出错误。

我尝试了相同的方法,并使用了%I,%L,%S。

do $$
declare
v_out text;
v_inp text := '{"id" : "1"'||trim(col1)||'}';
begin
execute format('select %s from tab',v_inp) into v_out;
raise info 'out: %',v_out;
exception
when others then
raise info  'error mssg %',sqlerrm;
end $$;

获取错误:列“ col1”不存在

实际:表和colmn都存在并且查询工作正常

从标签中选择'{“ id”:“ 1”'|| trim(col1)||'}}'

1 个答案:

答案 0 :(得分:0)

问题是这样的声明:

v_inp text := '{"id" : "1"'||trim(col1)||'}';

Postgres将在变量分配时执行/解析trim(col1),因为该位不是字符串的一部分,它是一个sql命令,其结果是与分配给该字符串的字符串连接的结果变量。由于此时没有“ col1”,因此它会失败。

由于要创建动态查询,因此希望稍后在读取表期间而不是在变量分配时执行该查询。因此,该位必须是字符串,在执行动态语句时该字符串将变为sql。

可以通过转义单引号(通过双引号)来实现:

DO $$
DECLARE
        var1 TEXT := '''{"id":"'' || TRIM(t) || ''"}''';
        query TEXT;
BEGIN
        query := FORMAT('SELECT %s FROM table', var1);
        RAISE NOTICE '%', query;
END $$

结果:

SELECT '{"id":"' || TRIM(t) || '"}' FROM table

(或者您的情况是v_inp text := '''{"id" : "1"''||trim(col1)||''}''';

当postgres执行该操作时,您将获得一个有效的查询。对要连接的位用双引号将单引号放在实际命令中,以中断字符串并在那一点执行TRIM。

(您还需要对整个字符串加双引号,以便在动态语句中对字符串进行单引号。)