【问题标题】:SSRS - Empty valueSSRS - 空值
【发布时间】:2016-09-09 14:06:10
【问题描述】:

我在 SSRS 中有一个参数 @Destinataire,它有一个值列表和一个空字符串

我创建了一个设置为可用值的查询,它为我提供了下拉列表

SELECT code_name FROM tableA UNION ALL SELECT ''

使用空字符串运行报告时,我没有结果

我尝试将参数设置为文本框,它也没有做任何事情

但在运行我用来运行此报告的 sql 查询时,一切都很好,因为我检索到了所有行(请参阅下面的查询)

DECLARE @DateCmt DATE = '05/09/2015',
        @DateFin DATE = '05/09/2016',
        @Restriction INT = 1,
        @Destinataire VARCHAR(5) = ''
        --
        ;

--SELECT @DateCmt,@DateFin

 SELECT DISTINCT 
CFE_EDI.IU_LIASSE
,CFE_EDI.ETAT
,CFE_EDI.DATHRMAJ -- nouveau
,CFE_EDI.ESP_APPLI
,CFE_EDI.NOM_RS
,PARTENAIRES.LIBEL
,PARTENAIRES.CODE_INSEE
,CFE_EDI.DATHR_ENV -- nouveau
,CFE_EDI.DATHR_MEF -- nouveau
,CFE_EDI.DATHR_PRE -- nouveau
,CFE_EDI.DATHR_OUV -- nouveau
--,CFE_EDI.DATEHR_DEPOT-- mettre l'heure
,CFE_EDI.GESTDEL
--,CFE_SERVICE_DEST.IU_DEST
--,CFE_SERVICE.IU_LIASSE
,CASE WHEN CFE_EDI.ETAT = 'MEF' THEN 'En Attente le'
     WHEN CFE_EDI.ETAT = 'PRE' THEN 'Préparé le' 
     WHEN CFE_EDI.ETAT = 'ENV' THEN 'Envoyé le'
     WHEN CFE_EDI.ETAT = 'OUV' THEN 'Réceptionné le'
     WHEN CFE_EDI.ETAT = 'NRM' THEN 'Non remis le'
     WHEN CFE_EDI.ETAT = 'NAQ' THEN 'Non acquitté le'
     END AS ChampEtat
,CASE WHEN CFE_EDI.ETAT = 'OUV' THEN 'Date d''envoi : ' + CONVERT(VARCHAR,CFE_EDI.DATHR_ENV,103)
END AS Date_Envoi,
CASE 
WHEN CFE_EDI.ETAT='MEF' THEN  CONVERT(VARCHAR,CFE_EDI.DATHR_MEF,103) 
WHEN CFE_EDI.ETAT='PRE' THEN  CONVERT(VARCHAR,CFE_EDI.DATHR_PRE,103) 
WHEN CFE_EDI.ETAT='ENV' THEN  CONVERT(VARCHAR,CFE_EDI.DATHR_ENV,103) 
WHEN CFE_EDI.ETAT='OUV' THEN  CONVERT(VARCHAR,CFE_EDI.DATHR_OUV,103) 
ELSE CONVERT(VARCHAR,CFE_EDI.DATHR_DEPOT,103) END AS DateMaj ,
CASE
WHEN CFE_EDI.ETAT='MEF' then CONVERT(VARCHAR,CFE_EDI.DATHR_MEF,108) 
WHEN CFE_EDI.ETAT='PRE' then CONVERT(VARCHAR,CFE_EDI.DATHR_PRE,108) 
WHEN CFE_EDI.ETAT='ENV' then CONVERT(VARCHAR,CFE_EDI.DATHR_ENV,108) 
WHEN CFE_EDI.ETAT='OUV' then CONVERT(VARCHAR,CFE_EDI.DATHR_OUV,108)
ELSE CONVERT(VARCHAR,CFE_EDI.DATHR_DEPOT,108) END AS HeureMaj,
PARTENAIRES.LIBEL + '(' + CFE_EDI.CODE_INSEE + ')' AS LibelDestinataire
--,CASE WHEN @Restriction = 1 THEN '1'
--     WHEN @Restriction = 0 THEN '0' END AS Restriction
,CASE WHEN @DateCmt != @DateFin AND @DateCmt <  @DateFin THEN 'Diffusion Xml du ' + CONVERT(VARCHAR,(@DateCmt),103) + ' au ' + CONVERT(VARCHAR,(@DateFin),103) ELSE 
'Diffusion EDI Xml du ' + CONVERT(VARCHAR,@DateCmt,103) END AS Plage_Diffusion
-- INTO 
 FROM   
 (PARTENAIRES 
 INNER JOIN dbo.CFE_EDI ON PARTENAIRES.CODE_INSEE = CFE_EDI.CODE_INSEE) 
