SQL Server:将列拆分为触发器中的表

时间:2015-01-20 21:03:03

标签: sql sql-server

我有一张看起来像这样的表:

UserID  Email
-----------------------------------
1       1_0@email.com;1_1@email.com
2       2_0@email.com;2_1@email.com
3       3_0@email.com;3_3@email.com

我需要创建一个如下所示的临时表:

UserID  Email
-----------------------------------
1       1_0@email.com
1       1_1@email.com
2       2_0@email.com
2       2_1@email.com
3       3_0@email.com
3       3_1@email.com

临时表将用于更新触发器,我想知道是否有比这样做更优雅的方法:

-- Create temp table to hold the result table
CREATE TABLE #resultTable(
   UserID int,
   Email  nvarchar(50)
)

-- Create temp table to help iterate through table
CREATE TABLE #tempTable(
   ID int IDENTITY(1,1),
   UserID int,
   Email  nvarchar(50)
)

-- Insert data from updated table into temp table
INSERT INTO #tempTable
   SELECT [UserId], [Email] 
   FROM inserted

-- Iterate through temp table
DECLARE @count int = @@ROWCOUNT
DECLARE @index int = 1

WHILE (@index <= @count)
BEGIN
    DECLARE @userID int
    DECLARE @email nvarchar(50)

    -- Get the user ID and email values
    SELECT 
        @userID = [UserID], @email = [Email]
    FROM #tempTable
    WHERE [ID] = @index

    -- Insert the parsed email address into the result table
    INSERT INTO #resultTable([UserID], [Email])
       SELECT @userID, [Data]
       FROM myFunctionThatSplitsAColumnIntoATable(@email, ';')

    SET @index = @index + 1
END

-- Do stuff with the result table

1 个答案:

答案 0 :(得分:5)

除非严格必要,否则在使用 T-SQL 时,尤其是内部触发器时,最好避免使用迭代方法。

您可以使用APPLY运算符。

来自 MSDN

  

APPLY运算符允许您为查询的外表表达式返回的每一行调用表值函数。

因此,您可以尝试用以下代码替换所有代码:

INSERT INTO #resultTable(UserID, Email)
SELECT T1.UserID
      ,T2.Data
FROM updated T1
CROSS APPLY myFunctionThatSplitsAColumnIntoATable(T1.Email, ';') AS T2