使用条件在 SQL 函数中设置变量
Set Variable in SQL Function with Condition
尝试根据当前日期设置变量并传递给 SQL 函数中的查询。它在 IF 语句处出错。有什么想法吗?
CREATE FUNCTION CS_AwaredRCPs
(
@currentDate DATE,
@fiscalYear INT
IF DATEPART(m,@currentDate) > 10
SET @fiscalYear = DATEPART(yyyy,@currentDate)
ELSE
SET @fiscalYear = DATEPART(yyyy,@currentDate) - 1
END
)
RETURNS TABLE
AS
RETURN
(
SELECT dbo.tbl_requirementManagement.postaward_specialist_id,
SUM(dbo.tbl_requirementManagement.actual_award_value) AS AwardValue,
COUNT(dbo.tbl_requirementManagement.postaward_specialist_id) AS AwardCount
FROM dbo.tbl_requirementManagement RIGHT OUTER JOIN
dbo.vw_ContractSpecialists ON dbo.tbl_requirementManagement.postaward_specialist_id = dbo.vw_ContractSpecialists.user_certificateSerialNumber
GROUP BY dbo.tbl_requirementManagement.statusID, dbo.tbl_requirementManagement.postaward_specialist_id, dbo.tbl_requirementManagement.fiscal_year
HAVING (dbo.tbl_requirementManagement.statusID = 4) AND
(dbo.tbl_requirementManagement.postaward_specialist_id <> 0) AND
(dbo.tbl_requirementManagement.fiscal_year = @fiscalYear)
)
`
您不能在函数 parameter list
中执行 if-else
检查。将 If-else
部分移至函数 body
。试试这个。
CREATE FUNCTION Cs_awaredrcps (@currentDate DATE)
RETURNS @ret_table TABLE (
postaward_specialist_id INT,
AwardValue INT,
AwardCount INT )
AS
BEGIN
DECLARE @fiscalYear INT
IF Datepart(Month, @currentDate) > 10
SET @fiscalYear = Datepart(yyyy, @currentDate)
ELSE
SET @fiscalYear = Datepart(yyyy, @currentDate) - 1
INSERT INTO @ret_table
SELECT dbo.tbl_requirementManagement.postaward_specialist_id,
Sum(dbo.tbl_requirementManagement.actual_award_value) AS AwardValue,
Count(dbo.tbl_requirementManagement.postaward_specialist_id) AS AwardCount
FROM dbo.tbl_requirementManagement
RIGHT OUTER JOIN dbo.vw_ContractSpecialists
ON dbo.tbl_requirementManagement.postaward_specialist_id = dbo.vw_ContractSpecialists.user_certificateSerialNumber
GROUP BY dbo.tbl_requirementManagement.statusID,
dbo.tbl_requirementManagement.postaward_specialist_id,
dbo.tbl_requirementManagement.fiscal_year
HAVING ( dbo.tbl_requirementManagement.statusID = 4 )
AND ( dbo.tbl_requirementManagement.postaward_specialist_id <> 0 )
AND ( dbo.tbl_requirementManagement.fiscal_year = @fiscalYear )
RETURN
END
你根本不需要使用IF
,你可以简单地做你的谓词:
fiscal_year = DATEPART(YEAR, @currentDate)
+ CASE WHEN DATEPART(MONTH, @CurrentDate) <= 10 THEN -1 ELSE 0 END
那么你根本不需要 @FiscalYear
参数。对于它的价值,您还应该在函数中更改许多其他内容
使用 table 别名可以显着减少文本量,因此与其一遍又一遍地使用 dbo.tbl_requirementManagement
,不如使用 rm
事实上,您在 where 子句中引用了外部 table,将您的 RIGHT OUTER JOIN
变成了 INNER JOIN
,因此您也可以只使用和 INNER JOIN
。澄清一下,您有 (dbo.tbl_requirementManagement.statusID = 4)
,因此在 tbl_requirementManagement
中没有匹配项的地方,statusID
将是 NULL
,而 NULL = 4
returns NULL
,这是不正确的,因此不会返回该行。
您的谓词不引用聚合,因此应该在 WHERE
子句中,而不是 HAVING
因此您的最终函数变为:
CREATE FUNCTION CS_AwaredRCPs (@currentDate DATE)
RETURNS TABLE
AS
RETURN
( SELECT rm.postaward_specialist_id,
SUM(rm.actual_award_value) AS AwardValue,
COUNT(rm.postaward_specialist_id) AS AwardCount
FROM dbo.tbl_requirementManagement AS rm
INNER JOIN dbo.vw_ContractSpecialists AS cs
ON rm.postaward_specialist_id = cs.user_certificateSerialNumber
WHERE rm.fiscal_year = DATEPART(YEAR,@currentDate)
+ CASE WHEN DATEPART(MONTH, @CurrentDate) <= 10 THEN -1 ELSE 0 END
AND rm.statusID = 4
AND rm.postaward_specialist_id <> 0
GROUP BY rm.statusID, rm.postaward_specialist_id, rm.fiscal_year
);
尝试根据当前日期设置变量并传递给 SQL 函数中的查询。它在 IF 语句处出错。有什么想法吗?
CREATE FUNCTION CS_AwaredRCPs
(
@currentDate DATE,
@fiscalYear INT
IF DATEPART(m,@currentDate) > 10
SET @fiscalYear = DATEPART(yyyy,@currentDate)
ELSE
SET @fiscalYear = DATEPART(yyyy,@currentDate) - 1
END
)
RETURNS TABLE
AS
RETURN
(
SELECT dbo.tbl_requirementManagement.postaward_specialist_id,
SUM(dbo.tbl_requirementManagement.actual_award_value) AS AwardValue,
COUNT(dbo.tbl_requirementManagement.postaward_specialist_id) AS AwardCount
FROM dbo.tbl_requirementManagement RIGHT OUTER JOIN
dbo.vw_ContractSpecialists ON dbo.tbl_requirementManagement.postaward_specialist_id = dbo.vw_ContractSpecialists.user_certificateSerialNumber
GROUP BY dbo.tbl_requirementManagement.statusID, dbo.tbl_requirementManagement.postaward_specialist_id, dbo.tbl_requirementManagement.fiscal_year
HAVING (dbo.tbl_requirementManagement.statusID = 4) AND
(dbo.tbl_requirementManagement.postaward_specialist_id <> 0) AND
(dbo.tbl_requirementManagement.fiscal_year = @fiscalYear)
)
`
您不能在函数 parameter list
中执行 if-else
检查。将 If-else
部分移至函数 body
。试试这个。
CREATE FUNCTION Cs_awaredrcps (@currentDate DATE)
RETURNS @ret_table TABLE (
postaward_specialist_id INT,
AwardValue INT,
AwardCount INT )
AS
BEGIN
DECLARE @fiscalYear INT
IF Datepart(Month, @currentDate) > 10
SET @fiscalYear = Datepart(yyyy, @currentDate)
ELSE
SET @fiscalYear = Datepart(yyyy, @currentDate) - 1
INSERT INTO @ret_table
SELECT dbo.tbl_requirementManagement.postaward_specialist_id,
Sum(dbo.tbl_requirementManagement.actual_award_value) AS AwardValue,
Count(dbo.tbl_requirementManagement.postaward_specialist_id) AS AwardCount
FROM dbo.tbl_requirementManagement
RIGHT OUTER JOIN dbo.vw_ContractSpecialists
ON dbo.tbl_requirementManagement.postaward_specialist_id = dbo.vw_ContractSpecialists.user_certificateSerialNumber
GROUP BY dbo.tbl_requirementManagement.statusID,
dbo.tbl_requirementManagement.postaward_specialist_id,
dbo.tbl_requirementManagement.fiscal_year
HAVING ( dbo.tbl_requirementManagement.statusID = 4 )
AND ( dbo.tbl_requirementManagement.postaward_specialist_id <> 0 )
AND ( dbo.tbl_requirementManagement.fiscal_year = @fiscalYear )
RETURN
END
你根本不需要使用IF
,你可以简单地做你的谓词:
fiscal_year = DATEPART(YEAR, @currentDate)
+ CASE WHEN DATEPART(MONTH, @CurrentDate) <= 10 THEN -1 ELSE 0 END
那么你根本不需要 @FiscalYear
参数。对于它的价值,您还应该在函数中更改许多其他内容
使用 table 别名可以显着减少文本量,因此与其一遍又一遍地使用
dbo.tbl_requirementManagement
,不如使用rm
事实上,您在 where 子句中引用了外部 table,将您的
RIGHT OUTER JOIN
变成了INNER JOIN
,因此您也可以只使用和INNER JOIN
。澄清一下,您有(dbo.tbl_requirementManagement.statusID = 4)
,因此在tbl_requirementManagement
中没有匹配项的地方,statusID
将是NULL
,而NULL = 4
returnsNULL
,这是不正确的,因此不会返回该行。您的谓词不引用聚合,因此应该在
WHERE
子句中,而不是HAVING
因此您的最终函数变为:
CREATE FUNCTION CS_AwaredRCPs (@currentDate DATE)
RETURNS TABLE
AS
RETURN
( SELECT rm.postaward_specialist_id,
SUM(rm.actual_award_value) AS AwardValue,
COUNT(rm.postaward_specialist_id) AS AwardCount
FROM dbo.tbl_requirementManagement AS rm
INNER JOIN dbo.vw_ContractSpecialists AS cs
ON rm.postaward_specialist_id = cs.user_certificateSerialNumber
WHERE rm.fiscal_year = DATEPART(YEAR,@currentDate)
+ CASE WHEN DATEPART(MONTH, @CurrentDate) <= 10 THEN -1 ELSE 0 END
AND rm.statusID = 4
AND rm.postaward_specialist_id <> 0
GROUP BY rm.statusID, rm.postaward_specialist_id, rm.fiscal_year
);