#sql-server #dynamic #execution #clrstoredprocedure
#sql-сервер #динамический #выполнение #clrstoredprocedure
Вопрос:
Есть ли способ динамически изменять код процедуры CLR в SQL Server?
Предположим, у вас есть сборка с вашей бизнес-логикой, развернутая в MS SQL Server 2008 R2. Эта сборка (или сборки) используется постоянно (например, вызывая некоторые функции для каждой строки таблицы в нескольких одновременных запросах). Таким образом, вы не можете просто удалить сборку. Есть ли способ динамического изменения моей бизнес-логики или какой-либо способ выполнения внешнего изменяемого кода?
Я уже исследовал эти подходы, но ни один из них не сработал:
- Отражение.Испускать
- Mono.Сесил
- Загрузка внешней сборки в сборку, развернутую на SQL Server
ОБНОВЛЕНИЕ: Вопрос был не о процессе выпуска: я хочу иметь возможность динамически устанавливать некоторые правила безопасности через графический интерфейс.
Например, некоторые пользователи должны иметь возможность видеть только клиентов без их адресов или транзакций за последний год и так далее.
Правила не сложны, но они могут меняться почти каждый день, и мы не можем поместить их в код. Остальная бизнес-логика реализована в TSQL. Среда CLR была выбрана из-за проблемы с производительностью (динамический SQL слишком медленный).
Был другой вариант: генерировать кластеризованные представления (с правилами в разделе WHERE), но это было недостаточно быстро.
Еще несколько деталей:
Предположим, у нас есть некоторый код, выбирающий часть большой таблицы dbo.Транзакции
select *
from dbo.Transactions
where ... --filters from your business logic
Если мы хотим отфильтровать результат, чтобы показать разрешенные строки, мы могли бы сгенерировать некоторое индексированное представление и объединить его с результирующим набором следующим образом:
select *
from dbo.Transactions t
inner join dbo.vw_Transactions v
on t.id = v.id
where ... --filters from your business logic
Но если мы проверим план выполнения, в большинстве случаев анализатор запросов решает не фильтровать dbo.Транзакция, а затем объединение с помощью vw_Transactions, но сначала объединение, а затем фильтрация (что абсолютно нежелательно). Такие подсказки, как ПРИНУДИТЕЛЬНЫЙ ПОРЯДОК, не помогают.
Комментарии:
1. Итак, вы рады обойти любой формальный процесс выпуска? Для этого у вас есть CLR?
2. @gbn Вопрос был не о процессе выпуска: я хочу иметь возможность динамически устанавливать некоторые правила безопасности через графический интерфейс. Например, некоторые пользователи должны иметь возможность видеть только клиентов без их адресов или транзакций за последний год и так далее. Правила не сложны, но они могут меняться почти каждый день, и мы не можем включить их в код. Остальная часть бизнес-логики реализована в TSQL. Среда CLR была выбрана из-за проблемы с производительностью (динамический SQL работает слишком медленно). Был другой вариант: генерировать кластеризованные представления (с правилами в разделе WHERE), но это было недостаточно быстро.
3. это не очевидно в вашем вопросе…
Ответ №1:
Я не эксперт по сборке CLR, но очевидные варианты:
- ИЗМЕНИТЬ СБОРКУ
- Удалите и заново создайте сборку внутри транзакции
- Определите окно обслуживания и затем разверните его
замечание gbn о процессах выпуска является хорошим. Если ваши процедуры (и, следовательно, ваши бизнес-операции) действительно постоянно выполняются 24×7, то, по-видимому, у вас уже есть некоторая форма избыточности системы и установленные процедуры обслуживания для исправления и обновления приложений? Если это так, просто разверните свой новый код в обычном окне обслуживания.
Комментарии:
1. После пересмотра идеи я обнаружил, что повторное использование требуется в довольно редких случаях, поэтому мы можем выполнять, когда никто не подключен (приложение не выполняется 24×7). @Pondlife, @gbn вы были правы: вопрос касался процесса выпуска (но он был скрыт)
Ответ №2:
Есть хорошая библиотека для динамического вычисления арифметического выражения (с параметрами) — Fleet
В моем случае мне не пришлось выполнять ничего.Чистый код — только выражения типа «Date > ‘20100101’ Или Status = 2», поэтому Fleet удовлетворяет почти полностью. Единственная проблема заключается в том, что его логические операторы не работают с типом SqlBoolean (который используется в выражениях sql), но добавить эту функцию не составляет большого труда.
Но в общем случае, кажется, невозможно выполнить dynamic.Сетевой код внутри узла Sql Server.
Комментарии:
1. Это невозможно из-за отражения. Эмиссия блокируется атрибутом защиты хоста. смотрите msdn.microsoft.com/en-us/library/ms403285.aspx