【问题标题】:DB_NAME() in SQL Server when using [DBName].[SchemaName].[TblName] query syntax使用 [DBName].[SchemaName].[TblName] 查询语法时 SQL Server 中的 DB_NAME()
【发布时间】:2019-02-26 11:55:32
【问题描述】:

以下查询返回当前数据库的名称:

USE [DB1]
SELECT DB_NAME() AS Current_DB
FROM [dbo].[TblName]

结果:

Current_DB
----------
DB1

DB_NAME() 与以[DBName].[SchemaName].[TblName] 表示法从表中选择的查询一起使用时,我看到了非常奇怪的结果:

T-SQL

USE [DB1]
SELECT DB_NAME() AS Current_DB
FROM [DB1].[dbo].TblName
UNION
SELECT DB_NAME() AS Current_DB
FROM [DB2].[dbo].TblName
UNION
SELECT DB_NAME() AS Current_DB
FROM [DB3].[dbo].TblName
UNION
SELECT DB_NAME() AS Current_DB
FROM [DB4].[dbo].TblName

结果:

Current_DB
----------
DB1

T-SQL

USE [DB1]
SELECT DB_NAME() AS Current_DB
FROM [DB1].[dbo].TblName
UNION ALL
SELECT DB_NAME() AS Current_DB
FROM [DB2].[dbo].TblName
UNION ALL 
SELECT DB_NAME() AS Current_DB
FROM [DB3].[dbo].TblName
UNION ALL
SELECT DB_NAME() AS Current_DB
FROM [DB4].[dbo].TblName

结果:

Current_DB
----------
DB1
DB1
DB1
...  (632,788 rows of DB1 !!!)

即使我从 T-SQL 查询中省略 USE [DB1],我也会得到相同的结果 - 在 SSMS 的查询目标下拉菜单中选择的数据库是出现在结果中的数据库。

如何使用[DBName].[SchemaName].[TblName] 格式在多个查询中获得正确的DB_NAME()

【问题讨论】:

  • 如你所说returns the name of the current database。不是 FROM 子句中表的数据库。
  • 你想要达到什么目的?当您使用 [DB1].[dbo].TraceContactSource 时,您已经知道数据库名称
  • 你不能。让DB_NAME() 返回您想要的名称的唯一方法是先执行use [dbname]。如果你能做到这一点,你已经有了名字......

标签: sql sql-server tsql sql-server-2008 sql-server-2012


【解决方案1】:

DB_NAME()不带参数显示当前连接会话的数据库名称,而不是你正在查询的对象的底层数据库。

来自文档:

A.返回当前数据库名称。此示例返回名称 当前数据库。

SELECT DB_NAME() AS [当前数据库];

否则,如果您在数据库之间进行连接并调用 DB_NAME(),您会期望什么?

SELECT
    DB_NAME() -- ??
FROM
    Database1.dbo.Table1 AS T
    CROSS JOIN Database2.dbo.Table2 AS N

您可以使用USE <DatabaseName> 语句切换连接的数据库。

【讨论】:

    【解决方案2】:

    如果未指定database_id 参数,DB_NAME() 函数将返回当前数据库的名称

    当前数据库不是指你查询的表所在的数据库,而是你当前连接的数据库。

    unionunion all 查询之间的区别在于 union 返回不同的值 - 由于您在每个查询中选择相同的值,因此返回单个值。

    【讨论】:

    • 谢谢。知道为什么 UNION ALL 会返回 632,788,即使只有 4 个查询是 UNION ALL 的?
    • 是的 - 所有表中总共有 632,788 行。如果你在哪里做(select count(*) from table1) + (select count(*) from table2) 等等,这就是你会得到的数字。
    • 谢谢,有道理! :)
    【解决方案3】:

    DB_NAME() 返回您当前连接的数据库的名称。一个查询可以引用FROM 中的多个数据库,那么查询会是什么样子呢?

    SELECT DB_NAME()
    FROM DB1.dbo.YourTable YT
         JOIN DB2.dbo.OtherTable OT ON OT.ID = YT.ID;
    

    对于您的查询,您需要在查询中指定数据库的名称:

    USE [DB1]
    SELECT N'DB1' AS Current_DB
    FROM [DB1].[dbo].TraceContactSource
    UNION ALL
    SELECT N'DB2' AS Current_DB
    FROM [DB2].[dbo].TraceContactSource
    UNION ALL 
    SELECT N'DB3' AS Current_DB
    FROM [DB3].[dbo].TraceContactSource
    UNION ALL
    SELECT N'DB4' AS Current_DB
    FROM [DB4].[dbo].TraceContactSource
    

    但是,根据 cmets,如果您实际上是在寻找(非系统)数据库列表,那么这也许可以实现您的目标:

    SELECT [name] AS Current_DB
    FROM sys.databases
    WHERE database_id > 4;
    

    【讨论】:

    • 除非从实际表中添加记录,否则from 子句是多余的——你可以简单地做SELECT N'DB1' As Current_Db UNION ALL SELECT N'DB2' UNION ALL SELECT N'DB3'...
    • 事实上,SELECT [name] AS Current_Db FROM sys.databases WHERE database_id > 4; 可能会更好,这取决于他们的目标,@ZoharPeled,取决于他们的目标。
    • 我正在寻找一种方法来做到这一点,而无需在查询中对数据库名称进行硬编码 - 我正在使用 sp_executesql 并在 100 多个数据库中运行此代码以创建比较报告。我现在找到了一种方法......无论如何谢谢:)
    • 听起来我们这里有一个 XY 问题,@Adam。
    猜你喜欢
    • 2010-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-16
    • 1970-01-01
    • 2016-04-17
    • 1970-01-01
    • 2018-09-23
    相关资源
    最近更新 更多