Pertanyaan ini sepertinya sering muncul di sini. Tandai memiliki jawaban yang benar (dan paling umum digunakan), tetapi izinkan saya mencoba menambahkan apa yang saya bisa untuk membuatnya lebih jelas.
Pesan kesalahannya sedikit menyesatkan. SQL Server memberi tahu Anda bahwa ia tidak memiliki cukup memori untuk berjalan kueri, tetapi yang sebenarnya berarti tidak memiliki cukup memori untuk mengurai kueri.
Dalam hal berlari query, SQL Server dapat menggunakan semua yang diinginkan - gigabyte jika perlu. Parsing adalah cerita lain; server harus membangun pohon parse dan hanya ada jumlah memori yang sangat terbatas yang tersedia untuk itu. Saya tidak pernah menemukan batas aktual yang didokumentasikan di mana pun kecuali untuk kumpulan tipikal yang penuh dengan INSERT
pernyataan, tidak dapat menangani lebih dari beberapa MB sekaligus.
Jadi saya minta maaf untuk memberi tahu Anda ini tetapi Anda tidak bisa buat SQL Server mengeksekusi skrip ini persis seperti yang tertulis. Tidak mungkin, tidak bagaimana, tidak peduli pengaturan apa yang Anda atur. Namun, Anda memiliki sejumlah opsi untuk mengatasinya:
Secara khusus, Anda memiliki tiga opsi:
-
Gunakan
GO
pernyataan. Ini digunakan oleh SSMS dan berbagai alat lain sebagai pemisah batch. Alih-alih pohon parse tunggal yang dihasilkan untuk seluruh skrip, pohon parse individu dihasilkan untuk setiap segmen kumpulan yang dipisahkan olehGO
. Inilah yang dilakukan kebanyakan orang, dan sangat mudah untuk membuat skrip tetap aman untuk transaksi, seperti yang telah ditunjukkan oleh orang lain dan saya tidak akan mengulanginya di sini. -
Alih-alih membuat skrip besar untuk menyisipkan semua baris, simpan data dalam file teks (yaitu dipisahkan koma). Kemudian impor menggunakan utilitas bcp . Jika Anda ingin ini menjadi "scriptable" - yaitu impor harus terjadi dalam skrip/transaksi yang sama dengan
CREATE TABLE
pernyataan, lalu gunakan MASUKKAN BULK alih-alih. MeskipunBULK INSERT
adalah operasi yang tidak dicatat, percaya atau tidak, itu masih dapat ditempatkan dalamBEGIN TRAN
/COMMIT TRAN
blokir. -
Jika Anda benar-benar menginginkan
INSERT
untuk menjadi operasi yang dicatat, dan tidak ingin penyisipan terjadi dalam batch, maka Anda dapat menggunakan OPENROWSET untuk membuka file teks, file excel, dll. sebagai "tabel" ad-hoc, lalu masukkan ini ke dalam tabel yang baru Anda buat. Saya biasanya enggan merekomendasikan penggunaanOPENROWSET
, tetapi karena ini jelas merupakan skrip administratif, itu bukan masalah besar.
Komentar sebelumnya menunjukkan bahwa Anda tidak nyaman dengan #1, meskipun itu mungkin hanya karena asumsi yang salah bahwa itu tidak dapat dilakukan dalam satu transaksi, dalam hal ini lihat Thomas
jawaban. Tetapi jika Anda tidak yakin dengan cara lain, saya sarankan menggunakan #2, membuat file teks dan menggunakan BULK INSERT
. Contoh skrip "aman" adalah:
BEGIN TRAN
BEGIN TRY
CREATE TABLE MyTable (...)
BULK INSERT MyTable
FROM 'C:\Scripts\Data\MyTableData.txt'
WITH (
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\r\n',
BATCHSIZE = 1000,
MAXERRORS = 1
)
COMMIT
END TRY
BEGIN CATCH
ROLLBACK
END CATCH
Semoga ini membantu menempatkan Anda di jalur yang benar. Saya cukup yakin ini mencakup semua opsi "dalam kotak" Anda yang tersedia - di luar ini, Anda harus mulai menulis program aplikasi atau skrip shell yang sebenarnya untuk melakukan pekerjaan itu, dan saya tidak berpikir bahwa tingkat kerumitannya adalah benar-benar dijamin di sini.