在 SQL Server 中,是否可以DB_ID
从调用堆栈更远的上下文中获取 ?
我的目标是在开发沙箱数据库中创建一些方便的(并且公认的 hacky)实用程序函数,使获取对象的完全限定名称变得简单而简洁,给定它们的短名称或碎片名称,另外删除使用相同短名称的对象. 这些实用程序函数将位于单个实用程序数据库中,但会从同一服务器上的其他数据库调用。
从我从测试中可以看出:
ORIGINAL_DB_NAME()
按预期返回连接字符串中的任何内容,而不是当前上下文(由 设置USE [dbname]
)。DB_NAME()
返回定义该函数的数据库的名称。另一种说法是,函数或存储过程内的上下文是定义它的数据库的上下文我知道引擎会跟踪调用堆栈上下的每个数据库上下文(请参见下面的证明)。那么有没有办法访问这些信息呢?
我希望能够在调用者数据库的上下文中查找和操作对象,即使执行代码不在同一个数据库中。例如:
use SomeDB
EXEC util.dbo.frobulate_table 'my_table'
Run Code Online (Sandbox Code Playgroud)
我知道我能做到
EXEC util.dbo.frobulate_table 'SomeDB.dbo.my_table'
Run Code Online (Sandbox Code Playgroud)
但我真的很好奇是否可以通过这种方式查询调用堆栈。
更新/注意
我确实从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 …
Run Code Online (Sandbox Code Playgroud) 简短版本:是否有某种方法可以使用 SQL Server Data Tools for Visual Studio 2010 有条件地编译 SQL Server 数据项目中的 TSQL 代码块?
我在 Visual Studio 2010 中使用 SQL Server Data Tools 来处理实验性 SQL Server Express 数据库。如果一切顺利,最终目标将是企业 SQL Server 平台。我在一个机器上有一个 2008 年的实例,另一个在另一个机器上有一个 2012 年的实例,因为我的公司也正在从 2008 年到 2012 年迁移许多企业数据库。
在我使用过的其他编程语言中,预处理器指令可以轻松地有条件地编译代码库的一部分。最常见的用途是在受限部分为不同平台使用不同的代码,或者从发布版本中排除调试输出代码。
在我正在处理的一些存储过程中,这两者都可能非常有帮助。有这样的东西吗?我知道我可以sqlcmd
在部署期间使用变量来换出特定的值,但我无法弄清楚如何使用它来包含或排除后续的代码块。
例子:
#IF $(DebugVersion) = 'True'
-- A bunch of useful PRINTs and what not
#ELSE
SET NOCOUNT ON
#ENDIF
#IF $(SSVersion) = '2012'
SET @pretty_date = FORMAT(@some_date, …
Run Code Online (Sandbox Code Playgroud) 我从对象 ID 和数据库 ID 开始。在用户定义的函数中,我想获取数据库、架构和对象的全名和 ID。如何在不使用 UDFS 内部禁止的动态 SQL 的情况下获取架构ID?
笔记:
DB_NAME
OBJECT_NAME
因为它接受数据库 ID 作为第二个参数OBJECT_SCHEMA_NAME
因为它也接受数据库 ID 作为第二个参数[db_name_i_want].sys.schemas
,但这在 UDF 中是不允许的更新(目的)
为了从更远的调用堆栈中解决DB_ID 上下文的可能解决方案,我正在调整Gabriel McAdams 的一些调用堆栈函数以跨多个数据库工作。他的版本只是将每个调用级别的 proc ID 推送到CONTEXT_INFO
流中。我已经修改了它以推送数据库 ID。我也可以推送模式 ID,但随后事情开始变得拥挤,因为它CONTEXT_INFO
被限制为 128 字节。因此,我希望能够从创建调用堆栈视图 (CallStackView) 的函数中的 db id 和对象 id 重建架构 ID。
代码
-- @db_id, @proc_id are saved in a logging function
DECLARE @db_name …
Run Code Online (Sandbox Code Playgroud) 我有一些简单的用户定义的字符串操作函数。它们中的大多数实际上是 CLR 函数,但并非全部都是。我从同一台服务器上的多个数据库中使用它们。放置这些的正确位置是什么?
到目前为止,我一直将它们放在主数据库中。这是一个坏主意吗?如果是这样,为什么?拥有一个没有数据而只有可编程对象的实用程序数据库是标准做法吗?