복붙노트

[SQL] SQLite는 - UPSERT *하지 * INSERT 또는 REPLACE

SQL

SQLite는 - UPSERT *하지 * INSERT 또는 REPLACE

http://en.wikipedia.org/wiki/Upsert

삽입, 업데이트 SQL Server에서 proc 디렉토리에 저장

내가 생각하지 않은 것을 SQLite는이 작업을 수행하는 몇 가지 현명한 방법이 있나요?

기본적으로 나는 기록이있는 경우 네 개의 열 세 밖으로을 업데이트하려면, 그렇지 내가 네 번째 열에 대한 디폴트 (NUL) 값을 가진 레코드를 삽입 할 존재하는 경우.

오직 UPSERT에 하나 개의 레코드가있을 것입니다, 그래서 ID는 기본 키입니다.

(나는 분명히 UPDATE 또는 INSERT 할 필요가 있는지 확인하기 위해 SELECT의 오버 헤드를 피하기 위해 노력하고 있어요)

제안?

나는 TABLE 구문 SQLite는에 사이트를 만드는 것이 확신 할 수 없습니다. 나는 그것을 테스트 할 수있는 데모를 내장하지 않은,하지만 지원 될 것 같지 않습니다 ..

그것이 경우 실제로 같을 것이다, 그래서 나는 세 개의 열이 있습니다

CREATE TABLE table1( 
    id INTEGER PRIMARY KEY ON CONFLICT REPLACE, 
    Blob1 BLOB ON CONFLICT REPLACE, 
    Blob2 BLOB ON CONFLICT REPLACE, 
    Blob3 BLOB 
);

그러나 처음 두 얼룩이 충돌이 발생하지 않습니다 만 ID는 것 내가 asusme 그래서 Blob1 및 Blob2 교체되지 않을 것이다 (필요에 따라)

SQLite는의 업데이트 데이터 바인딩은 의미 완전한 거래 때 업데이트 할 각 보냈습니다 행이 필요합니다 / 바인딩 / 스텝 /의 Finalize 문을 준비 리셋 기능의 사용을 허용하는 INSERT 달리

성명 개체의 수명은 이런 식입니다 :

UPDATE 나는 천천히 INSERT와 비교 추측,하지만 어떻게 그것은 기본 키를 사용하여 SELECT 비교합니까?

아마도 내가 처음 3 열에 대한 새 데이터로 원래 4 열을 혼합 새로운 기록을 작성 REPLACE 사용 후는 4 열 (Blob3를) 읽을 선택 사용한다?

