programing

SQLite 데이터베이스에 한 번에 여러 행을 삽입할 수 있습니까?

lovejava 2023. 5. 19. 23:53

SQLite 데이터베이스에 한 번에 여러 행을 삽입할 수 있습니까?

MySQL에서는 다음과 같은 여러 행을 삽입할 수 있습니다.

INSERT INTO 'tablename' ('column1', 'column2') VALUES
    ('data1', 'data2'),
    ('data1', 'data2'),
    ('data1', 'data2'),
    ('data1', 'data2');

하지만 이런 일을 하려고 하면 오류가 발생합니다.SQLite 데이터베이스에 한 번에 여러 행을 삽입할 수 있습니까?그것을 하기 위한 구문은 무엇입니까?

갱신하다

Brian Campbell이 여기서 지적했듯이 SQLite 3.7.11 이상은 이제 원래 게시물의 단순한 구문을 지원합니다.그러나 기존 데이터베이스 간의 최대 호환성을 원하는 경우에는 표시된 접근 방식이 적합합니다.

원답

만약 제가 특권을 가지고 있다면, 저는 리버의 대답을 뛰어넘을 것입니다.SQLite에 여러 행을 삽입할 수 있으므로 다른 구문이 필요합니다.OPS MySQL의 예는 다음과 같습니다.

INSERT INTO 'tablename' ('column1', 'column2') VALUES
  ('data1', 'data2'),
  ('data1', 'data2'),
  ('data1', 'data2'),
  ('data1', 'data2');

이는 다음과 같이 SQLite에 다시 캐스트할 수 있습니다.

     INSERT INTO 'tablename'
          SELECT 'data1' AS 'column1', 'data2' AS 'column2'
UNION ALL SELECT 'data1', 'data2'
UNION ALL SELECT 'data1', 'data2'
UNION ALL SELECT 'data1', 'data2'

연주에 관한 주의.

저는 원래 Ruby on Rails에서 대용량 데이터 세트를 효율적으로 로드하기 위해 이 기술을 사용했습니다.하지만 제이미 쿡이 지적했듯이, 이것이 더 빨리 포장하는 개인인지는 확실하지 않습니다.INSERTs단일 트랜잭션 내:

BEGIN TRANSACTION;
INSERT INTO 'tablename' table VALUES ('data1', 'data2');
INSERT INTO 'tablename' table VALUES ('data3', 'data4');
...
COMMIT;

효율성이 목표라면 먼저 이것을 시도해야 합니다.

유니언 대 유니언 올에 대한 메모

이 댓글을 달아주신 처럼 몇분댓달이듯셨아주글이당몇을 하면 만신약들이.UNION ALL(), 이 에는 (으)ㄹ 수 있다, (으)ㄹ 수 있다, (으)ㄹ 수 있다, (으)ㄹ 수 있다, (으)ㄹ 수 있다, (으)ㄹ 수 있다, (으)ㄹ 수 data1, data2를 하면,ALL그러면 중복 행이 제거되고 작업 속도가 다소 느려집니다.원래 게시물의 의미와 더 일치하기 때문에 UNION ALL을 사용하고 있습니다.

마지막으로

추신: 먼저 해결책을 제시했으니 +1강의 답변을 부탁드립니다.

예, 가능하지만 일반적인 쉼표로 구분된 삽입 값으로는 불가능합니다.

해보세요...

insert into myTable (col1,col2) 
     select aValue as col1,anotherValue as col2 
     union select moreValue,evenMoreValue 
     union...

예, 값 집합에서 문 생성을 자동화할 수 있을 정도로 약간 추악하지만 쉽습니다.또한 첫 번째 선택에서 열 이름만 선언하면 됩니다.

예, SQLite 3.7.11부터 이 기능은 SQLite에서 지원됩니다.SQLite 설명서에서 다음을 수행합니다.

SQLite INSERT 문 구문

(이 답변이 처음 작성되었을 때 지원되지 않았습니다.)

이전 버전의 SQLite와의 호환성을 위해 다음을 사용하여 Andy 및 fearless_fool에서 제안한 trick을 사용할 수 있습니다.UNION그러나 3.7.11 이상의 경우에는 여기에 설명된 간단한 구문을 선호해야 합니다.

서드 파티

한 가지 샘플은 다음과 같습니다.

