sql-server - T-SQL 如何从带有命令列表的参数中获取最后一个 T-Sql 命令
问题描述
我的应用程序在一个参数中向 sql 发送了一些命令,我需要仅包含最后一个命令的文本子串并执行它。我知道,最后一个命令是从“select”开始的,而不是从“declare”开始,最后一个语句可能很复杂,例如内部选择,或者只是“select * from ....”
在我的应用程序(系统报告)中,管理员用户准备了语句列表(类似于在 t-sql 中创建过程),最后一条语句始终是带有结果的表。我的任务是通过 SQL 代理使用这些语句作为夜间 XML 格式的预准备结果。我需要添加到最后一条语句“select( xml 路径的最后一条语句 ('Table'))”。如何找到最后一条语句。
例如
set @commands =
'select * from table1
select A, b=(select top 1 id from table3 where id >10) from table2
select Number, count(*) from table3 group by Number
select *, b=(select top 1 id from table3 where id >10) from table2), x.Total
from table4 y
inner join (select Id, date from table5) x on x.Id = y.Id
'
declare @lastCommand = ....
execute (@lastCommand) ```
解决方案
代码找到最后一个 SELECT 语句。我假设 SELECT 语句中的任何重复单词“SELECT”总是在圆括号之间,例如
select *, b=(select top 1 id from table3 where id >10), x.Total from table4 y inner join (select Id, date from table5) x on x.Id = y.Id'。
代码创建命令副本并通过用空格替换字母“S”来破坏 SELECT 语句内部的任何“选择”字。然后查找最后一条语句位置的程序是在命令副本中搜索最后一个“选择”字。
declare @commands varchar(max)
set @commands =
'select * from table1
select A, b=(select top 1 id from table3 where id >10) from table2
select Number, count(*) from table3 group by Number
select *, b=(select top 1 id from table3 where id >10), x.Total
from table4 y
inner join (select Id, date from table5) x on x.Id = y.Id
'
declare @CopyOfCommands varchar(max)
set @CopyOfCommands = @commands
declare @lenCommandsText int
declare @i int = 0
declare @brockets int = 0
set @lenCommandsText = LEN(@CopyOfCommands)
while (@i < @lenCommandsText)
--Replacing any 'select' word to ' elect' between brockets
begin
if ((SUBSTRING(@CopyOfCommands,@i,1)) = '(')
set @brockets = @brockets + 1
else if ((SUBSTRING(@CopyOfCommands,@i,1)) = ')')
set @brockets = @brockets - 1
else if ((UPPER(SUBSTRING(@CopyOfCommands,@i,1))) = 'S' and @brockets > 0)
set @CopyOfCommands = SUBSTRING(@CopyOfCommands,0,@i) + ' ' + SUBSTRING(@CopyOfCommands,@i+1,@lenCommandsText - @i)
set @i = @i + 1
end
-- Finding a position of the word 'SELECT' in the reverse text of commands (Word 'SELECT' => 'TCELES'). Converting result to reverse position in original commands list
declare @lastCommand varchar(max)
set @lastCommand = (select SUBSTRING(@commands,@lenCommandsText - CHARINDEX('TCELES',Upper(REVERSE(@CopyOfCommands)))-4,CHARINDEX('TCELES',Upper(REVERSE(@CopyOfCommands)))+5))
select @lastCommand
--execute (@lastCommand)
推荐阅读
- nested - 使用 for...in chrome 控制台嵌套对象键值对返回未定义
- javascript - Vue - 更新子组件而不更新父组件。最好的方法?
- sql - 如何计算“夜班”小时数Postgresql
- c# - 如何正确访问我的项目所依赖的另一个项目中的本地化资源
- ruby - Cucumber:如何打印/获取所有已执行的场景计数,状态为“执行报告 - 总计:5,通过:4,失败:1”
- android - 在改造中的 ssl 问题后使用 picasso android 加载图像表单 URL 时出现错误 HTTP 504
- sql-server - 来自类似 T-SQL 查询的不同结果
- php - SQLSTATE [22P02]:无效的文本表示:7 错误:整数的输入语法无效
- google-cloud-platform - 使用 Statuspage 监控 Google Cloud Platform
- wordpress - Wordpress 插件 ID 帖子