【问题标题】:Can I dynamically call a stored procedure from a view?我可以从视图中动态调用存储过程吗?
【发布时间】:2012-05-24 12:07:51
【问题描述】:

具体来说,我可以在视图中从 当前数据库 调用 proc。我已经知道openrowset hack,所以这是可行的,例如:

create view MyView as
    select *
    from openrowset (
        'sqloledb',
        'server=(local);trusted_connection=yes;',
        'exec MyDatabase.dbo.MyStoredProcedure' -- Works fine
    )

但我希望能够从当前数据库调用 proc,而无需像这样对名称进行硬编码:

create view MyView as
    select *
    from openrowset (
        'sqloledb',
        'server=(local);trusted_connection=yes;',
        'exec ' + db_name() + '.dbo.MyStoredProcedure' -- Don't want to hard-code DB name
    )

不幸的是,这不起作用,因为 openrowset 需要文字字符串,而不是任何类型的变量。

不管安全性和性能方面的考虑,是否有解决方法?这将使遗留系统的维护更容易忍受,因为此视图将调用的 proc 根据环境(开发、测试、产品)连接到不同的数据库。

【问题讨论】:

标签: sql-server stored-procedures sql-server-2008-r2 dynamic-sql sql-view


【解决方案1】:

不,您不能在视图中使用动态 SQL。如果只有三个不同的“环境”,您可以只创建三个视图,和/或根据环境使用同义词。例如,您可以拥有三个视图(伪/修剪):

create view dbo.devMyView as
    select * ... 'exec Dev.dbo.MyStoredProcedure'
go
create view dbo.testMyView as
    select * ... 'exec Test.dbo.MyStoredProcedure'
go
create view dbo.prodMyView as
    select * ... 'exec Prod.dbo.MyStoredProcedure'

然后您可以在代码中使用动态 SQL 来指定您想要的视图,或者您可以在要模拟每个环境时删除并创建同义词,例如

DROP SYNONYM dbo.MyView;
GO
CREATE SYNONYM dbo.MyView FOR dbo.devMyView;

现在引用 dbo.MyView 的代码最终将调用 dev 数据库中的存储过程。这样做的缺点是在任何给定时间只能激活/重定向一个同义词。

【讨论】:

  • 谢谢,亚伦。在这种情况下,同义词是一个有趣的替代方案......看起来我将使用部署后脚本动态创建它们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 2020-04-03
  • 2012-07-17
  • 2011-08-13
  • 1970-01-01
  • 1970-01-01
  • 2023-01-22
相关资源
最近更新 更多