【问题标题】:how to declare database as variable in sql statment如何在sql语句中将数据库声明为变量
【发布时间】:2019-04-13 18:51:00
【问题描述】:

我在将 sql 语句 (MS SQL) 数据库声明为变量时遇到问题,我有这个过程, 任何人都可以帮助谢谢:)

DECLARE @ID int = 700001158
DECLARE @STRING VARCHAR(250) = 'StringResource_EN'

SELECT string.[value],item.[id] FROM ItemResource item LEFT JOIN **@STRING** string ON item.[name_id] = string.[code]
WHERE item.[id] = @ID

我得到了错误:

[42000] [Microsoft][SQL Server Native Client 11.0][SQL Server]必须声明表变量“@STRING”。 (1087) 块引用

虽然应该是这样的结果:

id = 700001158 value = Devildom Purge: Shield

编辑: 我试过了

DECLARE @ID int = 700001158
DECLARE @STRING VARCHAR(250) = 'StringResource_EN'
DECLARE @sql NVARCHAR(1000)

SET @sql =  'SELECT string.[value],item.[id] FROM ItemResource item LEFT JOIN '+@STRING+' string ON item.[name_id] = string.[code]
WHERE item.[id] = @ID'

EXEC sp_executesql @sql;

我也得到了这个

[42000] [Microsoft][SQL Server Native Client 11.0][SQL Server]必须声明标量变量“@ID”。 (137)

【问题讨论】:

  • 也总是包含错误信息。它们很重要。请解释一下“数据库作为变量”是什么意思
  • 好的,谢谢,我会添加
  • 另外,如果@IN_STRING_DB 是一个动态对象,则没有理由将其声明为nvarchar(255)。对象名称的最长长度为 128 个字符,因此请使用 nvarchar(128)sysname
  • 如果您想将数据库声明为变量,您有两种选择:1) 通过将 sql 命令存储在变量中来使用动态 sql,或者 2) 使用 sqlcmd 模式,您可以在其中标记数据库名称作为变量docs.microsoft.com/en-us/sql/ssms/scripting/…
  • 为了回答您的问题,在您的第二个块中,您在语句中嵌入了字符串 @id,而不是该变量中包含的 value。您的逻辑也不正确(或您的描述具有误导性)。 [at]string 中包含的值必须是对象名称 - 您说的是数据库名称,但这是不正确的。鉴于术语问题,您应该重新考虑导致此路径的决策。这超出了您的技能水平,您将难以实施和维护。

标签: sql-server tsql


【解决方案1】:

您将需要为此使用动态 SQL:

ALTER PROCEDURE [dbo].[cpanel_get_warehouse_item]
@IN_ACCOUNT_ID      INT,
@IN_STRING_DB VARCHAR(255),
@ITEM_COUNT         INT OUTPUT,
@GOLD           INT OUTPUT

AS
SET NOCOUNT ON
SET @ITEM_COUNT = (SELECT COUNT(*) FROM [Telecaster].dbo.[Item] WHERE [account_id] = @IN_ACCOUNT_ID AND [code] > 0)
SET @GOLD = (SELECT [cnt] FROM [Telecaster].dbo.[Item] WHERE [account_id] = @IN_ACCOUNT_ID AND [code] = 0 AND [gcode] = 126)

DECLARE @sql NVARCHAR(1000);

SELECT @sql =  'SELECT string.[value] as name,item.[code] as id ,item.[cnt],item.[level],item.[enhance],data.[icon_file_name] as icon
FROM [Telecaster].dbo.[Item] item LEFT JOIN [Arcadia].dbo.[ItemResource] data on data.[id] = item.[code]
LEFT JOIN [Arcadia].dbo.' + @IN_STRING_DB +  'string on data.[name_id] = string.[code]
WHERE item.[account_id] = ' + @IN_ACCOUNT_ID' + AND item.[code] > 0 ORDER BY item.[sid] asc'

EXEC sp_executesql @sql;

正如 Milney 正确指出的那样,无论何时使用动态 SQL,都应该注意 SQL 注入。

【讨论】:

  • 请记住,如果变量由用户以任何方式控制,这会使您面临 SQL 注入攻击:acunetix.com/websitesecurity/sql-injection,因此您通常最好找到解决此问题的应用程序级解决方案
  • 我做了,我得到了 [42000] [Microsoft][SQL Server Native Client 11.0][SQL Server]必须声明标量变量“@ID”。 (137)
  • @Jim Jimson 请检查帖子!我已经按照你的建议做了
  • QUOTENAME 是你的朋友。这是一个注入问题。
  • 我已经更新了。但是,我找不到您会看到该错误的任何地方。请检查您的参数。
猜你喜欢
  • 2023-03-20
  • 1970-01-01
  • 2014-04-12
  • 2013-01-15
  • 1970-01-01
  • 1970-01-01
  • 2017-09-06
  • 2020-06-21
  • 1970-01-01
相关资源
最近更新 更多