我想创建一个函数,但是会出错。 以下是查询:
CREATE FUNCTION WFSlaTimer
(
@OBJECT_PK_ID INT = 110
)
RETURNS TABLE
AS BEGIN
DECLARE
@TIMER_START_ACTIVITY_ID INT,
@TIMER_START_ACTIVITY_COMPLETED_ON DATETIME,
@TIMER_END_ACTIVITY_ID INT,
@TIMER_END_ACTIVITY_COMPLETED_ON DATETIME,
@SLA_TIME_SCHEDULE_IN_DAYS INT,
@SLA_DISPLAY VARCHAR(20),
@START_DATE DATETIME,
@END_DATE DATETIME,
@BUSINESS_START_TIME VARCHAR(10),
@BUSINESS_END_TIME VARCHAR(10),
@BUSINESS_HOURS INT,
@SLA_CUT_OFF_TIME VARCHAR(10),
@IS_OBJECT_STATUS_IS_TERMINAL INT,
@COMPLETED_ACTION_ID INT,
@UNCHECKED_ACTION_ID INT,
@DAY_ADDED INT
SELECT @IS_OBJECT_STATUS_IS_TERMINAL = CASE when wos.FLG_STATUS_TYPE = 'W' THEN 0 ELSE 1 END
FROM WF.WF_OBJECT_INSTANCE woi
INNER JOIN WF.WF_OBJECT_STATUS wos ON wos.OBJECT_STATUS_ID = woi.OBJECT_STATUS_ID
WHERE woi.LINK_PK_ID = @OBJECT_PK_ID
SET @SLA_TIME_SCHEDULE_IN_DAYS = (SELECT CASE WHEN s.SLA_SCHEDULE_ID = 1 THEN lr.RUSH_NO_OF_DAYS ELSE s.NUM_OF_DAYS END --1= [RUSH]
FROM loan.LOAN_REQUEST lr
INNER JOIN WF.WF_SLA_SCHEDULE s
ON s.SLA_SCHEDULE_ID = ISNULL(lr.SLA_SCHEDULE_ID, 2) --{2= SLA-Schedule 5 Days}
WHERE lr.LOAN_REQUEST_ID = @OBJECT_PK_ID)
SET @SLA_DISPLAY = (SELECT
CASE WHEN s.SLA_SCHEDULE_ID = 1 THEN s.DISPLAY_NAME + ' (' + CAST(lr.RUSH_NO_OF_DAYS AS VARCHAR) + ')' ELSE s.DISPLAY_NAME END --1= [RUSH]
FROM loan.LOAN_REQUEST lr
INNER JOIN WF.WF_SLA_SCHEDULE s
ON s.SLA_SCHEDULE_ID = ISNULL(lr.SLA_SCHEDULE_ID, 2) --{2= SLA-Schedule 5 Days}
WHERE lr.LOAN_REQUEST_ID = @OBJECT_PK_ID)
SET @BUSINESS_START_TIME = (SELECT s.CONFIG_VALUE FROM SYS_CONFIG_ENTRY s WHERE s.NAME = 'BUSINESS_START_TIME')
SET @BUSINESS_END_TIME = (SELECT s.CONFIG_VALUE FROM SYS_CONFIG_ENTRY s WHERE s.NAME = 'BUSINESS_END_TIME')
SET @BUSINESS_HOURS = (SELECT CAST(DATEDIFF(hour, CAST(@BUSINESS_START_TIME AS DATETIME), CAST(@BUSINESS_END_TIME AS DATETIME)) AS INT))
SET @SLA_CUT_OFF_TIME = (SELECT DATEPART(hour, CAST(s.CONFIG_VALUE AS TIME)) FROM SYS_CONFIG_ENTRY s WHERE s.NAME = 'SLA_CUT_OFF_TIME')
SET @COMPLETED_ACTION_ID = (SELECT ACTION_TYPE_ID FROM WF.WF_ACTION_TYPE WHERE NAME = 'ACTIVITY_COMPLETED')
SET @UNCHECKED_ACTION_ID = (SELECT ACTION_TYPE_ID FROM WF.WF_ACTION_TYPE WHERE NAME = 'ACTIVITY_UNCHECKED')
--GET SLA TIMER ACTIVITY IDs
SELECT @TIMER_START_ACTIVITY_ID = t.START_ACTIVITY_ID,
@TIMER_END_ACTIVITY_ID = t.END_ACTIVITY_ID
FROM [WF].WF_TIMER t
WHERE t.NAME = 'SLA_TIMER'
--Get START ACTIVITY ON
SELECT @TIMER_START_ACTIVITY_COMPLETED_ON = ACTION_ON
FROM [WF].WF_OBJECT_ACTIVITY_HISTORY woah
WHERE LINK_PK_ID = @OBJECT_PK_ID
AND woah.ACTIVITY_ID = @TIMER_START_ACTIVITY_ID
AND ACTION_ID = @COMPLETED_ACTION_ID
AND
--{
woah.APPLICATION_HISTORY_ID > ISNULL((SELECT TOP 1 ISNULL(APPLICATION_HISTORY_ID, 0)
FROM WF.WF_OBJECT_ACTIVITY_HISTORY
WHERE LINK_PK_ID = @OBJECT_PK_ID
AND ACTIVITY_ID = @TIMER_START_ACTIVITY_ID
AND ACTION_ID = @UNCHECKED_ACTION_ID
ORDER BY ACTION_ON DESC
), 0)
--}
--AND
----{
--0 = ISNULL((SELECT TOP 1 ISNULL(APPLICATION_HISTORY_ID, 0)
-- FROM WF.WF_OBJECT_ACTIVITY_HISTORY
-- WHERE LINK_PK_ID = @OBJECT_PK_ID
-- AND ACTIVITY_ID = @TIMER_END_ACTIVITY_ID
-- AND ACTION_ID = @COMPLETED_ACTION_ID
-- ORDER BY ACTION_ON DESC), 0)
----}
ORDER BY ACTION_ON DESC
--Get END ACTIVITY ON
SELECT @TIMER_END_ACTIVITY_COMPLETED_ON = ACTION_ON
FROM [WF].WF_OBJECT_ACTIVITY_HISTORY woah
WHERE LINK_PK_ID = @OBJECT_PK_ID
AND woah.ACTIVITY_ID = @TIMER_END_ACTIVITY_ID
AND ACTION_ID = @COMPLETED_ACTION_ID
AND
--{
woah.APPLICATION_HISTORY_ID > ISNULL((SELECT TOP 1 ISNULL(APPLICATION_HISTORY_ID, 0)
FROM WF.WF_OBJECT_ACTIVITY_HISTORY
WHERE LINK_PK_ID = @OBJECT_PK_ID
AND ACTIVITY_ID = @TIMER_END_ACTIVITY_ID
AND ACTION_ID = @UNCHECKED_ACTION_ID
ORDER BY ACTION_ON DESC
), 0)
--}
ORDER BY ACTION_ON DESC
--TO DO
--SET @TIMER_START_ACTIVITY_COMPLETED_ON = '2014-05-15 02:40:21.100'
--SET @TIMER_END_ACTIVITY_COMPLETED_ON = '2014-05-14 12:40:21.100'
SET @START_DATE = @TIMER_START_ACTIVITY_COMPLETED_ON
SET @DAY_ADDED = @SLA_TIME_SCHEDULE_IN_DAYS -- SLA Schedule Days
+ CASE WHEN DATEPART(hour, @TIMER_START_ACTIVITY_COMPLETED_ON) >= @SLA_CUT_OFF_TIME THEN 0 ELSE -1 END -- SLA Cut Off Time
SET @END_DATE = @START_DATE + @DAY_ADDED
--Exclud Holidays
--{
DECLARE @START_ON_DATE DATETIME = CAST(@START_DATE AS DATE)
WHILE @DAY_ADDED > 0
BEGIN
SELECT @END_DATE = @START_ON_DATE + @DAY_ADDED
--COUNT NO OF HOLIDAYS IF FALLING WITHIN START-DATE AND END-DATE
SELECT @DAY_ADDED = COUNT(*) FROM [WF].WF_CALENDAR WC --HOLIDAY LIST
WHERE WC.DATE BETWEEN @START_ON_DATE+1 AND @END_DATE AND (WC.IS_WEEKEND = 1 OR WC.IS_HOLIDAY = 1)
SET @START_ON_DATE = @END_DATE
END
--}
SET @END_DATE = (CAST(CAST(CAST(@END_DATE AS DATE) AS DATETIME) + CAST(@BUSINESS_END_TIME AS TIME) AS DATETIME))
;WITH TIMER_CTE AS (
SELECT @START_DATE AS OBJECT_CREATED_ON,
@END_DATE AS OBJECT_END_ON,
DIFFERENCE_IN_DAYS = DATEDIFF(dd, GETDATE(), @END_DATE),
TODAY_REMAINING_MINUTES =
CASE WHEN CONVERT(VARCHAR(10), @END_DATE, 112) >= CONVERT(VARCHAR(10), GETDATE(), 112)
THEN DATEDIFF(minute, GETDATE(), (CAST(CAST(CAST(GETDATE() AS DATE) AS DATETIME) + CAST(@BUSINESS_END_TIME AS TIME) AS DATETIME)))
ELSE 0 END,
TODAY_REMAINING_HOURS =
CASE WHEN CONVERT(VARCHAR(10), @END_DATE, 112) >= CONVERT(VARCHAR(10), GETDATE(), 112)
THEN (DATEDIFF(minute, GETDATE(), (CAST(CAST(CAST(GETDATE() AS DATE) AS DATETIME) + CAST(@BUSINESS_END_TIME AS TIME) AS DATETIME)))/60)
ELSE 0 END
)
RETURN (
SELECT
IS_SHOW_SLA = CASE WHEN @TIMER_START_ACTIVITY_COMPLETED_ON IS NULL
--OR @IS_OBJECT_STATUS_IS_TERMINAL = 1
--OR @TIMER_START_ACTIVITY_COMPLETED_ON IS NULL
THEN 0
ELSE 1 END,
@START_DATE AS [START_DATE], @END_DATE AS [END_DATE],
SLA_TYPE = @SLA_DISPLAY,
SLA_DUE = CONVERT(VARCHAR(10), CONVERT(DATETIME, tc.OBJECT_END_ON, 1), 101),
@BUSINESS_END_TIME AS BUSINESS_END_TIME,
SLA_START_ACTIVITY_CHECKED_ON = tc.OBJECT_CREATED_ON,
SLA_END_ACTIVITY_CHECKED_ON = @TIMER_END_ACTIVITY_COMPLETED_ON,
SLA_MISSED = CASE WHEN
--TODAY_REMAINING_MINUTES <= 0
--AND CONVERT(VARCHAR(10), @END_DATE, 112) = CONVERT(VARCHAR(10), GETDATE(), 112)
--OR
( GETDATE()> @END_DATE)
OR @TIMER_START_ACTIVITY_COMPLETED_ON IS NULL
THEN 'Missed' ELSE NULL END,
tc.TODAY_REMAINING_HOURS,
tc.TODAY_REMAINING_MINUTES,
LAST_DAY_TIME_REMAINING =
CASE
WHEN @TIMER_END_ACTIVITY_COMPLETED_ON <= @END_DATE THEN 'Successful Completed'
WHEN CONVERT(VARCHAR(10), @END_DATE, 112) = CONVERT(VARCHAR(10), GETDATE(), 112)
THEN
CASE WHEN
tc.TODAY_REMAINING_HOURS <=0 AND tc.TODAY_REMAINING_MINUTES > 0 THEN
CASE WHEN tc.TODAY_REMAINING_MINUTES = 1 THEN CAST(tc.TODAY_REMAINING_MINUTES AS VARCHAR) + ' min remaining'
ELSE CAST(tc.TODAY_REMAINING_MINUTES AS VARCHAR) + ' mins remaining' END
WHEN tc.TODAY_REMAINING_HOURS =1 THEN CAST(tc.TODAY_REMAINING_HOURS AS VARCHAR) + ' hour remaining'
WHEN tc.TODAY_REMAINING_HOURS >1 THEN CAST(tc.TODAY_REMAINING_HOURS AS VARCHAR) + ' hours remaining'
ELSE NULL
END
ELSE NULL
END,
REMAINING_DAYS = CASE WHEN tc.DIFFERENCE_IN_DAYS <=0 THEN '0 day'
WHEN tc.DIFFERENCE_IN_DAYS > 1 THEN CAST(tc.DIFFERENCE_IN_DAYS AS VARCHAR) + ' days '
ELSE CAST(tc.DIFFERENCE_IN_DAYS AS VARCHAR) + ' day ' END
FROM TIMER_CTE tc
)
END;
GO
我收到此错误:
Msg 156, Level 15, State 1, Procedure WFSlaTimer, Line 144
Incorrect syntax near the keyword 'RETURN'.
Msg 178, Level 15, State 1, Procedure WFSlaTimer, Line 144
A RETURN statement with a return value cannot be used in this context.
Msg 102, Level 15, State 31, Procedure WFSlaTimer, Line 189
Incorrect syntax near 'BEGIN'.
请帮助
答案 0 :(得分:1)
返回表有两种功能。内联函数和多语句函数。你的是多语句。以下是此语法:
--Transact-SQL Multistatement Table-valued Function Syntax
CREATE FUNCTION [ schema_name. ] function_name
( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type
[ = default ] [READONLY] }
[ ,...n ]
]
)
RETURNS @return_variable TABLE <table_type_definition>
[ WITH <function_option> [ ,...n ] ]
[ AS ]
BEGIN
function_body
RETURN
END
[ ; ]
有关更多信息,请参阅CREATE FUNCTION (Transact-SQL) BOL
文档。
答案 1 :(得分:0)
您必须定义返回表格的结构(字段和数据类型)
1)在函数定义中添加变量名称(上例中为@tableVariable
)。
2)填写表定义(列和数据类型)
3)修改函数以将结果插入到已定义的表变量中,然后在函数返回时使用空RETURN
语句。
第一步
CREATE FUNCTION WFSlaTimer
(
@OBJECT_PK_ID INT = 110
)
RETURNS @tableVariable TABLE (
IS_SHOW_SLA INT,
StartDate DATETIME2,
EndDate DATETIME2
/** List all of your returned columns like when you creating a table **/
)
AS
BEGIN
/** Do your stuff **/
INSERT INTO @tableVariable ( /* field list */) VALUES (/* value list */)
-- OR --
INSERT INTO @tableVariable ( /* field list */)
SELECT /* FieldList */ FROM myCTE
RETURN
END
第二步
修改你的RETURN()语句,如下所示:
INSERT INTO @tableVanriable (IS_SHOW_SLA , StartDate , EndDate)
SELECT
IS_SHOW_SLA = CASE WHEN @TIMER_START_ACTIVITY_COMPLETED_ON IS NULL
--OR @IS_OBJECT_STATUS_IS_TERMINAL = 1
--OR @TIMER_START_ACTIVITY_COMPLETED_ON IS NULL
THEN 0
ELSE 1 END,
@START_DATE AS [START_DATE], @END_DATE AS [END_DATE],
SLA_TYPE = @SLA_DISPLAY
/** .... **/
FROM TIMER_CTE tc
/** 3rd step **/
RETURN