我正在为我正在编写的报告中的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)
答案 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