Saya punya proses yang mengambil banyak catatan (1000-an) dan beroperasi pada mereka, dan ketika saya selesai, saya perlu menandai sejumlah besar dari mereka sebagai diproses. Saya dapat menunjukkan ini dengan daftar besar ID. Saya mencoba untuk menghindari pola "pembaruan dalam satu lingkaran", jadi saya ingin menemukan cara yang lebih efisien untuk mengirim tas ID ini ke dalam proc MS SQL Server 2008 yang disimpan.
Proposal # 1 - Parameter Tabel Bernilai. Saya bisa mendefinisikan tipe tabel w / hanya bidang ID dan mengirim tabel penuh ID untuk memperbarui.
Proposal # 2 - Parameter XML (varchar) dengan OPENXML () di badan proc.
Proposal # 3 - Daftar parsing. Saya lebih suka menghindari ini, jika mungkin, karena tampaknya sulit dan rawan kesalahan.
Adakah preferensi di antara ini, atau ada ide yang saya lewatkan?
sumber
Jawaban:
Artikel terbaik yang pernah ada tentang masalah ini adalah oleh Erland Sommarskog:
Dia mencakup semua opsi dan menjelaskan dengan cukup baik.
Maaf atas jawaban yang singkat, tetapi artikel Erland tentang Array adalah seperti buku-buku Joe Celko tentang pohon dan suguhan SQL lainnya :)
sumber
Ada diskusi hebat tentang ini di StackOverflow yang mencakup banyak pendekatan. Yang saya lebih suka untuk SQL Server 2008+ adalah menggunakan parameter tabel-dihargai . Ini pada dasarnya adalah solusi SQL Server untuk masalah Anda - mengirimkan daftar nilai ke prosedur tersimpan.
Keuntungan dari pendekatan ini adalah:
Namun, perhatikan: Jika Anda memanggil prosedur tersimpan yang menggunakan TVP melalui ADO.NET atau ODBC dan melihat aktivitas dengan SQL Server Profiler, Anda akan melihat bahwa SQL Server menerima beberapa
INSERT
pernyataan untuk memuat TVP, satu untuk setiap baris di TVP , diikuti dengan panggilan ke prosedur. Ini dengan desain . Kumpulan iniINSERT
perlu dikompilasi setiap kali prosedur dipanggil, dan merupakan overhead yang kecil. Namun, bahkan dengan overhead ini, TVP masih menyingkirkan pendekatan lain dalam hal kinerja dan kegunaan untuk sebagian besar kasus penggunaan.Jika Anda ingin mempelajari lebih lanjut, Erland Sommarskog memiliki informasi lengkap tentang cara kerja parameter yang dihargai tabel dan memberikan beberapa contoh.
Berikut adalah contoh lain yang saya buat:
sumber
CREATE TYPE
pernyataan di awal berjalan dengan sukses? Versi SQL Server apa yang Anda jalankan?@customer_list
bukan@param1
. Contoh tersebut hanya menunjukkan bahwa Anda dapat mencampur berbagai jenis parameter.Seluruh subjek dibahas di dalam artikel definitif oleh Erland Sommarskog: "Array dan Daftar di SQL Server" . Pilih versi mana yang akan dipilih.
Ringkasan, untuk pra SQL Server 2008 di mana TVP mengalahkan sisanya
Artikel ini layak dibaca untuk melihat teknik dan pemikiran lain.
Sunting: jawaban terlambat untuk daftar besar di tempat lain: Melewati parameter array ke prosedur tersimpan
sumber
Saya tahu saya terlambat untuk pesta ini, tapi saya punya masalah di masa lalu, harus mengirim hingga 100 ribu angka bigint, dan melakukan beberapa tolok ukur. Kami akhirnya mengirim mereka dalam format biner, sebagai gambar - yang lebih cepat dari yang lainnya hingga 100 ribu angka.
Ini kode lama saya (SQL Server 2005):
Kode berikut mengemas integer ke dalam gumpalan biner. Saya membalik urutan byte di sini:
sumber
Saya bingung antara merujuk Anda ke SO atau menjawabnya di sini, karena ini hampir merupakan pertanyaan pemrograman. Tapi karena saya sudah punya solusi saya menggunakan ... Saya akan memposting itu;)
Cara ini bekerja adalah Anda memberi string yang dibatasi koma (split sederhana, tidak melakukan pemisahan gaya CSV) ke dalam prosedur tersimpan sebagai varchar (4000) dan kemudian mengumpankan daftar itu ke dalam fungsi ini dan mendapatkan tabel yang berguna kembali, meja varchars yang adil.
Ini memungkinkan Anda untuk mengirimkan nilai hanya id yang ingin Anda proses, dan Anda dapat melakukan penggabungan sederhana pada titik itu.
Bergantian Anda bisa melakukan sesuatu dengan CLR DataTable dan memasukkan itu, tapi itu sedikit lebih banyak untuk mendukung dan semua orang mengerti daftar CSV.
sumber
Saya secara teratur menerima set 1000-an baris dan 10.000-an baris yang dikirim dari aplikasi kita untuk diproses oleh berbagai prosedur yang tersimpan SQL Server.
Untuk memenuhi tuntutan kinerja, kami menggunakan TVP, tetapi Anda harus menerapkan abstrak dbDataReader Anda sendiri untuk mengatasi beberapa masalah kinerja dalam mode pemrosesan standarnya. Saya tidak akan membahas bagaimana dan mengapa mereka berada di luar ruang lingkup untuk permintaan ini.
Saya tidak mempertimbangkan pemrosesan XML karena saya belum menemukan implementasi XML yang tetap memiliki lebih dari 10.000 "baris".
Pemrosesan daftar dapat ditangani dengan pemrosesan tabel penghitungan satu dimensi dan dua dimensi. Kami telah berhasil menggunakan ini di berbagai bidang, tetapi TVP yang dikelola dengan lebih baik lebih berkinerja ketika ada lebih dari beberapa ratus "baris".
Seperti semua pilihan tentang pemrosesan SQL Server, Anda harus menentukan pilihan berdasarkan model penggunaan.
sumber
Saya akhirnya mendapat kesempatan untuk melakukan beberapa TableValuedParameters dan mereka bekerja dengan baik, jadi saya akan menempelkan seluruh kode lotta yang menunjukkan bagaimana saya menggunakannya, dengan sampel dari beberapa kode saya saat ini: (catatan: kami menggunakan ADO .BERSIH)
Juga perhatikan: Saya menulis beberapa kode untuk layanan, dan saya punya banyak bit kode yang sudah ditentukan sebelumnya di kelas lain, tapi saya menulis ini sebagai aplikasi konsol sehingga saya bisa men-debug-nya, jadi saya ripping semua ini dari aplikasi konsol. Maafkan gaya pengkodean saya (seperti string koneksi hardcoded) karena itu semacam "membangun satu untuk membuang". Saya ingin menunjukkan bagaimana saya menggunakan
List<customObject>
dan mendorongnya ke dalam database dengan mudah sebagai sebuah tabel, yang dapat saya gunakan dalam prosedur tersimpan. Kode C # dan TSQL di bawah ini:Juga, saya akan menerima kritik konstruktif pada gaya pengkodean saya jika Anda memiliki itu untuk ditawarkan (kepada semua pembaca yang menemukan pertanyaan ini) tetapi tolong tetap konstruktif;) ... Jika Anda benar-benar menginginkan saya, temukan saya di ruang obrolan di sini . Semoga dengan potongan kode ini orang dapat melihat bagaimana mereka dapat menggunakan
List<Current>
seperti yang saya definisikan sebagai tabel di db danList<T>
di aplikasi mereka.sumber
Saya akan pergi dengan proposal # 1 atau, sebagai alternatif, membuat tabel awal yang hanya menampung id yang diproses. Masukkan ke dalam tabel itu selama pemrosesan, kemudian setelah selesai, panggil proc seperti di bawah ini:
Anda akan melakukan banyak sisipan, tetapi mereka akan ke meja kecil, jadi itu harus cepat. Anda juga dapat mengelompokkan sisipan Anda menggunakan ADO.net atau adaptor data apa pun yang Anda gunakan.
sumber
Judul pertanyaan mencakup tugas untuk mengirimkan data dari aplikasi ke dalam prosedur tersimpan. Bagian itu dikecualikan oleh badan pertanyaan, tetapi izinkan saya mencoba untuk menjawab ini juga.
Dalam konteks sql-server-2008 seperti yang ditentukan oleh tag ada artikel hebat lain oleh E. Sommarskog Array dan Daftar di SQL Server 2008 . BTW saya menemukannya di artikel yang dimaksud Marian dalam jawabannya.
Alih-alih hanya memberikan tautan, saya mengutip daftar isinya:
Di luar teknik yang disebutkan di sana, saya merasa bahwa dalam beberapa kasus, bulkcopy dan bulk insert layak disebutkan dalam lingkup kasus umum.
sumber
Untuk MS SQL 2016 versi terbaru
Dengan MS SQL 2016 mereka memperkenalkan fungsi baru: SPLIT_STRING () untuk mem-parsing beberapa nilai.
Ini dapat memecahkan masalah Anda dengan mudah.
Untuk MS SQL Versi Lama
Jika Anda menggunakan versi yang lebih lama, ikuti langkah ini:
Pertama, buat satu fungsi:
Setelah membuat ini, sampaikan string Anda ke fungsi ini dengan pemisah.
Saya harap ini dapat membantu anda. :-)
sumber
Gunakan ini untuk membuat "buat tabel tipe". contoh sederhana untuk pengguna
sumber