Sql 路由网络功能问题
继a之后,我在PL/PgSQL中使用Sql 路由网络功能问题,sql,sql-server,postgresql,plpgsql,Sql,Sql Server,Postgresql,Plpgsql,继a之后,我在PL/PgSQL中使用EXECUTE成功运行了一些动态SQL,但它似乎没有达到预期效果 以下代码是我创建的plpgsql函数的一部分。这是为了找到位于同一轨道上的每个点,并为每个点找到其最近的点,以便最终我将在所有轨道之间创建一个网络。由于某些原因,它不能正常工作 i表示当前曲目的编号 DECLARE _r record; i int := 0; source_geom character varying; target_geom characte
EXECUTE
成功运行了一些动态SQL,但它似乎没有达到预期效果
以下代码是我创建的plpgsql函数的一部分。这是为了找到位于同一轨道上的每个点,并为每个点找到其最近的点,以便最终我将在所有轨道之间创建一个网络。由于某些原因,它不能正常工作
i表示当前曲目的编号
DECLARE
_r record;
i int := 0;
source_geom character varying;
target_geom character varying;
BEGIN
WHILE i < 3 --DEPENDS ON THE NUMBER OF TRACKS
LOOP
FOR _r IN EXECUTE ' 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 ' || quote_ident (geom_table) ||' AS a INNER JOIN ' || quote_ident(geom_table) || ' 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 '
LOOP
source_geom := _r.source;
target_geom := _r.target;
EXECUTE 'update ' || quote_ident(geom_table) ||
' SET source = ''' || source_geom ||'''
, target = ''' || target_geom || '''
WHERE ' || quote_ident(gid_cname) || ' = ' || _r.id;
END LOOP;
i = i + 1;
END LOOP;
RETURN 'OK';
END;
不要使用
| |
,引用文字
引用标识
尝试使用格式()
和执行。。。使用
看
当查询在普通SQL中工作时,PL/PgSQL中失败的常见原因是名称与PL/PgSQL中声明的变量冲突,但这不适用于动态EXECUTE
查询,因为它们不能引用PL/PgSQL函数中声明的变量
在这种情况下,我认为在将其转换为动态查询时更可能出错
尝试替换:
EXECUTE 'SELECT ...'
与:
其中query\u text
是DECLARE
d作为text
前面的。查看您生成的查询文本是否与手动运行的查询匹配
如果动态SQL的格式更好,那么调试它就容易多了。尝试更类似于:
EXECUTE format(
$query$
SELECT a.%1$I AS id,
st_astext(a.%2$I) AS source,
st_astext(b.%2$I) AS target,
ST_Distance(a.%2$I, b.%2$I) AS dist_ft
FROM %3$I AS a INNER JOIN %3$I As b
ON ST_DWithin(a.%2$I , b.%2$I, 1000)
WHERE b.%1$I > a.%1$I
AND b.%4$I = 0 AND a.%4$I = 0
ORDER BY dist_ft
LIMIT %5$L
$query$,
gid_cname, geo_cname, geom_table, tid_cname, 1
);
没有必要使用
子句,因为没有传递文本参数。我看到一个非常小的区别:限制1。如果您在动态SQL中省略了这一点,这会解决问题吗
致以亲切的问候
是的,是的,我已经看到了答案。感染,谢谢你的建议。但是,你知道为什么它不能在plpgsql中正常工作吗?因为我已经试了好几个小时了。或者你能给我解释一下执行过程中的具体原因吗?@Ryan啊,这是你之前的问题。很多问题都会出现,所以很容易忘记,尤其是当代码不同时。如果你提到它/链接到它,会有帮助的。正如我所说,在将函数转换为动态SQL时,很可能会出错;尝试更新答案中的建议。@Ryan也要确保它实际上不起作用;可能是UPDATE
s实际上是问题所在,因此外部循环查询可以工作,但您从未看到任何结果。再次,添加raisenotice
行以进行验证。@Ryan执行中的所有FOR\u r都是执行查询文本,对于查询返回的每一行,将该行存储在记录变量\r
中,然后执行循环。当您说不能正常工作时,您的确切意思是什么?错误?没有结果?炸掉你的猫?这意味着它只给出很少的结果,而不是预期的全部结果,并且没有全部纠正。
query_text = 'SELECT ...'
RAISE NOTICE 'About to run: %',query_text;
EXECUTE query_text;
EXECUTE format(
$query$
SELECT a.%1$I AS id,
st_astext(a.%2$I) AS source,
st_astext(b.%2$I) AS target,
ST_Distance(a.%2$I, b.%2$I) AS dist_ft
FROM %3$I AS a INNER JOIN %3$I As b
ON ST_DWithin(a.%2$I , b.%2$I, 1000)
WHERE b.%1$I > a.%1$I
AND b.%4$I = 0 AND a.%4$I = 0
ORDER BY dist_ft
LIMIT %5$L
$query$,
gid_cname, geo_cname, geom_table, tid_cname, 1
);