INNER JOIN dbo.CFE_SERVICE ON CFE_EDI.IU_LIASSE = CFE_SERVICE.IU_LIASSE
INNER JOIN dbo.CFE_SERVICE_DEST ON (PARTENAIRES.IU_PART = CFE_SERVICE_DEST.IU_PART_CFE)
WHERE 
case when @Restriction = 1
              then case when CFE_EDI.ETAT in('ENV','OUV') then 1 else 0 end
           when @Restriction = 0
              then case when CFE_EDI.ETAT not in('ENV','OUV') then 1 else 0 end
           else case when CFE_EDI.ETAT <> '' then 1 else 0 end
       end = 1
AND 
CFE_EDI.CODE_INSEE IS NOT NULL AND CFE_EDI.CODE_INSEE != '' 
    AND    CASE --WHEN CFE_EDI.CODE_INSEE IS NOT NULL AND CFE_EDI.CODE_INSEE !=''
           --THEN CASE 
           WHEN @Destinataire != '' AND (@Destinataire) IS NOT NULL
              THEN CASE WHEN CFE_EDI.CODE_INSEE = @Destinataire THEN 1 ELSE 0 END
           ELSE CASE WHEN CFE_EDI.CODE_INSEE = PARTENAIRES.CODE_INSEE 
                    AND cfe_edi.dathrmaj > @DateCmt AND cfe_edi.dathrmaj < @DateFin 
                    AND CFE_EDI.GESTDEL = '1' THEN 1 ELSE 0 END  
           END = 1

第一个问题是知道是否有办法在不使用我的愚蠢技巧的情况下设置参数。

第二个问题是为什么带有空字符串参数的查询会起作用,而一旦使用 SSRS,什么都没有。

提前感谢您的帮助

更新我尝试将WHEN LEN(@Destinataire) &gt; 0 设置为@Destinataire = '',但没有成功。

更新 2 我现在的目标是找到一个可以检索所有数据的解决方案,以防 @Destinataire 等于 '' 或 NULL。然而,仔细想想,这个解决方案相当于在@Destinataire 中填充了所有值。所以我会说一种或另一种方式。

最终更新我从头开始重新创建了所有内容,哦!魔术,分组或一切选项如愿以偿。我仍然不知道出了什么问题,但我对结果很好。非常感谢您的帮助和支持。

【问题讨论】:

  • 为什么不传递空字符串,而不是传递其他“空”,然后调整查询或设置查询传递时的案例“空”设置@Destinataire = '' .
  • 嗨@newGuy 不,你的建议没有做它应该做的事情
  • 嗨@mike-honey,你有机会看看吗?
  • 今天晚上醒来时,我有一个洞察力。为什么不使用len(@Destinataire) &gt; 0?让我星期一试试
  • 您可以使用值“ALL”而不是空字符串然后检查您的情况是否有 Destinaire != 'ALL'

标签: sql sql-server reporting-services


【解决方案1】:

