【发布时间】:2019-11-18 11:15:21
【问题描述】:
我正在使用STUFF 函数准备select 查询。
给定:
DECLARE @GeoID VARCHAR(MAX) = '1,2,3,4'
DECLARE @TableName VARCHAR(100) = 'Table1'
SELECT STUFF((SELECT ' UNION ALL SELECT t.* FROM ['+@TableName+'] t WHERE ( Select GeoPath from dbo.TableGeo Where GeoID = '''+f.Item+''').STIntersects(geometry::Point(ISNULL(Lat,''''), ISNULL(Long,''''),4326))=1'
FROM f_Split(@GeoID,',') f
FOR XML PATH('')),1,11,'')
这里我想执行select union all查询而不将其存储到变量中然后执行。
【问题讨论】:
-
"这里我想执行 select union all 查询,不存储到变量中然后执行。" 你不能;创建动态语句时,您必须首先将其放入变量中,因为您无法将表达式传递给
sp_executesql以获取参数(包括@stmt)。此外,您确实需要解决您遇到的注入问题。'...['+@TableName+']...'是不安全的。如果@TableName的值为:'sys].[tables]; DROP TABLE Table1; --',你认为会发生什么? Dos and Don'ts of Dynamic SQL -
您不是在执行 STUFF 查询,而是在使用 XML 技术来连接刚刚拆分的字符串。你想做什么?您想要解决的实际问题是什么?您试图从该连接中产生什么?
-
例如,这个查询只有一个表,为什么要使用UNION ALL呢?如果您想搜索特定的 GeoID,为什么不使用
IN子句? -
@MAK 我认为这段代码太复杂了,看不到它应该做什么。为什么
IN与STIntersects有任何关系?它将GeoID与'1,2,3,4'中的值进行比较。本质上,它是一个昂贵的GeoID in (1,2,3,4),它受到 SQL 注入问题的影响。至于STIntersects,尝试使用可能包含空值的单个点。当它不抛出时,它会非常慢。 -
@MAK 你可以写
select t.* from ThatTable t inner join TableGeo g g on t.ThatPoint.Intersects(g.GeoPath) where GeoID IN (1,2,3,4)。要点应该是由索引覆盖的实际geography列,以获得任何性能优势。 点 与开放路径相交的机会基本上为 0,除非它与路径的节点之一完全匹配。如果路径不包含开放路径,STContains会更好。
标签: sql-server tsql sql-server-2012