另一个数据库中对象的OBJECT_ID - 如何查找数据库ID或名称/完全限定对象名称?

时间:2009-12-03 21:43:00

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

示例:

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存根(或更改任何内容)来帮助我。

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

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

    直接访问元数据表

5 个答案:

答案 0 :(得分:20)

你应该可以这样做:

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而不是元数据函数。

答案 1 :(得分:10)

我是否正确理解您想要AnotherDB的数据库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

或者在其他dbs中执行SP:

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

答案 2 :(得分:5)

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

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

返回:

AnotherDB

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

返回:

ASchema

如果要求非完全限定,如果要求输入未包含在字符串中的名称部分,则会得到空结果:

select parsename('ASchema.ATable',3)

返回:

NULL

答案 3 :(得分:2)

我遇到了同样的问题,但也有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)))

答案 4 :(得分:0)

我使用以下解决方案:

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