Próbuję przekazać parametr tablicy do polecenia SQL w C # jak poniżej, ale to nie działa. Czy ktoś to wcześniej spotkał?
string sqlCommand = "SELECT * from TableA WHERE Age IN (@Age)";
SqlConnection sqlCon = new SqlConnection(connectString);
SqlCommand sqlComm = new SqlCommand();
sqlComm.Connection = sqlCon;
sqlComm.CommandType = System.Data.CommandType.Text;
sqlComm.CommandText = sqlCommand;
sqlComm.CommandTimeout = 300;
sqlComm.Parameters.Add("@Age", SqlDbType.NVarChar);
StringBuilder sb = new StringBuilder();
foreach (ListItem item in ddlAge.Items)
{
if (item.Selected)
{
sb.Append(item.Text + ",");
}
}
sqlComm.Parameters["@Age"].Value = sb.ToString().TrimEnd(',');
Odpowiedzi:
Wartości w tablicy trzeba będzie dodawać pojedynczo.
AKTUALIZACJA: Oto rozszerzone i wielokrotnego użytku rozwiązanie, które wykorzystuje odpowiedź Adama wraz z jego sugerowaną edycją. Poprawiłem go trochę i uczyniłem z niego metodę rozszerzającą, aby jeszcze bardziej ułatwić wywoływanie.
Nazywa się to tak ...
Zauważ, że „{Age}” w instrukcji sql jest tym samym, co nazwa parametru, który wysyłamy do AddArrayParameters. AddArrayParameters zastąpi wartość prawidłowymi parametrami.
źródło
var paramPlaceholder = "{" & paramNameRoot & "}";
Debug.Assert(cmd.CommandText.Contains(paramPlaceholder), "Parameter Name Root must exist in the Source Query");
Powinno to pomóc programistom, jeśli zapomną dopasować paramNameRoot do zapytania.Chciałem rozwinąć odpowiedź, że Brian przyczynił się do tego, aby było to łatwe do wykorzystania w innych miejscach.
Możesz użyć tej nowej funkcji w następujący sposób:
Edycja: Oto ogólna odmiana, która działa z tablicą wartości dowolnego typu i można jej używać jako metody rozszerzającej:
Następnie możesz użyć tej metody rozszerzenia w następujący sposób:
Upewnij się, że ustawiłeś CommandText przed wywołaniem AddArrayParameters.
Upewnij się również, że nazwa parametru nie będzie częściowo pasować do niczego innego w instrukcji (np. @AgeOfChild)
źródło
AddWithValue
funkcji, czy jest szansa, że możesz to naprawić?Jeśli możesz użyć narzędzia takiego jak „elegancki”, może to być po prostu:
Dapper zajmie się rozpakowaniem tego do indywidualnych parametrów za Ciebie .
źródło
'{1,2,3}'
argumentach stylu funkcji (nie klauzuli WHERE IN), ale wolę używać zwykłego ODBC, jeśli nie problemy z tablicą. Przypuszczam, że w tym przypadku również potrzebowałbym Dapper ODBC. Oto, co chce ciągnąć. snipboard.io/HU0RpJ.jpg . Może powinienem przeczytać więcej o Dapper ...Jeśli używasz MS SQL Server 2008 i nowszych, możesz używać parametrów wycenianych w tabeli, jak opisano tutaj http://www.sommarskog.se/arrays-in-sql-2008.html .
1. Utwórz typ tabeli dla każdego typu parametru, którego będziesz używać
Następujące polecenie tworzy typ tabeli dla liczb całkowitych:
2. Wdrożenie metod pomocniczych
3. Używaj tego w ten sposób
źródło
table.Rows.Add(id);
powoduje delikatny zapach kodu podczas korzystania z SonarQube. Użyłem tej alternatywy wewnątrz foreach:var row = table.NewRow(); row["id"] = id; table.Rows.Add(row);
.Ponieważ jest metoda
wygodniej byłoby utworzyć metodę akceptującą parametr (nazwę) do zastąpienia i listę wartości. Nie jest na poziomie parametrów (jak AddWithValue ), ale na samym poleceniu, więc lepiej jest nazwać go AddParametersWithValues, a nie tylko AddWithValues :
pytanie:
stosowanie:
metoda rozszerzenia:
źródło
Chcę zaproponować inny sposób rozwiązania ograniczenia za pomocą operatora IN.
Na przykład mamy następujące zapytanie
Chcemy przekazać kilka identyfikatorów, aby filtrować użytkowników. Niestety nie da się tego zrobić w C # w łatwy sposób. Ale mam obejście tego problemu za pomocą funkcji „string_split”. Musimy nieco przepisać nasze zapytanie na następujące.
Teraz możemy łatwo przekazać jeden parametr wyliczający wartości oddzielone przecinkami.
źródło
Przekazanie tablicy elementów jako zwiniętego parametru do klauzuli WHERE..IN nie powiedzie się, ponieważ zapytanie będzie miało postać
WHERE Age IN ("11, 13, 14, 16")
.Ale możesz przekazać swój parametr jako tablicę serializowaną do XML lub JSON:
Za pomocą
nodes()
metody:Za pomocą
OPENXML
metody:To trochę więcej po stronie SQL i potrzebujesz odpowiedniego XML (z rootem).
Przy użyciu
OPENJSON
metody (SQL Server 2016+):Zauważ, że w przypadku ostatniej metody musisz również mieć poziom zgodności na poziomie 130+.
źródło
Omówienie: Użyj DbType, aby ustawić typ parametru.
źródło
Użyj
.AddWithValue()
, więc:sqlComm.Parameters.AddWithValue("@Age", sb.ToString().TrimEnd(','));
Alternatywnie możesz użyć tego:
Twój całkowity przykład kodu będzie wyglądał następująco:
źródło
Oto niewielki wariant odpowiedzi Briana, który może być przydatny dla kogoś innego. Pobiera listę kluczy i upuszcza ją na listę parametrów.
źródło
próbować
źródło
spróbuj tego w ten sposób
źródło