2008-10-23 57 views
2

我正在考虑即时创建存储过程。即时创建存储过程。有什么风险/问题?

即运行CREATE PROCEDURE ...当(web)应用程序正在运行时。

它可能导致什么风险或问题?

  • 我知道数据库帐户需要额外的权限。
  • 它不会每天都发生。只是不时。
  • 我使用的是sql server,对mysql和postgres也很感兴趣。

UPDATE1:

感谢您的意见,我正在考虑创建存储过程的新版本和切换,而不是改变SP。例如:SP1 - > SP2 - > SP3

UPDATE2:

的原因:由于自定义字段的

我的架构更改(未知数和列型) 我试图动态SQL和sp_executesql的第一。当然,它的作品。动态sql的工作原理为1,2,3简单更新,插入。

但它太难看了,很多工作,它不能很好地与存储过程混合,因为在存储过程中使用sql参数化的问题,并且编译时不知道参数的数量和类型(很长的故事)。

至少这个解决方案的基本情况并不复杂。 sp的逻辑不会改变。对于每个自定义字段,我必须为sp添加一个新参数并添加一列以更新,插入等。

我还考虑过使存储过程参数动态化,如接受任何数量和类型的参数但无法找到的sp_executesql一种方式。

+0

如果你不介意我问,你能详细说明一些你考虑这个选项的“很好的理由”吗? – ninesided 2008-10-23 07:25:24

+0

由于自定义字段,模式正在更改。我可以去动态SQL,但缺点是性能问题,并使其他事情变得困难。动态sql在简单的情况下运行良好,但对于一些复杂的存储过程并不适用。有很多细节... – user30683 2008-10-23 07:33:50

回答

0

首先,这个问题的答案实际上取决于这个存储过程的目的是做什么。如果只是读取数据或创建报告结果集,并且不介意是否有点不一致,那么您可能没有问题。如果它对你的数据做了任何有趣的事情,那么这是一件非常冒险的事情。您应该考虑两个用户用户(或同一个用户两次)是否有可能(以及会发生什么情况)同时运行同一存储过程的多个版本。闻起来像一列火车撞向我。一种选择是只允许在没有其他用户登录到系统时进行此过程更改,或者如果这些更改是强制将其从数据库引导的话。另一种选择是创建名称略有不同的新存储过程,并在您认为安全的情况下将它们交换。

+0

逻辑不会改变。只有列被添加到更新,插入。 简单地说,使用新的sp代替动态sql。 我不知道是否可以同时运行sp的两个版本,但如果发生它不会是一个问题。它就像运行动态sql(具有不同列)的变体 – user30683 2008-10-23 07:43:35

0

另一个问题是存储过程的一个主要优点是执行计划被缓存,这意味着它的执行速度会更快。如果您在飞行中创建它们,则会失去该优势。

+0

我提到它不是每天发生。只有一次在 – user30683 2008-10-23 08:30:22

0

如果您确实需要这样做,那么您应该随机输入程序的名称以避免与其他用户冲突。请记住,其他用户可能会同时做自己的事情 - 大多数数据库系统不会为存储过程提供事务隔离(Postgres是我所知的唯一一个)。

这将是非常罕见的,这将是一个理想的事情要做 - 你能详细说明是什么让你选择这种方法?

0

我不会那样做。

如上所述,您将需要额外的权限来授予对创建/更改数据库对象的访问权限。这可能会造成严重的安全风险,因为如果有人在其中发现安全漏洞,则无法阻止应用程序创建恶意存储过程。

如果您的模式更改,请使用模式更改存储过程。

0

如果一个或多个用户正在运行该过程或引用您的过程的其他过程,您将无法更改过程。你会阻止,直到所有的依赖程序和你想编译的程序(我认为你从程序中调用的程序,但我不确定)没有被使用。在繁忙的生产系统上这可能会很长时间,如果您不幸运,您可能会超时等待所有依赖项不被使用(Oracle上为5分钟)。
你也可以进入非常丑陋的情况(我有)。以存储过程B和C为例,它们都调用A,您正试图编译的过程。当没有人运行B时,系统锁定B.现在任何试图运行B的用户都将停止运行。然后系统尝试锁定C,但是C正在生成一个非常冗长的报告,而这个报告不会再持续10分钟。您将超时等待锁定,并且您的某些用户在5分钟内会出现无响应的系统。我的经验是与甲骨文,我会确保你的目标数据库管理系统不以相同的方式行事,或有更快的失败或更好的锁定获取策略。
我想我警告说,在繁忙的生产系统上看起来像在开发服务器上工作可能会失败。

0

我不知道该由托尼BanBrahim讨论的锁定是SQL Server 2005确实

我有一些长时间运行的SP(约30分过程的3小时批量处理),和我已经能够在SP仍在运行的时候改变它。 (我不相信这些更改会在下一次运行之前生效,但它不会导致任何阻塞或任何错误)。现在,外部长时间运行的SP既用EXEC动态地调用SP,又静态地调用SP,但在运行时没有错误消息或块,我更改了根和嵌套SP。

WRT你原来的问题,我认为你的策略是好的,如果以可控的方式使用。

1

您提到您将在添加和/或更改存储过程的调用配置文件时进行此更改。你如何锁定新的呼叫配置文件与调用此应用程序?如果您需要恢复所做的更改,那么您的回滚计划是什么?

过去我所做的只是在新的调用配置文件中为存储过程名添加递增的数字后缀 - 然后您可以修改SP的旧版本以调用具有默认值的新版本为参数,然后您可以释放您的软件调用新版本。

如果新版本中出现问题并且需要回滚,调用旧的存储过程仍然可以正常工作,只需使用默认值填充自定义字段即可。

0

我不知道是肯定的,但它听起来像是一个或两个:

  • 一个结构问题
  • 是现有的代码锁定从应用架构表?

我想看看哪些代码锁定模式表并重写该代码。你有第三方的东西或其他锁定这些表的东西吗?