7

SQLite で一括挿入するにはどうすればよいですか?

調べてみたところ、select文で挿入しているようです。私はググって例を見ましたが、それらはすべて、あるテーブルから別のテーブルにデータをコピーしているように見えます。または、SQLite と互換性がありません。私は何かをしたい

"INSERT INTO user_msg_media (recipientId, mediaId, catagory, current_media_date) " +
"VALUES(@mediaId, @catagory, @current_media_date)";
where the value of recipientId is the watcher from each of
"SELECT watcher FROM userwatch WHERE watched=@watched";

以下のコードを試してみたところ、「SQLite error no such column: watcher」というエラーが表示されました。

        command.CommandText =
            "CREATE TABLE if not exists user_msg_media( " +
            "msgId        INTEGER PRIMARY KEY, " +
            "recipientId  INTEGER, " +
            "mediaId      INTEGER, " +
            "catagory     INTEGER, " +
            "current_date DATE);";
        command.ExecuteNonQuery();

        //user media
        command.CommandText =
            "CREATE TABLE if not exists user_watch( " +
            "indx INTEGER PRIMARY KEY, " +
            "watcher INTEGER, " +
            "watched INTEGER);";
        command.ExecuteNonQuery();
        //...

    command.CommandText = "SELECT watcher FROM user_watch WHERE watched=:watched;";
    command.Parameters.Add(":watched", DbType.Int64).Value = 1;
    command.ExecuteNonQuery(); //is ok

    command.CommandText =
        "INSERT INTO user_msg_media (recipientId, mediaId, catagory, current_media_date) " +
        "SELECT watcher, :mediaId, :category, :current_media_date" +
        "FROM user_watch WHERE watched=:watched;";
    command.Parameters.Add(":mediaId", DbType.Int64).Value = 0;
    command.Parameters.Add(":category", DbType.Int64).Value = 0;
    command.Parameters.Add(":current_media_date", DbType.Int64).Value = 0;
    command.Parameters.Add(":watched", DbType.Int64).Value = 1;
    command.ExecuteNonQuery();
4

3 に答える 3

7

SQLite で一括挿入を容易にするためのクラスを作成しました。うまくいけば、それは役に立ちます:

http://procbits.com/2009/09/08/sqlite-bulk-insert/

-JP

于 2009-09-08T19:50:44.347 に答える
2

SQlite は @variable 表記をサポートしていませんが、(わかりやすくするために sqlite の Python バインディングでサポートされている名前付きプレースホルダー スタイルを使用して) これは機能するはずです。

INSERT INTO user_msg_media (userId, mediaId, catagory, current_media_date)
SELECT watcher, :mediaId, :category, :current_media_date
FROM userwatch WHERE watched=:watched

編集: SQLite は、どの列名が間違っているかを誤診しているようです。列名がすべて固定されているので、次の Python コードが機能します (他にどの言語を使用しているかはわかりませんが、sqlite と対話するのに最も便利なのは Python です)。

import sqlite3 as sq

con = sq.connect(':memory:')
cur = con.cursor()
cur.execute("CREATE TABLE if not exists user_msg_media( " +
            "msgId        INTEGER PRIMARY KEY, " +
            "recipientId  INTEGER, " +
            "mediaId      INTEGER, " +
            "catagory     INTEGER, " +
            "current_date DATE)")
cur.execute("CREATE TABLE if not exists user_watch( " +
            "indx INTEGER PRIMARY KEY, " +
            "watcher INTEGER, " +
            "watched INTEGER)")

cur.execute("INSERT INTO user_watch VALUES (1, 2, 3)")

cur.execute("SELECT watcher FROM user_watch WHERE watched=:watched",
            dict(watched=3))
print cur.fetchall()

print cur.execute("INSERT INTO user_msg_media (recipientId, mediaId, catagory, current_date) " +
        "SELECT watcher, :mediaId, :category, :current_media_date " +
        "FROM user_watch WHERE watched=:watched;",
        dict(mediaId=0, category=0, current_media_date=0, watched=3)
)

cur.execute("SELECT * FROM user_msg_media")
print cur.fetchall()

しかし、current_date と current_media_date などの SQL の不一致を再現するとwatcher、その列が実際には問題なくても、欠落している列が であると誤診する可能性があります。この修正されたコードをお気に入りの言語に戻して、どのように動作するかを確認してみませんか?

于 2009-05-30T03:01:34.243 に答える
1

StackOverflow の友人からDapper ORMを使用することをお勧めします。パフォーマンスのセクションを見ると、Dapper よりもはるかに高速になることはありません。

コマンドを複数回実行する
同じシグネチャを使用すると、コマンドを便利かつ効率的に複数回実行することもできます (たとえば、データの一括読み込みなど)。

使用例:

connection.Execute(@"insert MyTable(colA, colB) values (@a, @b)",
    new[] { new { a=1, b=1 }, new { a=2, b=2 }, new { a=3, b=3 } }
  ); // 3 rows inserted: "1,1", "2,2" and "3,3"

これは、一部の T に対して IEnumerable を実装する任意のパラメーターで機能します。

于 2011-11-15T10:43:34.640 に答える