使用"IN"关键字和动态数据的SQL语法问题

use*_*521 3 sql t-sql sql-server sql-server-2000 subquery

我正在使用SQL Server 2000并且在SQL代码块(下面)中遇到了一个奇怪的问题:
用户可以输入"GM"作为可能的参数或"F".如果用户在存储的proc查询字符串中输入"GM"作为参数,我需要AutoDivision包含GMC,CAD,CHE,SAT

declare @AutoDivision as varchar(15) 
set @AutoDivision = 'GM' 

if @AutoDivision = 'GM' 
            Begin 
                Select @AutoDivision = '''Cad'', ''GMC'', ''Sat'', ''Che'''
            End 

            SELECT 
                 oh.OrderNumber, lg.[lgh_number]
            FROM 
                [dbo].[OrderHeader] oh (NOLOCK)
            INNER JOIN 
                [dbo].[DistrctHeader] lg (NOLOCK) ON oh.[inv_number] = lg.[inv_number]
            INNER JOIN
                [dbo].[DealerCompany] c (NOLOCK) ON c.cmp_id = LEFT(oh.[ordernumber],3)
            INNER JOIN
                [dbo].[divisionXREF] x (NOLOCK) ON x.Division = c.comp_revtype
            WHERE
                oh.ord_number = '113-889257'
                AND x.AutoDivision IN (@AutoDivision)
                --AND x.AutoDivision IN ('Cad', 'Sat', 'GMC', 'Che')
                AND lg.[lgh_outstatus] IN ('AVAIL', 'PLAN', 'DISP', 'STRTD', 'PEND','COMP')  
Run Code Online (Sandbox Code Playgroud)

但是,当我运行下面的代码时,我没有找回任何记录.当我取消注释代码行时
--AND x.AutoDivision IN ('Cad', 'Sat', 'GMC', 'Che')

它工作(我得到一个记录返回).

我什么时候print 'AND x.AutoDivision IN (' + cast(@AutoDivision as varchar) + ')'
回去AND x.AutoDivision IN ('Cad', 'GMC', 'Sat', 'Che')

我在这里错过了什么?

OMG*_*ies 10

您不能使用单个变量来表示SQL中的逗号分隔的IN参数列表 - Oracle,MySQL,SQL Server ......无关紧要.

要使此变量方法起作用,您需要使用动态SQL,以便能够首先将查询创建为字符串(使用串联从变量中获取IN参数),然后执行查询语句:

DECLARE @cmd VARCHAR(1000)

SET @cmd = 'SELECT oh.OrderNumber, 
                   lg.[lgh_number]
              FROM [dbo].[OrderHeader] oh (NOLOCK)
              JOIN [dbo].[DistrctHeader] lg (NOLOCK) ON oh.[inv_number] = lg.[inv_number]
              JOIN [dbo].[DealerCompany] c (NOLOCK) ON c.cmp_id = LEFT(oh.[ordernumber],3)
              JOIN [dbo].[divisionXREF] x (NOLOCK) ON x.Division = c.comp_revtype
             WHERE oh.ord_number = '113-889257'
               AND x.AutoDivision IN ('+ @AutoDivision +')
               AND lg.[lgh_outstatus] IN (''AVL'', ''PLN'', ''DSP'', ''STD'', ''PND'',''CMP'')  '

EXEC(@cmd)
Run Code Online (Sandbox Code Playgroud)

我建议在实现动态SQL解决方案之前阅读动态SQL的诅咒和祝福.

表值函数

一个表值函数将允许你做你想要的东西,而无需使用动态SQL -有在这篇文章中的详细信息.


小智 5

为避免这种情况,您可以创建临时表,填写,然后使用

IN (SELECT myField from #myTable)
Run Code Online (Sandbox Code Playgroud)