在SQL Server中,是否可以DB_ID
从较远的调用堆栈中从上下文中获取?
我的目标是在dev沙箱数据库中创建一些方便的工具(并且很容易被发现),使给定其短名称或零散名称的对象的标准名称变得简单明了,并使用相同的短名称删除对象。这些实用程序功能将在单个实用程序数据库中,但会从同一服务器上的其他数据库调用。
从测试中我可以看到:
ORIGINAL_DB_NAME()
按预期返回连接字符串中的内容,而不是当前上下文(由设置USE [dbname]
)。- 在函数中调用时,
DB_NAME()
返回定义该函数的数据库的名称。换句话说,函数或存储过程内部的上下文是定义该上下文的数据库的上下文
我知道引擎会跟踪调用堆栈上下的每个数据库上下文(请参见下面的证明)。那么有什么方法可以访问此信息?
我希望能够在调用者数据库的上下文中找到对象并对其进行操作,即使执行代码不在同一数据库中也是如此。例如:
use SomeDB
EXEC util.dbo.frobulate_table 'my_table'
我知道我能做
EXEC util.dbo.frobulate_table 'SomeDB.dbo.my_table'
但是我真的很好奇,是否可以通过这种方式查询调用堆栈。
更新/注释
我确实从Gabriel McAdams的博客中阅读并下载了代码。这提供了堆栈上上下的调用过程ID的记录,但仍假定所有内容都在同一数据库中。
证明SQL Server可以记住数据库上下文上下调用堆栈
示例:在具有数据库TestDB1和TestDB2的开发服务器上
use TestDB1
GO
CREATE FUNCTION dbo.ECHO_DB_NAME() RETURNS nvarchar(128) BEGIN RETURN DB_NAME() END
GO
use TestDB2
GO
CREATE PROCEDURE dbo.ECHO_STACK AS
BEGIN
DECLARE @name nvarchar(128)
SET @name = DB_NAME()
PRINT 'Before, DB_NAME inside dbo.ECHO_STACK : ' + @name
SET @name = TestDB1.dbo.ECHO_DB_NAME()
PRINT 'TestDB1.dbo.ECHO_DB_NAME returned : ' + @name
SET @name = DB_NAME()
PRINT 'After, DB_NAME inside dbo.ECHO_STACK : ' + @name
END
GO
use master
SELECT DB_NAME() -- Returns 'master'
EXEC TestDB2.dbo.ECHO_STACK
ECHO_STACK proc打印:
Before, DB_NAME inside dbo.ECHO_STACK : TestDB2
TestDB1.dbo.ECHO_DB_NAME returned : TestDB1
After, DB_NAME inside dbo.ECHO_STACK : TestDB2
老实说,我不能说我有充分的理由证明为什么这是必要的。我发现它非常有趣,如果能弄清楚,我会将其放在沙盒开发数据库中使用的两个方便的小proc中:一个给出对象的全名,给出该名称的最短可识别片段(例如in我在问题中的第一个示例),另一个通过使用另一个函数获取全名来杀死对象,并且还使用所标识对象的类型来生成
—
Joshua Honig
DROP
语句。
@SQLKiwi问题已相应更新。也感谢您的其他回答。我已经有许多用于字符串操作的CLR函数,因此这对我来说自然是下一步。
—
Joshua Honig
USE xyz;
内容?