【问题标题】:Insert entire record with cursor after checking if it exists检查是否存在后用光标插入整条记录
【发布时间】:2020-08-31 17:25:16
【问题描述】:

如果表中不存在记录,我有以下脚本使用游标将记录插入表中。这可行,但我想修改它以插入整个记录,而不必单独指定每个字段。是否可以引用整条记录并插入?

SET @Cursor = CURSOR FOR
SELECT [COMPANY],[LOCATION],[id] FROM [GG].[dbo].[LOCATION]

 OPEN @Cursor;
FETCH NEXT FROM @Cursor INTO @COMPANY, @Location, @id;

WHILE @@FETCH_STATUS = 0
BEGIN
    select @numFound = count(*) FROM [GG].[dbo].[gsLocation] where company = @COMPANY and location = @Location;
    IF @numFound = 0
    BEGIN
        -- Want to be able to insert entire record instead of specifying fields
        insert into [GG].[dbo].[gsLocation] (company, Location, id) values (@COMPANY, @Location, @id)
    END

    FETCH NEXT FROM @Cursor INTO @COMPANY, @Location, @id;
END

【问题讨论】:

  • 为什么是光标?????
  • 为什么要使用光标来处理任何事情,尤其是像INSERT ... SELECT ... 这样简单的事情?使用游标是在数据库中使用数据的最慢的方法。在这种特殊情况下,它将为 100 行执行 100 次 INSERT,而不是单个 INSERT
  • 在插入时指定列名是一种常见的最佳实践。虽然理论上您的表可能具有相同的列,但即使列的顺序也可能不同(例如,如果它们的创建方式不同)。恕我直言,您不应该在未指定列的情况下将数据插入表中。您可以使用动态 SQL 查询来获取列名并像这样创建插入语句。

标签: sql-server tsql database-cursor


【解决方案1】:

没有光标你可以做的更简单:

Insert into [GG].[dbo].[gsLocation] (COMPANY, LOCATION, id)
Select  L.COMPANY, 
        L.LOCATION, 
        L.id
From [GG].[dbo].[LOCATION] L
where not exists (Select * From [GG].[dbo].[gsLocation] where company = L.COMPANY and location = L.LOCATION)

最好指定列的名称。

【讨论】:

  • 您不需要在 EXISTS 表达式中使用 TOP - 引擎在几年前就变得聪明了。您也不需要使用文字 - “*”也可以,并且通常不会让没有经验的人感到困惑。
  • 有意思,1年前就养成了用top的习惯。这是你从未想过的事情之一。根据您的建议更新了答案。
  • WHERE NOT EXISTSLEFT JOIN gsLocation on ... where gsLocation.company is NULL
  • 旁白:由于 exists 查询 (select 666 where exists ( select 1 / 0 from sys.columns );) 忽略了 选择列表,并且有些人在查询中被鞭打成 NEVER USING *,我使用42 作为占位符来提醒我,我考虑过要选择什么并且什么都不需要。
猜你喜欢
  • 2021-01-23
  • 1970-01-01
  • 2012-03-06
  • 2015-10-04
  • 2016-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-31
相关资源
最近更新 更多