在执行 SELECT INTO (SQL Server) 之前检查行的存在

Posted

技术标签:

【中文标题】在执行 SELECT INTO (SQL Server) 之前检查行的存在【英文标题】:checking existence of a row before doing a SELECT INTO (SQL Server) 【发布时间】:2010-10-13 20:21:18 【问题描述】:

我想修改一条 SQL 语句。就目前而言,我正在运行一个简单的 SELECT INTO,但我想对其进行修改,以便仅附加目标表中不存在的记录(由我的标准确定)。

这是我最初的声明:

SELECT b.BallotID, m.MeetingDate
    INTO StagingTable
    FROM Ballot INNER JOIN Meeting on b.MeetingID = m.MeetingID
    WHERE b.LastModifiedDate < '01-01-2010' AND ( b.BallotType = 'Agenda Vote' AND m.MeetingDate < GETDATE())  

我想进行一些更改,以便仅在选票尚不存在时填充 StagingTable。这是一种可以接受的方式吗,还是有更好的选择?

SELECT b.BallotID, m.MeetingDate
    INTO StagingTable
    FROM Ballot INNER JOIN Meeting on b.MeetingID = m.MeetingID
    WHERE b.LastModifiedDate < '01-01-2010' AND ( b.BallotType = 'Agenda Vote' AND m.MeetingDate < GETDATE())   
    AND NOT EXISTS(SELECT 1 from StagingTable where BallotID = b.BallotID)) )

【问题讨论】:

如果没有额外的锁定提示,您可能仍然会在高负载下获得重复项。见Related Question 【参考方案1】:

您的技术看起来不错,只是 SELECT...INTO 语法用于创建一个全新的表。相反,您希望使用下面的代码向现有表添加行:

INSERT INTO StagingTable
    (BallotID, MeetingDate)
    SELECT b.BallotID, m.MeetingDate
        FROM Ballot b
            INNER JOIN Meeting m
                on b.MeetingID = m.MeetingID
        WHERE b.LastModifiedDate < '01-01-2010' 
            AND (b.BallotType = 'Agenda Vote' AND m.MeetingDate < GETDATE())   
            AND NOT EXISTS(SELECT 1 from StagingTable where BallotID = b.BallotID)

【讨论】:

感谢您获取我的 SQL,并感谢您对 EXISTS 的确认。实际代码是 SELECTing INTO 临时表,以供以后处理。这个想法是限制临时表中的行数。对不起,我的帖子中的疏忽,我试图精简 SQL 语句以便于查看!【参考方案2】:

SELECT INTO 创建一个新表,而不是将数据插入到现有表中。因此,我会检查表是否存在,然后在运行现有 SQL 之前删除该表。这将确保每次都删除并重新创建 StagingTable。

    IF OBJECT_ID('StagingTable','U') IS NOT NULL
    BEGIN
         DROP TABLE StagingTable
    END


        SELECT b.BallotID, m.MeetingDate
        INTO StagingTable
        FROM Ballot INNER JOIN Meeting on b.MeetingID = m.MeetingID
        WHERE b.LastModifiedDate < '01-01-2010' AND ( b.BallotType = 'Agenda Vote' 
        AND m.MeetingDate < GETDATE()) 

如果您想向现有表添加行,那么您应该按照 Joe Stefanelli 的回答使用 INSERT INTO

【讨论】:

以上是关于在执行 SELECT INTO (SQL Server) 之前检查行的存在的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server SELECT INTO 和临时表阻塞

PL/SQL SELECT INTO 错误 (ORA-00905)

mybatis 中用insert into select ..... 报错命令未正确结束,但把这句sql放到plsql中执行正常

mybatis 中用insert into select ..... 报错命令未正确结束,但把这句sql放到plsql中执行正常

oracle 在sql>状态下 执行insert into select 正常 将这一段复制到存储过程中 再EXEC 就很慢

如何在 Oracle PL SQL 中将 INTO 与 SELECT AS 一起使用?