【问题标题】:Execute STUFF return query string without storing into variable执行 STUFF 返回查询字符串而不存储到变量中
【发布时间】: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 我认为这段代码太复杂了,看不到它应该做什么。为什么INSTIntersects 有任何关系?它将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


【解决方案1】:

当您将内置的自定义拆分功能切换到最新版本的 SQL Server 时,该代码有效:

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.value+''').STIntersects(geometry::Point(ISNULL(Lat,''''), ISNULL(Long,''''),4326))=1' 
             FROM string_split(@GeoID,',') f
             FOR XML PATH('')),1,11,'')

【讨论】:

  • 至少解决了巨大的注入问题。
  • 另外,OP 明确标记了sql-server-2012STRING_SPLIT 在 2012 年不存在。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-24
  • 1970-01-01
  • 2021-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多