动态查询无法正常工作。它抛出错误。
我尝试了相同的方法,并使用了%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)||'}}'
答案 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。
(您还需要对整个字符串加双引号,以便在动态语句中对字符串进行单引号。)