是否有可能找到一个从中调用存储过程的数据库?

时间:2013-12-05 04:35:40

标签: sql-server tsql

想象一下,我在SQL Server 2008R2 +上的数据库A中有一个过程。

USE A
GO

CREATE PROCEDURE dbo.My_Test
AS 
BEGIN
    PRINT ORIGINAL_DB_NAME()
    PRINT DB_NAME()
END
GO

现在我在数据库B中调用该程序。

USE B
GO

EXEC A.dbo.My_Test

它会返回:

A
A

ORIGINAL_DB_NAME()会为您提供登录时的默认数据库(如果有)。在这种情况下它是A但它可能是任何东西,它不是最新/当前/超级上下文数据库。

现在想象一下,在My_Test中你想要做一个RESTORE DATABASE B.如果你在master或A中调用它,它会起作用,但是如果你在B中则因为错误而失败(因为该数据库正在使用中)。 / p>

Msg 3102, Level 16, State 1, Line 2
RESTORE cannot process database 'B' because it is in use by this session. It is recommended that the master database be used when performing this operation.

我打算抓住并处理这个异常,但我发现问题很有意思,因为似乎没有办法提前“发现”你在B中。而且你不能在程序中做一个USE master来避免这个问题(use语句在程序中无效)。

是否有可能提前发现您在数据库B中?

1 个答案:

答案 0 :(得分:1)

1 /将DB名称作为参数发送到存储过程

2 /要使SP在当前连接的上下文中运行,您需要在master数据库上创建SP并使其成为系统对象。

USE MASTER 
GO 

-- name should start with "sp_"
CREATE PROCEDURE dbo.sp_My_Test
@OriginalDB SYSNAME
AS 
BEGIN
    PRINT ORIGINAL_DB_NAME()
    PRINT DB_NAME()
END
GO

EXEC sp_ms_marksystemobject 'sp_My_Test'
GO

USE Test2
GO

EXEC master..sp_My_Test @OriginalDB = DB_NAME