INSERT INTO MyTable 
    ( Column_foo, Column_CreatedOn) 
    VALUES 
        ('foo 1', '2023-02-20 14:10:00.001'),
        ('foo 2', '2023-02-20 14:10:00.002'),
        ('foo 3', '2023-02-20 14:10:00.003')    

저는 루비 코드를 작성하여 일련의 삽입 문에서 단일 500 요소 멀티 행 삽입을 생성했습니다. 이는 개별 삽입을 실행하는 것보다 상당히 빠른 속도입니다.그런 다음 여러 개의 삽입물을 한 번의 트랜잭션으로 간단히 포장해 보았더니 상당히 적은 코드로 동일한 속도를 낼 수 있었습니다.

BEGIN TRANSACTION;
INSERT INTO table VALUES (1,1,1,1);
INSERT INTO table VALUES (2,2,2,2);
...
COMMIT;

이 페이지에서는 지원되지 않습니다.

  • 2007-12-03 : 다중 행 INSERT 또는 복합 INSERT가 지원되지 않습니다.
  INSERT INTO table (col1, col2) VALUES 
      ('row1col1', 'row1col2'), ('row2col1', 'row2col2'), ...

실제로 SQL92 표준에 따르면 VALUE 표현식은 자체적으로 존재할 수 있습니다.를 들어,은 세 행이 .VALUES 'john', 'mary', 'paul';

버전 3.7.11부터 SQLite다중 행 삽입을 지원합니다.Richard Hipp 논평:

"새로운 다중값 인서트는 복합 인서트를 위한 통사적 설탕(sic)일 뿐입니다.어느 쪽이든 성능 면에서 이점은 없습니다."

버전 2012-03-20(3.7.11)부터 sqlite는 다음 INSERT 구문을 지원합니다.

INSERT INTO 'tablename' ('column1', 'column2') VALUES
  ('data1', 'data2'),
  ('data3', 'data4'),
  ('data5', 'data6'),
  ('data7', 'data8');

설명서 읽기: http://www.sqlite.org/lang_insert.html

PS: Brian Campbell의 답변에 +1로 답변해 주십시오.내 것이 아닙니다!그가 먼저 해결책을 제시했습니다.

예, sql은 이렇게 할 수 있지만 구문이 다릅니다.참고로, sqlite 문서는 꽤 좋습니다.또한 여러 행을 삽입하는 유일한 방법은 삽입할 데이터의 원본으로 선택 문을 사용하는 것입니다.

다른 포스터에서 말했듯이 SQLite는 이 구문을 지원하지 않습니다.복합 INSERT가 SQL 표준의 일부인지는 모르겠지만, 제 경험으로는 많은 제품에 구현되지 않았습니다.

또한 명시적 트랜잭션에서 여러 INSERT를 래핑하면 SQLite의 INSERT 성능이 상당히 향상됩니다.

INSERT INTO TABLE_NAME 
            (DATA1, DATA2) 
VALUES      (VAL1, VAL2), 
            (VAL1, VAL2), 
            (VAL1, VAL2), 
            (VAL1, VAL2), 
            (VAL1, VAL2), 
            (VAL1, VAL2), 
            (VAL1, VAL2), 
            (VAL1, VAL2); 

SQLite3는 SELECT를 통해가 아니면 SQL에서 직접 이 작업을 수행할 수 없으며 SELECT가 식의 "행"을 반환할 수는 있지만 가짜 열을 반환하도록 할 방법은 없습니다.

그러나 CLI는 다음을 수행할 수 있습니다.

.import FILE TABLE     Import data from FILE into TABLE
.separator STRING      Change separator used by output mode and .import

$ sqlite3 /tmp/test.db
SQLite version 3.5.9
Enter ".help" for instructions
sqlite> create table abc (a);
sqlite> .import /dev/tty abc
1
2
3
99
^D
sqlite> select * from abc;
1
2
3
99
sqlite> 

CLI를 INSERT에 를 둘 INSERT가 됩니다..import명령을 실행한 다음 SQLite FAQ의 지침에 따라 INSERT 속도를 확인하십시오.

기본적으로 각 INSERT 문은 자체 트랜잭션입니다.그러나 여러 INSERT 문을 BEGIN...COMMIT로 둘러싸면 모든 삽입이 단일 트랜잭션으로 그룹화됩니다.트랜잭션을 커밋하는 데 필요한 시간은 동봉된 모든 삽입 문에서 상각되므로 삽입 문당 시간이 크게 줄어듭니다.

