2015-01-20 43 views
1

我有一个表,看起来是这样的:SQL服务器:在触发分裂列到表

UserID Email 
----------------------------------- 
1  [email protected];[email protected] 
2  [email protected];[email protected] 
3  [email protected];[email protected] 

,我需要创建一个临时表,将是这样的:

UserID Email 
----------------------------------- 
1  [email protected] 
1  [email protected] 
2  [email protected] 
2  [email protected] 
3  [email protected] 
3  [email protected] 

临时表将在更新触发器使用,我想知道是否有比做这样的事情一个更好的方法:

-- 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

到目前为止,最好的办法是让你的主表正常化。在单个列中允许多个值是一个皮塔,可以使用并违反1NF。这里有一篇关于分割字符串的文章。 http://sqlperformance.com/2012/07/t-sql-queries/split-strings – 2015-01-20 21:23:03

回答

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