如何从查询中的字段运行更新语句

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。您为什么不从头开始,告诉我们您在此处真正想要达到的目标。 另外,带有TOPUPDATE 很奇怪,但是带有TOP 且没有ORDER BYUPDATE非常 不一致的结果(不是说你可以在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 个索引 谢谢大家的帮助

【讨论】:

以上是关于如何从查询中的字段运行更新语句的主要内容,如果未能解决你的问题,请参考以下文章

运行MongoDB查询以更新循环中的序列字段

Access 中的 SQL 查询更新多个字段

使用子查询更新语句

SQL语句把同一个表中的a字段中的数据复制到另一个字段b中

SQLSERVER如何在数据库里根据某个字段,查出该表名字

数据库 查询语句中如何让同1个字段中的相同数据只显示1次