Saya memiliki prosedur tersimpan yang mengubah data pengguna dengan cara tertentu. Saya meneruskannya user_id dan itu tidak apa-apa. Saya ingin menjalankan kueri pada tabel dan kemudian untuk setiap user_id saya menemukan menjalankan prosedur tersimpan sekali pada user_id itu
Bagaimana saya menulis permintaan untuk ini?
sql
sql-server
stored-procedures
MetaGuru
sumber
sumber
Jawaban:
gunakan kursor
ADDENDUM: [Contoh kursor MS SQL]
di MS SQL, inilah contoh artikel
perhatikan bahwa kursor lebih lambat dari operasi berbasis set, tetapi lebih cepat dari loop sementara manual; lebih detail dalam pertanyaan SO ini
ADDENDUM 2: jika Anda akan memproses lebih dari hanya beberapa catatan, tarik mereka ke dalam tabel temp pertama dan jalankan kursor di atas tabel temp; ini akan mencegah SQL naik ke kunci-tabel dan mempercepat operasi
LAMPIRAN 3: dan tentu saja, jika Anda dapat menyesuaikan apa pun prosedur tersimpan yang Anda lakukan untuk setiap ID pengguna dan menjalankan semuanya sebagai pernyataan pembaruan SQL tunggal, itu akan menjadi optimal
sumber
cobalah untuk mengubah metode Anda jika Anda perlu mengulang!
dalam prosedur tersimpan induk, buat tabel #temp yang berisi data yang Anda perlu proses. Panggil prosedur tersimpan anak, tabel #temp akan terlihat dan Anda dapat memprosesnya, semoga bekerja dengan seluruh rangkaian data dan tanpa kursor atau loop.
ini sangat tergantung pada apa yang dilakukan oleh prosedur penyimpanan anak ini. Jika Anda UPDATE, Anda dapat "memperbarui dari" bergabung dalam tabel #temp dan melakukan semua pekerjaan dalam satu pernyataan tanpa loop. Hal yang sama dapat dilakukan untuk INSERT dan DELETEs. Jika Anda perlu melakukan beberapa pembaruan dengan IF, Anda dapat mengonversinya menjadi banyak
UPDATE FROM
dengan tabel #temp dan menggunakan pernyataan KASUS atau kondisi WHERE.Ketika bekerja dalam suatu basis data mencoba menghilangkan pola pikir dari perulangan, itu adalah penguras kinerja nyata, akan menyebabkan penguncian / pemblokiran dan memperlambat pemrosesan. Jika Anda berputar di mana-mana, sistem Anda tidak akan skala dengan sangat baik, dan akan sangat sulit untuk mempercepat ketika pengguna mulai mengeluh tentang refresh lambat.
Posting konten dari prosedur ini yang ingin Anda panggil dalam satu lingkaran, dan saya akan bertaruh 9 dari 10 kali, Anda bisa menulisnya untuk bekerja pada satu set baris.
sumber
Sesuatu seperti pergantian ini akan diperlukan untuk tabel dan nama bidang Anda.
sumber
Anda dapat melakukannya dengan kueri dinamis.
sumber
Apakah ini tidak dapat dilakukan dengan fungsi yang ditentukan pengguna untuk mereplikasi apa pun yang dilakukan oleh prosedur tersimpan Anda?
di mana udfMyFunction adalah fungsi yang Anda buat yang mengambil ID pengguna dan melakukan apa pun yang perlu Anda lakukan dengannya.
Lihat http://www.sqlteam.com/article/user-defined-functions untuk sedikit lebih banyak latar belakang
Saya setuju bahwa kursor benar-benar harus dihindari jika memungkinkan. Dan biasanya itu mungkin!
(tentu saja, jawaban saya mengandaikan bahwa Anda hanya tertarik untuk mendapatkan output dari SP dan bahwa Anda tidak mengubah data aktual. Saya menemukan "mengubah data pengguna dengan cara tertentu" sedikit ambigu dari pertanyaan awal, jadi saya pikir saya akan menawarkan ini sebagai solusi yang mungkin. Sangat tergantung pada apa yang Anda lakukan!)
sumber
Gunakan variabel tabel atau tabel sementara.
Seperti yang telah disebutkan sebelumnya, kursor adalah pilihan terakhir. Sebagian besar karena menggunakan banyak sumber daya, masalah mengunci dan mungkin menjadi tanda Anda tidak mengerti cara menggunakan SQL dengan benar.
Buat variabel tabel seperti ini (jika Anda bekerja dengan banyak data atau kekurangan memori, gunakan tabel sementara sebagai gantinya):
Itu
id
penting.Ganti
parent
danchild
dengan beberapa data yang baik, misalnya pengidentifikasi yang relevan atau seluruh rangkaian data yang akan dioperasikan.Masukkan data dalam tabel, misalnya:
Nyatakan beberapa variabel:
Dan akhirnya, buat loop sementara di atas data dalam tabel:
Pilih pertama mengambil data dari tabel sementara. Pilihan kedua memperbarui @id.
MIN
mengembalikan nol jika tidak ada baris yang dipilih.Pendekatan alternatif adalah untuk mengulang sementara tabel memiliki baris,
SELECT TOP 1
dan menghapus baris yang dipilih dari tabel temp:sumber
Saya suka cara permintaan dinamis dari Dave Rincon karena tidak menggunakan kursor dan kecil dan mudah. Terima kasih, Dave, telah berbagi.
Tetapi untuk kebutuhan saya pada Azure SQL dan dengan "berbeda" dalam permintaan, saya harus memodifikasi kode seperti ini:
Saya harap ini membantu seseorang ...
sumber