我能否在视图中动态调用存储过程?

3
具体来说,我能否从当前数据库中的视图中调用存储过程。我已经知道关于“openrowset hack”的信息,因此这个例子可以工作: openrowset hack
create view MyView as
    select *
    from openrowset (
        'sqloledb',
        'server=(local);trusted_connection=yes;',
        'exec MyDatabase.dbo.MyStoredProcedure' -- Works fine
    )

但是我希望能够在当前数据库中调用该存储过程,而不是像这样硬编码名称:

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需要字面字符串,而不是任何类型的变量。

无论安全性和性能考虑如何,是否有解决方法? 这将使遗留系统的维护更加容易,因为此视图调用的存储过程会根据环境(开发,测试,生产)连接到不同的数据库。


不行,你不能调用存储过程。 - Lamak
可能是重复的问题:如何在视图中调用存储过程? - Lamak
你可以使用 openrowset。这是一种有点 hack 的方法,诚然,我正在寻找更大的 hack 方法。 - Tim Lehner
1个回答

2

不可以在视图中使用动态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的代码最终将调用开发数据库中的存储过程。这种方法的缺点是一次只能有一个同义词处于活动/重定向状态。

谢谢,艾伦。同义词在这种情况下是一个有趣的选择...看起来我需要通过发布后脚本动态创建它们。 - Tim Lehner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接