查看您的查询以及传递@Destinataire 的位置,您应该能够根据where 子句传递一个空值,并获得与传递''相同的效果

 CASE --WHEN CFE_EDI.CODE_INSEE IS NOT NULL AND CFE_EDI.CODE_INSEE !=''
       --THEN CASE 
       WHEN @Destinataire != '' AND (@Destinataire) IS NOT NULL
          THEN CASE WHEN CFE_EDI.CODE_INSEE = @Destinataire THEN 1 ELSE 0 END
       ELSE CASE WHEN CFE_EDI.CODE_INSEE = PARTENAIRES.CODE_INSEE 
                AND cfe_edi.dathrmaj > @DateCmt AND cfe_edi.dathrmaj < @DateFin 
                AND CFE_EDI.GESTDEL = '1' THEN 1 ELSE 0 END  
       END = 1

我会尝试仅设置该特定参数以允许 ssrs 报告中的空值可以在参数设置窗口中作为复选框找到。

【讨论】:

  • 嗨@Zi0n1,您提出的使用NULL的解决方案也不起作用...... Headbanging
  • 我想我不明白为什么它也像 '' 这样的空格.现在你可能正在抛弃 SSRS,因为你并没有真正传递任何类型的值。
  • 我什至更改了我的参数以包含All然后我将查询更改为条件WHEN @Destinataire != '' AND (@Destinataire) IS NOT NULL AND @Destinataire != 'All'。即使这样,什么也没有出现!!!
  • 我想我现在明白了。因此,目前您的 destinataire 参数必须满足所有这些条件才能满足 case 语句的后半部分。尝试将这些 AND 更改为 OR,并在其周围加上括号,如下所示:(WHEN Destinataire != '' OR (Destinataire) IS NOT NULL OR Destinataire != 'All')
  • 我尝试了括号,然后是 AND 和 OR,每次,我都面临着什么结果......
【解决方案2】:

有一个混合选项,您可以将可见参数保持原样,然后使用隐藏的级联参数在查询中引用。因此,如果您确实在使用空白或空值作为参数来制定查询时遇到问题,这将解决这个问题。步骤如下:

  • 创建一个新数据集。

一个小问题,您确实需要确保更改选择始终添加一个新值以强制刷新级联参数,但这很容易做到:

SELECT code_name FROM tableA WHERE @Destinataire='' OR @Destinataire=code_name
--Dummy value needed to force update of parameter value in some cases:
UNION SELECT 'zz' + @Destinataire AS code_name
  • 设置新参数@MultiDestataire。允许它接受多个值并将新数据集用作其可用值和默认值。将其可见性设置为隐藏。

在隐藏新参数之前运行报告会显示它是如何工作的:

  • 编辑查询以在其WHERE 子句中使用新的多值参数。

从这里开始,这只是将查询更改为使用IN 语句,应该如下所示:

CFE_EDI.CODE_INSEE IS NOT NULL AND CFE_EDI.CODE_INSEE != '' 
AND CFE_EDI.CODE_INSEE IN (@MultiDestinataire)
...

如果您在查询中遇到导致意外结果的其他问题,尝试此操作最终可能会成为中间步骤,因为您应该能够在那里测试空值。

【讨论】:

  • 嗨@bitnine 你给了我一些我需要明天尝试的想法。我会给你一个更新。
  • 嗨@bitnine,正如我对 Zi0n1 所说,我没有弄清楚出了什么问题,所以最终我从头开始重新创建我的报告,问题自行解决了。感谢您来到这里。
【解决方案3】:

这只是我的两分钱,基本上你有两个选择。

多值参数选项

将您的参数定义为允许多值,在Available valuesDefault values 属性中使用相同的数据集。因此,当您的用户未选择任何值时,该参数将填充所有值。否则,您的参数将仅填充用户选择的值。

在这种情况下,您将不得不使用IN 运算符,因为您的参数表示用户选择或不选择的多个值。

...
WHERE CFE_EDI.CODE_INSEE IN (@Destinataire)
...

