2009-05-30 35 views
7

Tôi làm cách nào để chèn hàng loạt bằng SQLite?Làm cách nào để chèn hàng loạt với SQLite?

Tôi đã tra cứu và có vẻ như tôi chèn một câu lệnh chọn. Tôi googled, nhìn vào các ví dụ và tất cả họ trông giống như họ đang sao chép dữ liệu từ một bảng khác hoặc không tương thích với SQLite. Tôi muốn làm một cái gì đó giống như

"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 [email protected]"; 

Tôi đã thử đoạn code dưới đây và tôi nhận được lỗi "lỗi SQLite không có cột như: 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(); 
+0

Bạn đang sử dụng System.Data.Sqlite? –

+0

Lưu ý CREATE cho bảng usr_msg_media tạo một cột có tên là current_date, nhưng INSERT cố gắng đặt current_media_date thay vào đó: Tôi tin rằng lỗi này đang bị sai lệch bởi SQLite (nó bị nhầm lẫn và tuyên bố cột bị thiếu là người xem), vì tôi có thể tái tạo thông báo lỗi sai - nhưng nếu tôi sửa lỗi thực, nó hoạt động, xem mã mẫu Python trong câu trả lời của tôi. –

Trả lời

2

SQLite không hỗ trợ ký hiệu @variable, nhưng (bằng cách sử dụng kiểu giữ chỗ được đặt tên như được hỗ trợ bởi ràng buộc Python của sqlite để rõ ràng), điều này sẽ hoạt động:

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

Chỉnh sửa: SQLite có vẻ sai lầm về tên cột nào sai. Với tên cột tất cả cố định, mã Python sau làm việc cho tôi (không chắc chắn những gì ngôn ngữ khác mà bạn đang sử dụng, Python là những gì handiest với tôi để tương tác với SQLite):

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() 

Nhưng nếu tôi sao chép sai lệch trong SQL của bạn chẳng hạn như current_date vs current_media_date, tôi có thể làm cho nó chẩn đoán sai rằng cột bị thiếu là watcher, mặc dù cột đó thực tế là tốt. Bạn muốn thử đặt mã đã sửa này trở lại ngôn ngữ yêu thích của bạn và xem nó hoạt động như thế nào?

+0

Tôi đã thử nó, tôi nhận được không có lỗi cột như vậy. –

+0

Điều đó cho thấy một trong các tên cột của bạn được viết sai chính tả - câu lệnh 'CREATE TABLE' cho bảng' user_msg_media' là gì? –

+0

(tức là, giả sử bất kỳ ngôn ngữ nào bạn đang sử dụng đều sử dụng cú pháp tương tự cho trình giữ chỗ như pysqlite và bạn cũng chuyển vào đúng dict, băm hoặc bất kỳ thứ gì) ... –

1

tôi sẽ đề nghị sử dụng Dapper ORM từ bạn bè của chúng tôi tại StackOverflow. Nếu bạn nhìn vào phần về hiệu suất, bạn không thể nhanh hơn Dapper nhiều.

Thực hiện một lệnh nhiều lần
Chữ ký này cũng cho phép bạn để thuận tiện và hiệu quả thực thi một lệnh nhiều lần (ví dụ số liệu số lượng lớn-load)

Ví dụ sử dụng:

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" 

Điều này phù hợp với bất kỳ thông số nào triển khai IEnumerable cho một số T.

+0

haha, 2,5 năm đến trễ. sử dụng dapper (hoặc chọn) và orm của riêng tôi (cho mọi thứ khác) mà đá ass ra khỏi subsonic và crapped khác được gọi là orms –

+1

Tôi vui mừng khi nghe bạn đang có thành công với Dapper Tôi chỉ đề nghị nó để đưa vào sản xuất của chúng tôi ứng dụng. – BrokeMyLegBiking

Các vấn đề liên quan