Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

SQL Server 2005 Kesalahan 701 - kehabisan memori

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:

  1. 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 oleh GO . 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.

  2. 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. Meskipun BULK INSERT adalah operasi yang tidak dicatat, percaya atau tidak, itu masih dapat ditempatkan dalam BEGIN TRAN / COMMIT TRAN blokir.

  3. 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 penggunaan OPENROWSET , 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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Berbagai cara untuk menghasilkan kunci asing utama tipe int terbaru dalam kode

  2. Entity Framework 4 Code First - Cegah DB Drop/Create

  3. Permintaan SQL untuk mengambil data dari dua tabel dengan tidak dalam kondisi

  4. Gagal masuk. Login gagal untuk pengguna 'NT AUTHORITY\SYSTEM'

  5. Gunakan TYPE_NAME() untuk Mendapatkan Nama Tipe Data di SQL Server