标量函数中的多个SQL或Case语句

时间:2015-04-14 16:55:15

标签: sql sql-server function

我正在为我正在编写的报告中的SQL函数而苦苦挣扎。该函数轮询审计表以获取特定字段的原始值(SecondarySchoolCode)。如果它在审计表中找到当前行的值,则应返回该值,如果当前行没有值,则应返回我提供给该函数的原始参数。我尝试过使用Case语句,但如果审计表中没有匹配项,则不会返回参数。有关如何实现这一目标的任何建议吗?

ALTER FUNCTION [dbo].[fn_AuditOriginalHSAttendingCode]
(
@StudentID VARCHAR(255),
@SecondarySchoolCode VARCHAR(255),
@ColumnName VARCHAR(255)
)
RETURNS VARCHAR(255)
AS
BEGIN
DECLARE @Result AS VARCHAR(255);


RETURN (SELECT TOP (1) 
CASE WHEN @ColumnName <> 'SecondarySchoolCode' 
THEN  @SecondarySchoolCode 
ELSE dbo.GDSAuditDetail.ValueBeforeChange END
FROM     dbo.GDSAuditDetail 
INNER JOIN dbo.StudentSchool 
INNER JOIN dbo.Student ON dbo.StudentSchool.StudentId = dbo.Student.ID 
INNER JOIN dbo.SecondarySchool ON dbo.StudentSchool.SecondarySchoolId = dbo.SecondarySchool.ID 
INNER JOIN dbo.GDSAudit ON dbo.Student.ID = dbo.GDSAudit.EntityId ON dbo.GDSAuditDetail.GDSAuditId = dbo.GDSAudit.ID 
WHERE  (dbo.Student.ID = @studentID) and dbo.GDSAuditDetail.GDSColumn='SecondarySchoolCode'
ORDER BY dbo.GDSAudit.InsertedDate ASC)

对函数的调用如下所示:

dbo.fn_AuditOriginalHSAttendingCode(dbo.Student.ID
                                  , dbo.SecondarySchool.SecondarySchoolCode
                                  , dbo.GDSAuditDetail.GDSColumn) 

3 个答案:

答案 0 :(得分:1)

Biscuits提供了最容易实施的解决方案:

我的意思是,像ISNULL(dbo.fn_AuditOriginalHSAttendingCode(...),&#39; SecondarySchoolCode&#39;) - 饼干59分钟前

答案 1 :(得分:0)

我不确定您的所有关系是什么,但根据您声明的要求和您当前的查询,您将加入一些您不需要的表格。当审计不存在时,您没有得到任何回报的原因是因为没有行可以从中选择TOP 1。这应始终为现有学生至少返回一行。

SELECT TOP (1) ISNULL(dbo.GDSAuditDetail.ValueBeforeChange, @SecondarySchoolCode)
FROM dbo.Student 
LEFT JOIN dbo.GDSAudit 
    ON dbo.Student.ID = dbo.GDSAudit.EntityId 
LEFT JOIN dbo.GDSAuditDetail 
    ON dbo.GDSAuditDetail.GDSAuditId = dbo.GDSAudit.ID 
       AND dbo.GDSAuditDetail.GDSColumn='SecondarySchoolCode'
WHERE (dbo.Student.ID = @studentID) 
ORDER BY dbo.GDSAudit.InsertedDate ASC

答案 2 :(得分:0)

您的联接到处都是一个有点固定的版本看起来像这样......

ALTER FUNCTION [dbo].[fn_AuditOriginalHSAttendingCode]
(
@StudentID VARCHAR(255),
@SecondarySchoolCode VARCHAR(255),
@ColumnName VARCHAR(255)
)
RETURNS VARCHAR(255)
AS
BEGIN
DECLARE @Result AS VARCHAR(255);

    RETURN(SELECT TOP (1)  
                    CASE 
                         WHEN @ColumnName <> 'SecondarySchoolCode' 
                         THEN  @SecondarySchoolCode 
                         ELSE AD.ValueBeforeChange 
                    END
    FROM       dbo.GDSAuditDetail  AD
    INNER JOIN dbo.GDSAudit        A  ON AD.GDSAuditId        = A.ID 
    INNER JOIN dbo.Student         S  ON S.ID                 = A.EntityId 
    INNER JOIN dbo.StudentSchool   SS ON SS.StudentId         = S.ID 
    INNER JOIN dbo.SecondarySchool SE ON SS.SecondarySchoolId = SE.ID 
    WHERE  S.ID = @studentID
      AND  AD.GDSColumn = 'SecondarySchoolCode'
    ORDER BY AD.InsertedDate ASC)

END