Sql server TSQL更新问题
好的,SQL Server的粉丝们,我有一个遗留存储过程的问题,它位于SQL Server 2008 R2实例中,我继承了PROD数据,至少可以说是可怕的。此外,我不能对数据或表结构进行任何更改 这就是我的问题,这个存储过程每天都在运行,用于更新Sql server TSQL更新问题,sql-server,tsql,join,sql-update,Sql Server,Tsql,Join,Sql Update,好的,SQL Server的粉丝们,我有一个遗留存储过程的问题,它位于SQL Server 2008 R2实例中,我继承了PROD数据,至少可以说是可怕的。此外,我不能对数据或表结构进行任何更改 这就是我的问题,这个存储过程每天都在运行,用于更新employee表。从我的示例中可以看到,传入数据(#新员工)包含更新的数据,我需要使用它来更新员工中的数据。数据存储在#现有员工表中。多年来,使用了不同格式的EMP_ID值,并且必须保持原样(我打过这场仗,输了那场仗)。谢天谢地,我已经成功地更改了#N
employee
表。从我的示例中可以看到,传入数据(#新员工
)包含更新的数据,我需要使用它来更新员工
中的数据。数据存储在#现有员工表中。多年来,使用了不同格式的EMP_ID
值,并且必须保持原样(我打过这场仗,输了那场仗)。谢天谢地,我已经成功地更改了#New_Employees
表中EMP_ID
列的格式(耶!),谢天谢地,任何新记录都将使用这种格式
因此,现在您可能看到了我的问题,我需要通过将EMP\u ID
列与#Existing#u Employees
表中相应的ID进行匹配(您猜对了),来更新#New#u Employees
表中的ID
列。因此,我想出了一种非常粗糙的方法来处理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
需要处理的行数(1M+)
一百万员工?每天
我想我应该添加第三个表:
create table #ids ( id INT not NULL PRIMARY KEY
, emp_id not NULL NVARCHAR(50) unique );
使用LTRIM(STR(CAST)
、ahem、算法填充该表,并直接从这三个表的联接中更新员工
我建议使用ANSIupdate,而不是Microsoft的非标准update…from
,因为ANSI版本在from
生成多行的情况下防止出现不确定的结果
需要处理的行数(1M+)
每天有一百万员工
我想我应该添加第三个表:
create table #ids ( id INT not NULL PRIMARY KEY
, emp_id not NULL NVARCHAR(50) unique );
使用LTRIM(STR(CAST)
、ahem、算法填充该表,并直接从这三个表的联接中更新员工
我建议使用ANSIupdate,而不是Microsoft的非标准的
update…from
,因为ANSI版本在from
生成多行的情况下可以防止不确定的结果。您能创建索引视图来工作吗?这将使您能够计算修剪后的视图或数字id值,在可能的情况下,对它们进行一次索引以提高性能。任何以通配符开头的模式(如模式)都不能使用索引(除非作为更快的表扫描方式)。还有。不,我被我所拥有的东西困住了,他们拒绝做出更改。投票否决这篇文章的人能解释一下吗?他们是否理解视图不是对任何现有架构或数据的更改,只是访问现有数据的附加手段?所以你有权更改存储过程,但无权创建索引视图?这毫无意义。在这种愚蠢的限制下,很难改善这种情况。你能创建索引视图来工作吗?这将使你能够在可能的情况下计算一次修剪的或数字的id值,并为它们的性能编制索引。任何以通配符开头的模式都无法使用索引(除了作为更快的表扫描方式外。)。还有。不,我被我所拥有的东西困住了,他们拒绝做出更改。投票否决这篇文章的人能解释一下吗?他们是否理解视图不是对任何现有架构或数据的更改,只是访问现有数据的附加手段?所以你有权更改存储过程,但无权创建索引观点?这毫无意义。用这种愚蠢的限制很难改善现状。