Как передать массив в хранимую процедуру SQL Server?
Например, у меня есть список сотрудников. Я хочу использовать этот список в качестве таблицы и объединить ее с другой таблицей. Но список сотрудников должен быть передан как параметр из C #.
c#
sql-server
tsql
stored-procedures
Сергей
источник
источник
Ответы:
SQL Server 2008 (или новее)
Сначала в вашей базе данных создайте следующие два объекта:
Теперь в вашем коде C #:
SQL Server 2005
Если вы используете SQL Server 2005, я бы по-прежнему рекомендовал функцию разделения по XML. Сначала создайте функцию:
Теперь ваша хранимая процедура может быть:
И в вашем коде C # вы просто должны передать список как
'1,2,3,12'
...Я считаю, что метод передачи табличных параметров упрощает поддержку решения, которое его использует, и часто имеет более высокую производительность по сравнению с другими реализациями, включая XML и разбиение строк.
Входные данные четко определены (никто не должен догадываться, является ли разделитель запятой или точкой с запятой), и у нас нет зависимостей от других функций обработки, которые не очевидны без проверки кода для хранимой процедуры.
По сравнению с решениями, включающими определяемую пользователем XML-схему вместо UDT, это включает в себя аналогичное количество шагов, но, по моему опыту, намного проще код для управления, обслуживания и чтения.
источник
SELECT [colA] FROM [MyTable] WHERE [Id] IN (SELECT [Id] FROM @ListOfIds)
.Исходя из моего опыта, путем создания выражения с разделителями из employeeID, есть хитрое и хорошее решение для этой проблемы. Вы должны только создать строковое выражение, например,
';123;434;365;'
in-which123
,434
и365
это несколько employeeID. Вызвав приведенную ниже процедуру и передав ей это выражение, вы можете получить нужные записи. Вы можете легко присоединить «другую таблицу» к этому запросу. Это решение подходит во всех версиях SQL-сервера. Кроме того, по сравнению с использованием табличной переменной или временной таблицы, это очень быстрое и оптимизированное решение.источник
Используйте табличный параметр для вашей хранимой процедуры.
Когда вы передадите его из C #, вы добавите параметр с типом данных SqlDb.Structured.
Смотрите здесь: http://msdn.microsoft.com/en-us/library/bb675163.aspx
Пример:
источник
Вам нужно передать его как параметр XML.
Изменить: быстрый код из моего проекта, чтобы дать вам идею:
Затем вы можете использовать временную таблицу для соединения со своими таблицами. Мы определили arrayOfUlong как встроенную XML-схему для поддержания целостности данных, но вам не нужно этого делать. Я бы порекомендовал использовать его, так что вот быстрый код, чтобы убедиться, что вы всегда получаете XML с длинными.
источник
Контекст всегда важен, например размер и сложность массива. Для небольших и средних списков несколько ответов, опубликованных здесь, просто хороши, хотя некоторые пояснения должны быть сделаны:
text()
Функция XML. Для получения дополнительной информации (т. Е. Анализа производительности) об использовании XML для разделения списков, посмотрите "Использование XML для передачи списков в качестве параметров в SQL Server" от Phil Factor.DataTable
означает дублирование данных в памяти, когда они копируются из оригинальной коллекции. Следовательно, использованиеDataTable
метода передачи в TVP не работает хорошо для больших наборов данных (т.е. не хорошо масштабируется).DataTable
метод TVP, XML не масштабируется, так как он более чем удваивает размер данных в памяти, поскольку ему необходимо дополнительно учитывать накладные расходы XML-документа.С учетом всего вышесказанного, ЕСЛИ данные, которые вы используете, являются большими или не очень большими, но все же постоянно растут, то
IEnumerable
метод TVP является лучшим выбором, так как он передает данные на SQL Server (какDataTable
метод), НО не делает требуется любое дублирование коллекции в памяти (в отличие от любого другого метода). Я разместил пример кода SQL и C # в этом ответе:Передача словаря в хранимую процедуру T-SQL
источник
В sql server нет поддержки массива, но есть несколько способов передать коллекцию в сохраненный процесс.
Ссылка ниже может помочь вам
передача коллекции в хранимую процедуру
источник
Я искал все примеры и ответы о том, как передать любой массив на сервер sql без хлопот создания нового типа таблицы, пока не нашел этот linK , ниже показано , как я применил его к своему проекту:
Следующий код получит массив в качестве параметра и вставит значения этого массива в другую таблицу.
Надеюсь, тебе понравится
источник
@s
CSV, то было бы быстрее просто разделить это (то есть INSERT INTO ... SELECT FROM SplitFunction). Преобразование в XML медленнее, чем в CLR, а XML на основе атрибутов намного быстрее. И это простой список, но передача в XML или TVP также может обрабатывать сложные массивы. Не уверен, что получается, избегая простого, одноразовогоCREATE TYPE ... AS TABLE
.Это поможет вам. :) Следуйте следующим шагам,
Скопируйте Вставьте следующий код, как он есть, он создаст функцию, которая преобразует строку в Int
Создайте следующую хранимую процедуру
Выполните этот SP, используя
exec sp_DeleteId '1,2,3,12'
эту строку идентификаторов, которые вы хотите удалить,Вы конвертируете свой массив в строку в C # и передаете его как параметр хранимой процедуры
Это удалит несколько строк, всего наилучшего
источник
Мне потребовалось много времени, чтобы понять это, поэтому на случай, если это кому-нибудь понадобится ...
Это основано на методе SQL 2005 в ответе Аарона и использовании его функции SplitInts (я просто удалил параметр delim, так как я всегда буду использовать запятые). Я использую SQL 2008, но я хотел что-то, что работает с типизированными наборами данных (XSD, TableAdapters), и я знаю, что строковые параметры работают с ними.
Я пытался заставить его функцию работать в предложении типа «где в (1,2,3)», и мне не повезло прямым путем. Итак, я сначала создал временную таблицу, а затем сделал внутреннее соединение вместо «где». Вот мой пример использования, в моем случае я хотел получить список рецептов, которые не содержат определенные ингредиенты:
источник
Как уже отмечалось выше, один из способов сделать это - преобразовать массив в строку, а затем разбить строку внутри SQL Server.
Начиная с SQL Server 2016, есть встроенный способ разделения строк, который называется
Он возвращает набор строк, которые вы можете вставить в вашу временную таблицу (или реальную таблицу).
даст:
Если вы хотите полюбоваться:
даст вам те же результаты, что и выше (за исключением того, что имя столбца «thenumber»), но отсортированы. Вы можете использовать переменную таблицы как любую другую таблицу, так что вы можете легко объединить ее с другими таблицами в БД, если хотите.
Обратите внимание, что ваша установка SQL Server должна быть на уровне совместимости 130 или выше, чтобы
STRING_SPLIT()
функция могла быть распознана. Вы можете проверить уровень совместимости с помощью следующего запроса:Большинство языков (включая C #) имеют функцию «соединения», которую можно использовать для создания строки из массива.
Затем вы передаете в
sqlparam
качестве параметра хранимой процедуре выше.источник
источник