gpt4 book ai didi

sql - 函数中的临时表和循环

转载 作者:行者123 更新时间:2023-11-29 12:47:20 25 4
gpt4 key购买 nike

我在 plpgsql 中有一个函数,它创建一个临时表,然后它有一个循环。问题是每次循环时它也会执行创建临时表的部分,因此会弹出一个错误提示;

ERROR:  relation "tmpr" already exists
CONTEXT: SQL statement "CREATE TEMPORARY TABLE tmpr (
id int,
source geometry,
target geometry,
dist_ft character varying
)"

有什么办法可以防止部分代码被多次执行?
您可以在下面找到代码:

DECLARE
_r record;
t record;
i int := 0;
j int := 1;
count int := 0;
source_geom character varying;
target_geom character varying;
BEGIN
BEGIN
CREATE TEMPORARY TABLE tmpr (
id int,
source geometry,
target geometry,
dist_ft character varying
);
END;

BEGIN
CREATE TEMPORARY TABLE tmp (
ogc_fid int,
wkb_geometry character varying,
track_fid int
);
END;
-- END IF;
WHILE i < 3 --DEPENDS ON THE NUMBER OF TRACKS
LOOP

--j := 1;

--WHILE j < 29 --DEPENDS ON THE NUMBER OF TRACK POINTS
--LOOP

EXECUTE 'INSERT INTO tmp (ogc_fid, wkb_geometry, track_fid)
SELECT '|| quote_ident(gid_cname) ||' , ' ||quote_ident(geo_cname)||' , ' || quote_ident(tid_cname) ||'
FROM ' ||quote_ident(geom_table)|| '
WHERE ' ||quote_ident(tid_cname)|| ' = ' || i;

FOR _r IN EXECUTE
' SELECT *'
||' FROM tmp'

LOOP

EXECUTE 'INSERT INTO tmpr (id, source, target, dist_ft)
SELECT a.'|| quote_ident(gid_cname) || ' AS id,'
|| ' st_astext( a.'||quote_ident(geo_cname)||') AS source,'
|| ' st_astext(b.'||quote_ident(geo_cname)||') AS target, '
|| ' ST_Distance(a.'||quote_ident(geo_cname) || ' , b.'||quote_ident(geo_cname)||') As dist_ft '
|| ' FROM tmp AS a INNER JOIN tmp As b ON ST_DWithin(a.'||quote_ident(geo_cname)|| ', b.'||quote_ident(geo_cname)|| ',1000)'
|| ' WHERE b.'||quote_ident(gid_cname)|| ' > a.'||quote_ident(gid_cname)|| ' AND b.'||quote_ident(tid_cname)|| ' = '||i|| 'AND a.'||quote_ident(tid_cname)|| ' = '||i||
' ORDER BY dist_ft '
|| ' Limit 1 ';

--source_geom := temp.source;
--target_geom := temp.target;

EXECUTE 'update ' || quote_ident(geom_table) ||
' SET source = tmpr.source
, target = tmpr.target
FROM tmpr
WHERE ' || quote_ident(gid_cname) || ' = tmpr.id';

EXECUTE 'delete from tmpr';

END LOOP;

--j = j + 1;

--END LOOP;
EXECUTE 'delete from tmp';

i = i + 1;

END LOOP;

RETURN 'OK';
END;

最佳答案

您可以使用 IF NOT EXISTS避免异常的子句(在 pg 9.1 中引入):

CREATE TEMPORARY TABLE <b>IF NOT EXISTS</b> tmpr (...);

这种情况你最好检查表中是否有行:

IF EXISTS (SELECT 1 FROM tmpr) THEN  -- table itself exists after above command
DELETE FROM tmpr;
END IF;

为避免函数的后续调用发生冲突,或者通常情况下,如果您在函数完成后不再需要临时表,请添加 ON COMMIT DROP:

CREATE TEMPORARY TABLE IF NOT EXISTS tmpr (...) <b>ON COMMIT DROP;</b>

如果您在单个事务 中重复调用该函数,这仍然会失败。在这种情况下,您可以将显式 DROP TABLE 语句添加到函数的末尾。

关于sql - 函数中的临时表和循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13019369/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com