Jak przekazać tablicę do procedury przechowywanej programu SQL Server?
Na przykład mam listę pracowników. Chcę użyć tej listy jako tabeli i połączyć ją z inną tabelą. Ale listę pracowników należy przekazać jako parametr z C #.
c#
sql-server
tsql
stored-procedures
Siergiej
źródło
źródło
Odpowiedzi:
SQL Server 2008 (lub nowszy)
Najpierw w swojej bazie danych utwórz następujące dwa obiekty:
Teraz w kodzie C #:
SQL Server 2005
Jeśli korzystasz z programu SQL Server 2005, nadal polecałbym funkcję podziału zamiast XML. Najpierw utwórz funkcję:
Teraz procedura składowana może być po prostu:
A w kodzie C # wystarczy przekazać listę jako
'1,2,3,12'
...Uważam, że metoda przekazywania parametrów wycenianych w tabeli upraszcza konserwację rozwiązania, które z niej korzysta i często ma większą wydajność w porównaniu z innymi implementacjami, w tym XML i dzielenie ciągów.
Dane wejściowe są jasno zdefiniowane (nikt nie musi zgadywać, czy separatorem jest przecinek czy średnik) i nie mamy zależności od innych funkcji przetwarzania, które nie są oczywiste bez sprawdzenia kodu procedury przechowywanej.
W porównaniu z rozwiązaniami obejmującymi zdefiniowany przez użytkownika schemat XML zamiast UDT, wymaga to podobnej liczby kroków, ale z mojego doświadczenia wynika, że kod jest o wiele prostszy w zarządzaniu, utrzymywaniu i czytaniu.
źródło
SELECT [colA] FROM [MyTable] WHERE [Id] IN (SELECT [Id] FROM @ListOfIds)
.Z mojego doświadczenia wynika, że tworzenie identyfikatora oddzielonego od identyfikatora pracownika jest trudnym i przyjemnym rozwiązaniem tego problemu. Należy utworzyć tylko wyrażenie łańcuchowe, takie jak
';123;434;365;'
in-which123
,434
i365
są to niektóre identyfikatory pracowników. Wywołując poniższą procedurę i przekazując do niej to wyrażenie, możesz pobrać żądane rekordy. Łatwo możesz dołączyć „kolejną tabelę” do tego zapytania. To rozwiązanie jest odpowiednie we wszystkich wersjach serwera SQL. Ponadto, w porównaniu z użyciem tabeli zmiennych lub tabeli temperatur, jest to bardzo szybsze i zoptymalizowane rozwiązanie.źródło
Użyj parametru o wartościach przechowywanych w tabeli dla procedury składowanej.
Po przekazaniu go z C # dodasz parametr o typie danych SqlDb.Structured.
Zobacz tutaj: http://msdn.microsoft.com/en-us/library/bb675163.aspx
Przykład:
źródło
Musisz przekazać go jako parametr XML.
Edytuj: szybki kod z mojego projektu, aby dać ci pomysł:
Następnie możesz użyć tabeli tymczasowej, aby połączyć się ze swoimi tabelami. Zdefiniowaliśmy arrayOfUlong jako wbudowany schemat XML, aby zachować integralność danych, ale nie musisz tego robić. Polecam go użyć, więc oto krótki kod, aby upewnić się, że zawsze otrzymujesz XML z długimi.
źródło
Kontekst jest zawsze ważny, na przykład rozmiar i złożoność tablicy. W przypadku list od małych do średnich kilka opublikowanych tutaj odpowiedzi jest w porządku, choć należy wyjaśnić:
text()
Funkcja XML Aby uzyskać więcej informacji (np. Analizę wydajności) na temat używania XML do dzielenia list, zobacz „Używanie XML do przekazywania list jako parametrów w SQL Server” Phila Factora.DataTable
oznacza duplikowanie danych w pamięci podczas kopiowania z oryginalnej kolekcji. Stąd korzystanie zDataTable
metody przekazywania w TVP nie działa dobrze w przypadku większych zestawów danych (tj. Nie jest dobrze skalowane).DataTable
metoda TVP, XML nie skaluje się dobrze, ponieważ podwaja rozmiar danych w pamięci, ponieważ musi dodatkowo uwzględniać narzut dokumentu XML.Biorąc to wszystko pod uwagę, JEŻELI używane dane są duże lub jeszcze niezbyt duże, ale stale rosną, to
IEnumerable
metoda TVP jest najlepszym wyborem, ponieważ przesyła dane do SQL Server (jakDataTable
metoda), ALE nie wymagają jakiegokolwiek powielenia kolekcji w pamięci (w przeciwieństwie do innych metod). W tej odpowiedzi opublikowałem przykład kodu SQL i C #:Przekaż słownik do procedury składowanej T-SQL
źródło
Serwer SQL nie obsługuje tablicy, ale istnieje kilka sposobów przekazywania kolekcji do przechowywanego proc.
Poniższy link może ci pomóc
przekazanie kolekcji do procedury składowanej
źródło
Przeszukiwałem wszystkie przykłady i odpowiedzi, jak przekazać dowolną tablicę do serwera SQL bez kłopotów z tworzeniem nowego typu tabeli, dopóki nie znalazłem tego linK , poniżej jest to, jak zastosowałem go do mojego projektu:
- Poniższy kod pobiera tablicę jako parametr i wstawia wartości tej tablicy do innej tabeli
Mam nadzieję, że ci się spodoba
źródło
@s
jest CSV, szybsze byłoby po prostu podzielenie tego (tj. INSERT INTO ... SELECT FROM SplitFunction). Konwersja na XML przebiega wolniej niż CLR, a XML oparty na atrybutach i tak jest znacznie szybszy. Jest to prosta lista, ale przekazywanie w XML lub TVP może również obsługiwać złożone tablice. Nie jestem pewien, co zyskasz, unikając prostego, jednorazowego działaniaCREATE TYPE ... AS TABLE
.To ci pomoże. :) Wykonaj kolejne kroki,
Kopiuj Wklej następujący kod w obecnej postaci, utworzy on funkcję, która przekształci ciąg na Int
Utwórz następującą procedurę składowaną
Wykonaj ten SP. Używając
exec sp_DeleteId '1,2,3,12'
tego jest ciąg identyfikatorów, które chcesz usunąć,Konwertujesz tablicę na ciąg w C # i przekazujesz ją jako parametr procedury składowanej
Spowoduje to usunięcie wielu wierszy, wszystkiego najlepszego
źródło
Zajęło mi to dużo czasu, aby to zrozumieć, więc na wypadek, gdyby ktoś tego potrzebował ...
Jest to oparte na metodzie SQL 2005 w odpowiedzi Aarona i użyciu jego funkcji SplitInts (właśnie usunąłem parametr delim, ponieważ zawsze będę używać przecinków). Korzystam z SQL 2008, ale chciałem czegoś, co będzie działać z typowymi zestawami danych (XSD, TableAdapters) i wiem, że parametry ciągów działają z nimi.
Próbowałem zmusić jego funkcję do działania w klauzuli typu „gdzie w (1,2,3)” i nie miałem szczęścia w prosty sposób. Więc najpierw stworzyłem tabelę tymczasową, a następnie wykonałem wewnętrzne połączenie zamiast „gdzie w”. Oto moje przykładowe użycie, w moim przypadku chciałem uzyskać listę przepisów, które nie zawierają niektórych składników:
źródło
Jak zauważyli inni powyżej, jednym ze sposobów jest przekonwertowanie tablicy na ciąg, a następnie podzielenie ciągu wewnątrz SQL Server.
Począwszy od SQL Server 2016, istnieje wbudowany sposób na dzielenie ciągów o nazwie
Zwraca zestaw wierszy, które można wstawić do tabeli tymczasowej (lub tabeli rzeczywistej).
dałoby:
Jeśli chcesz zdobyć bardziej fantazyjne:
dałoby takie same wyniki jak powyżej (z wyjątkiem tego, że nazwa kolumny to „numer”), ale posortowane. Możesz używać zmiennej tabeli jak każdej innej tabeli, więc możesz łatwo połączyć ją z innymi tabelami w bazie danych, jeśli chcesz.
Należy pamiętać, że instalacja programu SQL Server musi mieć poziom zgodności 130 lub wyższy, aby
STRING_SPLIT()
funkcja została rozpoznana. Możesz sprawdzić poziom zgodności za pomocą następującego zapytania:Większość języków (w tym C #) ma funkcję „łączyć”, za pomocą której można utworzyć ciąg z tablicy.
Następnie przekazujesz
sqlparam
jako parametr powyższej procedury składowanej.źródło
źródło