【问题标题】:Retrieve Database name from an variable [duplicate]从变量中检索数据库名称[重复]
【发布时间】:2019-03-11 13:55:45
【问题描述】:

我有一个简单的要求,我需要用来自另一个表的数据库名称替换一个变量。

我有一个叫做配置设置的表

键值

ClubcardDB ClubardDetailsDB

代码

Declare @Value varchar(100)
select @Value= value configsetting where Code=’ ClubcardDB’
Select top 10 * from  [@Value].[dbo].[ClubcardDetails]

它给出了一个错误: 无效的对象名称 '@Value.dbo.ClubcardDetails'。

我不想构建动态查询..

【问题讨论】:

  • 你需要动态 sql。
  • 你为什么不想构建动态查询

标签: sql-server


【解决方案1】:

尝试使用SQLCMD Mode。在 SSMS 中,点击Query -> SQLCMD Mode

:setvar dbname "YourDB" 

SELECT * FROM $(dbName).dbo.YourTable

Read more about SQLCMD.

【讨论】:

    【解决方案2】:

    这是我在我的机器上制作的一个工作示例:

    Declare @Value varchar(100)='Test'
    DECLARE @SQL NVARCHAR(MAX)
    
    SET @SQL='Select * from ' + QUOTENAME(@Value) + '.[sys].[all_columns];'
    EXECUTE sp_executesql @SQL
    

    一种更安全的方法,因为它验证值实际上是数据库名称:

    Declare @Value varchar(100)='Test'
    DECLARE @SQL NVARCHAR(MAX)
    
    SELECT @SQL='Select * from ' + QUOTENAME(name) + '.[sys].[all_columns];'
    FROM master.dbo.sysdatabases
    WHERE name=@Value
    
    EXECUTE sp_executesql @SQL
    

    【讨论】:

    • 您至少需要在这里处理 SQL 注入。这只是一个安全漏洞。
    • 虽然如此,但如果您无法控制自己的配置表中的值,您的问题就会更大。
    • 我仍然建议至少正确使用QUOTENAME。恶意的人可以很容易地逃脱括号。例如SET @Value = N'master].sys.objects; CREATE LOGIN t WITH PASSWORD=''1'',CHECK_POLICY=OFF,CHECK_EXPIRY=OFF;--'
    • 真的吗?当您尝试'...FROM ' + QUOTENAME(@value) + '.sys...' 时,什么不起作用?
    • @Larnu 我没有删除文字中的 [];答案已更新
    猜你喜欢
    • 1970-01-01
    • 2014-09-11
    • 1970-01-01
    • 1970-01-01
    • 2014-10-22
    • 2011-05-09
    • 2016-06-02
    • 1970-01-01
    • 2022-11-24
    相关资源
    最近更新 更多