복붙노트

[SQL] SQL 서버 삽입하지가 존재하는 경우

SQL

SQL 서버 삽입하지가 존재하는 경우

내 테이블에 데이터를 삽입하지만 이미 내 데이터베이스에 존재하지 않는 경우에만 데이터를 삽입 할.

여기 내 코드는 다음과 같습니다

ALTER PROCEDURE [dbo].[EmailsRecebidosInsert]
  (@_DE nvarchar(50),
   @_ASSUNTO nvarchar(50),
   @_DATA nvarchar(30) )
AS
BEGIN
   INSERT INTO EmailsRecebidos (De, Assunto, Data)
   VALUES (@_DE, @_ASSUNTO, @_DATA)
   WHERE NOT EXISTS ( SELECT * FROM EmailsRecebidos 
                   WHERE De = @_DE
                   AND Assunto = @_ASSUNTO
                   AND Data = @_DATA);
END

그리고 오류 :

해결법

  1. ==============================

    1.대신 코드 아래에

    대신 코드 아래에

    BEGIN
       INSERT INTO EmailsRecebidos (De, Assunto, Data)
       VALUES (@_DE, @_ASSUNTO, @_DATA)
       WHERE NOT EXISTS ( SELECT * FROM EmailsRecebidos 
                       WHERE De = @_DE
                       AND Assunto = @_ASSUNTO
                       AND Data = @_DATA);
    END
    

    교체

    BEGIN
       IF NOT EXISTS (SELECT * FROM EmailsRecebidos 
                       WHERE De = @_DE
                       AND Assunto = @_ASSUNTO
                       AND Data = @_DATA)
       BEGIN
           INSERT INTO EmailsRecebidos (De, Assunto, Data)
           VALUES (@_DE, @_ASSUNTO, @_DATA)
       END
    END
    

    업데이트 : (감사 @Marc Durdin를 가리키는 경우)

    처음 연결이 INSERT, 즉 경쟁 조건을 실행하기 전에 두 번째 연결이 IF를 전달할 수 있기 때문에, 높은 하중이 여전히 종종 실패 점에 유의하지 시험 존재한다. 트랜잭션 심지어 포장이 해결되지 않는 이유에 대한 좋은 대답을 stackoverflow.com/a/3791506/1836776을 참조하십시오.

  2. ==============================

    2.가장 빠른 방법을 찾고 사람들을 위해, 나는 최근에 5000 만 개 기록 이상 빠른 것으로 밝혀졌다 분명히 사용하여 이러한 벤치 마크 "SELECT를 제외하고 ... INSERT SELECT를 ..."우연히 만났다.

    가장 빠른 방법을 찾고 사람들을 위해, 나는 최근에 5000 만 개 기록 이상 빠른 것으로 밝혀졌다 분명히 사용하여 이러한 벤치 마크 "SELECT를 제외하고 ... INSERT SELECT를 ..."우연히 만났다.

    다음은 기사의 일부 샘플 코드입니다 (코드 3 블록은 가장 빠르다) :

    INSERT INTO #table1 (Id, guidd, TimeAdded, ExtraData)
    SELECT Id, guidd, TimeAdded, ExtraData
    FROM #table2
    WHERE NOT EXISTS (Select Id, guidd From #table1 WHERE #table1.id = #table2.id)
    -----------------------------------
    MERGE #table1 as [Target]
    USING  (select Id, guidd, TimeAdded, ExtraData from #table2) as [Source]
    (id, guidd, TimeAdded, ExtraData)
        on [Target].id =[Source].id
    WHEN NOT MATCHED THEN
        INSERT (id, guidd, TimeAdded, ExtraData)
        VALUES ([Source].id, [Source].guidd, [Source].TimeAdded, [Source].ExtraData);
    ------------------------------
    INSERT INTO #table1 (id, guidd, TimeAdded, ExtraData)
    SELECT id, guidd, TimeAdded, ExtraData from #table2
    EXCEPT
    SELECT id, guidd, TimeAdded, ExtraData from #table1
    ------------------------------
    INSERT INTO #table1 (id, guidd, TimeAdded, ExtraData)
    SELECT #table2.id, #table2.guidd, #table2.TimeAdded, #table2.ExtraData
    FROM #table2
    LEFT JOIN #table1 on #table1.id = #table2.id
    WHERE #table1.id is null
    
  3. ==============================

    3.내가 병합을 사용합니다 :

    내가 병합을 사용합니다 :

    create PROCEDURE [dbo].[EmailsRecebidosInsert]
      (@_DE nvarchar(50),
       @_ASSUNTO nvarchar(50),
       @_DATA nvarchar(30) )
    AS
    BEGIN
       with data as (select @_DE as de, @_ASSUNTO as assunto, @_DATA as data)
       merge EmailsRecebidos t
       using data s
          on s.de = t.de
         and s.assunte = t.assunto
         and s.data = t.data
        when not matched by target
        then insert (de, assunto, data) values (s.de, s.assunto, s.data);
    END
    
  4. ==============================

    4.코드 아래에보십시오

    코드 아래에보십시오

    ALTER PROCEDURE [dbo].[EmailsRecebidosInsert]
      (@_DE nvarchar(50),
       @_ASSUNTO nvarchar(50),
       @_DATA nvarchar(30) )
    AS
    BEGIN
       INSERT INTO EmailsRecebidos (De, Assunto, Data)
       select @_DE, @_ASSUNTO, @_DATA
       EXCEPT
       SELECT De, Assunto, Data from EmailsRecebidos
    END
    
  5. ==============================

    5.삽입 명령은 WHERE 절을하지 않는다 - 당신이 이런 식으로 작성해야합니다 :

    삽입 명령은 WHERE 절을하지 않는다 - 당신이 이런 식으로 작성해야합니다 :

    ALTER PROCEDURE [dbo].[EmailsRecebidosInsert]
      (@_DE nvarchar(50),
       @_ASSUNTO nvarchar(50),
       @_DATA nvarchar(30) )
    AS
    BEGIN
       IF NOT EXISTS (SELECT * FROM EmailsRecebidos 
                       WHERE De = @_DE
                       AND Assunto = @_ASSUNTO
                       AND Data = @_DATA)
       BEGIN
           INSERT INTO EmailsRecebidos (De, Assunto, Data)
           VALUES (@_DE, @_ASSUNTO, @_DATA)
       END
    END
    
  6. ==============================

    6.나는 SQL 서버 2012 같은 일을했고, 그것은 일

    나는 SQL 서버 2012 같은 일을했고, 그것은 일

    Insert into #table1 With (ROWLOCK) (Id, studentId, name)
    SELECT '18769', '2', 'Alex'
    WHERE not exists (select * from #table1 where Id = '18769' and studentId = '2')
    
  7. ==============================

    7.는 IF 제외하고 SQL Server 버전 (? 2012)에 따라 당신은 또한과 같이 병합을 사용할 수 있습니다 존재합니다

    는 IF 제외하고 SQL Server 버전 (? 2012)에 따라 당신은 또한과 같이 병합을 사용할 수 있습니다 존재합니다

    ALTER PROCEDURE [dbo].[EmailsRecebidosInsert]
        ( @_DE nvarchar(50)
        , @_ASSUNTO nvarchar(50)
        , @_DATA nvarchar(30))
    AS BEGIN
        MERGE [dbo].[EmailsRecebidos] [Target]
        USING (VALUES (@_DE, @_ASSUNTO, @_DATA)) [Source]([De], [Assunto], [Data])
             ON [Target].[De] = [Source].[De] AND [Target].[Assunto] = [Source].[Assunto] AND [Target].[Data] = [Source].[Data]
         WHEN NOT MATCHED THEN
            INSERT ([De], [Assunto], [Data])
            VALUES ([Source].[De], [Source].[Assunto], [Source].[Data]);
    END
    
  8. ==============================

    8.코드 아래에서 설명하고있는 바와 같이 : 쿼리 아래 실행하고 자신을 확인합니다.

    코드 아래에서 설명하고있는 바와 같이 : 쿼리 아래 실행하고 자신을 확인합니다.

    CREATE TABLE `table_name` (
      `id` int(11) NOT NULL auto_increment,
      `name` varchar(255) NOT NULL,
      `address` varchar(255) NOT NULL,
      `tele` varchar(255) NOT NULL,
      PRIMARY KEY  (`id`)
    ) ENGINE=InnoDB;
    

    레코드를 삽입 :

    INSERT INTO table_name (name, address, tele)
    SELECT * FROM (SELECT 'Nazir', 'Kolkata', '033') AS tmp
    WHERE NOT EXISTS (
        SELECT name FROM table_name WHERE name = 'Nazir'
    ) LIMIT 1;
    Query OK, 1 row affected (0.00 sec)
    Records: 1 Duplicates: 0 Warnings: 0
    
    SELECT * FROM `table_name`;
    
    +----+--------+-----------+------+
    | id | name   | address   | tele |
    +----+--------+-----------+------+
    |  1 | Nazir  | Kolkata   | 033  |
    +----+--------+-----------+------+
    

    이제, 다시 같은 레코드를 삽입하려고 :

    INSERT INTO table_name (name, address, tele)
    SELECT * FROM (SELECT 'Nazir', 'Kolkata', '033') AS tmp
    WHERE NOT EXISTS (
        SELECT name FROM table_name WHERE name = 'Nazir'
    ) LIMIT 1;
    
    Query OK, 0 rows affected (0.00 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    
    +----+--------+-----------+------+
    | id | name   | address   | tele |
    +----+--------+-----------+------+
    |  1 | Nazir  | Kolkata   | 033  |
    +----+--------+-----------+------+
    

    다른 레코드를 삽입 :

    INSERT INTO table_name (name, address, tele)
    SELECT * FROM (SELECT 'Santosh', 'Kestopur', '044') AS tmp
    WHERE NOT EXISTS (
        SELECT name FROM table_name WHERE name = 'Santosh'
    ) LIMIT 1;
    
    Query OK, 1 row affected (0.00 sec)
    Records: 1 Duplicates: 0 Warnings: 0
    
    SELECT * FROM `table_name`;
    
    +----+--------+-----------+------+
    | id | name   | address   | tele |
    +----+--------+-----------+------+
    |  1 | Nazir  | Kolkata   | 033  |
    |  2 | Santosh| Kestopur  | 044  |
    +----+--------+-----------+------+
    
  9. ==============================

    9.당신은 GO 명령을 사용할 수 있습니다. 즉 오류가 발생한 후 SQL 문장의 실행을 다시 시작합니다. 내 경우에는 내가 레코드의 소수가 데이터베이스에 이미 몇 천 INSERT 문을 가지고, 난 그냥 어떤 것들 모른다. 나는 몇 백을 처리 한 후, 실행 그냥 레코드가 이미 존재대로 삽입 할 수 없다는 오류 메시지와 함께 중지 것으로 나타났다. 아주 짜증나지만, GO 퍼팅이 문제를 해결했다. 그것은 가장 빠른 솔루션이 아닐 수 있지만, 속도는 내 문제가 아니 었습니다.

    당신은 GO 명령을 사용할 수 있습니다. 즉 오류가 발생한 후 SQL 문장의 실행을 다시 시작합니다. 내 경우에는 내가 레코드의 소수가 데이터베이스에 이미 몇 천 INSERT 문을 가지고, 난 그냥 어떤 것들 모른다. 나는 몇 백을 처리 한 후, 실행 그냥 레코드가 이미 존재대로 삽입 할 수 없다는 오류 메시지와 함께 중지 것으로 나타났다. 아주 짜증나지만, GO 퍼팅이 문제를 해결했다. 그것은 가장 빠른 솔루션이 아닐 수 있지만, 속도는 내 문제가 아니 었습니다.

    GO
    INSERT INTO mytable (C1,C2,C3) VALUES(1,2,3)
    GO
    INSERT INTO mytable (C1,C2,C3) VALUES(4,5,6)
     etc ...
    
  10. from https://stackoverflow.com/questions/20971680/sql-server-insert-if-not-exists by cc-by-sa and MIT license