动态创建存储过程。有哪些风险/问题?

时间:2008-10-23 07:12:22

标签: sql sql-server tsql stored-procedures

我正在考虑动态创建存储过程。

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

它可能带来哪些风险或问题?

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

UPDATE1:

感谢评论,我正在考虑创建一个新版本的存储过程并切换而不是改变sp。例如:sp1 - > sp2 - > SP3

Update2:

原因:

由于自定义字段(未知数量和列类型),我的架构发生了变化 我首先尝试了动态sql和sp_executesql。当然有效。动态sql适用于1,2,3简单更新,插入。

但它太丑陋而且工作量很大而且它与存储过程没有很好的混合,sql参数化的问题因为它在存储过程中使用而且在编译时不知道params的数量和类型(long故事)。

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

我还考虑使存储过程参数像sp_executesql一样动态,它接受任何数量和类型的参数,但找不到方法。

9 个答案:

答案 0 :(得分:1)

对于交易系统来说,它可能相当昂贵。如果您有一个大型批处理作业并且由于某种原因想要使用代码生成器(在ETL工具中非常常见的架构,特别是Oracle Warehouse BuilderWherescape Red),那么这样做是不合理的。

答案 1 :(得分:1)

您提到在执行此更改时,您将添加和/或更改存储过程的调用配置文件。你如何用调用它的应用程序锁定新的调用配置文件?如果您必须还原所做的更改,那么您的回滚计划是什么?

过去我所做的只是使用新的调用配置文件向存储过程名称附加一个递增的数字后缀 - 然后您可以修改旧版本的SP以使用默认值调用新版本的SP参数,然后您可以发布调用新版本的软件。

如果您的新版本出现问题并且您必须回滚,则对旧存储过程的调用仍然可以正常运行,并且只使用您的默认值填充自定义字段。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

另一个问题是存储过程的主要好处之一是执行计划被缓存,这意味着它将更快地执行。如果你在飞行中创造它们就会失去这种优势。

答案 4 :(得分:0)

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

这将是一件非常罕见的事情 - 你能否详细说明是什么让你选择这种方法?

答案 5 :(得分:0)

我不会亲自这样做。

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

如果架构发生更改,请使用架构更改存储过程。

答案 6 :(得分:0)

如果一个或多个用户正在运行该过程,或者另一个引用您的过程的过程,您将无法更改该过程。你将阻塞所有依赖的程序和你想编译的程序(我认为你从程序中调用的程序,但我不确定)没有被使用。在繁忙的生产系统上这可能需要很长时间,如果您运气不好,可能会超时等待所有依赖项无法使用(Oracle上5分钟)。
你也可以陷入非常丑陋的境地(我有)。以存储过程B和C为例,两者都调用A,即您尝试编译的过程。当没有人在运行B时,系统会锁定B.现在任何试图运行B的用户都会停止。然后系统尝试锁定C,但是C生成一个非常冗长的报告,不会在另外10分钟内完成。您将超时等待锁定,并且您的一些用户将在5分钟内没有响应系统。我的经验是使用Oracle,我会确保您的目标DBMS不会以相同的方式运行,或者更快的故障或更好的锁定获取策略。
我想我是警告在开发服务器上看起来可能起作用的东西可能会在繁忙的生产系统上显着失败。

答案 7 :(得分:0)

我不确定Tony BanBrahim讨论的锁定在SQL Server 2005中是否正确。

我有一些长时间运行的SP(大约30个子进程的3小时批处理过程),并且我能够在它仍在运行时更改SP。 (我不相信这些更改会在下次运行之前生效,但不会导致任何阻塞或任何错误)。现在,外部长时间运行的SP同时使用EXEC和静态动态调用SP,但是我在运行时更改了根SP和嵌套SP而没有错误消息或块。

写下您原来的问题,如果以受控制的方式使用,我认为您的策略很好。

答案 8 :(得分:0)

我不确定,但听起来像是其中之一:

  • 建筑问题
  • 是从应用程序锁定架构表的现有代码吗?

我将看看哪些代码锁定了架构表并重写了该代码。你有第三方锁定这些表的东西吗?