当您使用Default values 属性时,默认情况下会选择所有下拉列表值,并且您的报告会在未应用任何过滤器的情况下运行(至少在您的用户未选择任何值或值的情况下)。

另外,我会避免使用''(空白),它没有提供任何信息,您的用户可能会认为这是某种错误或您的参数未正确填充。

当您想要显示来自多个值(在您的情况下为全部)的数据时,为什么要使用单个值参数?

单值选项(无意义 IMO)

为了实现这一点,您必须将参数设置为Allow blank value ("")Allow null value。您的查询应如下所示:

WHERE
  CASE WHEN @Destinataire = '' OR @Destinataire is null THEN 1 ELSE 0 END = 1
  OR
  CFE_EDI.CODE_INSEE = @Destinataire

在您的查询中,我认为可能是这样的:

WHERE  CASE 
         WHEN @Restriction = 1 THEN 
           CASE 
             WHEN cfe_edi.etat IN( 'ENV', 'OUV' ) THEN 1 
             ELSE 0 
           END 
         WHEN @Restriction = 0 THEN 
           CASE 
             WHEN cfe_edi.etat NOT IN( 'ENV', 'OUV' ) THEN 1 
             ELSE 0 
           END 
         ELSE 
           CASE 
             WHEN cfe_edi.etat <> '' THEN 1 
             ELSE 0 
           END 
       END = 1 
       AND cfe_edi.code_insee IS NOT NULL 
       AND cfe_edi.code_insee != '' 
       AND ( CASE 
               --WHEN CFE_EDI.CODE_INSEE IS NOT NULL AND CFE_EDI.CODE_INSEE !=''  
               --THEN CASE   
               WHEN ( @Destinataire = '' 
                       OR @Destinataire IS NULL ) 
                    AND cfe_edi.code_insee = partenaires.code_insee
                    AND cfe_edi.dathrmaj > @DateCmt 
                    AND cfe_edi.dathrmaj < @DateFin 
                    AND cfe_edi.gestdel = '1' THEN 1 
               ELSE 0 
             END = 1 
              OR cfe_edi.code_insee = @Destinataire )  

还要考虑这个评估AND cfe_edi.code_insee = partenaires.code_insee,即使你的JOIN运营商强制满足条件,是否有必要? INNER JOIN dbo.CFE_EDI ON PARTENAIRES.CODE_INSEE = CFE_EDI.CODE_INSEE

第三个选项可以使用隐藏参数来清除用户的null'' 选项,以生成填充了所有值的参数。在参与隐藏/内部参数方法之前尝试上述选项。

如果这有帮助,请告诉我。

【讨论】:

  • 嗨@alejandro-zuleta,感谢您的回复。让我们一步一步来。重写WHERE CASE 没有帮助。我假设Category,你的意思是Destinataire?我想使用 IN 运算符,但如果我这样做,选项 WHEN ( @Destinataire = '' OR @Destinataire IS NULL ) 就没有意义了,对吧?任何反馈都非常受欢迎,因为我感到很困惑
  • @AndyK,Category 参数是多值参数的一个示例。如果您将参数设置为多值并使用相同的数据集 (SELECT code_name FROM tableA) 作为可用值和默认值,则默认情况下将使用所有值填充参数。注意多值参数包括Select All选项自动选择所有值,不需要使用''(空白)。如果您仍想使用带有'' 选项的单值参数,请确保将其设置为Allow blank value ("")Allow null value。我已经在一个基本示例中测试了提议的 WHERE 子句并且它有效。
  • 那我为什么会有这个问题呢?我做错了吗?
  • @AndyK,当您在参数中选择一个值时,您的查询是否返回某些内容?
  • @AndyK,不客气!我希望如果我的回答对您没有帮助,它可以让您对 SSRS 参数有一个基本的了解。在 SSRS 中很难重现问题,主要是因为大多数情况下没有数据源。我很高兴你能解决它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多