또 다른 옵션은 PRAGMA 동기식=을 실행하는 것입니다.OFF. 이 명령을 실행하면 SQLite에서 디스크 표면에 도달할 때까지 데이터를 기다리지 않으므로 쓰기 작업이 훨씬 더 빨라집니다.그러나 트랜잭션 도중에 전원이 차단되면 데이터베이스 파일이 손상될 수 있습니다.

알렉스 말이 맞아요. "선택..."union" 문은 일부 사용자에게 매우 중요한 순서를 잃게 됩니다.특정 순서로 삽입할 때도 sqlite는 내용을 변경하므로 삽입 순서가 중요한 경우 트랜잭션을 사용하는 것을 선호합니다.

create table t_example (qid int not null, primary key (qid));
begin transaction;
insert into "t_example" (qid) values (8);
insert into "t_example" (qid) values (4);
insert into "t_example" (qid) values (9);
end transaction;    

select rowid,* from t_example;
1|8
2|4
3|9

fearless_message는 이전 버전에 대한 훌륭한 답변을 제공합니다.저는 당신이 모든 열을 나열했는지 확인해야 한다는 것을 덧붙이고 싶습니다.따라서 열이 3개인 경우에는 선택 항목이 3개 열에 작용하는지 확인해야 합니다.

예:나는 3개의 열이 있지만 2개의 열 값의 데이터만 삽입하려고 합니다.첫 번째 열은 표준 정수 ID이므로 상관없다고 가정합니다.제가 할 수 있는 일은...

INSERT INTO 'tablename'
      SELECT NULL AS 'column1', 'data1' AS 'column2', 'data2' AS 'column3'
UNION SELECT NULL, 'data3', 'data4'
UNION SELECT NULL, 'data5', 'data6'
UNION SELECT NULL, 'data7', 'data8'

참고: "선택..."을 기억하십시오.union" 문은 주문을 잃게 됩니다. (AG1부터)

당신은 할 수 없지만 저는 당신이 놓친 것이 없다고 생각합니다.

항상 sqlite를 호출하기 때문에 1개의 insert 문을 실행하든 100개의 insert 문을 실행하든 성능에는 거의 문제가 없습니다.그러나 커밋은 시간이 많이 걸리므로 트랜잭션 내부에 100개의 인서트를 삽입합니다.

SQLite는 매개 변수화된 쿼리를 사용할 때 훨씬 더 빠르기 때문에(파싱이 훨씬 덜 필요함) 다음과 같은 큰 문을 연결하지 않습니다.

insert into mytable (col1, col2)
select 'a','b'
union 
select 'c','d'
union ...

연결된 모든 문이 다르기 때문에 반복적으로 구문 분석해야 합니다.

mysqlite에서 여러 값을 삽입할 수는 없지만 연결을 한 번만 연 다음 모든 삽입을 수행하고 연결을 닫으면 시간을 절약할 수 있습니다.시간을 많이 절약합니다.

단순하고, 자기 설명적입니다.

버전 3.36.0 11/20/21에서 테스트합니다.

CREATE TEMP TABLE x (col1 TEXT, col2 TEXT, col3 TEXT);

INSERT INTO x 
VALUES 
('xx','yy','cc'),
('xx','yy','cc'),
('xx','yy','cc'),
('xx','yy','cc'),
('xx','yy','cc'),
('xx','yy','cc');

SELECT * FROM x;

출력:

col1|col2|col3|
----+----+----+
xx  |yy  |cc  |
xx  |yy  |cc  |
xx  |yy  |cc  |
xx  |yy  |cc  |
xx  |yy  |cc  |
xx  |yy  |cc  |

버전 확인:

SELECT sqlite_version();

출력:

sqlite_version()|
----------------+
3.36.0          |

어떤 사람들은 이렇게 말할지도 모릅니다 - 모든 "..UNION ." 답변은 구식입니다. 그럼에도 불구하고 매우 유용합니다.때때로 우리 모두는 "과거로부터의 폭발"로 책상에 앉습니다. 그리고 나서 15년 된 쪽지가 우리의 하루를 구합니다.

트랜잭션을 사용할 때의 문제는 읽기를 위해서도 테이블을 잠글 수 있다는 것입니다.따라서 삽입할 데이터가 너무 많아서 미리 보기 등과 같이 데이터에 액세스해야 하는 경우에는 이 방법이 제대로 작동하지 않습니다.

