查询中的变量不起作用

时间:2016-07-13 12:48:25

标签: sql sql-server

我在使用SQL查询时遇到了一些问题,我正在创建一个变量:

 declare @material varchar(500)
 declare @typ varchar(200)
 declare @strsql varchar(max)
 set @typ = 'papier'

 select @material = (SELECT + rtrim(ltrim([grupa])) + ','
                     FROM [test].[dbo].[GT] 
                     WHERE (typ = @typ) FOR XML PATH(''))
 set @material =  left(@material, len(@material)-1)
 set @material  = replace(@material, ',' ,''',''')
 set @material = '''' + @material + ''''

 select @material

变量的输出是:

'test','test2'

这是我主要代码的一小部分:

 SELECT
     Number,
     isnull(sum((case 
                    when [Group] in ('test','test2') 
                       then isnull(cast([Quantity] as int), 0) 
                 end)), 0) as other
 FROM
     [dbo].[test-table]

这是正确的,但当我尝试这样做时:

 SELECT
     Number,
     isnull(sum((case 
                    when [Group] in (@material) 
                       then isnull(cast([Quantity] as int), 0) 
                  end)), 0) as other
 FROM
     [dbo].[test-table]

输出错误(不同)。谁能告诉我为什么?这有点像。

3 个答案:

答案 0 :(得分:1)

它有点相同,但它不一样。您希望获得的是:in ('test','test2'),您得到的是:in (''test','test2'')

您必须动态构建其余查询,例如:

DECLARE @SQL NVARCHAR(MAX) = 'SELECT
 Number
 ,isnull(sum((case when [Group] in ('+ @material + ') 
 then isnull(cast([Quantity] as int),0) end)),0) as other
 from [dbo].[test-table]'

EXEC sys.sp_executesql @SQL

如果您说输出错误,最好显示实际输出及其错误原因。说"输出与第一个查询相比有所不同 - 它应该是相同的"在大多数情况下是不够的。

修改

如果你不想使用动态sql(这很有意义),你可以做这样的事情(实际上比动态更可读):

SELECT      Number
,           ISNULL(SUM(data),0) as other
FROM        (
                SELECT  Number
                ,       CASE WHEN [Group] IN (SELECT grupa FROM [dbo].[GT] WHERE typ = @typ) 
                                THEN ISNULL(CAST([Quantity] AS INT), 0) 
                         END data
                FROM    [dbo].[test-table] 
            ) TT
GROUP BY    Number

我在这里做了很多关于你的目标,架构和数据的假设。没有更多的信息,这可能是我能做的最好的...(可能会有一些性能调整要做,但这是本质)

答案 1 :(得分:1)

尝试使用函数来拆分字符串:

CREATE FUNCTION [dbo].[FN_SplitString](@String nvarchar(4000), @Delimiter char(1))
RETURNS @Results TABLE (Items nvarchar(4000))
AS
    BEGIN
    IF @String IS NULL RETURN
    IF LTRIM(RTRIM(@String)) = '' RETURN
    DECLARE @INDEX INT
    DECLARE @SLICE nvarchar(4000)
    SELECT @INDEX = 1
    WHILE @INDEX !=0
        BEGIN   
            SELECT @INDEX = CHARINDEX(@Delimiter,@STRING)

        IF @INDEX !=0
            SELECT @SLICE = LEFT(@STRING,@INDEX - 1)
        ELSE
            SELECT @SLICE = @STRING
        INSERT INTO @Results(Items) VALUES(@SLICE)
        SELECT @STRING = RIGHT(@STRING,LEN(@STRING) - @INDEX)
        IF LEN(@STRING) = 0 BREAK
END
RETURN

然后以这种方式使用它:

SELECT
 Number
 ,isnull(sum((case when [Group] in (SELECT  Items, FROM FN_SplitString(@material,',')) 
 then isnull(cast([Quantity] as int),0) end)),0) as other
 from [dbo].[test-table]

答案 2 :(得分:1)

SQL Server中,如果您将comma分隔的列表作为IN Clause T-SQL中的变量传递给error,则不会给<script> tinymce.init({ selector: '#body', }); </script> <textarea id="body" name="body"></textarea> ,但您不会甚至得到预期的结果。

有两种解决方案可以解决这个问题:

  1. 使用动态查询
  2. 使用分割功能