plpgsql动态添加select查询到变量
plpgsql dynamically add select query to variable
我正在尝试遍历具有许多模式的 varchar 数组并动态构建大量 select 语句。 1st 2 raise 通知工作正常,但我不知道如何将动态 select 语句附加到一个大的 select.
理想情况下我想要这样的东西
SELECT
st_asmvtgeom(st_transform(t.geom,3857),b.geom) AS geom
,parcel_id
FROM schema1.parcel t
JOIN bounds b
ON st_intersects(t.geom,st_transform(b.geom,4269))
UNION
SELECT
st_asmvtgeom(st_transform(t.geom,3857),b.geom) AS geom
,parcel_id
FROM schema2.parcel t
JOIN bounds b
ON st_intersects(t.geom,st_transform(b.geom,4269))
代码
DO
$do$
DECLARE
a varchar[] := array['schema1','schema2'];
i integer;
slct varchar;
BEGIN
FOR i IN 1 .. array_upper(a, 1)
LOOP
RAISE NOTICE '%', a[i];
RAISE NOTICE 'SELECT st_asmvtgeom(st_transform(t.geom,3857),b.geom) AS geom,parcel_id
FROM %.parcel t join bounds b
on st_intersects(t.geom,st_transform(b.geom,4269))',a[i];
EXECUTE 'SELECT st_asmvtgeom(st_transform(t.geom,3857),b.geom) AS geom,parcel_id
FROM %.parcel t join bounds b
on st_intersects(t.geom,st_transform(b.geom,4269))',a[i] into slct;
END LOOP;
END
$do$;
错误
ERROR: query "SELECT 'SELECT st_asmvtgeom(st_transform(t.geom,3857),b.geom) AS geom,parcel_id
FROM %.parcel t join bounds b
on st_intersects(t.geom,st_transform(b.geom,4269))',a[i]" returned 2 columns
CONTEXT: PL/pgSQL function inline_code_block line 17 at EXECUTE
SQL state: 42601
更新了查询和错误
EXECUTE 'SELECT st_asmvtgeom(st_transform(t.geom,3857),b.geom) AS geom,parcel_id
FROM .parcel t join bounds b
on st_intersects(t.geom,st_transform(b.geom,4269))' into slct
using a[i];
错误
ERROR: syntax error at or near ""
LINE 2: FROM .parcel t join bounds b
^
QUERY: SELECT st_asmvtgeom(st_transform(t.geom,3857),b.geom) AS geom,parcel_id
FROM .parcel t join bounds b
on st_intersects(t.geom,st_transform(b.geom,4269))
CONTEXT: PL/pgSQL function inline_code_block line 17 at EXECUTE
SQL state: 42601
如果您的架构数量有限,那么您可以使用 SQL 之类的
SELECT ...
FROM schema1.parcel t
JOIN bounds b
ON st_intersects(t.geom,st_transform(b.geom,4269))
WHERE 'schema1' = any(array['schema1','schema2'])
UNION
SELECT ...
FROM schema2.parcel t
JOIN bounds b
ON st_intersects(t.geom,st_transform(b.geom,4269))
WHERE 'schema2' = any(array['schema1','schema2'])
UNION
SELECT ...
FROM schema3.parcel t
JOIN bounds b
ON st_intersects(t.geom,st_transform(b.geom,4269))
WHERE 'schema3' = any(array['schema1','schema2'])
如果您想以动态方式构建查询,那么您可以在单个查询中完成:
select
string_agg(format($$SELECT * FROM %I.parcel t
JOIN bounds b
ON st_intersects(t.geom,st_transform(b.geom,4269)
$$, shm), e'UNION\n') as sql
FROM unnest(array['schema1','schema2']) as shm;
┌───────────────────────────────────────────────────────┐
│ sql │
├───────────────────────────────────────────────────────┤
│ SELECT * FROM schema1.parcel t ↵│
│ JOIN bounds b ↵│
│ ON st_intersects(t.geom,st_transform(b.geom,4269)↵│
│ UNION ↵│
│ SELECT * FROM schema2.parcel t ↵│
│ JOIN bounds b ↵│
│ ON st_intersects(t.geom,st_transform(b.geom,4269)↵│
│ │
└───────────────────────────────────────────────────────┘
使用此查询的结果作为 EXECUTE
语句的参数。
几个笔记。
您可以使用美元引号引起来的字符串来保持语法高亮显示。比较
select 'select
*
from foo';
select $$select
*
from foo$$;
使用 format()
函数和 %I
标识符占位符:
select format('%s %I', 'FooBar', 'FooBar');
┌─────────────────┐
│ format │
├─────────────────┤
│ FooBar "FooBar" │
└─────────────────┘
我正在尝试遍历具有许多模式的 varchar 数组并动态构建大量 select 语句。 1st 2 raise 通知工作正常,但我不知道如何将动态 select 语句附加到一个大的 select.
理想情况下我想要这样的东西
SELECT
st_asmvtgeom(st_transform(t.geom,3857),b.geom) AS geom
,parcel_id
FROM schema1.parcel t
JOIN bounds b
ON st_intersects(t.geom,st_transform(b.geom,4269))
UNION
SELECT
st_asmvtgeom(st_transform(t.geom,3857),b.geom) AS geom
,parcel_id
FROM schema2.parcel t
JOIN bounds b
ON st_intersects(t.geom,st_transform(b.geom,4269))
代码
DO
$do$
DECLARE
a varchar[] := array['schema1','schema2'];
i integer;
slct varchar;
BEGIN
FOR i IN 1 .. array_upper(a, 1)
LOOP
RAISE NOTICE '%', a[i];
RAISE NOTICE 'SELECT st_asmvtgeom(st_transform(t.geom,3857),b.geom) AS geom,parcel_id
FROM %.parcel t join bounds b
on st_intersects(t.geom,st_transform(b.geom,4269))',a[i];
EXECUTE 'SELECT st_asmvtgeom(st_transform(t.geom,3857),b.geom) AS geom,parcel_id
FROM %.parcel t join bounds b
on st_intersects(t.geom,st_transform(b.geom,4269))',a[i] into slct;
END LOOP;
END
$do$;
错误
ERROR: query "SELECT 'SELECT st_asmvtgeom(st_transform(t.geom,3857),b.geom) AS geom,parcel_id
FROM %.parcel t join bounds b
on st_intersects(t.geom,st_transform(b.geom,4269))',a[i]" returned 2 columns
CONTEXT: PL/pgSQL function inline_code_block line 17 at EXECUTE
SQL state: 42601
更新了查询和错误
EXECUTE 'SELECT st_asmvtgeom(st_transform(t.geom,3857),b.geom) AS geom,parcel_id
FROM .parcel t join bounds b
on st_intersects(t.geom,st_transform(b.geom,4269))' into slct
using a[i];
错误
ERROR: syntax error at or near ""
LINE 2: FROM .parcel t join bounds b
^
QUERY: SELECT st_asmvtgeom(st_transform(t.geom,3857),b.geom) AS geom,parcel_id
FROM .parcel t join bounds b
on st_intersects(t.geom,st_transform(b.geom,4269))
CONTEXT: PL/pgSQL function inline_code_block line 17 at EXECUTE
SQL state: 42601
如果您的架构数量有限,那么您可以使用 SQL 之类的
SELECT ...
FROM schema1.parcel t
JOIN bounds b
ON st_intersects(t.geom,st_transform(b.geom,4269))
WHERE 'schema1' = any(array['schema1','schema2'])
UNION
SELECT ...
FROM schema2.parcel t
JOIN bounds b
ON st_intersects(t.geom,st_transform(b.geom,4269))
WHERE 'schema2' = any(array['schema1','schema2'])
UNION
SELECT ...
FROM schema3.parcel t
JOIN bounds b
ON st_intersects(t.geom,st_transform(b.geom,4269))
WHERE 'schema3' = any(array['schema1','schema2'])
如果您想以动态方式构建查询,那么您可以在单个查询中完成:
select
string_agg(format($$SELECT * FROM %I.parcel t
JOIN bounds b
ON st_intersects(t.geom,st_transform(b.geom,4269)
$$, shm), e'UNION\n') as sql
FROM unnest(array['schema1','schema2']) as shm;
┌───────────────────────────────────────────────────────┐
│ sql │
├───────────────────────────────────────────────────────┤
│ SELECT * FROM schema1.parcel t ↵│
│ JOIN bounds b ↵│
│ ON st_intersects(t.geom,st_transform(b.geom,4269)↵│
│ UNION ↵│
│ SELECT * FROM schema2.parcel t ↵│
│ JOIN bounds b ↵│
│ ON st_intersects(t.geom,st_transform(b.geom,4269)↵│
│ │
└───────────────────────────────────────────────────────┘
使用此查询的结果作为 EXECUTE
语句的参数。
几个笔记。
您可以使用美元引号引起来的字符串来保持语法高亮显示。比较
select 'select
*
from foo';
select $$select
*
from foo$$;
使用 format()
函数和 %I
标识符占位符:
select format('%s %I', 'FooBar', 'FooBar');
┌─────────────────┐
│ format │
├─────────────────┤
│ FooBar "FooBar" │
└─────────────────┘