2

SQLiteAndroidで次のクエリを実行するとエラーが発生します

sDataBase.execSQL(query);

連絡先(ID、FirstName、LastName、PhoneNumber、EmailId、Status)に挿入values('ae0caa6a-8ff6-d63f-0253-110b20ac2127'、'xxx'、'xxx'、 '9008987887'、'xxx@gmail.com'、 'はい')、( '9afab56e-a18a-47f2-fd62-35c78d8e0d94'、'yyy'、'yyy'、 '7890988909'、'yyy@gmail.com'、'はい')、( '378d757a-ee60-07a4 -e8bc-396b402c3270'、' zzz'、' zzz'、' 9000898454'、' zzz@gmail.com'、' Yes​​')

注:これはSQLServerで正常に実行され、AndroidSQLiteでエラーが発生します。

Error: sqlite returned: error code = 1, msg = near ",": syntax error, db=/data/data/myapp.contactmanager/databases/webview.db

編集1:値の間にスペースを追加しましたがまだエラーが発生します

insert into Contacts(ID, FirstName, LastName, PhoneNumber, EmailId,Status) values
('ae0caa6a-8ff6-d63f-0253-110b20ac2127', 'xxx', 'xxx','9008987887', 'xxx@gmail.com', 'Yes'), 
('9afab56e-a18a-47f2-fd62-35c78d8e0d94', 'yyy', 'yyy', '7890988909', 'yyy@gmail.com', 'Yes'), 
('378d757a-ee60-07a4-e8bc-396b402c3270', 'zzz', 'zzz', '9000898454', 'zzz@gmail.com', 'Yes')

編集2:を使用してクエリを変更しましたSQLiteデータベースに一度に複数の行を挿入することは可能ですか?まだ動作していません

INSERT INTO Contacts 
SELECT 'ae0caa6a-8ff6-d63f-0253-110b20ac2127' AS ID, 'xxx' AS FirstName, 'xxx' AS LastName, '9008987887' AS PhoneNumber, 'xxx@gmail.com' AS EmailId, 'Yes' AS Status, 
UNION SELECT '9afab56e-a18a-47f2-fd62-35c78d8e0d94', 'yyy', 'yyy', '7890988909', 'yyy@gmail.com', 'Yes' 
UNION SELECT '378d757a-ee60-07a4-e8bc-396b402c3270', 'zzz', 'zzz', '9000898454', 'zzz@gmail.com', 'Yes'

編集3:編集2で小さな間違いをしました。同期の終了ステータスはbefore UNION i have included comma、であるため、エラーが発生しました。これで削除され、正常に動作しています

INSERT INTO Contacts 
SELECT 'ae0caa6a-8ff6-d63f-0253-110b20ac2127' AS ID, 'xxx' AS FirstName, 'xxx' AS LastName, '9008987887' AS PhoneNumber, 'xxx@gmail.com' AS EmailId, 'Yes' AS Status 
UNION SELECT '9afab56e-a18a-47f2-fd62-35c78d8e0d94', 'yyy', 'yyy', '7890988909', 'yyy@gmail.com', 'Yes' 
UNION SELECT '378d757a-ee60-07a4-e8bc-396b402c3270', 'zzz', 'zzz', '9000898454', 'zzz@gmail.com', 'Yes'
4

3 に答える 3

4

SQLiteエラーに複数の行を挿入

私はあなたのアプローチが本当に好きではありません。それはとてもハードコアで、スパゲッティコードのように見えます。また、 1つの挿入には1つの値しか持てないため、このアプローチは機能しません。だからあなたはそれを間違ってやっています。API insert()挿入用に直接設計した方法を使ってみませんか?

また、速度性能とセキュリティの観点からも、使用することをお勧めしますTRANSACTION。しかし、特にあなたのためにいくつかのコードを書きに行きましょう。

public void insertMultiple(List<Contact> contacts) {
    Contact c = null;
    ContentValues values = new ContentValues();
    try {
        if (db != null) {
            db.beginTransaction();
            for (Contact c: contacts) {
                values.put(SQLConstants.FIRSTNAME, c.getFirstName());
                values.put(SQLConstants.LASTNAME, c.getLastName());
                ...
                db.insertOrThrow("Contacts", SQLConstants.FIRSTNAME, values);
                values.clear();
            }
            db.setTransactionSuccessful();
        }
    }
    finally {
        if (db != null && db.inTransaction()) {
            db.endTransaction();
        }
    }
}

ノート:

Constactsというテーブルがあることに気付いたので、オブジェクトのプロパティがテーブルの列と等しいアプリケーション層でテーブルを表す独自のオブジェクト連絡先を作成することをお勧めします。このアプローチを使用することをお勧めします。理由は次のとおりです。

  • spagetthiコードではありません
  • かなり速いです
  • それははるかに安全です

最後にいくつかの提案:

execSQL()SQLiteOpenHelper悪くはありませんが、テーブルを作成、削除、変更するためのサブクラスを作成する場合にのみ、一般的に使用しています。使用法はかなり適しています。しかし、あなたへの主な推奨事項は次のとおりです。

  • トランザクションの使用を挿入、更新、削除するたびに、常に非常に良い方法があります。これは、速度パフォーマンスの向上(特に多数の行を挿入する場合)を除いて、データベースでの作業がはるかに安全になるためです。

情報のみ: SQLiteに1000、10000、100 000行を挿入したときにいくつかのテストを行いましたが、100000行の挿入には55,346秒しかかからなかったことがわかります。トランザクションなしで1000行を挿入すると、73,398秒もかかりました。

  • 1つ以上のテーブルから選択、挿入、更新するたびに、プレースホルダー、つまりパラメーター化されたステートメントを使用し、ハードコードされていません。これにより、クエリはより安全に、より速く、より人間が読めるようになります。結合する場合は、常に結合句を使用してください。選択できるのが最善です。

アップデート:

これがあなたのコードを動かしています:

insert into Contacts(ID, FirstName, LastName, PhoneNumber, EmailId, Status) 
select 'someId' as ID, 'xxx' as FirstName, 'xxx' as LastName , '9008987887' as PhoneNumber , 'xxx@gmail.com' as EmaiId, 'Yes' as Status
union all select 'someId', 'xxx', 'xxx', '9008987887', 'xxx@gmail.com', 'Yes'
union all select 'someId', 'xxx', 'xxx', '9008987887', 'xxx@gmail.com', 'Yes'

アップデート2:

@Korniltsev AnatolyがSQLiteで指摘したようにSQLITE_MAX_COMPOUND_SELECT、一度に500を超えるユニオンを使用できないことを意味する制約があります。

于 2013-03-25T11:27:14.503 に答える
2

@Sajmonの答えに加えて:

sqliteには制限があります-SQLITE_MAX_COMPOUND_SELECTは、ほとんどすべてのデバイスで500以上です。つまり、一度に500を超えるユニオンを使用することはできません。もっと使用すると、SQLクエリが失敗する可能性があります。

于 2013-03-26T07:12:49.183 に答える
1

これは、SQLiteに複数の行を挿入する方法ではありません。詳細については、この投稿を参照してください。

私があなたなら、その質問の答えの構文を使用するか、一度に1つの行を挿入できるようにしたい場合は、標準INSERT INTO db (one, two) VALUES (one, two)を実行して、挿入する行ごとに1回実行します。君による!

于 2013-03-25T11:17:45.667 に答える