我有一张看起来像这样的表:
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
答案 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