我需要构建一个 SQL 存储过程,它基本上使用 ID 更新现有表(大约 150,000 行)。
该存储过程将运行的表基本上是人员列表、他们的姓名、地址等。
现在该人的 id 的算法如下: - 最多占用人名的前 4 个字符。- 最多占用人员姓氏的前 2 个字符。- 用 0 填充其余部分,最后加上计数,直到字段为 8 个字符。
例如,名称 JOHN SMITH 的 ID 为“JOHNSM00”。如果有 2 个 JOHN SMITH,则下一个人的 ID 将是 JOHNSM01。例如,如果人名是 FI LYNN,则 ID 将为 FILY0000。
我已经编写了以下存储过程,但运行大约需要 9 个小时!有没有我想念的更好的方法?
ALTER PROCEDURE [dbo].[LM_SP_UPDATE_PERSON_CODES]
AS
DECLARE @NAMEKEY NVARCHAR(10)
DECLARE @NEWNAMEKEY NVARCHAR(10)
DECLARE @LENGTH INT
DECLARE @KEYCOUNT INT
DECLARE @I INT
DECLARE @PADDING NVARCHAR(8)
DECLARE @PERSONS CURSOR
DECLARE @FIRSTNAME NVARCHAR(30)
DECLARE @LASTNAME NVARCHAR(30)
SET @PADDING = '00000000'
--FIRST CLEAR OLD NEW NAMEKEYS IF ANY EXIST
UPDATE LM_T_PERSONS SET NEW_NAMEKEY = NULL
SET @PERSONS = CURSOR FOR
SELECT NAMEKEY, NAME_2, NAME_1 FROM LM_T_PERSONS
OPEN @PERSONS
FETCH NEXT FROM @PERSONS INTO @NAMEKEY, @FIRSTNAME, @LASTNAME
WHILE @@FETCH_STATUS = 0
BEGIN
--CHECK THE LENGTH OF FIRST NAME TO MAKE SURE NOTHING EXCEEDS 4
SET @LENGTH = LEN(@FIRSTNAME)
IF @LENGTH > 4
SET @LENGTH = 4
SET @NEWNAMEKEY = SUBSTRING(@FIRSTNAME,1,@LENGTH)
--CHECK THE LENGTH OF LAST NAME TO MAKE SURE NOTHING EXCEEDS 2
SET @LENGTH = LEN(@LASTNAME)
IF @LENGTH > 2
SET @LENGTH = 2
SET @NEWNAMEKEY = @NEWNAMEKEY + SUBSTRING(@LASTNAME,1,@LENGTH)
SET @LENGTH = LEN(@NEWNAMEKEY)
SET @I = 0
SET @PADDING = SUBSTRING('00000000',1,8 - LEN(@NEWNAMEKEY) - LEN(CONVERT(NVARCHAR(8),@I)))
--SEE IF THIS KEY ALREADY EXISTS
SET @KEYCOUNT = (SELECT COUNT(1) FROM LM_T_PERSONS WHERE NEW_NAMEKEY = @NEWNAMEKEY + @PADDING + CONVERT(NVARCHAR(8),@I) )
WHILE @KEYCOUNT > 0
BEGIN
SET @I = @I+1
SET @PADDING = SUBSTRING('00000000',1,8 - LEN(@NEWNAMEKEY) - LEN(CONVERT(NVARCHAR(8),@I)))
SET @KEYCOUNT = (SELECT COUNT(1) FROM LM_T_PERSONS WHERE NEW_NAMEKEY = @NEWNAMEKEY + @PADDING + CONVERT(NVARCHAR(8),@I) )
END
UPDATE LM_T_PERSONS SET NEW_NAMEKEY = @NEWNAMEKEY + @PADDING + CONVERT(NVARCHAR(8),@I) WHERE NAMEKEY = @NAMEKEY
FETCH NEXT FROM @PERSONS INTO @NAMEKEY, @FIRSTNAME, @LASTNAME
END
CLOSE @PERSONS
DEALLOCATE @PERSONS