小编Jos*_*nig的帖子

来自更远调用堆栈的 DB_ID 上下文

在 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

11
推荐指数
1
解决办法
510
查看次数

SQL Server 存储过程的条件编译

简短版本:是否有某种方法可以使用 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)

sql-server stored-procedures

8
推荐指数
1
解决办法
3206
查看次数

是否可以在不使用动态 sql 的情况下在另一个数据库中获取架构 ID?

我从对象 ID 和数据库 ID 开始。在用户定义的函数中,我想获取数据库、架构和对象的全名和 ID。如何在不使用 UDFS 内部禁止的动态 SQL 的情况下获取架构ID

笔记:

  • 我可以获得数据库名称 DB_NAME
  • 我可以通过使用来获取对象名称,OBJECT_NAME因为它接受数据库 ID 作为第二个参数
  • 我可以通过使用来获取模式名称OBJECT_SCHEMA_NAME因为它也接受数据库 ID 作为第二个参数
  • 使用动态 SQL 可以轻松获取架构 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)

schema sql-server

5
推荐指数
2
解决办法
3617
查看次数

在 SQL Server 中将实用程序(不是管理)存储过程放在哪里?

可能的重复:
为其他数据库中的内部存储过程设置中央 CLR 存储过程/函数存储库库以使用?

我有一些简单的用户定义的字符串操作函数。它们中的大多数实际上是 CLR 函数,但并非全部都是。我从同一台服务器上的多个数据库中使用它们。放置这些的正确位置是什么?

到目前为止,我一直将它们放在主数据库中。这是一个坏主意吗?如果是这样,为什么?拥有一个没有数据而只有可编程对象的实用程序数据库是标准做法吗?

sql-server stored-procedures

3
推荐指数
1
解决办法
200
查看次数

标签 统计

sql-server ×4

stored-procedures ×2

schema ×1