다른 솔루션의 문제는 삽입 순서를 잃는다는 것입니다.

insert into mytable (col)
select 'c'
union 
select 'd'
union 
select 'a'
union 
select 'b';

sqlite에서 데이터는 a,b,c,d...를 저장할 것입니다.

버전 3.7.11부터 SQLite는 다중 행 삽입을 지원합니다.Richard Hipp 논평:

3.6.13을 사용합니다.

나는 다음과 같이 명령합니다.

insert into xtable(f1,f2,f3) select v1 as f1, v2 as f2, v3 as f3 
union select nextV1+, nextV2+, nextV3+

한 번에 50개의 레코드를 삽입하면 1초 이내에 완료됩니다.

sqlite를 사용하여 한 번에 여러 행을 삽입하는 것은 매우 가능합니다.@Andy가 썼습니다.

감사합니다 앤디 +1

INSERT INTO tabela(coluna1,coluna2) 
SELECT 'texto','outro'
UNION ALL 
SELECT 'mais texto','novo texto';

쿼리를 동적으로 만들 수 있습니다.내 테이블은 다음과 같습니다.

CREATE TABLE "tblPlanner" ("probid" text,"userid" TEXT,"selectedtime" DATETIME,"plannerid" TEXT,"isLocal" BOOL,"applicationid" TEXT, "comment" TEXT, "subject" TEXT)

그리고 나는 모든 데이터를 A를 통해 얻고 있습니다.JSON그래서 모든 것을 안에 넣은 후에.NSArray나는 이것을 따랐습니다.

    NSMutableString *query = [[NSMutableString alloc]init];
    for (int i = 0; i < arr.count; i++)
    {
        NSString *sqlQuery = nil;
        sqlQuery = [NSString stringWithFormat:@" ('%@', '%@', '%@', '%@', '%@', '%@', '%@', '%@'),",
                    [[arr objectAtIndex:i] objectForKey:@"plannerid"],
                    [[arr objectAtIndex:i] objectForKey:@"probid"],
                    [[arr objectAtIndex:i] objectForKey:@"userid"],
                    [[arr objectAtIndex:i] objectForKey:@"selectedtime"],
                    [[arr objectAtIndex:i] objectForKey:@"isLocal"],
                    [[arr objectAtIndex:i] objectForKey:@"subject"],
                    [[arr objectAtIndex:i] objectForKey:@"comment"],
                    [[NSUserDefaults standardUserDefaults] objectForKey:@"applicationid"]
                    ];
        [query appendString:sqlQuery];
    }
    // REMOVING LAST COMMA NOW
    [query deleteCharactersInRange:NSMakeRange([query length]-1, 1)];

    query = [NSString stringWithFormat:@"insert into tblPlanner (plannerid, probid, userid, selectedtime, isLocal, applicationid, subject, comment) values%@",query];

마지막으로 출력 쿼리는 다음과 같습니다.

insert into tblPlanner (plannerid, probid, userid, selectedtime, isLocal, applicationid, subject, comment) values 
<append 1>
('pl1176428260', '', 'US32552', '2013-06-08 12:00:44 +0000', '0', 'subj', 'Hiss', 'ap19788'),
<append 2>
('pl2050411638', '', 'US32552', '2013-05-20 10:45:55 +0000', '0', 'TERI', 'Yahoooooooooo', 'ap19788'), 
<append 3>
('pl1828600651', '', 'US32552', '2013-05-21 11:33:33 +0000', '0', 'test', 'Yest', 'ap19788'),
<append 4>
('pl549085534', '', 'US32552', '2013-05-19 11:45:04 +0000', '0', 'subj', 'Comment', 'ap19788'), 
<append 5>
('pl665538927', '', 'US32552', '2013-05-29 11:45:41 +0000', '0', 'subj', '1234567890', 'ap19788'), 
<append 6>
('pl1969438050', '', 'US32552', '2013-06-01 12:00:18 +0000', '0', 'subj', 'Cmt', 'ap19788'),
<append 7>
('pl672204050', '', 'US55240280', '2013-05-23 12:15:58 +0000', '0', 'aassdd', 'Cmt', 'ap19788'), 
<append 8>
('pl1019026150', '', 'US32552', '2013-06-08 12:15:54 +0000', '0', 'exists', 'Cmt', 'ap19788'), 
<append 9>
('pl790670523', '', 'US55240280', '2013-05-26 12:30:21 +0000', '0', 'qwerty', 'Cmt', 'ap19788')

