如何从查询中的字段运行更新语句
Posted
技术标签:
【中文标题】如何从查询中的字段运行更新语句【英文标题】:how to run Update statement from field in a query 【发布时间】:2020-12-08 12:15:10 【问题描述】:我有一个返回 1 列的查询 此列是包含更新语句的字符串 如何通过运行此查询来运行所有更新?
SELECT 'UPDATE TOP (' + CAST([Deploy] AS varchar(10)) + ') TRV
SET TRV.SourceStationID = ' + CAST([Station_From] AS varchar(10)) + ',
TRV.MissingStationSourceCode = 888
FROM [Tickets].[dbo].TCK_STG_Fact_Contract_Magnetic_Travels1 TRV
LEFT OUTER JOIN [Tickets].[dbo].[TCK_DWH_Dim_Date] DAT ON CAST(TRV.[ExitDate] AS DATE) = CAST(DAT.Date AS DATE)
LEFT OUTER JOIN [Tickets].[dbo].[TCK_DWH_Dim_Manual_PartOfDay] POD ON DATEPART(HOUR,TRV.[ExitDate]) = POD.PartOfDay_Hour
WHERE DAT.Day_Type_Code = ' + CAST([Day_Type_Code] AS varchar(10)) + '
AND POD.PartOfDay_Code = ' + CAST([PartOfDay_Code] AS varchar(10)) + '
AND TRV.DestinationStation = ' + CAST([DestinationStation] AS varchar(10)) + '
AND TRV.SourceStationID IS NULL'
FROM [Tickets].[dbo].[TCK_TMP_Fact_ALL_Travels_History_FromMissing]
【问题讨论】:
这是动态 SQL。您需要使用exec
(或者更好的是exec spexecutesql
来运行代码。
这看起来像一个严重的XY Problem。您为什么不从头开始,告诉我们您在此处真正想要达到的目标。
另外,带有TOP
的UPDATE
很奇怪,但是带有TOP
且没有ORDER BY
的UPDATE
是非常 不一致的结果(不是说你可以在UPDATE
中有一个ORDER BY
,以及为什么有一个TOP
很奇怪)。
我支持这似乎是XY Problem,我们需要了解您的真正目标是什么。
@Gines:您需要使用游标遍历结果并为每一行使用EXEC
(或sp_executesql
)。但我在这里和拉努在一起。如果您在此处解释您尝试解决的潜在问题,您将获得更好的帮助。
【参考方案1】:
在您阅读此答案之前,我想先做几件事:
-
我仍然相信这是XY Problem,我们应该真正回答您遇到的真正问题;那是什么(你还没有告诉我们)。
我已经按字面意思回答了这个问题。这将远远达不到性能,它仍然没有得到
TOP
的订单。
这是未经测试,因为缺少样本数据。
无论如何,您可以使用CURSOR
和参数化 动态语句来做到这一点。我猜测您的数据类型,由于我没有样本数据,我无法测试这是否有效。如果动态语句出错,您必须自己解决问题,因为我无法运行它(显然是在修复所有位置的数据类型之后)。
我还删除了 3 部分命名,并在批处理之前强制连接到 Tickets
数据库。
USE Tickets;
GO
DECLARE @SQL nvarchar(MAX),
@CRLF nchar(2) = NCHAR(13) + NCHAR(10);
SET @SQL = N'UPDATE TOP (@Deploy) TRV' + @CRLF + --Don't forget, this translates to @Deploy Arbirtrary rows, not the "top" @Deploy rows, due to a lack of any ordering.
N'SET TRV.SourceStationID = @StationFrom,' + @CRLF +
N' TRV.MissingStationSourceCode = 888' + @CRLF +
N'FROM [dbo].TCK_STG_Fact_Contract_Magnetic_Travels1 TRV' + @CRLF +
N' LEFT OUTER JOIN [dbo].[TCK_DWH_Dim_Date] DAT ON CAST(TRV.[ExitDate] AS DATE) = CAST(DAT.Date AS DATE)' + @CRLF +
N' LEFT OUTER JOIN [dbo].[TCK_DWH_Dim_Manual_PartOfDay] POD ON DATEPART(HOUR,TRV.[ExitDate]) = POD.PartOfDay_Hour' + @CRLF +
N'WHERE DAT.Day_Type_Code = @DayTypeCode' + @CRLF +
N' AND POD.PartOfDay_Code = @PartOfDayCode' + @CRLF +
N' AND TRV.DestinationStation = @DestinationStation' + @CRLF +
N' AND TRV.SourceStationID IS NULL;';
DECLARE Missing_Cursor CURSOR FAST_FORWARD FOR
SELECT Deploy,
Station_From,
Day_Type_Code,
PartOfDay_Code,
DestinationStation
FROM [dbo].[TCK_TMP_Fact_ALL_Travels_History_FromMissing]
DECLARE @Deploy int, --Assumed data type, due to being used in TOP
@StationFrom int, --Guessed Datatype
@DayTypeCode int, --Guessed Datatype
@PartOfDayCode int, --Guessed Data Type
@DestinationStation varchar(10); --Guessed Data Type
OPEN Missing_Cursor;
FETCH NEXT FROM Missing_Cursor
INTO @Deploy, @StationFrom, @DayTypeCode, @PartOfDayCode, @DestinationStation;
WHILE @@FETCH_STATUS = 0 BEGIN
--Uses same assumed data types
EXEC sys.sp_executesql @SQL, N'@Deploy int, @StationFrom int, @DayTypeCode int, @PartOfDayCode int, @DestinationStation varchar(10)', @Deploy, @StationFrom, @DayTypeCode, @PartOfDayCode, @DestinationStation;
FETCH NEXT FROM Missing_Cursor
INTO @Deploy, @StationFrom, @DayTypeCode, @PartOfDayCode, @DestinationStation;
END
CLOSE Missing_Cursor;
DEALLOCATE Missing_Cursor;
【讨论】:
【参考方案2】:这里的建议是同时完成的。 解决性能问题的方法是添加 2 个索引 谢谢大家的帮助
【讨论】:
以上是关于如何从查询中的字段运行更新语句的主要内容,如果未能解决你的问题,请参考以下文章