【问题标题】:OBJECT_ID of object in another database - how to find database ID or name/fully qualified object name?另一个数据库中对象的 OBJECT_ID - 如何查找数据库 ID 或名称/完全限定的对象名称?
【发布时间】:2009-12-03 21:43:00
【问题描述】:

例子:

USE AnotherDB
-- This works - same ID as from other DB
SELECT OBJECT_ID('AnotherDB.ASchema.ATable')
-- This works
SELECT OBJECT_NAME(OBJECT_ID('AnotherDB.ASchema.ATable'))

USE ThisDB
-- This works - same ID as from other DB
SELECT OBJECT_ID('AnotherDB.ASchema.ATable')
-- Gives NULL
SELECT OBJECT_NAME(OBJECT_ID('AnotherDB.ASchema.ATable'))

显然元数据函数需要一个当前数据库。对于 OBJECT_NAME 等函数,BOL 条目通常具有类似这样的语言:

Microsoft SQL Server 2005 数据库 引擎假设 object_id 在 当前数据库的上下文。一种 引用 object_id 的查询 另一个数据库返回 NULL 或 结果不正确。

我需要能够做到这一点的原因:

  1. 我无法在 SP 中使用其他数据库

  2. 我无法在其他数据库或 master(或除我自己之外的任何其他数据库)中创建代理 UDF 存根(或更改任何内容)来帮助我。

那么当我在 ThisDB 中时,如何从 OBJECT_ID('AnotherDB.ASchema.ATable') 获取数据库?

我的目标是从配置表中获取可能部分限定的名称,在当前上下文中将其解析为完全限定的名称,使用 PARSENAME 获取数据库名称,然后使用动态 SQL 构建脚本以获取直接使用database.sys.*USE db; sys.* 到元数据表

【问题讨论】:

  • 您是否拥有某个对象的实际 id,例如 234521345,并且您想从另一个 db 中检索该 id 的名称。但是您拥有所有 db 的名称?
  • 我并不真的需要身份证,但如果我在路上用一个就可以了。

标签: sql-server sql-server-2005 metadata


【解决方案1】:

你应该可以这样做:

SELECT
   name
FROM
    AnotherDB.sys.objects   --changes context
WHERE
    object_id = OBJECT_ID('AnotherDB.ASchema.ATable')

这就是您使用OBJECT_ID('AnotherDB.ASchema.ATable') 所做的有效操作

这意味着您可以依赖 dbname.sys.objects 并避免与元数据函数混淆。

注意:new Catalog views 旨在用于使用,而不是根据链接在版本之间更改。在过去,使用系统表被认为是不好的做法,但污名仍然存在。 因此,您可以放心地依赖 sys.objects 而不是元数据功能。

【讨论】:

    【解决方案2】:

    你想要AnotherDB的db id我理解正确吗?

    SELECT *
    FROM    master..sysdatabases
    WHERE   name = 'AnotherDB'
    

    否则,如果有帮助,您可以在动态 SQL 中使用其他数据库:

    DECLARE @SQL    NVARCHAR(MAX)
    ,   @objId  INT
    
    SET @SQL = N'
        USE AnotherDB
    
        SELECT  @id = OBJECT_ID(''customer'')
    '
    
    EXEC SP_EXECUTESQL @SQL
        ,   N'@id INT OUTPUT'
        ,   @id = @objId OUTPUT
    
    SELECT  @objId
    

    或在其他数据库中执行 SP:

    EXEC AnotherDB.dbo.ProcedureName 
          @paramX = ...
    ,     @paramY = ...
    

    【讨论】:

    • 是的,有没有办法从对象名称(可能是也可能不是完全限定的 - 表、schema.table 或 db.schema.table)中获取它?
    • 对 - 它归结为采用可能的部分限定名称,在当前上下文中解析它,然后使用 PARSENAME 获取数据库名称,然后像你动态地完成我的其余部分一样工作。
    【解决方案3】:

    查看PARSENAME function in TSQL - 将允许您提取完全(或非完全)限定名称的 4 部分中的任何部分。对于您示例中的数据库:

    select parsename('AnotherDB.ASchema.ATable',3)
    

    返回:

    另一个数据库

    select parsename('AnotherDB.ASchema.ATable',2)
    

    返回:

    架构

    如果不是完全限定的,如果您询问未包含在字符串中的名称部分,您将得到空结果:

    select parsename('ASchema.ATable',3)
    

    返回:

    【讨论】:

    • 如果我可以将部分限定名称解析为完全限定名称,那就太好了。你知道怎么做吗?
    • 不,使用本机功能是不可能的——除了检查实例上的每个数据库以查找与给定的非限定名称匹配的对象之外,真的没有办法做到这一点,但是你如何处理可能的冲突呢?您可以轻松创建一个过程,该过程将遍历系统上的所有数据库,以查找与给定架构/名称匹配的对象(可能利用 sp_MSforeachdb 系统过程,或者只是通过 sys.databases 的游标) - 这就是您想要的?即,如果没有 db 合格,则返回具有与给定模式/名称匹配的对象的所有数据库?
    • 其实很简单 isnull(parsename('unqualified',3),DB_NAME()) 。这显然假设不合格的名称应该解析为当前数据库,但这并不是一个延伸,因为这是预期的行为。
    【解决方案4】:

    我遇到了同样的问题,但也遇到了 OJBECT_SCHEMA_NAME。从 chadhoc 使用 parsename 的响应开始,它与 OBJECT_NAME 一起使用,例如:

    DECLARE @OrigTableName NVARCHAR(MAX);
    
    SELECT @OrigTableName = 'AnotherDB.ASchema.ATable'
    
    SELECT OBJECT_NAME(OBJECT_ID(@OrigTableName), DB_ID(PARSENAME(@OrigTableName, 3)))
    , OBJECT_SCHEMA_NAME(OBJECT_ID(@OrigTableName), DB_ID(PARSENAME(@OrigTableName, 3)))
    

    【讨论】:

    • 如果您已经拥有完全限定名称,这将毫无意义。只需像 @ChadHoc 那样使用 ParseName() once 即可。 SELECT PARSENAME('AnotherDB.ASchema.ATable', 1) 将返回 ATable。这比为相同的值调用 4 个函数(Object_NameObject_IDDB_IDParseName)的开销更好、更清晰。
    【解决方案5】:

    我使用了以下解决方案:

    DECLARE @SchemaName varchar(255) = 'SchemaName'
    DECLARE @ObjectName varchar(255) = 'ObjectName'
    
    SELECT     o.*
    FROM       AnotherDB.sys.objects AS o
    INNER JOIN AnotherDB.sys.schemas AS s ON o.schema_id = s.schema_id
    WHERE      s.name = @SchemaName
    AND        o.name = @ObjectName
    

    【讨论】:

      猜你喜欢
      • 2015-07-28
      • 1970-01-01
      • 2014-03-13
      • 1970-01-01
      • 2014-01-09
      • 2019-03-20
      • 2011-05-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多