连接查询中的IIF或CASE

时间:2018-04-30 01:23:23

标签: tsql

我有以下查询是标量变量函数的一部分,但我得到了相同的结果,试图运行查询,因此看起来问题出现在串联和/或变量的使用中。

DECLARE @useCompTitle BIT
SET @useCompTitle = (SELECT z.useComplianceTitle FROM dbo.tblConfiguration z WHERE z.id = 1)
DECLARE @Output as VARCHAR(MAX) = '';
DECLARE @ReturnValue as VARCHAR(MAX)='';
SELECT @Output = @Output + 
                '<tr><td style="vertical-align:top">' + 
                p.ProcessNumber + 
                '</td><td>' + 
                (IIF(@useCompTitle = 0, p.Process, p.title)) + 
                '</td><td style="vertical-align:top">' + 
                CASE p.recordStatus 
                    WHEN 1 THEN N'Active' 
                    WHEN 2 THEN N'Inactive' 
                END  + 
                '</td></tr>'
FROM dbo.tblProcess p
CROSS JOIN dbo.Security_Compliance_Record_List(1, 0, 0) AS p1
INNER JOIN dbo.tblERLinkedRecords l ON p.id = l.recID
WHERE l.eventID = 1172 
AND l.linkType = 'C' 
AND p.id = p1.id 
AND p.recordStatus < 3
ORDER BY p.ProcessNumber
PRINT @OutputThe result should return multiple values in @Output but I am only getting the last record in the set.

我也尝试了一个CASE语句,结果相同。如果我用一个简单的字段名称替换IIF(或CASE),我会得到正确数量的值。 如果IIF被简单的字段值(例如p.title)替换,则p.RecordStatus的CASE可以正常工作。 我们在许多存储过程中使用@useCompTitle过程,但这是串联查询中的第一次。

3 个答案:

答案 0 :(得分:0)

如果查询返回一行,则SQL Server将该值存储在变量中。但是,如果有多行,那实际上没有意义。变量包含单个值,但要存储多个值。它可能会出错,但微软选择让它只存储最后一个值。它本可以存储第一个,但这不是他们决定的。一般来说,这不是一个好的行为,因为它从语义的角度来看是不合理的。

事实上,我认为这是你陷入困境的地方。虽然可以认为查询已经是表和行的for循环,但事实并非如此。它是对元组(行)集的一系列操作。从概念上讲,结果是一组“一次”“到达”的行。没有执行行的顺序(不仅仅是存在的数组的执行顺序)。因此,这没有任何意义。

现在,您想要实现的目标 本身是合理的。您需要一个基本上连接返回多行的查询结果的字符串。想象一下,你有一个更简单的查询,你只想总结一些数字而不是连接字符串。您只需使用SUM()聚合,可能使用GROUP BY子句。结果可以存储到变量中。由于聚合会使结果集中只有一行,因此您不必担心哪一行保存该值。字符串聚合的工作方式相同。除了... SQL Server在SQL Server 2017之前没有STRING_SUM()操作。也就是说,在所有版本的SQL Server中仍然有办法执行此操作。您可以使用XML技巧,也可以编写自己的自定义聚合函数(使用.NET语言)。有关如何执行此操作的详情,请参阅I need to write a query like group_concat in SQL Server

希望这足以让你前进!

答案 1 :(得分:0)

使用<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <ul> <li class="ui-state-default" id="L1"><input type="text" name="N1" id="I1" disabled value="abc" /></li> <li class="ui-state-default" id="L2"><input type="text" name="N2" id="I2" disabled /></li> <li class="ui-state-default" id="L3"><input type="text" name="N3" id="I3" disabled /></li> </ul>IIF

演示

CONCAT

答案 2 :(得分:0)

感谢所有输入。经过一些测试后,我发现问题出现在ORDER BY中,并且是一个已知的issue。这是一篇很棒的文章。我通过根据建议更改功能来解决问题,这一切都正常。

  CREATE FUNCTION [dbo].[CR_Events_Linked_Compliance] 

(     @ parameter1 INT,     @ parameter2 BIT = 0,     @recID INT,     @useCompTitle BIT ) 退货VARCHAR(MAX) 如 开始     DECLARE @Output as VARCHAR(MAX)=&#39;&#39 ;;     DECLARE @ReturnValue as VARCHAR(MAX)=&#39;&#39 ;;     SELECT @Output =(SELECT&#39;&#39; + p.ProcessNumber +&#39;&#39; + IIF(@useCompTitle = 0,p.Process,p.title)+&#39;&# 39; + IIF(p.recordStatus = 1,&#39; Active&#39;,&#39; Inactive&#39;)+&#39;&#39;     来自dbo.tblProcess p     CROSS JOIN dbo.Security_Compliance_Record_List(@ parameter1,@ parameter2,0)AS p1     INNER JOIN dbo.tblERLinkedRecords l ON p.id = l.recID     WHERE l.eventID = @recID和l.linkType =&#39; C&#39; AND p.id = p1.id AND p.recordStatus&lt; 3     ORDER BY p.ProcessNumber     FOR XML PATH(&#39;&#39;),TYPE     )。价值(&#39;&#39;,&#39; VARCHAR(最大)&#39;)     如果@Output =&#39;&#39;         SET @ReturnValue =&#39;&#39;                 其他         SET @ReturnValue =&#39; 数字 流程 状态&#39; + @Output +&#39;&#39;     返回@ReturnValue END