해결법

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

    1.테이블에 세 개의 열을 가정 : ID, 이름, 역할을

    테이블에 세 개의 열을 가정 : ID, 이름, 역할을

    BAD :이 삽입하거나 ID = 1 새 값으로 모든 열을 대체합니다 :

    INSERT OR REPLACE INTO Employee (id, name, role) 
      VALUES (1, 'John Foo', 'CEO');
    

    BAD :이 삽입하거나 열이 대체됩니다 ... 이름 열은 NULL 또는 기본 값으로 설정됩니다 :

    INSERT OR REPLACE INTO Employee (id, role) 
      VALUES (1, 'code monkey');
    

    GOOD : 사용 SQLite는에 충돌 절 SQLite는의 UPSERT 지원! UPSERT 구문 버전 3.24.0와 SQLite는 추가되었습니다!

    UPSERT는 INSERT가 고유성 제약 조건을 위반하는 경우 UPDATE 또는 무 조작으로 작동 할 수있는 INSERT 원인 삽입하는 특수 구문의 추가이다. UPSERT 표준 SQL이 아니다. SQLite는에 UPSERT PostgreSQL의 설립 구문을 따른다.

    좋은 그러나 tendous :이 열이 업데이트됩니다. ID = 1이 존재하는 경우, 이름은 영향을받지 않습니다. ID = 1이 존재하지 않는 경우, 이름은 기본 (NULL)이 될 것입니다.

    INSERT OR REPLACE INTO Employee (id, role, name) 
      VALUES (  1, 
                'code monkey',
                (SELECT name FROM Employee WHERE id = 1)
              );
    

    이 열이 업데이트됩니다. ID = 1이 존재하는 경우, 롤은 영향을받지 않을 것이다. ID = 1이 존재하지 않는 경우, 역할은 'Benchwarmer'대신에 기본 값으로 설정됩니다.

    INSERT OR REPLACE INTO Employee (id, name, role) 
      VALUES (  1, 
                'Susan Bar',
                COALESCE((SELECT role FROM Employee WHERE id = 1), 'Benchwarmer')
              );
    
  2. ==============================

    2.INSERT OR REPLACE는 "UPSERT"에 해당 아닙니다.

    INSERT OR REPLACE는 "UPSERT"에 해당 아닙니다.

    나는 필드 ID, 이름, 역할 테이블 직원이 말 :

    INSERT OR REPLACE INTO Employee ("id", "name", "role") VALUES (1, "John Foo", "CEO")
    INSERT OR REPLACE INTO Employee ("id", "role") VALUES (1, "code monkey")
    

    붐, 당신은 기본 값으로 대체 한 직원 수 1 SQLite는의 이름을 잃었습니다.

    UPSERT의 예상 출력은 역할을 변경하고 이름을 유지하는 것입니다.

  3. ==============================

    3.기존 행에서 하나 아니면 두 개의 열을 보존하려면 에릭 B의 대답은 OK입니다. 당신이 열을 많이 유지하려면, 그것은 너무 빨리 성가신됩니다.

    기존 행에서 하나 아니면 두 개의 열을 보존하려면 에릭 B의 대답은 OK입니다. 당신이 열을 많이 유지하려면, 그것은 너무 빨리 성가신됩니다.

    여기에 양쪽에 열 금액에 잘 조정됩니다 접근 방식이다. 그것을 설명하기 위해 나는 다음과 같은 스키마를 가정합니다 :

     CREATE TABLE page (
         id      INTEGER PRIMARY KEY,
         name    TEXT UNIQUE,
         title   TEXT,
         content TEXT,
         author  INTEGER NOT NULL REFERENCES user (id),
         ts      TIMESTAMP DEFAULT CURRENT_TIMESTAMP
     );
    

    특히 주 이름은 행의 자연 열쇠라고 - 새 행을 삽입 할 때 SQLite는이 ID 값 자체를 선택하는 요점은, 그래서 ID가 만 외래 키에 사용됩니다. 그 이름에 따라 기존 행을 업데이트 할 때, 나는 그것이 기존의 ID 값이 계속하려면 (분명히을!).

    나는 다음과 같은 구조를 가진 진정한 UPSERT을 달성 :

     WITH new (name, title, author) AS ( VALUES('about', 'About this site', 42) )
     INSERT OR REPLACE INTO page (id, name, title, content, author)
     SELECT old.id, new.name, new.title, old.content, new.author
     FROM new LEFT JOIN page AS old ON new.name = old.name;
    

    이 쿼리의 정확한 형태는 약간 다를 수 있습니다. 키는 새로운 값으로 기존 행 가입 왼쪽 외부와 INSERT SELECT의 사용에 가입한다.

    행 이전에 존재하지 않았던 경우 여기, old.id는 NULL이 될 것이며, SQLite는가 자동으로 ID를 할당하지만, 이미 행이 있다면, old.id 실제 값을가집니다 것이며, 이것은 다시 사용됩니다. 어느 내가 원하는 정확히입니다.

    사실 이것은 매우 유연합니다. 참고 어떻게 TS 열은 완전히 모든면에서 누락 된 -는 디폴트 값을 가지고 있기 때문에 나는 그것을 자신을 돌볼 필요가 없습니다, SQLite는 그냥 어떤 경우에 옳은 일을 할 것입니다.

    또한 사용 후 예를 신규 및 기존 양쪽에 열을 포함 할 수 있습니다 외부 SELECT에 COALESCE는 (new.content, old.content) "그렇지 않으면 기존 내용을 유지, 어떤이 있다면 새로운 내용을 삽입"말을 - 예를 경우는 고정 된 쿼리를 사용하고 자리에 새 값을 바인딩한다.

  4. ==============================

    4.당신은 일반적으로 업데이트를 수행하는 경우 나는 것 ..

    당신은 일반적으로 업데이트를 수행하는 경우 나는 것 ..

    당신은 일반적으로 삽입을하고 있다면 나는 것

    이 방법 당신은 선택을 방지하고 당신은 트랜잭션 SQLite는에 소리가있다.

  5. ==============================

    5.이 답변은 업데이트되지 및 의견 있도록 아래에 더 이상 적용 할 수있다.

    이 답변은 업데이트되지 및 의견 있도록 아래에 더 이상 적용 할 수있다.

    2018년 5월 18일 STOP 키를 누릅니다.

    SQLite는의 UPSERT 지원! UPSERT 구문 버전 3.24.0 (출원)에 SQLite는 추가되었습니다!

    UPSERT는 INSERT가 고유성 제약 조건을 위반하는 경우 UPDATE 또는 무 조작으로 작동 할 수있는 INSERT 원인 삽입하는 특수 구문의 추가이다. UPSERT 표준 SQL이 아니다. SQLite는에 UPSERT PostgreSQL의 설립 구문을 따른다.

    다른 방법 :

    이 인 일을하는 또 다른 완전히 다른 방법 : 내에서 메모리를 설정 내 응용 프로그램에서 내가 메모리에 행을 만들 때 long.MaxValue로 ROWID. 이 MAXVALUE 다음은 삽입을 필요로하는 경우 (MAXVALUE는 라이브 충분히 .... ROWID가 아닌 그런 경우 값이 다음 이미 데이터베이스에 있어야하지 않을 것이라는 ID로 사용되지 않습니다 그래서 업데이 트를 필요로한다. 앱에서 당신의 ROWID를 추적 할 수있는 경우에만 유용합니다.

  6. ==============================

    6.나는이 오래된 스레드 실현하지만 난 말 기준으로 sqlite3를에서 일한지 및 더 나은 동적 매개 변수화 된 쿼리를 생성하는 내 요구에 적합한이 방법을 함께했다 :

    나는이 오래된 스레드 실현하지만 난 말 기준으로 sqlite3를에서 일한지 및 더 나은 동적 매개 변수화 된 쿼리를 생성하는 내 요구에 적합한이 방법을 함께했다 :

    insert or ignore into <table>(<primaryKey>, <column1>, <column2>, ...) values(<primaryKeyValue>, <value1>, <value2>, ...); 
    update <table> set <column1>=<value1>, <column2>=<value2>, ... where changes()=0 and <primaryKey>=<primaryKeyValue>; 
    

    아직 업데이트에 where 절과 2 개 쿼리입니다하지만 트릭을 할 것으로 보인다. 또한 변화에 ()에 대한 호출이 0보다 큰 전적으로 경우 sqlite가 업데이트 문을 최적화 할 수있는 내 머리에이 비전을 가지고있다. 여부는 실제로 내 지식을 넘어 않지만, 사람이 그가 할 수없는 꿈을 꿀 수? ;)

    보너스 포인트 위해 당신은 당신이 새로 삽입 된 행 또는 기존 행이든 행의 ID를 반환이 줄을 추가 할 수 있습니다.

    select case changes() WHEN 0 THEN last_insert_rowid() else <primaryKeyValue> end;
    
  7. ==============================

    7.여기 정말 UPSERT (UPDATE 또는 INSERT) 대신 (많은 상황에서 다르게 작동)는 INSERT OR REPLACE가있는 솔루션입니다.

    여기 정말 UPSERT (UPDATE 또는 INSERT) 대신 (많은 상황에서 다르게 작동)는 INSERT OR REPLACE가있는 솔루션입니다.

    그것은 다음과 같이 작동합니다 : 동일한 ID를 가진 레코드가있는 경우 1. 봅니다 업데이트합니다. 2. 업데이트는 행 변경하지 않은 경우 (접촉 변경 AS를 NOT EXISTS (SELECT 변경 () 위치를 변경 <> 0)), 다음 레코드를 삽입합니다.

    그러니 기존 레코드가 업데이트 된 또는 삽입이 수행됩니다.

    중요한 세부 사항 업데이트 문이 기존 기록을 명중하고 어떤 기록을 명중하지 않은 경우에만 삽입 문을 수행 할 수 있는지 확인하는 변경 () SQL 함수를 사용하는 것입니다.

    언급 한 가지는 변경 () 함수는 그 계정에 걸릴해야하므로, 변경 낮은 수준의 트리거 (http://sqlite.org/lang_corefunc.html#changes 참조)에 의해 수행 반환하지 않습니다.

    여기에 SQL은 ...

    테스트 업데이트 :

    --Create sample table and records (and drop the table if it already exists)
    DROP TABLE IF EXISTS Contact;
    CREATE TABLE [Contact] (
      [Id] INTEGER PRIMARY KEY, 
      [Name] TEXT
    );
    INSERT INTO Contact (Id, Name) VALUES (1, 'Mike');
    INSERT INTO Contact (Id, Name) VALUES (2, 'John');
    
    -- Try to update an existing record
    UPDATE Contact
    SET Name = 'Bob'
    WHERE Id = 2;
    
    -- If no record was changed by the update (meaning no record with the same Id existed), insert the record
    INSERT INTO Contact (Id, Name)
    SELECT 2, 'Bob'
    WHERE NOT EXISTS(SELECT changes() AS change FROM Contact WHERE change <> 0);
    
    --See the result
    SELECT * FROM Contact;
    

    테스트 삽입 :

    --Create sample table and records (and drop the table if it already exists)
    DROP TABLE IF EXISTS Contact;
    CREATE TABLE [Contact] (
      [Id] INTEGER PRIMARY KEY, 
      [Name] TEXT
    );
    INSERT INTO Contact (Id, Name) VALUES (1, 'Mike');
    INSERT INTO Contact (Id, Name) VALUES (2, 'John');
    
    -- Try to update an existing record
    UPDATE Contact
    SET Name = 'Bob'
    WHERE Id = 3;
    
    -- If no record was changed by the update (meaning no record with the same Id existed), insert the record
    INSERT INTO Contact (Id, Name)
    SELECT 3, 'Bob'
    WHERE NOT EXISTS(SELECT changes() AS change FROM Contact WHERE change <> 0);
    
    --See the result
    SELECT * FROM Contact;
    
  8. ==============================

    8.문서에서 :

    문서에서 :

    이미지 출처 : https://www.sqlite.org/images/syntax/upsert-clause.gif

  9. ==============================

    9.당신은 참으로 SQLite는의 upsert을 수행 할 수 있습니다, 그것은 단지 당신이 사용하는 것보다 조금 다른 보인다. 그것은 같이 보일 것입니다 :

    당신은 참으로 SQLite는의 upsert을 수행 할 수 있습니다, 그것은 단지 당신이 사용하는 것보다 조금 다른 보인다. 그것은 같이 보일 것입니다 :

    INSERT INTO table name (column1, column2) 
    VALUES ("value12", "value2") WHERE id = 123 
    ON CONFLICT DO UPDATE 
    SET column1 = "value1", column2 = "value2" WHERE id = 123
    
  10. ==============================

    10.아리스토텔레스의 대답에 확장 당신은 더미 '싱글'테이블 (단일 행으로 자신의 창조의 테이블)을 선택할 수 있습니다. 이것은 약간의 중복을 방지 할 수 있습니다.

    아리스토텔레스의 대답에 확장 당신은 더미 '싱글'테이블 (단일 행으로 자신의 창조의 테이블)을 선택할 수 있습니다. 이것은 약간의 중복을 방지 할 수 있습니다.

    또한 MySQL과 SQLite는에서 휴대용 예를 유지하고 열을 첫 번째 시간을 설정할 수있는 방법의 예로서 'DATE_ADDED'열을 사용했습니다.

     REPLACE INTO page (
       id,
       name,
       title,
       content,
       author,
       date_added)
     SELECT
       old.id,
       "about",
       "About this site",
       old.content,
       42,
       IFNULL(old.date_added,"21/05/2013")
     FROM singleton
     LEFT JOIN page AS old ON old.name = "about";
    
  11. ==============================

    11.가장 좋은 방법의 I의 노하우를 삽입 한 다음 업데이 트를 수행하는 것입니다. 은 "선별의 오버 헤드가"필요하다, 그러나 당신이 빠르고 기본 키에 검색 이후 끔찍한 부담하지 않습니다.

    가장 좋은 방법의 I의 노하우를 삽입 한 다음 업데이 트를 수행하는 것입니다. 은 "선별의 오버 헤드가"필요하다, 그러나 당신이 빠르고 기본 키에 검색 이후 끔찍한 부담하지 않습니다.

    당신은 당신이 원하는 것을 할 테이블 및 필드 이름 아래의 문장을 수정 할 수 있어야한다.

    --first, update any matches
    UPDATE DESTINATION_TABLE DT
    SET
      MY_FIELD1 = (
                  SELECT MY_FIELD1
                  FROM SOURCE_TABLE ST
                  WHERE ST.PRIMARY_KEY = DT.PRIMARY_KEY
                  )
     ,MY_FIELD2 = (
                  SELECT MY_FIELD2
                  FROM SOURCE_TABLE ST
                  WHERE ST.PRIMARY_KEY = DT.PRIMARY_KEY
                  )
    WHERE EXISTS(
                SELECT ST2.PRIMARY_KEY
                FROM
                  SOURCE_TABLE ST2
                 ,DESTINATION_TABLE DT2
                WHERE ST2.PRIMARY_KEY = DT2.PRIMARY_KEY
                );
    
    --second, insert any non-matches
    INSERT INTO DESTINATION_TABLE(
      MY_FIELD1
     ,MY_FIELD2
    )
    SELECT
      ST.MY_FIELD1
     ,NULL AS MY_FIELD2  --insert NULL into this field
    FROM
      SOURCE_TABLE ST
    WHERE NOT EXISTS(
                    SELECT DT2.PRIMARY_KEY
                    FROM DESTINATION_TABLE DT2
                    WHERE DT2.PRIMARY_KEY = ST.PRIMARY_KEY
                    );
    
  12. ==============================

    12.누군가가 코르도바에서 SQLite는 내 솔루션을 읽고 싶은 경우에, 나는 위의 @ 데이비드 대답이 일반적인 JS 방법 감사를 얻었다.

    누군가가 코르도바에서 SQLite는 내 솔루션을 읽고 싶은 경우에, 나는 위의 @ 데이비드 대답이 일반적인 JS 방법 감사를 얻었다.

    function    addOrUpdateRecords(tableName, values, callback) {
    get_columnNames(tableName, function (data) {
        var columnNames = data;
        myDb.transaction(function (transaction) {
            var query_update = "";
            var query_insert = "";
            var update_string = "UPDATE " + tableName + " SET ";
            var insert_string = "INSERT INTO " + tableName + " SELECT ";
            myDb.transaction(function (transaction) {
                // Data from the array [[data1, ... datan],[()],[()]...]:
                $.each(values, function (index1, value1) {
                    var sel_str = "";
                    var upd_str = "";
                    var remoteid = "";
                    $.each(value1, function (index2, value2) {
                        if (index2 == 0) remoteid = value2;
                        upd_str = upd_str + columnNames[index2] + "='" + value2 + "', ";
                        sel_str = sel_str + "'" + value2 + "', ";
                    });
                    sel_str = sel_str.substr(0, sel_str.length - 2);
                    sel_str = sel_str + " WHERE NOT EXISTS(SELECT changes() AS change FROM "+tableName+" WHERE change <> 0);";
                    upd_str = upd_str.substr(0, upd_str.length - 2);
                    upd_str = upd_str + " WHERE remoteid = '" + remoteid + "';";                    
                    query_update = update_string + upd_str;
                    query_insert = insert_string + sel_str;  
                    // Start transaction:
                    transaction.executeSql(query_update);
                    transaction.executeSql(query_insert);                    
                });
            }, function (error) {
                callback("Error: " + error);
            }, function () {
                callback("Success");
            });
        });
    });
    }
    

    그래서, 먼저이 기능을 열 이름을 선택 :

    function get_columnNames(tableName, callback) {
    myDb.transaction(function (transaction) {
        var query_exec = "SELECT name, sql FROM sqlite_master WHERE type='table' AND name ='" + tableName + "'";
        transaction.executeSql(query_exec, [], function (tx, results) {
            var columnParts = results.rows.item(0).sql.replace(/^[^\(]+\(([^\)]+)\)/g, '$1').split(','); ///// RegEx
            var columnNames = [];
            for (i in columnParts) {
                if (typeof columnParts[i] === 'string')
                    columnNames.push(columnParts[i].split(" ")[0]);
            };
            callback(columnNames);
        });
    });
    }
    

    그런 다음 프로그램 트랜잭션을 구축 할 수 있습니다.

    "값은"당신이 전에 구축해야 배열이며 행이이 테이블에 삽입하거나 업데이트 할 나타냅니다.

    내 원격 서버와 동기화하고있어 이후 "remoteid는"참조로 사용되는 아이디 I입니다.

    SQLite는 코르도바 플러그인의 사용에 대한 공식 링크를 참조하시기 바랍니다

  13. ==============================

    13.아리스토텔레스 Pagaltzis 에릭 B의 대답에서 유착의 아이디어에 따라, 여기가 존재하지 않는 경우에만 몇 열 또는 전체 행 삽입을 업데이트 할 upsert 옵션입니다.

    아리스토텔레스 Pagaltzis 에릭 B의 대답에서 유착의 아이디어에 따라, 여기가 존재하지 않는 경우에만 몇 열 또는 전체 행 삽입을 업데이트 할 upsert 옵션입니다.

    이 경우, 그 제목을 상상과 내용은 기존의 이름을 찾을 수없는 경우 제공된 것들을 삽입 할 때 다른 이전 값을 유지, 업데이트해야합니다 :

    INSERT가이 자동 증가 있어야하는데로 할 때 참고 ID는 NULL이 될 것을 강요한다. 이 유착 그럼 그냥 생성 된 기본 키도 사용할 수있는 경우 (아리스토텔레스 Pagaltzis 설명을 참조).

    WITH new (id, name, title, content, author)
         AS ( VALUES(100, 'about', 'About this site', 'Whatever new content here', 42) )
    INSERT OR REPLACE INTO page (id, name, title, content, author)
    SELECT
         old.id, COALESCE(old.name, new.name),
         new.title, new.content,
         COALESCE(old.author, new.author)
    FROM new LEFT JOIN page AS old ON new.name = old.name;
    

    당신은 당신이 업데이트 값으로 할 때, 이전 값, 사용 유착을 유지하려면 일반적인 규칙이 될 것입니다 그래서, 사용 new.fieldname

  14. ==============================

    14.ON CONFLICT 절 :이 당신을 위해 무엇을 찾고있는 것 같아요.

    ON CONFLICT 절 :이 당신을 위해 무엇을 찾고있는 것 같아요.

    이 같은 테이블을 정의하는 경우 :

    CREATE TABLE table1( 
        id INTEGER PRIMARY KEY ON CONFLICT REPLACE, 
        field1 TEXT 
    ); 
    

    이미 존재하는 ID와 함께 INSERT를 할 경우 지금, SQLite는은 자동적으로 대신 INSERT의 UPDATE를 수행합니다.

    제 H ...

  15. ==============================

    15.이 방법은이 질문에 대한 답변에서 다른 방법 중 몇 작품으로 CTE (공통 테이블 식)의 사용을 포함한다. 나는 다음 쿼리를 소개 내가 무슨 짓을 한 이유를 설명합니다.

    이 방법은이 질문에 대한 답변에서 다른 방법 중 몇 작품으로 CTE (공통 테이블 식)의 사용을 포함한다. 나는 다음 쿼리를 소개 내가 무슨 짓을 한 이유를 설명합니다.

    나는 신입 사원을 추가 할 것이다, 그렇지 않으면 직원 (300)가있는 경우 DAVIS에 직원 300 마지막으로 이름을 변경하고 싶습니다.

    테이블 이름 : 직원 열 : ID, FIRST_NAME, LAST_NAME

    쿼리는 다음과 같습니다

    INSERT OR REPLACE INTO employees (employee_id, first_name, last_name)
    WITH registered_employees AS ( --CTE for checking if the row exists or not
        SELECT --this is needed to ensure that the null row comes second
            *
        FROM (
            SELECT --an existing row
                *
            FROM
                employees
            WHERE
                employee_id = '300'
    
            UNION
    
            SELECT --a dummy row if the original cannot be found
                NULL AS employee_id,
                NULL AS first_name,
                NULL AS last_name
        )
        ORDER BY
            employee_id IS NULL --we want nulls to be last
        LIMIT 1 --we only want one row from this statement
    )
    SELECT --this is where you provide defaults for what you would like to insert
        registered_employees.employee_id, --if this is null the SQLite default will be used
        COALESCE(registered_employees.first_name, 'SALLY'),
        'DAVIS'
    FROM
        registered_employees
    ;
    

    기본적으로, 선택 문이 디폴트 값을 결정하는 데 사용되어야하는 횟수를 줄이기 위해 CTE를 사용했다. 이것은 CTE이기 때문에, 우리는 단지 테이블에서 우리가 원하는 열을 선택하고 INSERT 문은 다음을 사용합니다.

    이제 값이 있어야 할 무엇으로 COALESCE 함수는 널 (null)을 대체하여 사용할 것 기본적으로 결정할 수 있습니다.

  16. ==============================

    16.당신은이 작업에서이 일을 생각하지 마십시오.

    당신은이 작업에서이 일을 생각하지 마십시오.

    단계 :

    1) 새로운 항목을 추가합니다 "INSERT 또는 무시"

    2) 업데이트 "UPDATE"있는 항목을 기존

    두 단계의 입력은 새로운 또는 업데이트 할 수 동일한 항목 모음입니다. 변경이 필요없는 기존 항목과 벌금을 작동합니다. 그들은 업데이트,하지만 같은 데이터 때문에 최종 결과로 변경되지 않습니다됩니다.

    물론, 느린 등 비효율적. 네.

    쉬운 SQL을 작성하고 유지하고 그것을 이해하는? 명확히.

    그것은 고려하는 트레이드 오프입니다. 작은 upserts에 좋은 작품. 코드 유지 보수를위한 희생 효율성을 생각하지 않는 사람들을 위해 좋은 작동합니다.

  17. ==============================

    17.그냥이 스레드를 읽은하고 그냥 보내고이 "UPSERT"에 쉽지 않았다 실망하고, 내가 더 조사 ...

    그냥이 스레드를 읽은하고 그냥 보내고이 "UPSERT"에 쉽지 않았다 실망하고, 내가 더 조사 ...

    당신은 실제로 SQLite는 직접 쉽게이 작업을 수행 할 수 있습니다.

    대신 사용 : INSERT INTO

    사용 : INSERT OR REPLACE INTO

    이것은 당신이 뭘 원하는지 정확히 않습니다!

  18. ==============================

    18.

    SELECT COUNT(*) FROM table1 WHERE id = 1;
    

    COUNT (*) = 0이

    INSERT INTO table1(col1, col2, cole) VALUES(var1,var2,var3);
    

    다른 경우 COUNT (*)> 0

    UPDATE table1 SET col1 = var4, col2 = var5, col3 = var6 WHERE id = 1;
    
  19. from https://stackoverflow.com/questions/418898/sqlite-upsert-not-insert-or-replace by cc-by-sa and MIT license