Являются ли хранимые процедуры CLR предпочтительными над хранимыми процедурами TSQL в SQL 2005+?
В моем текущем представлении нет, предпочитайте хранимые процедуры Transact SQL, потому что они более легкие и, возможно, более эффективные, тогда как процедуры CLR позволяют разработчикам преодолевать всевозможные ошибки.
Однако в последнее время мне пришлось отлаживать некоторые очень плохо написанные TSQL хранимые процедуры. Как обычно, я обнаружил многие проблемы из-за того, что первоначальный разработчик разработчика не имел реального опыта TSQL, они были сосредоточены на ASP.NET/С#.
Таким образом, использование процедур CLR сначала обеспечит гораздо более привычный набор инструментов для этого типа разработчиков, а во-вторых, средства отладки и тестирования более мощные (например, Visual Studio вместо SQL Management Studio).
Мне было бы очень интересно услышать ваш опыт, так как кажется, что это не простой выбор.
Ответы
Ответ 1
Есть места как для хорошо написанных, хорошо продуманных T-SQL и CLR. Если некоторая функция часто не вызывается, и если для SQL Server 2000 требуются расширенные процедуры, CLR может быть вариантом. Также могут быть привлекательными такие вещи, как вычисление прямо рядом с данными. Но решение плохих программистов, бросая в новую технологию, звучит как плохая идея.
Ответ 2
Сохраненные процедуры CLR не предназначены для замены запросов на основе набора. Если вам нужно запросить базу данных, вам все равно придется поместить SQL в ваш код CLR, как если бы он был встроен в обычный код. Это будет пустой тратой усилий.
Хранимые процедуры CLR предназначены для двух основных целей: 1) взаимодействие с ОС, например чтение из файла или удаление сообщения в MSMQ, и 2) выполнение сложных вычислений, особенно если у вас уже есть код, написанный на a.NET для вычисления.
Ответ 3
Хостинг CLR в SQL Server предназначен для предоставления разработчикам баз данных более гибких опций в том, как они стремились выполнять задачи. Как и многие другие, SQL отлично подходит для операций и модификаций наборов данных. Любой, кто сделал обширную обширную разработку приложений со сложными правилами бизнеса/домена, скорее всего, скажет вам - попытка принудительного применения некоторых из этих правил с использованием чистого SQL (несколько раз в одном макропроцессе) может стать поистине кошмаром.
Есть только определенные задачи, которые лучше обрабатываются в процедурной или OO-моде. Имея выбор использования .NET-кода для разбивки последовательности логики, операции запроса могут быть легче читать и отлаживать. Воспользовавшись хранимыми процедурами CLR, я могу сказать, что вы перешагиваете с помощью отладчика, что облегчает отслеживание того, что происходит на уровне базы данных.
Только один пример, мы часто используем хранимые процедуры CLR здесь как "шлюз" для динамических поисковых запросов. Произнесите запрос поиска, который может содержать до 30 различных параметров поиска. Пользователи, очевидно, не используют все 30 из них, поэтому переданная структура данных будет иметь 30 параметров, но в основном DBNULL. Клиентская сторона не имеет возможности генерировать динамическую инструкцию по очевидным соображениям безопасности. Получающееся в результате динамическое выражение создается внутренне, не опасаясь внешних "дополнительных".
Ответ 4
В общем, вы используете CLR, если у вас есть что-то, что не нужно многому взаимодействовать с базой данных. Итак, скажем, вы разбираете или декодируете значение. Это проще сделать в CLR, а затем вернуть значение.
Попытка выполнить запрос compelx в среде CLR просто не подходит.
Кстати, это тоже не изменилось в 2008 году.
Ответ 5
Я считаю, что эти два не эквивалентны... подходят друг другу.
Предполагается, что интеграция с CLR должна прекратить "расширенные хранимые процедуры". У нас есть некоторые из них на нашем рабочем месте... по существу блоки обработки/логики над SQL-данными, которые были слишком сложными/невозможными через обычные DB Хранимые процедуры /T SQL. Поэтому они написали это как расширенные хранимые процедуры в С++ DLL, которые можно вызвать аналогичным образом.
Теперь они были поэтапно отменены, и интеграция CLR является заменой
- Хранимые процедуры: если это можно сделать в T SQL Stored procs, сделайте это.
- CLR Хранимые процедуры: если логика слишком сложна или утомительна для выполнения через T SQL... если это что-то, что займет меньше строк кода CLR, чтобы справиться с ней (строковая манипуляция, сложная/пользовательская сортировка или фильтрация и т.д. ) используют этот подход.
Ответ 6
Помимо доступа к файловой системе (где CLR procs имеет очень выраженное преимущество), я бы использовал процедуры T-SQL. Если у вас есть особенно сложные вычисления, вы можете поместить эту часть в CLR функцию и вызвать ее из своего proc (udf - это то место, где я обнаружил, что интеграция CLR действительно светит). Затем вы получаете преимущества интеграции CLR для этой части своей задачи, но сохраняйте как можно больше своей сохраненной логики proc в БД.
Ответ 7
Учитывая то, что вы сказали, я бы предпочел, чтобы вы получили должным образом подготовленные девелоперы в t-SQl и базы данных, а не позволяли им создавать значительно больший урон производительности, позволяя им выполнять задачи t-sql в CLR. Разработчики, которые не понимают базы данных, используют это как оправдание, чтобы не делать то, что лучше для производительности базы данных, потому что они хотят воспринимать то, что они считают более легким маршрутом.
Ответ 8
Это всегда сводится к правильному инструменту для работы, поэтому это действительно зависит от того, что вы пытаетесь выполнить.
Однако, как правило, вы правы, что CLR-процессы имеют большие накладные расходы и никогда не будут выполняться при заданных операциях, таких как T-SQL. Мое руководство делает все это в T-SQL, если только вы не будете слишком сложны в T-SQL. Затем постарайтесь, чтобы подход T-SQL работал.:-)
Процессы CLR велики и имеют свое место, но их использование должно быть исключением, а не правилом.
Ответ 9
В электронной документации по SQL Server на странице перечислены эти преимущества:
-
Лучшая модель программирования. Языки .NET Framework во многом богаче Transact-SQL, предлагая конструкции и возможности, ранее недоступные разработчикам SQL Server. Разработчики могут также использовать возможности библиотеки .NET Framework, которая предоставляет обширный набор классов, которые могут быть использованы для быстрого и эффективного решения проблем программирования.
-
Повышенная безопасность и безопасность. Управляемый код работает в среде с общим языковым режимом, размещенной в базе данных. SQL Server использует это, чтобы обеспечить более безопасную и более безопасную альтернативу расширенным хранимым процедурам, доступным в более ранних версиях SQL Server.
-
Возможность определять типы данных и агрегатные функции. Пользовательские типы и агрегаты, определенные пользователем, представляют собой два новых объекта управляемой базы данных, которые расширяют возможности хранения и запросов SQL Server.
-
Оптимизированная разработка через стандартизованную среду. Разработка базы данных интегрирована в будущие выпуски среды разработки Microsoft Visual Studio.NET. Разработчики используют одни и те же инструменты для разработки и отладки объектов и сценариев базы данных, поскольку они используют для написания компонентов и сервисов средней уровня или клиентского уровня .NET Framework.
-
Потенциал для повышения производительности и масштабируемости. Во многих ситуациях модели компиляции и исполнения языка .NET Framework обеспечивают улучшенную производительность по сравнению с Transact-SQL.
Ответ 10
Мы столкнулись с ситуацией с функцией CLR, которая была вызвана тысячами раз в регулярном SQL-процессе. Это был процесс импорта данных из другой системы. Функция достоверно подтвердила данные и обработала нули.
Если мы выполнили операцию в TSQL, процесс завершился примерно через 15 секунд. Если мы использовали функцию CLR, процесс завершился через 20 - 40 минут. Функция CLR выглядела более изящной, но, насколько мы могли судить, для каждого использования функции CLR был начальный удар. Поэтому, если у вас есть большая операция, выполненная с использованием одной функции CLR, это прекрасно, поскольку время запуска мало по сравнению с временем выполнения операции. Или, если вы вызываете функцию CLR на небольшое количество раз, общее время запуска для всех вызовов функции будет небольшим. Но будьте осторожны с петлями.
Кроме того, для удобства обслуживания лучше не иметь больше языков, чем вам действительно нужно.
Ответ 11
Я бы добавил несколько причин использовать CLR, которые, возможно, не были упомянуты.
- Заменить и расширить базовые запросы, не запросы и скалярные sql-функции.
A) Отчеты об ошибках и предупреждения могут быть интегрированы на основе определенных требований.
B) Легко определить уровни отладки.
C) Включить более простой способ взаимодействия с иностранными серверами SQL.
- Переместить устаревший код в управляемую среду.
Ответ 12
Я отправил следующий ответ на аналогичный вопрос: Преимущество SQL SERVER CLR.
Однако я добавлю, что С#/VB.net/etc является языком, с которым пользователь более удобен, чем T-SQL, не должен быть причиной использования SQLCLR над T-SQL. Если кто-то не знает, как выполнить что-то в T-SQL, сначала попросите о помощи в поиске решения T-SQL. Если этого не существует, перейдите по маршруту CLR.
SQLCLR/CLR Интеграция в SQL Server - это еще один инструмент, помогающий решить определенные (не все) проблемы. Есть несколько вещей, которые он делает лучше, чем то, что можно сделать в чистом T-SQL, и есть некоторые вещи, которые могут быть выполнены только через SQLCLR. Я написал статью для SQL Server Central, Stairway to SQLCLR Level 1: Что такое SQLCLR? (для чтения статей требуется бесплатная регистрация), который решает этот вопрос. Основы (подробнее см. Связанную статью):
- Потоковые табличные функции (sTVF)
- Динамический SQL (внутри функций)
- Улучшенный доступ к внешним ресурсам/Замена xp_cmdshell
- Прохождение данных проще.
- Получение нескольких столбцов набора результатов проще
- Нет внешних зависимостей (например, 7zip.exe)
- Лучшая защита через олицетворение
- Возможность многопоточности
- Обработка ошибок (внутри функций)
- Пользовательские агрегаты
- Пользовательские типы
- Изменить состояние (внутри функции и без
OPENQUERY
/OPENROWSET
)
- Выполнение хранимой процедуры (только для чтения; внутри функции и без
OPENQUERY
/OPENROWSET
)
- Производительность ( примечание: это не имеет значения во всех случаях, но определенно в некоторых случаях в зависимости от типа и сложности операции)
- Можно записать вывод (т.е. то, что отправлено на вкладку "Сообщения" в SSMS) (например,
PRINT
и RAISERROR
с серьезностью = от 0 до 10). Я забыл упомянуть об этом в статье;-).
Еще одна вещь, которую следует учитывать, иногда полезно иметь возможность совместно использовать код между приложением и БД, чтобы БД могла понять определенную бизнес-логику, не создавая настраиваемые внутренние экраны только для доступа к этому код приложения. Например, я работал над системой, которая импортировала файлы данных от клиентов и использовала пользовательский хэш большинства полей и сохранила это значение в строке в БД. Это позволило легко пропустить строки при импорте своих данных снова, поскольку приложение будет хэш-значения из входного файла и сравнить с хэш-значением, хранящимся в строке. Если бы они были одинаковыми, мы сразу поняли, что ни одно из полей не изменилось, поэтому мы перешли к следующей строке, и это было простое сравнение INT. Но этот алгоритм для выполнения хэша был только в коде приложения, поэтому, чтобы отлаживать клиентский случай или искать способы разгрузить некоторую обработку для внутренних служб, помещая строки, в которых было хотя бы одно поле с изменениями (изменения, поступающие из нашего приложения в отличие от поиска изменений в более новом файле импорта), я ничего не мог сделать. Это была бы отличная возможность иметь довольно простой бит бизнес-логики в БД, даже если это не для нормальной обработки; наличие того, что составляет закодированное значение в БД, не способное понять его значение, затрудняет решение проблем.
Если вы заинтересованы в том, чтобы увидеть некоторые из этих возможностей в действии без необходимости писать какой-либо код, Бесплатная версия SQL # (из которых я я автор) имеет функции RegEx, пользовательские агрегированные (UDA), пользовательские типы (UDT) и т.д.