코드를 통해서도 잘 실행되고 SQLite에 모든 것을 성공적으로 저장할 수 있습니다.

는 이전제가만든을 만들었습니다.UNION쿼리 항목 동적이지만 구문 오류가 발생하기 시작했습니다.어쨌든, 저는 잘 운영되고 있습니다.

아무도 준비된 진술을 언급하지 않은 것이 놀랍습니다.SQL을 사용하지 않고 다른 언어 내에서 사용하지 않는 경우, 트랜잭션으로 묶인 준비된 문이 여러 행을 삽입하는 가장 효율적인 방법이라고 생각합니다.

를 사용하는 경우Sqlite 매니저 Firefox 플러그인은 다음에서 대량 삽입을 지원합니다. INSERTSQL 문입니다.

사실 이것은 지원하지 않지만, Sqlite Browser는 지원합니다(Windows, OS X, Linux에서 작동).

sqlite 3.7.2에서:

INSERT INTO table_name (column1, column2) 
                SELECT 'value1', 'value1' 
          UNION SELECT 'value2', 'value2' 
          UNION SELECT 'value3', 'value3' 

등등

아래와 같은 질문이 있는데, ODBC 드라이버를 사용하면 SQLite에 "" 오류가 있습니다.저는 HTA(Html Application)에서 vbscript를 실행합니다.

    INSERT INTO evrak_ilac_iliskileri (evrak_id, ilac_id, 
baglayan_kullanici_id, tarih) VALUES (4150,762,1,datetime()),
(4150,9770,1,datetime()),(4150,6609,1,datetime()),(4150,3628,1,datetime()),
(4150,9422,1,datetime())

InsertHelper를 사용할 수 있습니다. 쉽고 빠릅니다.

설명서: http://developer.android.com/reference/android/database/DatabaseUtils.InsertHelper.html

튜토리얼: http://www.outofwhatbox.com/blog/2010/12/android-using-databaseutils-inserthelper-for-faster-insertions-into-sqlite-database/

편집: InsertHelper는 API 레벨 17에서 더 이상 사용되지 않습니다.

bash 셸을 사용하는 경우 다음을 사용할 수 있습니다.

time bash -c $'
FILE=/dev/shm/test.db
sqlite3 $FILE "create table if not exists tab(id int);"
sqlite3 $FILE "insert into tab values (1),(2)"
for i in 1 2 3 4; do sqlite3 $FILE "INSERT INTO tab (id) select (a.id+b.id+c.id)*abs(random()%1e7) from tab a, tab b, tab c limit 5e5"; done; 
sqlite3 $FILE "select count(*) from tab;"'

또는 sqlite CLI를 사용하는 경우 다음 작업을 수행해야 합니다.

create table if not exists tab(id int);"
insert into tab values (1),(2);
INSERT INTO tab (id) select (a.id+b.id+c.id)*abs(random()%1e7) from tab a, tab b, tab c limit 5e5;
INSERT INTO tab (id) select (a.id+b.id+c.id)*abs(random()%1e7) from tab a, tab b, tab c limit 5e5;
INSERT INTO tab (id) select (a.id+b.id+c.id)*abs(random()%1e7) from tab a, tab b, tab c limit 5e5;
INSERT INTO tab (id) select (a.id+b.id+c.id)*abs(random()%1e7) from tab a, tab b, tab c limit 5e5;
select count(*) from tab;

어떻게 작동합니까?테이블에 있는 경우 그것을 사용합니다.tab:

id int
------
1
2

그리고나서select a.id, b.id from tab a, tab b돌아온다

a.id int | b.id int
------------------
    1    | 1
    2    | 1
    1    | 2
    2    | 2

등등.첫 번째 실행 후에 우리는 2개의 행을 삽입하고, 그 다음에 2^3=8을 삽입합니다. (3개는 우리가 가지고 있기 때문입니다.)tab a, tab b, tab c)

두 번째 실행 후에 추가로 삽입합니다.(2+8)^3=1000행들

세 번째 이후에 우리는 약을 삽입합니다.max(1000^3, 5e5)=500000행 등...

이것은 SQLite 데이터베이스를 채우는 가장 빠른 방법입니다.

언급URL : https://stackoverflow.com/questions/1609637/is-it-possible-to-insert-multiple-rows-at-a-time-in-an-sqlite-database