Предпочтительны ли хранимые процедуры CLR по сравнению с хранимыми процедурами TSQL в SQL 2005+?

StackOverflow https://stackoverflow.com/questions/58190

  •  09-06-2019
  •  | 
  •  

Вопрос

На данный момент я считаю, что нет, предпочитаю хранимые процедуры Transact SQL, поскольку они имеют более легкий вес и (возможно) более производительный вариант, в то время как процедуры CLR позволяют разработчикам делать все виды шалостей.

Однако недавно мне пришлось отлаживать некоторые очень плохо написанные хранимые процедуры TSQL.Как обычно, я обнаружил множество проблем из-за того, что первоначальный разработчик не имел реального опыта работы с TSQL, они были ориентированы на ASP.NET/C#.

Таким образом, использование процедур CLR, во-первых, предоставит разработчикам такого типа гораздо более знакомый набор инструментов, а во-вторых, средства отладки и тестирования станут более мощными (т. е. Visual Studio вместо SQL Management Studio).

Мне было бы очень интересно услышать ваш опыт, поскольку кажется, что это не простой выбор.

Это было полезно?

Решение

Здесь есть место как хорошо написанному, продуманному T-SQL, так и CLR.Если какая-то функция вызывается нечасто и для нее требуются расширенные процедуры в SQL Server 2000, CLR может быть подходящим вариантом.Также может оказаться привлекательным выполнение таких операций, как вычисления, непосредственно рядом с данными.Но исправлять плохих программистов, внедряя новые технологии, кажется плохой идеей.

Другие советы

Хранимые процедуры CLR не предназначены для замены запросов на основе наборов.Если вам нужно запросить базу данных, вам все равно придется поместить SQL в свой код CLR, как если бы он был встроен в обычный код.Это было бы пустой тратой усилий.

Хранимые процедуры CLR предназначены для двух основных целей:1) взаимодействие с ОС, например чтение из файла или отправка сообщения в MSMQ, и 2) выполнение сложных вычислений, особенно если у вас уже есть код, написанный на языке .NET для выполнения вычислений.

Размещение CLR в SQL Server предназначено для того, чтобы дать разработчикам баз данных более гибкие варианты в том, как они стремились выполнить задачи.Как уже упоминалось, SQL отлично подходит для операций и модификаций наборы данных.Любой, кто занимался обширной разработкой крупных приложений со сложными бизнес-правилами/доменами, вероятно, скажет вам: попытка обеспечить соблюдение некоторых из этих правил с помощью чистого SQL (иногда в одном макрозапросе) может стать поистине кошмарной.

Есть только определенные задачи, которые лучше решать процедурным или объектно-ориентированным способом.Имея возможность использовать код .NET для разбивки последовательности логики, операции запроса можно легче читать и отлаживать.Используя хранимые процедуры CLR, я могу сказать вам, что использование отладчика действительно облегчает отслеживание того, что происходит на уровне базы данных.

Только один пример: мы часто используем здесь хранимые процедуры CLR в качестве «шлюза» для динамических поисковых запросов.Скажем, поисковый запрос, который может иметь до 30 различных параметров поиска.Пользователи, очевидно, не используют все 30 из них, поэтому передаваемая структура данных будет иметь 30 параметров, но в основном DBNULL.Клиентская сторона имеет нет выбора для создания динамического оператора по очевидным причинам безопасности.Результирующее динамическое заявление генерируется внутри компании, не опасаясь внешних «дополнений».

Обычно вы используете CLR, если у вас есть что-то, что не требует особого взаимодействия с базой данных.Допустим, вы анализируете или декодируете значение.Это проще сделать в CLR, а затем вернуть значение.

Попытка выполнить Compelx-запрос в CLR — не лучший вариант.

Кстати, это не изменилось и в 2008 году.

