Mam procedurę składowaną, która w pewien sposób zmienia dane użytkownika. Podaję user_id i robi to. Chcę uruchomić zapytanie w tabeli, a następnie dla każdego identyfikatora użytkownika znajduję procedurę przechowywaną raz dla tego identyfikatora użytkownika
Jak mam napisać zapytanie o to?
sql
sql-server
stored-procedures
MetaGuru
źródło
źródło
Odpowiedzi:
użyj kursora
DODATEK: [Przykład kursora MS SQL]
w MS SQL, oto przykładowy artykuł
zauważ, że kursory są wolniejsze niż operacje oparte na zestawach, ale szybsze niż ręczne pętle while; więcej szczegółów w tym pytaniu SO
DODATEK 2: jeśli będziesz przetwarzał więcej niż kilka rekordów, najpierw przeciągnij je do tabeli tymczasowej i przesuń kursor nad tabelą tymczasową; Zapobiegnie to eskalacji SQL do blokad tabel i przyspieszy działanie
DODATEK 3: i oczywiście, jeśli możesz wstawić cokolwiek procedura przechowywana robi do każdego identyfikatora użytkownika i uruchomić całość jako pojedynczą instrukcję aktualizacji SQL, byłoby to optymalne
źródło
spróbuj zmienić metodę, jeśli chcesz zapętlić!
w ramach nadrzędnej procedury składowanej utwórz tabelę #temp zawierającą dane, które musisz przetworzyć. Wywołaj potomną procedurę przechowywaną, tablica #temp będzie widoczna i możesz ją przetwarzać, miejmy nadzieję, pracując z całym zestawem danych i bez kursora lub pętli.
to naprawdę zależy od tego, co robi ta potomna procedura przechowywana. Jeśli aktualizujesz, możesz „zaktualizować”, dołączając do tabeli #temp i wykonując całą pracę w jednej instrukcji bez pętli. To samo można zrobić dla INSERT i DELETE. Jeśli potrzebujesz wykonać wiele aktualizacji za pomocą IF, możesz przekonwertować je na wiele
UPDATE FROM
za pomocą tabeli #temp i użyć instrukcji CASE lub GDZIE.Podczas pracy w bazie danych staraj się stracić nastawienie do zapętlania, jest to prawdziwy drenaż wydajności, spowoduje blokowanie / blokowanie i spowolni przetwarzanie. Jeśli wszędzie zapętlisz, twój system nie będzie skalował się zbyt dobrze i bardzo trudno będzie przyspieszyć, gdy użytkownicy zaczną narzekać na powolne odświeżanie.
Opublikuj treść tej procedury, którą chcesz wywołać w pętli, a ja postawię 9 na 10 razy, możesz napisać ją, aby działała na zestawie wierszy.
źródło
Takie tabele i nazwy pól będą potrzebne.
źródło
Możesz to zrobić za pomocą zapytania dynamicznego.
źródło
Czy nie można tego zrobić za pomocą funkcji zdefiniowanej przez użytkownika w celu zreplikowania wszystkiego, co robi procedura przechowywana?
gdzie udfMyFunction to twoja funkcja, która pobiera identyfikator użytkownika i robi wszystko, co trzeba z nim zrobić.
Zobacz http://www.sqlteam.com/article/user-defined-functions na
Zgadzam się, że w miarę możliwości należy unikać kursorów. I zwykle jest to możliwe!
(oczywiście moja odpowiedź zakłada, że jesteś zainteresowany tylko uzyskaniem danych wyjściowych z SP i że nie zmieniasz rzeczywistych danych. Uważam, że „w pewien sposób zmienia dane użytkownika” trochę niejednoznaczne z pierwotnego pytania, pomyślałem, że zaproponuję to jako możliwe rozwiązanie. Zależy to całkowicie od tego, co robisz!)
źródło
Użyj zmiennej tabeli lub tabeli tymczasowej.
Jak wspomniano wcześniej, kursor jest ostatecznością. Głównie dlatego, że zużywa dużo zasobów, powoduje blokady i może być znakiem, że po prostu nie rozumiesz, jak prawidłowo używać SQL.
Utwórz zmienną tabelową taką jak ta (jeśli pracujesz z dużą ilością danych lub brakuje pamięci, użyj tabeli tymczasowej ):
To
id
jest ważne.Zastąpić
parent
ichild
niektórych danych dobrych, np odpowiednimi identyfikatorami lub całego zbioru danych, które mają być eksploatowane na.Wstaw dane do tabeli, np .:
Zadeklaruj niektóre zmienne:
Na koniec utwórz pętlę while nad danymi w tabeli:
Pierwszy wybór pobiera dane z tabeli tymczasowej. Drugi wybór aktualizuje @id.
MIN
zwraca null, jeśli nie wybrano żadnych wierszy.Alternatywnym podejściem jest zapętlenie, gdy tabela ma wiersze,
SELECT TOP 1
i usunięcie wybranego wiersza z tabeli temp:źródło
Podoba mi się sposób dynamicznego zapytania Dave'a Rincon, ponieważ nie używa on kursorów i jest mały i łatwy. Dziękuję Dave za udostępnienie.
Ale dla moich potrzeb dotyczących Azure SQL i „wyraźnego” w zapytaniu musiałem zmodyfikować kod w następujący sposób:
Mam nadzieję, że to komuś pomoże ...
źródło