Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
重构循环SQL插入_Sql_Sql Server_Database_Sql Insert - Fatal编程技术网

重构循环SQL插入

重构循环SQL插入,sql,sql-server,database,sql-insert,Sql,Sql Server,Database,Sql Insert,这个insert语句有效。但是,我希望有人能教我一种更有效的方法来做这个查询。这是我得到的 我有一个名为Source的表,其中DealerID是一个非唯一ID(无论如何,在这个表中)。对于每个DealerID,都有多个名称。例如: 15 BillBoard 15 Event 15 Newspaper 16 BillBoard 16 Event 16 Newspaper 我知道,我知道。这是一种非常低效的数据存储方式。我们正在处理一个遗留应用程序,我现在无法彻底检查这个数据结构。所

这个insert语句有效。但是,我希望有人能教我一种更有效的方法来做这个查询。这是我得到的

我有一个名为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
更正它以包含DISTINCT,因为每个
DealerID
都会有多个其他
Name
s。如果性能有问题,则可以将
DISTINCT
向下移动到
表上的子查询,然后从那里开始执行
交叉连接

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)

作为OP的注意事项,这将取代您拥有的整个流程。不需要表变量或循环。整个事情就是这个插入语句。太棒了!谢谢你,汤姆。我来试试。我想S.Dealer应该是S.DealerId
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)
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)