Я считаю, что эти двое не эквивалентны...готовы противостоять друг другу.
Предполагается, что интеграция CLR приведет к поэтапному отказу от «расширенных хранимых процедур» прошлого. У нас на работе есть такие...по сути, блоки обработки/логики данных SQL, которые было слишком сложно/невозможно выполнить с помощью обычных хранимых процедур БД/T SQL.Поэтому они описали это как расширенные хранимые процедуры в DLL C++, которые можно вызывать аналогичным образом.Сейчас они сняты с производства и заменой является интеграция CLR.

  • Хранимые процедуры БД:если это можно сделать в хранимых процедурах T SQL, сделайте это.
  • Хранимые процедуры CLR:если логика слишком сложна или утомительна для выполнения через T SQL...если для решения этой задачи потребуется меньше строк кода CLR (манипуляции со строками, сложная/настраиваемая сортировка или фильтрация и т. д.), используйте этот подход.

Помимо доступа к файловой системе (где процедуры CLR имеют очень явное преимущество), я бы использовал процедуры T-SQL.Если у вас особенно сложные вычисления, вы можете поместить эту часть в CLR. функция и вызовите это из своего процесса (я обнаружил, что интеграция CLR действительно хороша в udf).Тогда вы получаете преимущества интеграции CLR для этой конкретной части вашей задачи, но сохраняете как можно большую часть логики хранимых процедур в БД.

Учитывая то, что вы сказали, я бы предпочел, чтобы вы должным образом обучили разработчиков t-SQl и базам данных в целом, чем позволили бы им нанести гораздо больший ущерб производительности, позволяя им выполнять задачи t-sql в CLR.Разработчики, которые не разбираются в базах данных, используют это как предлог, чтобы не делать что-либо способом, который лучше всего влияет на производительность базы данных, потому что они хотят выбрать более простой, по их мнению, путь.

Все всегда сводится к выбору подходящего инструмента для работы, поэтому все зависит от того, чего вы пытаетесь достичь.

Однако, как правило, вы правы в том, что процессы CLR имеют большие накладные расходы и никогда не будут выполнять операции над множествами, такие как T-SQL.Моя рекомендация — делать все это с помощью T-SQL, если только то, что вам нужно, не станет слишком сложным в T-SQL.Затем приложите больше усилий, чтобы заставить работать подход T-SQL.:-)

Процессы CLR великолепны и имеют свое место, но их использование должно быть исключением, а не правилом.

Электронная документация по SQL Server страница по теме перечисляет эти преимущества:

  • Улучшенная модель программирования. Языки .NET Framework во многих отношениях богаче Transact-SQL, предлагая конструкции и возможности, ранее недоступные разработчикам SQL Server.Разработчики также могут использовать возможности библиотеки .NET Framework, которая предоставляет обширный набор классов, которые можно использовать для быстрого и эффективного решения проблем программирования.

  • Повышенная безопасность и защищенность. Управляемый код выполняется в общеязыковой среде выполнения, размещенной в компоненте Database Engine.SQL Server использует это, чтобы предоставить более безопасную и надежную альтернативу расширенным хранимым процедурам, доступным в более ранних версиях SQL Server.

  • Возможность определения типов данных и агрегатных функций. Пользовательские типы и определяемые пользователем агрегаты — это два новых управляемых объекта базы данных, которые расширяют возможности хранения и выполнения запросов SQL Server.

  • Оптимизированная разработка в стандартизированной среде. Разработка баз данных интегрирована в будущие выпуски среды разработки Microsoft Visual Studio .NET.Разработчики используют те же инструменты для разработки и отладки объектов и сценариев базы данных, которые они используют для написания компонентов и служб .NET Framework среднего или клиентского уровня.

  • Потенциал для улучшения производительности и масштабируемости. Во многих ситуациях модели компиляции и выполнения языка .NET Framework обеспечивают более высокую производительность по сравнению с Transact-SQL.

Мы столкнулись с ситуацией, когда функция CLR вызывалась тысячи раз в обычной процедуре SQL.Это была процедура импорта данных из другой системы.Функция проверила данные и прекрасно обработала нули.

Если бы мы выполнили операцию в TSQL, процесс завершился бы примерно через 15 секунд.Если бы мы использовали функцию CLR, процесс завершился бы через 20–40 минут.Функция CLR выглядела более элегантно, но, насколько мы могли судить, при каждом использовании функции CLR происходил запуск.Поэтому, если у вас есть большая операция, выполняемая с использованием одной функции CLR, это нормально, поскольку время запуска мало по сравнению со временем выполнения операции.Или, если вы вызываете функцию CLR небольшое количество раз, общее время запуска для всех вызовов функции будет небольшим.Но будьте осторожны с петлями.

