Bagaimana seseorang dapat memanggil prosedur tersimpan untuk setiap baris dalam sebuah tabel, di mana kolom-kolom dari suatu baris adalah parameter input ke sp tanpa menggunakan Kursor?
sql
sql-server
stored-procedures
cursor
Johannes Rudolph
sumber
sumber
Jawaban:
Secara umum saya selalu mencari pendekatan berbasis set (kadang-kadang dengan mengorbankan mengubah skema).
Namun, cuplikan ini memang memiliki tempatnya ..
sumber
Anda dapat melakukan sesuatu seperti ini: pesanlah meja Anda dengan mis. CustomerID (menggunakan
Sales.Customer
tabel sampel AdventureWorks ), dan lakukan iterasi pada pelanggan tersebut menggunakan loop WHILE:Itu harus bekerja dengan tabel apa saja selama Anda dapat mendefinisikan beberapa jenis
ORDER BY
pada beberapa kolom.sumber
Ok, jadi saya tidak akan pernah memasukkan kode seperti itu ke dalam produksi, tetapi memenuhi persyaratan Anda.
sumber
Jawaban Marc baik (saya akan mengomentarinya jika saya bisa mengetahui caranya!)
Hanya berpikir saya akan menunjukkan bahwa mungkin lebih baik untuk mengubah loop jadi
SELECT
hanya ada sekali (dalam kasus nyata di mana saya perlu lakukan ini,SELECT
itu cukup rumit, dan menulisnya dua kali merupakan masalah pemeliharaan yang berisiko).sumber
Jika Anda bisa mengubah prosedur tersimpan menjadi fungsi yang mengembalikan tabel, maka Anda bisa menggunakan cross-apply.
Misalnya, Anda memiliki tabel pelanggan, dan Anda ingin menghitung jumlah pesanan mereka, Anda akan membuat fungsi yang mengambil CustomerID dan mengembalikan jumlahnya.
Dan Anda bisa melakukan ini:
Di mana fungsinya akan terlihat seperti:
Jelas, contoh di atas dapat dilakukan tanpa fungsi yang ditentukan pengguna dalam satu permintaan.
Kekurangannya adalah bahwa fungsi sangat terbatas - banyak fitur dari prosedur tersimpan tidak tersedia dalam fungsi yang ditentukan pengguna, dan mengubah prosedur tersimpan ke fungsi tidak selalu berfungsi.
sumber
Saya akan menggunakan jawaban yang diterima, tetapi kemungkinan lain adalah dengan menggunakan variabel tabel untuk menyimpan set nilai bernomor (dalam hal ini hanya bidang ID dari tabel) dan loop melalui mereka dengan Nomor Baris dengan GABUNG ke tabel untuk mengambil apa pun yang Anda butuhkan untuk tindakan di dalam loop.
sumber
Untuk SQL Server 2005 dan seterusnya, Anda dapat melakukan ini dengan CROSS APPLY dan fungsi bernilai tabel.
Hanya untuk kejelasan, saya merujuk pada kasus-kasus di mana prosedur tersimpan dapat dikonversi menjadi fungsi bernilai tabel.
sumber
Ini adalah variasi dari solusi n3rds di atas. Tidak diperlukan penyortiran dengan menggunakan ORDER BY, karena MIN () digunakan.
Ingat bahwa CustomerID (atau kolom numerik apa pun yang Anda gunakan untuk kemajuan) harus memiliki batasan unik. Selanjutnya, untuk membuatnya secepat mungkin, CustomerID harus diindeks.
Saya menggunakan pendekatan ini pada beberapa varchars yang saya perlu melihat, dengan menempatkan mereka di tabel sementara pertama, untuk memberi mereka ID.
sumber
Jika Anda tidak harus menggunakan kursor, saya pikir Anda harus melakukannya secara eksternal (dapatkan tabel, lalu jalankan untuk setiap pernyataan dan setiap kali panggil sp) itu sama dengan menggunakan kursor, tetapi hanya di luar SQL Mengapa Anda tidak menggunakan kursor?
sumber
Ini adalah variasi pada jawaban yang sudah disediakan, tetapi harus berkinerja lebih baik karena tidak memerlukan ORDER OLEH, COUNT atau MIN / MAX. Satu-satunya kelemahan dengan pendekatan ini adalah Anda harus membuat tabel temp untuk menampung semua Id (asumsinya adalah Anda memiliki celah dalam daftar CustomerIDs Anda).
Yang mengatakan, saya setuju dengan @ Mark Powell meskipun, secara umum, pendekatan berbasis set masih harus lebih baik.
sumber
Saya biasanya melakukannya dengan cara ini ketika beberapa baris:
(Pada dataset yang lebih besar saya akan menggunakan salah satu solusi yang disebutkan di atas).
sumber
DELIMITER //
sumber
Solusi yang lebih baik untuk ini adalah
Ini adalah Anda mendapatkan output diformat tabel bersih. Sementara jika Anda menjalankan SP untuk setiap baris, Anda mendapatkan hasil kueri terpisah untuk setiap iterasi yang jelek.
sumber
Dalam hal urutannya penting
sumber
Saya memiliki beberapa kode produksi yang hanya dapat menangani 20 karyawan sekaligus, di bawah ini adalah kerangka kerja untuk kode tersebut. Saya baru saja menyalin kode produksi dan menghapus hal-hal di bawah ini.
sumber
Saya suka melakukan sesuatu yang mirip dengan ini (meskipun masih sangat mirip dengan menggunakan kursor)
[kode]
[/kode]
Perhatikan bahwa Anda tidak perlu identitas atau kolom isIterated pada temp / tabel variabel Anda, saya hanya lebih suka melakukannya dengan cara ini jadi saya tidak perlu menghapus catatan teratas dari koleksi karena saya mengulangi melalui loop.
sumber