SQL服务器:存储过程中的更新发生了一件奇怪的事情

SQL Server : a strange thing happens with an Update inside a stored procedure

我在 SQL Server 2005 中有一个存储过程,里面的代码是这样的:

select Unique_ID as ID
into tmp_table 
from table1

然后,在其他一些陈述之后,我进行了此更新:

Update table1 
set Flag = ‘Y’
Where Unique_ID in (select Unique_ID from tmp_table)

如您所见,我在更新时故意将 ID 误认为 Unique_IDtmp_table 中的列名)。

现在发生了奇怪的事情,SQL服务器在我执行存储过程时没有显示错误。

它忽略错误所在的行:

Where Unique_ID in (select Unique_ID from tmp_table)

然后运行这个:

Update table1 set
Flag = ‘Y’

有什么想法吗?

非常感谢。

更新

存储过程代码如下:

SET QUOTED_IDENTIFIER ON
SET ANSI_NULLS ON
GO

CREATE PROCEDURE [dbo].[MyProc]
AS
BEGIN
    SET NOCOUNT ON

    DECLARE @date VARCHAR(20)

    SET @date = REPLACE(CONVERT(VARCHAR(8), GETUTCDATE(), 3), '/', '')
            + REPLACE(CONVERT(VARCHAR(8), GETUTCDATE(), 108), ':', '')

    DECLARE @PATH AS VARCHAR(500)
    SET @PATH = 'C:\MyPath\' 

    BEGIN TRY
            EXEC master.dbo.xp_create_subdir @PATH
    END TRY
    BEGIN CATCH
            PRINT 'FOLDER NOT CREATED'
    END CATCH

    IF EXISTS (SELECT name FROM sys.tables WHERE name = 'TMP_TABLE')
       DROP TABLE TMP_TABLE

    SELECT  
        UNIQUE_ID [Unique ID] ,
        'col1' COL1,
        'col2' COL2,
        'col3' COL3,
        'col4' COL4
    INTO    
        TMP_TABLE
    FROM    
        TABLE1
    WHERE 
        Flag IN 'N'

    --Try to generate file, If there was any problem, return from the SP => no update
    BEGIN TRY
        DECLARE @QUERY VARCHAR(MAX)

        SET @QUERY = 'EXEC master..xp_cmdshell ''sqlcmd -E -s"," -W -h-1 -Q "SET NOCOUNT ON;SELECT * FROM dbo.TMP_TABLE" | findstr /V /C:"-" /B > '
            + @PaTH + '\FileName_' + @date + '.csv'',no_output;'

        EXEC(@QUERY)
    END TRY
    BEGIN CATCH
        PRINT 'Exception during file generation'
        RETURN
    END CATCH

    PRINT 'File Generated'

    UPDATE TABLE1 
    SET Flag = 'Y',
        MODIFICATION_DATE = GETDATE()
    WHERE 
        UNIQUE_ID IN (SELECT UNIQUE_ID FROM TMP_TABLE)

    BEGIN TRY
        DROP TABLE dbo.TMP_TABLE
        PRINT 'TMP table dropped'
    END TRY
    BEGIN CATCH
        PRINT 'TMP table not dropped'
    END CATCH
END
GO

问题出在这一行:

WHERE UNIQUE_ID IN (SELECT **UNIQUE_ID** FROM TMP_TABLE)

我应该用 [UNIQUE ID]

替换 UNIQUE_ID

但是SQL服务器不会抛出错误,它只是更新所有记录。

这里是表 1 的结构:

CREATE TABLE [dbo].[TABLE1]
(
    UNIQUE_ID int NOT NULL IDENTITY(1, 1), --Primary key
    Flag [varchar] (1) ,
    MODIFICATION_DATE datetime,
) 

我假设您的查询有错字。你的桌子是这样的吗?

create table1 
( Unique_ID int  
, Flag char(1)
, ...
);

create tmp_table
( [Unique ID] int primary key
, ...
); 

在这种情况下,您的查询是:

Update table1 t1 set
Flag = ‘Y’
Where t1.Unique_ID in (select t1.Unique_ID from tmp_table)

除了您的 id 为 null 外,这是正确的。您只需将 table1 中的 Unique_ID 与其自身进行比较。

尝试通过使用 table 名称来明确引用要比较的列:

UPDATE TABLE1
SET Flag = 'Y',
    MODIFICATION_DATE = GETDATE()
WHERE 
    UNIQUE_ID IN (SELECT TMP_TABLE.UNIQUE_ID FROM TMP_TABLE)

混淆是因为在两个 table 上都有一个名为 UNIQUE_ID 的列,所以通过在子选择中使用 table 名称对其进行完全限定,您可以 100% 确定您指的是正确的列。