У меня есть процесс, который захватывает кучу записей (1000-х) и оперирует ими, и когда я закончу, мне нужно пометить большое количество их как обработанных. Я могу указать это большим списком идентификаторов. Я пытаюсь избежать шаблона «обновления в цикле», поэтому я хотел бы найти более эффективный способ отправки этого пакета идентификаторов в хранимый процесс MS SQL Server 2008.
Предложение № 1 - Таблица значений параметров. Я могу определить тип таблицы с помощью поля идентификаторов и отправить таблицу, полную идентификаторов, для обновления.
Предложение № 2 - параметр XML (varchar) с OPENXML () в теле протокола.
Предложение № 3 - Разбор списка. Я бы предпочел избежать этого, если это возможно, так как это кажется громоздким и подверженным ошибкам.
Любое предпочтение среди них, или какие-либо идеи, которые я пропустил?
источник
Ответы:
Лучшие из когда-либо опубликованных статей на этот счет Эрланд Соммарског:
Он охватывает все варианты и объясняет довольно хорошо.
Извините за краткость ответа, но статья Эрланда о массивах похожа на книги Джо Селко о деревьях и других SQL-трактатах :)
источник
На StackOverflow обсуждается множество вопросов, которые охватывают множество подходов. В SQL Server 2008+ я предпочитаю использовать табличные параметры . По сути, это решение SQL Server для вашей проблемы - передача списка значений хранимой процедуре.
Преимущества этого подхода:
Однако обратите внимание: если вы вызываете хранимую процедуру, которая использует TVP через ADO.NET или ODBC, и смотрите на действия с SQL Server Profiler, вы заметите, что SQL Server получает несколько
INSERT
операторов для загрузки TVP, по одному для каждой строки. в твп с последующим вызовом на процедуру. Это по замыслу . Эта партияINSERT
s должна быть скомпилирована каждый раз, когда вызывается процедура, и представляет собой небольшие накладные расходы. Тем не менее, даже с этими накладными расходами, TVP все еще отказываются от других подходов с точки зрения производительности и удобства использования для большинства случаев использования.Если вы хотите узнать больше, Erland Sommarskog имеет полное представление о том, как работают табличные параметры, и предоставляет несколько примеров.
Вот еще один пример, который я придумал:
источник
CREATE TYPE
Утверждение в начале прошло успешно? Какую версию SQL Server вы используете?@customer_list
не в этом@param1
. Пример просто демонстрирует, что вы можете смешивать разные типы параметров.Вся тема обсуждается в окончательной статье Эрланда Соммарского: «Массивы и список в SQL Server» . Выберите, какую версию выбрать.
Резюме, для до SQL Server 2008, где TVP превосходят остальных
Статью в любом случае стоит прочитать, чтобы увидеть другие приемы и мышление.
Изменить: поздний ответ для огромных списков в другом месте: передача параметров массива в хранимую процедуру
источник
Я знаю, что опаздываю на эту вечеринку, но у меня была такая проблема в прошлом, когда мне приходилось отправлять до 100 тысяч номеров bigint, и я сделал несколько тестов. В итоге мы отправили их в двоичном формате в виде изображения - это было быстрее, чем все остальное, до 100K номеров.
Вот мой старый (SQL Server 2005) код:
Следующий код упаковывает целые числа в двоичный двоичный объект. Я меняю порядок байтов здесь:
источник
Я разрываюсь между ссылкой на SO или ответом здесь, потому что это почти вопрос программирования. Но так как у меня уже есть решение, которое я использую ... Я опубликую это;)
Этот способ работает так: вы вводите строку с разделителями-запятыми (простое разбиение, не разбивает стиль CSV) в хранимую процедуру как varchar (4000), а затем передаете этот список в эту функцию и возвращаете удобную таблицу, стол только varchars.
Это позволяет вам отправлять значения только тех идентификаторов, которые вы хотите обработать, и в этот момент вы можете сделать простое объединение.
С другой стороны, вы могли бы сделать что-то с таблицей данных CLR и передать это, но это требует больше поддержки, и все понимают списки CSV.
источник
Я регулярно получаю наборы из 1000 строк и 10000 строк, отправленные из нашего приложения для обработки различными хранимыми процедурами SQL Server.
Чтобы удовлетворить требования к производительности, мы используем TVP, но вы должны реализовать свой собственный конспект dbDataReader, чтобы преодолеть некоторые проблемы с производительностью в режиме обработки по умолчанию. Я не буду вдаваться в «как» и «почему», поскольку они выходят за рамки этого запроса.
Я не рассматривал обработку XML, поскольку я не нашел реализацию XML, которая остается производительной с более чем 10 000 «строк».
Обработка списков может быть выполнена с помощью обработки одноразмерных и двумерных числовых таблиц. Мы успешно использовали их в различных областях, но хорошо управляемые TVP более эффективны, когда имеется более двух сотен «рядов».
Как и во всех вариантах обработки SQL Server, вы должны сделать свой выбор на основе модели использования.
источник
Наконец-то у меня появился шанс сделать некоторые TableValuedParameters, и они отлично работают, поэтому я собираюсь вставить целый лот-код, который показывает, как я их использую, с примером из моего текущего кода: (примечание: мы используем ADO .СЕТЬ)
Также обратите внимание: я пишу некоторый код для службы, и у меня есть много предопределенных битов кода в другом классе, но я пишу это как консольное приложение, чтобы я мог отлаживать его, поэтому я скопировал все это из консольное приложение. Извините, мой стиль кодирования (например, жестко закодированные строки подключения), так как он был своего рода "создать один, чтобы выбросить". Я хотел показать, как я использую,
List<customObject>
и легко помещать его в базу данных в виде таблицы, которую я могу использовать в хранимой процедуре. C # и код TSQL ниже:Кроме того, я буду конструктивно критиковать мой стиль кодирования, если у вас есть что предложить (всем читателям, которые сталкиваются с этим вопросом), но, пожалуйста, оставьте его конструктивным;) ... Если вы действительно хотите меня, найдите меня в чате здесь , Надеюсь, с помощью этого фрагмента кода можно увидеть, как они могут использовать,
List<Current>
как я определил, таблицу в БД и АList<T>
в своем приложении.источник
Я бы либо пошел с предложением № 1, либо, в качестве альтернативы, создал бы скретч-таблицу, которая просто содержит обработанные идентификаторы. Вставьте в эту таблицу во время обработки, затем, после завершения, вызовите процедуру, подобную приведенной ниже:
Вы сделаете много вставок, но они будут на маленьком столе, так что это должно быть быстро. Вы также можете пакетировать свои вставки, используя ADO.net или любой другой адаптер данных, который вы используете.
источник
Название вопроса включает в себя задачу по передаче данных из приложения в хранимую процедуру. Эта часть исключена телом вопроса, но позвольте мне попытаться ответить и на это.
В контексте sql-server-2008, как указано в тегах, есть еще одна замечательная статья E. Sommarskog Arrays and Lists в SQL Server 2008 . Кстати, я нашел это в статье, на которую ссылается Мэриан в своем ответе.
Вместо того, чтобы просто дать ссылку, я цитирую ее список содержания:
Помимо методов, упомянутых там, у меня есть ощущение, что в некоторых случаях объемная копия и объемная вставка заслуживают упоминания в контексте общего случая.
источник
Для MS SQL 2016 последняя версия
В MS SQL 2016 они вводят новую функцию: SPLIT_STRING () для анализа нескольких значений.
Это может решить вашу проблему легко.
Для MS SQL Старая версия
Если вы используете более старую версию, чем следовать этому шагу:
Сначала сделайте одну функцию:
Сделав это, просто передайте свою строку этой функции с разделителем.
Я надеюсь, что это полезно для вас. :-)
источник
Используйте это, чтобы создать «создать таблицу типов». простой пример для пользователя
источник