Sql server 是否可以找到调用存储过程的数据库?

Sql server 是否可以找到调用存储过程的数据库?,sql-server,tsql,Sql Server,Tsql,假设我在SQLServer2008R2+上的数据库a中有一个过程 USE A GO CREATE PROCEDURE dbo.My_Test AS BEGIN PRINT ORIGINAL_DB_NAME() PRINT DB_NAME() END GO 使用 去 创建过程dbo.My_测试 作为 开始 打印原件\u DB\u NAME() 打印数据库名称() 结束 去 现在我在数据库B中调用该过程 USE B GO EXEC A.dbo.My_Test 使用B 去 EXE

假设我在SQLServer2008R2+上的数据库a中有一个过程

USE A GO CREATE PROCEDURE dbo.My_Test AS BEGIN PRINT ORIGINAL_DB_NAME() PRINT DB_NAME() END GO 使用 去 创建过程dbo.My_测试 作为 开始 打印原件\u DB\u NAME() 打印数据库名称() 结束 去 现在我在数据库B中调用该过程

USE B GO EXEC A.dbo.My_Test 使用B 去 EXEC A.dbo.My_测试 它将返回以下内容:

A A A. A. ORIGINAL_DB_NAME()为您提供登录时的默认数据库(如果有)。在本例中,它是一个,但它可以是任何东西,它不是最新/当前/超级上下文数据库

现在想象一下,在My_测试中,您希望执行还原数据库B。如果您在master或a中调用它,则此操作有效,但如果您在B中,则会失败并出现错误(因为该数据库正在使用中)

Msg 3102,16级,状态1,第2行 还原无法处理数据库“B”,因为该数据库正在由该会话使用。建议在执行此操作时使用主数据库。 我计划捕获并处理该异常,但我发现这个问题很有趣,因为似乎没有办法“发现”您提前进入了B。而且,您也不能在过程中使用master来避免问题(USE语句在过程中无效)


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

1/将数据库名称作为参数发送到存储的进程中

2/要使SP在当前连接的上下文中运行,您需要在主数据库上创建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
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