Создание хранимой процедуры на лету. Каковы риски / проблемы? - PullRequest
2 голосов
/ 23 октября 2008

Я думаю о создании хранимых процедур на лету.

то есть работает CREATE PROCEDURE ... когда запущено (веб) приложение.

Какие риски или проблемы это может вызвать?

  • Я знаю, что учетная запись базы данных должна иметь дополнительные привилегии.
  • Это не происходит каждый день. Только время от времени.
  • Я использую sql server и также заинтересован в mysql и postgres.

Update1:

Благодаря комментариям я подумываю о создании новой версии хранимой процедуры и переключении вместо ALTERing sp. пример: sp1 -> sp2 -> sp3

Обновление2:

Причина:

Моя схема изменяется из-за пользовательских полей (неизвестное количество и тип столбцов) Сначала я попробовал динамический sql и sp_executesql. Конечно, это работает. Динамический sql работает лучше для 1,2,3 простого обновления, вставки.

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

По крайней мере, основной сценарий для этого решения не так уж сложен. Логика sp не меняется. Для каждого настраиваемого поля я должен добавить новый параметр в sp и добавить столбец для обновления, вставки и т. Д.

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

Ответы [ 9 ]

1 голос
/ 10 июля 2009

Вы упомянули, что вы будете добавлять и / или изменять профиль вызова хранимой процедуры, когда будете делать это изменение. Как вы блокируете новый профиль вызова с помощью приложения, которое делает вызов на это? Какой у вас план возврата, если вам когда-нибудь придется отменить внесенное изменение?

В прошлом я просто добавил увеличивающийся числовой суффикс к имени хранимой процедуры с новым профилем вызова - затем вы можете изменить старую версию SP, чтобы она вызывала новую версию со значением по умолчанию параметр, а затем вы можете освободить программное обеспечение, вызвав новую версию.

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

1 голос
/ 23 октября 2008

Для транзакционной системы это, вероятно, довольно дорого. Если у вас большое пакетное задание и вы хотите по какой-то причине использовать генератор кода (довольно распространенная архитектура в инструментах ETL, в частности Oracle Warehouse Builder и Wherescape Red ), это не является необоснованным сделать это.

0 голосов
/ 17 сентября 2013

Не знаю точно, но звучит как один или оба:

  • архитектурная проблема
  • существует ли существующий код, блокирующий таблицы схемы из приложения?

Я бы посмотрел, какой код блокирует таблицы схемы, и переписал бы этот код. Есть ли у вас какая-то сторонняя компания, которая блокирует эти таблицы?

0 голосов
/ 23 октября 2008

Я не уверен, что блокировка, обсуждаемая Тони Банбрахимом, верна в SQL Server 2005.

У меня есть несколько длительных SP (3-часовой пакетный процесс, включающий около 30 подпроцессов), и я смог изменить SP, пока он еще работает. (Я не верю, что изменения вступят в силу до следующего запуска, но это не вызывает блокировку или ошибку). Теперь внешний долгосрочный SP вызывает SP как динамически, так и статически, но я меняю корневой и вложенный SP, пока они работают без сообщений об ошибках или блоков.

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

0 голосов
/ 23 октября 2008

Вы не сможете изменить процедуру, если один или несколько пользователей запускают процедуру или другую процедуру, которая ссылается на вашу процедуру. Вы будете блокировать, пока все зависимые процедуры и процедура, которую вы хотите скомпилировать (и я думаю, что процедура, которую вы вызываете из своей процедуры, но я не уверен), не используются. Это может занять много времени в загруженной производственной системе, и если вам не повезло, вы можете приостановить ожидание того, что все зависимости не будут использоваться (5 минут в Oracle).
Вы также можете попасть в очень ужасные ситуации (у меня есть). Возьмем, к примеру, хранимые процедуры B и C, которые вызывают A, процедуру, которую вы пытаетесь скомпилировать. Когда никто не запускает B, система блокирует B. Теперь любой пользователь, пытающийся запустить B, остановится. Затем система пытается заблокировать C, но C генерирует очень длинный отчет, который не будет выполнен в течение еще 10 минут. Вы будете ожидать тайм-аут ожидания блокировки, и некоторые из ваших пользователей будут иметь систему без ответа на 5 минут. Мой опыт работы с Oracle, я бы позаботился о том, чтобы ваша целевая СУБД не работала таким же образом или имела более быстрые сбои или лучшую стратегию получения блокировки. Я предполагаю, что предупреждаю, что то, что выглядит, может работать на сервере разработки, может сильно потерпеть неудачу в загруженной производственной системе.

0 голосов
/ 23 октября 2008

Я бы не стал делать это лично.

Как вы упомянули, вам потребуются дополнительные привилегии для предоставления доступа к созданию / изменению объектов базы данных. Это может создать серьезную угрозу безопасности, поскольку ничто не помешает вашему приложению создать вредоносную хранимую процедуру, если кто-то обнаружит в ней дыру в безопасности.

Если ваша схема изменяется, измените хранимые процедуры со схемой.

0 голосов
/ 23 октября 2008

Если вам действительно нужно это сделать, вам следует выбрать имя процедуры случайным образом, чтобы избежать столкновения с другими пользователями. Всегда помните, что другие пользователи могут заниматься своими делами в одно и то же время - большинство систем баз данных не обеспечат транзакционную изоляцию для хранимых процедур (Postgres - единственный, кто мне известен).

Было бы крайне редко, чтобы это было желательно - можно ли вообще уточнить, что заставило вас выбрать этот подход?

0 голосов
/ 23 октября 2008

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

0 голосов
/ 23 октября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...