2016-02-09 111 views
2

此插入語句有效。但是,我希望也許有人可以教我一個更有效的方式來做這個查詢。這是我得到的...重構循環SQL插入

我有一個名爲Source的表,其中DealerID是一個非唯一的ID(在這個表中)。對於每個DealerID,都有多個名稱。例如:

15 BillBoard 
15 Event 
15 Newspaper 

16 BillBoard 
16 Event 
16 Newspaper 

我知道,我知道。這是存儲這些數據的一種非常低效的方式。我們正在處理遺留應用程序,現在我無法徹底檢查這個數據結構。所以我需要做的是爲每個DealerID添加兩條新記錄。一個用於'電話',一個用於'互聯網'。插入後,因此,它應該是這樣的:

15 BillBoard 
15 Event 
15 Newspaper 
15 Phone 
15 Internet 

16 BillBoard 
16 Event 
16 Newspaper 
16 Phone 
16 Internet 

以下作品的SQL語句,但我想知道如果有一個更好的辦法...

declare @SourceTemp table (
    [Id] int identity (1, 1) not null, 
    [DealerId] int 
) 

insert into @SourceTemp select distinct DealerId from Source where DealerId is not null 

declare @dealerid int 
declare @rowcount int = 1 
declare @idcount int 
select @idcount = max(Id) from @SourceTemp 

while @rowcount < (@idcount + 1) 
begin 
    select @dealerid = DealerId from @SourceTemp where Id = @rowcount 

    ---------------- Insert Phone 
    if not exists (select * from Source where DealerId = @dealerid and Name = 'Phone') 
    begin 
     insert into 
     Source 
      ([DealerID],[Name],[Service],[CampaignCode],[Description],[Created],[UserCreated],[Active]) 
     values 
      (@dealerid, 'Phone', 'Generic', 'CampaignCode', NULL, GETDATE(), 0, 1) 
    end 

    --------------- Insert Internet 
    if not exists (select * from Source where DealerId = @dealerid and Name = 'Internet') 
    begin 
     insert into 
     Source 
      ([DealerID],[Name],[Service],[CampaignCode],[Description],[Created],[UserCreated],[Active]) 
     values 
      (@dealerid, 'Internet', 'Generic', 'CampaignCode', NULL, GETDATE(), 0, 1) 
    end 

    set @rowcount = @rowcount + 1 
end 

編輯AFTER:

我不得不讓湯姆做出一個小小的回答,添加了DISTINCT。該工程...

INSERT INTO Source ([DealerID], [Name], [Service], [CampaignCode], [Description], [Created], [UserCreated], [Active]) 
SELECT DISTINCT 
    S.DealerId, SQ.Name, 'Generic', 'CampaignCode', NULL, GETDATE(), 0, 1 
FROM 
    Source S 
CROSS JOIN (SELECT 'Internet' AS Name UNION ALL SELECT 'Phone' AS Name) SQ 
WHERE 
    NOT EXISTS (SELECT * FROM Source WHERE DealerID = S.DealerID AND Name = SQ.Name) 

回答

5
INSERT INTO Source (DealerID, Name, Service, CampaignCode, Description, ...) 
SELECT DISTINCT 
    S.DealerID, SQ.Name, ... 
FROM 
    Source S 
CROSS JOIN (SELECT 'Internet' AS Name UNION ALL SELECT 'Phone' AS Name) SQ 
WHERE 
    NOT EXISTS (SELECT * FROM Source WHERE DealerID = S.DealerID AND Name = SQ.Name) 

更正它包括不同的,因爲將有多個其他Name S代表每個DealerID在那裏。如果性能是一個問題,那麼你可以移動DISTINCT下降到一個子查詢在Source表,然後CROSS JOIN從那裏:

INSERT INTO Source (DealerID, Name, Service, CampaignCode, Description, ...) 
SELECT DISTINCT 
    S.DealerID, SQ.Name, ... 
FROM 
    (SELECT DISTINCT DealerID 
    FROM Source 
    ) S 
CROSS JOIN (SELECT 'Internet' AS Name UNION ALL SELECT 'Phone' AS Name) SQ 
WHERE 
    NOT EXISTS (SELECT * FROM Source WHERE DealerID = S.DealerID AND Name = SQ.Name) 
+1

作爲一個說明的任擇議定書,這將取代你的整個過程。不需要表變量或循環。整個事情就是這個插入語句。 –

+0

非常好!謝謝湯姆。我會試試這個。 –

+0

我假設S.Dealer,應該是S.DealerId –