sql-server - 我可以从 View 中动态调用存储过程吗?

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

具体来说,我可以在 View 中从当前数据库调用一个过程吗?我已经知道 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 需要文字字符串,而不是任何类型的变量。

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

最佳答案

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

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 来指定你想要的 View ,或者你可以在你想模拟每个环境时删除并创建一个同义词,例如

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

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

关于sql-server - 我可以从 View 中动态调用存储过程吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10626836/

相关文章:

MySql存储过程: How to select from procedure table?

sql-server-2008-r2 - 无法将数据库从SQL Server 2008 R2还原到2012

sql-server - 在 SET 和 JOIN 子句中使用 TVP 名称

sql-server - 将列中相似(但不相同)的数据合并到单行中

sql - SQL Server 中的求和或乘法

sql-server - 删除 SQL Server 2016 中的部分重复行

sql - 为每个 sql 查询输出指定标题

sql-server - SQL Server 和事务中间的连接丢失

c# - Azure SQL DB 保持连接直到 EF 超时

mysql - 在 MySql Workbench 6.2 中调用 MySQL 存储过程时,影响 2 行而不是 1 行