Кроме того, с точки зрения удобства обслуживания лучше не иметь больше языков, чем вам действительно нужно.

Я бы добавил пару причин использовать CLR, о которых, возможно, не упоминалось.

  • Замените и расширите базовые функции запроса, не-запроса и скалярные функции sql.
    А) Отчеты об ошибках и оповещения могут быть интегрированы на основе определенных требований.Б) Легко определять уровни отладки.В) Обеспечить более простой способ взаимодействия с внешними SQL-серверами.
  • Переместите устаревший код в управляемую среду.

Я опубликовал следующий ответ на аналогичный вопрос: Преимущество SQL SERVER CLR.Однако я добавлю здесь, что C# / VB.net / и т. д. являются языком, который кому-то более удобен, чем T-SQL. нет быть причиной использования SQLCLR вместо T-SQL.Если кто-то не знает, как чего-то добиться с помощью T-SQL, сначала попросите помощи в поиске решения для T-SQL.Если такового не существует, затем пойти по пути CLR.


Интеграция SQLCLR/CLR с SQL Server — это всего лишь еще один инструмент, помогающий решить определенные (не все) проблемы.Есть некоторые вещи, которые он делает лучше, чем то, что можно сделать в чистом T-SQL, а есть некоторые вещи, которые можно сделать только через SQLCLR.Я написал статью для SQL Server Central, Лестница на уровень SQLCLR 1:Что такое SQLCLR? (для чтения статей необходима бесплатная регистрация), посвященная этому вопросу.Основы таковы (подробности см. В связанной статье):

  • Потоковая передача табличных функций (sTVF)
  • Динамический SQL (внутри функций)
  • Улучшенный доступ к внешним ресурсам/замена xp_cmdshell
    • Передавать данные стало проще
    • Получить обратно несколько столбцов набора результатов стало проще.
    • Никаких внешних зависимостей (например.7zip.exe)
    • Повышенная безопасность благодаря олицетворению
  • Возможность многопоточности
  • Обработка ошибок (внутри функций)
  • Пользовательские агрегаты
  • Пользовательские типы
  • Изменить состояние (внутри функции и без OPENQUERY / OPENROWSET)
  • Выполнить хранимую процедуру (только для чтения;внутри функции и без OPENQUERY / OPENROWSET)
  • Производительность (примечание: Это нет имеется в виду во всех случаях, но в некоторых случаях обязательно в зависимости от типа и сложности операции)
  • Может захватывать выходные данные (т.е.что отправляется на вкладку «Сообщения» в SSMS) (например. PRINT и RAISERROR с строгость = от 0 до 10) -- забыл упомянуть об этом в статье ;-).

Еще одна вещь, которую следует учитывать: иногда полезно иметь возможность совместного использования кода между приложением и БД, чтобы БД имела представление об определенной бизнес-логике без необходимости создавать собственные экраны только для внутреннего использования только для доступа к этому коду приложения.Например, я работал над системой, которая импортировала файлы данных от клиентов, использовала собственный хэш большинства полей и сохраняла это значение в строке в БД.Это позволило легко пропускать строки при повторном импорте их данных, поскольку приложение хешировало значения из входного файла и сравнивало их с хеш-значением, хранящимся в строке.Если они были одинаковыми, мы сразу знали, что ни одно из полей не изменилось, поэтому переходили к следующей строке и выполняли простое INT-сравнение.Но этот алгоритм для выполнения хэширования был только в коде приложения, поэтому будь то отладка обращения клиента или поиск способов переложить часть обработки на серверные службы, помечая строки, которые имели хотя бы одно поле с изменениями (изменения, поступающие из нашего приложения). в отличие от поиска изменений в новом файле импорта), я ничего не мог сделать.Это была бы прекрасная возможность иметь в БД довольно простую часть бизнес-логики, даже если и не для нормальной обработки;наличие закодированного значения в БД без возможности понять его значение значительно затрудняет решение проблем.

Если вы хотите увидеть некоторые из этих возможностей в действии без необходимости писать какой-либо код, бесплатная версия SQL# (автором которого я являюсь) имеет функции RegEx, пользовательские агрегаты (UDA), пользовательские типы (UDT) и т. д.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top