Sql server SQL查询在使用声明的变量时不返回结果,但在插入这些值时返回结果

Sql server SQL查询在使用声明的变量时不返回结果,但在插入这些值时返回结果,sql-server,tsql,Sql Server,Tsql,我有下面的SQL,它从一个表中获取“floor”和“unit”的值,并尝试将这些值与另一个表中的记录相匹配 DECLARE @lockerFloor varchar(max) = (SELECT TOP(1) lockerFloorArea FROM t_users_tempImport_parkingLockers) DECLARE @lockerUnit varchar(max) = (SELECT TOP(1) lockerUnitNumber FROM t_users_tempImpo

我有下面的SQL,它从一个表中获取“floor”和“unit”的值,并尝试将这些值与另一个表中的记录相匹配

DECLARE @lockerFloor varchar(max) = (SELECT TOP(1) lockerFloorArea FROM t_users_tempImport_parkingLockers)
DECLARE @lockerUnit varchar(max) = (SELECT TOP(1) lockerUnitNumber  FROM t_users_tempImport_parkingLockers)

SELECT id FROM t_buildings_units WHERE [floor] = @lockerFloor AND unit = @lockerUnit
以上结果不返回任何结果。但是,如果我执行以下操作:

DECLARE @lockerFloor varchar(max) = (SELECT TOP(1) lockerFloorArea FROM t_users_tempImport_parkingLockers)
DECLARE @lockerUnit varchar(max) = (SELECT TOP(1) lockerUnitNumber  FROM t_users_tempImport_parkingLockers)

SELECT @lockerFloor AS 'Floor', @lockerUnit AS 'Unit'
我得到以下结果:

现在,如果我使用上面的结果运行这个查询,我会得到预期的结果

SELECT id FROM t_buildings_units WHERE [floor]='LKR' AND unit='241'


我错过了什么

要点很简单:

DECLARE @lockerFloor varchar(max) = (SELECT TOP(1) lockerFloorArea 
                                     FROM t_users_tempImport_parkingLockers)
没有明确的排序依据的Top是不确定的
@lockerFloor
在多次执行之间可能具有不同的值


运行:

DECLARE @lockerFloor varchar(max) = (SELECT TOP(1) lockerFloorArea FROM t_users_tempImport_parkingLockers)
DECLARE @lockerUnit varchar(max) = (SELECT TOP(1) lockerUnitNumber  FROM t_users_tempImport_parkingLockers)

SELECT id FROM t_buildings_units WHERE [floor] = @lockerFloor AND unit = @lockerUnit
它可以返回任意一对。我们可以通过使用辅助变量来复制它

DECLARE @lockerFloor varchar(max) = (SELECT TOP(1) lockerFloorArea FROM t_users_tempImport_parkingLockers)
DECLARE @lockerUnit varchar(max) = (SELECT TOP(1) lockerUnitNumber  FROM t_users_tempImport_parkingLockers)

DECLARE @helper_lockerFloor VARCHAR(MAX) = @lockerFloor,
        @helper_lockerUnit  VARCHAR(MAX) = @lockerUnit;

SELECT @helper_lockerFloor,@helper_lockerUnit;

SELECT id FROM t_buildings_units 
WHERE [floor] = @helper_lockerFloor AND unit = @helper_lockerUnit;
请尝试以下查询:

SELECT id FROM t_buildings_units WHERE [floor] = '' + @lockerFloor + '' AND unit = '' + @lockerUnit + ''
我猜:

  • 您的表有一些索引
  • 第一个查询的实际查询计划使用不同的索引执行每个
    select top(1)
  • 您运行的第二个查询是另一个以不同方式优化的TSQL批处理
  • 您可以通过查看实际的查询计划来证明这一点。您可以通过SSMS选项“包含实际执行计划(CTRL+M)”,或者通过使用扩展事件会话,或者通过使用不推荐使用的SQL探查器来获取实际计划

    即使没有其他索引,您的第一个查询也可以自由选择它们想要的
    top
    行,因为没有指定
    orderby
    ,它们是单独的查询

    在第一个查询中,尝试在同一行上同时设置两个变量:

    -- use the same type as the column type to avoid implicit conversions
    DECLARE
        @lockerFloor varchar(100), -- changed from varchar(max)
        @lockerUnit varchar(100) -- changed from varchar(max)
    
    SELECT TOP 1
        @lockerFloor = [lockerFloorArea],
        @lockerUnit = [lockerUnitNumber]
    FROM t_users_tempImport_parkingLockers
    
    SELECT id FROM t_buildings_units WHERE [floor] = @lockerFloor AND unit = @lockerUnit
    
    :Facepalm:

    t_users_tempiort_parkingLockers表中的数据是通过CSV文件的大容量插入填充的。它正在导入带有换行符的lockerUnitNumber值。更换select上的换行符修复了该问题

    DECLARE @lockerFloor varchar(100) = (SELECT TOP(1) lockerFloorArea FROM t_users_tempImport_parkingLockers ORDER BY idx desc)
    DECLARE @lockerUnit varchar(100) = (SELECT TOP(1) REPLACE(REPLACE(lockerUnitNum,CHAR(13), ''), CHAR(10), '')  FROM t_users_tempImport_parkingLockers ORDER BY idx desc)
    SELECT id FROM t_buildings_units WHERE [floor] = @lockerFloor AND unit = @lockerUnit
    

    您需要使用临时表构建一个精简的可复制示例,让我们体验相同的行为。对于
    lockerFloorArea
    lockerUnitNumber
    (定义为数字的东西)的值,您真的需要2 GB的存储空间吗?如果
    lockerUnitNumber
    是一个数字,您推断可能需要存储编号
    1E+2147483648-1
    。这是一个巨大的数字。为什么
    '+@lockerFloor+'
    ?两边的
    '
    实现了什么?变量是字符串值。“变量是字符串值。”那么为什么要用空字符串包装它呢?@Larnu:SQL 20142016甚至不用单引号。现在,我怀疑SQL(20052008)的旧版本可能需要这样的报价包装器。在作品周围有两个单引号。如果使用三个引号,那么它需要作为动态sql执行。我甚至怀疑在SQLServer2000中需要这样的语法。当然不是2005年。但是,为什么要使用SQL Server 7.0所要求的语法?这已经有十多年不受支持了。即使按idx DESC或其中idx=X分别添加订单,也不会返回任何结果。@DigitalFusion是否使用辅助变量运行代码?
    idx
    列是唯一的吗?idx是唯一的,表中只有一行数据,辅助变量产生相同的问题