TSQL更新问题

时间:2016-01-08 01:02:46

标签: sql-server tsql join sql-update

Ok SQL Server粉丝我的遗留存储过程存在问题,该存储过程位于SQL Server 2008 R2实例中,我还继承了PROD数据,这至少是可怕的。另外,我不能对数据和表结构进行任何更改。

所以这是我的问题,有问题的存储过程每天运行,用于更新employee表。从我的示例中可以看出,传入的数据(#New_Employees)包含更新的数据,我需要使用它来更新Employee数据中的数据存储在#Existing_Employees表中。多年来,EMP_ID值的不同格式已经被使用,必须保持原样(我打过仗,失去了那场战斗)。值得庆幸的是,我已经成功地更改了EMP_ID表中#New_Employees列的格式(是的!),所有新记录都会使用这种格式,谢天谢地!

所以现在您可能会看到我的问题,我需要通过匹配来更新ID表中#New_Employees列与#Existing_Employees表中相应的ID(这是对的,你猜对了)EMP_ID列。所以我提出了一种非常hacky方式来处理EMP_ID列的不同格式,但考虑到我需要处理的行数(1M +),它非常慢。

我想创建一个临时表,我只需将EMP_ID列转换为INT,然后返回到每个表中的NVARCHAR以删除前导零,我就是那种倾向,但我想看看是否有另一种方法来处理这种功能失调的数据。欢迎提出任何建设性意见。

        IF OBJECT_ID(N'TempDB..#NEW_EMPLOYEES') IS NOT NULL
            DROP TABLE #NEW_EMPLOYEES

        CREATE TABLE #NEW_EMPLOYEES(
                            ID INT
                            ,EMP_ID NVARCHAR(50)
                            ,NAME NVARCHAR(50))
        GO 

        IF OBJECT_ID(N'TempDB..#EXISTING_EMPLOYEES') IS NOT NULL
            DROP TABLE #EXISTING_EMPLOYEES

        CREATE TABLE #EXISTING_EMPLOYEES(
                          ID INT PRIMARY KEY
                          ,EMP_ID NVARCHAR(50)
                          ,NAME NVARCHAR(50))
        GO

        INSERT INTO #NEW_EMPLOYEES
        VALUES(NULL, '00123', 'Adam Arkin')
                ,(NULL, '00345', 'Bob Baker')
                ,(NULL, '00526', 'Charles Nelson O''Reilly')
                ,(NULL, '04321', 'David Numberman')
                ,(NULL, '44321', 'Ida Falcone')

    INSERT INTO #EXISTING_EMPLOYEES
        VALUES(1, '123', 'Adam Arkin')
                ,(2, '000345', 'Bob Baker')
                ,(3, '526', 'Charles Nelson O''Reilly')
                ,(4, '0004321', 'Ed Sullivan')
                ,(5, '02143', 'Frank Sinatra')
                ,(6, '5567', 'George Thorogood')
                ,(7, '0000123-1', 'Adam Arkin')
                ,(8, '7', 'Harry Hamilton')

      -- First Method - Not Successful   
        UPDATE NE
            SET ID = EE.ID
        FROM
            #NEW_EMPLOYEES NE
                LEFT OUTER JOIN #EXISTING_EMPLOYEES EE 
                    ON EE.EMP_ID = NE.EMP_ID

        SELECT * FROM #NEW_EMPLOYEES

      -- Second Method - Successful but Slow
        UPDATE NE
            SET ID = EE.ID
        FROM
            dbo.#NEW_EMPLOYEES NE
                LEFT OUTER JOIN dbo.#EXISTING_EMPLOYEES EE 
                    ON CAST(CASE WHEN NE.EMP_ID LIKE N'%[^0-9]%' 
                        THEN NE.EMP_ID 
                        ELSE LTRIM(STR(CAST(NE.EMP_ID AS INT))) END AS NVARCHAR(50)) =
                       CAST(CASE WHEN EE.EMP_ID LIKE N'%[^0-9]%' 
                        THEN EE.EMP_ID 
                        ELSE LTRIM(STR(CAST(EE.EMP_ID AS INT))) END AS NVARCHAR(50))

        SELECT * FROM #NEW_EMPLOYEES

1 个答案:

答案 0 :(得分:0)

  

我需要处理的行数(1M +)。

一百万名员工?每天?

我想我会添加第3张表格:

create table #ids ( id INT not NULL PRIMARY KEY
                  , emp_id not NULL NVARCHAR(50) unique );

使用您的LTRIM(STR(CAST,ahem,算法填充该表,并直接从这三个表的联接中更新Employees。

我建议使用ANSI 更新,而不是Microsoft的非标准update ... from,因为ANSI版本会在FROM生成多行的情况下阻止不确定结果。