循环遍历SQL Server中的临时表记录

时间:2018-11-01 19:36:01

标签: sql sql-server tsql

下面是我的SQL脚本

SELECT * 
INTO #Temp 
FROM Users 
WHERE AccountCode = 'Basic'

DECLARE @userId VARCHAR(50)
DECLARE @iterator INT = 0
DECLARE @fullName VARCHAR(50)
DECLARE @generatedAccountCode VARCHAR(50)

WHILE EXISTS(SELECT * FROM #Temp)
BEGIN
    SELECT TOP 1 @userId = USERID 
    FROM #Temp

    SET @iterator = @iterator + 1
    SET @generatedAccountCode = 'PMT' + CAST(@iterator AS VARCHAR)
    SET @fullName = (Select u.FIRSTNAME + ' ' + u.LASTNAME FROM Users u where USERID = @userId)

    INSERT INTO Accounts(AccountCode, FullName, DateCreated)
    VALUES (@generatedAccountCode, @fullName, GETDATE());

    UPDATE Users 
    SET AccountCode = @generatedAccountCode
    WHERE USERID = @userId 

    DELETE #Temp 
    WHERE USERID = @userId
END

数据库的当前状态:#Temp表包含没有AccountCode的用户的记录。对于所有这些用户,表AccountCode中的Users设置为“基本”。

我要做什么

我想遍历#Temp表中的所有记录。我正在生成随机AccountCode。首先将AccountCode生成为PMT1,然后在下次循环时将其生成为PMT2。在AccountCode表中创建了Accounts之后,我想将AccountCode表中的Users设置为generateAccountCode。因此,这些用户中的每个用户在“帐户”表中都有唯一的帐户代码。

当我运行此脚本时,它将以我期望的序列化方式(PMT1,PMT2)的方式在表Users中生成帐户代码,但在Accounts表中的帐户却未以序列化方式生成。我究竟做错了什么?

这将是一次运行的脚本,此后,我将更改我的API,因此我们不必再次运行此脚本。

2 个答案:

答案 0 :(得分:0)

您可以避免循环:

CREATE TABLE #temp(AccountCode NVARCHAR(100), UserId INT);

--single run only(AccountCode is not stable sort)
MERGE INTO Accounts trg
USING (Select  AccountCode = CONCAT('PMT', ROW_NUMBER() OVER(ORDER BY 1/0))
          ,FullName = u.FIRSTNAME + ' ' + u.LASTNAME
          ,DateCreated = GETDATE()
          ,u.UserId
        From   Users u
        where AccountCode = 'Basic') src
ON trg.AccountCode = src.AccountCode
WHEN NOT MATCHED THEN 
   INSERT (AccountCode, FullName, DateCreated)
   VALUES (src.AccountCode, src.FullName, src.DateCreated)
OUTPUT inserted.AccountCode, src.UserId
INTO #temp;

Update u
set AccountCode = t.AccountCode
FROM users u
JOIN #temp t
  ON u.UserId = t.UserId;

db<>fiddle demo

答案 1 :(得分:0)

您可以执行以下操作而无需循环:

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

SELECT 
    USERID
,   FIRSTNAME + ' ' + LASTNAME FullName
,   'PMT' + CAST( ROW_NUMBER() OVER(ORDER BY USERID) AS VARCHAR(50) ) generatedAccountCode
INTO #Temp 
FROM 
    Users 
WHERE 
    AccountCode = 'Basic'

INSERT INTO Accounts(AccountCode, FullName, DateCreated)
SELECT 
    generatedAccountCode
,   FullName
,   GETDATE()
FROM 
    #Temp 

UPDATE u 
SET 
    AccountCode = generatedAccountCode
FROM 
    Users u 
JOIN #Temp tmp ON Tmp.USERID = u.USERID