PLSQL中的异常处理
我需要你的帮助来处理我包中的异常。我不知道在哪里写异常。我包括函数。问题是ACTY_COUNT是varchar类型。因此,如果用户在不知不觉中输入了一些字母,则整个程序包将无法工作,因为我们是该字段的总和。我需要为此编写一个例外,这样,如果该字段输入了任何字母值,它应该为该员工处理错误,同时显示其他员工的报告。提前谢谢PLSQL中的异常处理,plsql,Plsql,我需要你的帮助来处理我包中的异常。我不知道在哪里写异常。我包括函数。问题是ACTY_COUNT是varchar类型。因此,如果用户在不知不觉中输入了一些字母,则整个程序包将无法工作,因为我们是该字段的总和。我需要为此编写一个例外,这样,如果该字段输入了任何字母值,它应该为该员工处理错误,同时显示其他员工的报告。提前谢谢 FUNCTION ACTY_Ld_DAT(V_STARTDATE IN DATE,V_ENDDATE IN DATE) RETURN SYS_REFCURSOR IS ACT
FUNCTION ACTY_Ld_DAT(V_STARTDATE IN DATE,V_ENDDATE IN DATE) RETURN SYS_REFCURSOR IS
ACTY_DATA SYS_REFCURSOR;
BEGIN
OPEN ACTY_DATA FOR
/*Query to fetch the report field into ref cursor*/
SELECT
MAIN_DATA.EMPID AS "EMP_ID",
MAIN_DATA.FIRST_NAME AS "FIRST_NAME",
MAIN_DATA.LAST_NAME AS "LAST_NAME",
MAIN_DATA.LOCATION AS "LOCATION",
MAIN_DATA.ACTY_NAME AS "ACTY_NAME",
SUM(NVL(MAIN_DATA.ACTY_COUNT,0)) AS "ACTY_COUNT",
SUM(MAIN_DATA.REGULAR_HRS) AS "REG_HRS",
SUM(MAIN_DATA.OVERTIME_HRS) AS "OT_HRS",
SUM(MAIN_DATA.TOTAL_HRS) AS "TOTAL_HRS",
(
CASE
WHEN MAIN_DATA.ACTY_NAME = 'X' AND SUM(ACTY_COUNT) != 0 THEN
(100/SUM(MAIN_DATA.TOTAL_HRS)) * ROUND((1.33 * SUM(ACTY_COUNT)),1)
WHEN (MAIN_DATA.ACTY_NAME = 'Y' OR MAIN_DATA.ACTY_NAME = 'Z' OR MAIN_DATA.ACTY_NAME = 'U') AND SUM(ACTY_COUNT) != 0 THEN
(100/SUM(MAIN_DATA.TOTAL_HRS)) * ROUND((5 * SUM(ACTY_COUNT)),1)
WHEN MAIN_DATA.ACTY_NAME = 'V' AND SUM(ACTY_COUNT) != 0 THEN
(100/SUM(MAIN_DATA.TOTAL_HRS)) * ROUND((8 * SUM(ACTY_COUNT)),1)
ELSE
0
END
) "PROD_PERCENTAGE"
FROM
(
SELECT
DATA.EMPID,
DATA.FIRST_NAME,
DATA.LAST_NAME,
DATA.LOCATION,
DATA.ACTY_NAME,
SUM(NVL(DATA.ACTY_COUNT,0)) AS "ACTY_COUNT",
MIN("Regular_Hrs") AS "REGULAR_HRS",
MIN("Overtime_Hrs") AS "OVERTIME_HRS",
MIN("Regular_Hrs") + MIN("Overtime_Hrs") AS "TOTAL_HRS"
FROM
(
SELECT
P.PERSONID "EMPID",
P.FIRSTNM "FIRST_NAME",
P.LASTNM "LAST_NAME",
LABACCT.LABORLEV1NM "LOCATION",
ACT.ACTIVITYNM "ACTY_NAME",
SUM(NVL(RES.REPTXT,0)) AS "ACTY_COUNT",
MIN(SPAN.EVENTDTM) "EVENTDT",
(
SELECT
SUM(DURATIONSECSQTY/3600)
FROM
WFCTOTAL TOT,
PAYCODE PCD
WHERE
P.PERSONID = TOT.EMPLOYEEID AND
TOT.PAYCODEID = PCD.PAYCODEID AND
PCD.NAME IN ('Regular 1','Regular 2','Regular 3') and
TOT.APPLYDTM BETWEEN TRIM(V_STARTDATE) AND TRIM(V_ENDDATE)
) AS "Regular_Hrs",
(
SELECT
NVL(SUM(DURATIONSECSQTY/3600),0)
FROM
WFCTOTAL TOT,
PAYCODE PCD
WHERE
P.PERSONID = TOT.EMPLOYEEID AND
TOT.PAYCODEID = PCD.PAYCODEID AND
PCD.NAME IN ('Overtime 1','Overtime 2','Overtime 3') and
TOT.APPLYDTM BETWEEN TRIM(V_STARTDATE) AND TRIM(V_ENDDATE)
) AS "Overtime_Hrs"
FROM
PERSON P,
WFAREPACTYSPAN SPAN,
WFAREPLABACCT WFALABACCT,
LABORACCT LABACCT,
WFAREPACTYRES RES,
WFAACTIVITY ACT
WHERE
P.PERSONID = SPAN.EMPLOYEEID AND
WFALABACCT.WFAREPACTYSPANID = SPAN.WFAREPACTYSPANID AND
LABACCT.LABORACCTID = WFALABACCT.LABORACCTID AND
RES.WFAREPACTYSPANID(+) = SPAN.WFAREPACTYSPANID AND
ACT.WFAACTIVITYID = SPAN.WFAACTIVITYID AND
ACT.WFAACTIVITYID NOT IN (-1) AND
SPAN.DELETEDSW = 0 AND
SPAN.APPROVEDSW = 1 AND
SPAN.EVENTDTM BETWEEN TRIM(V_STARTDATE) AND TRIM(V_ENDDATE) AND
P.PERSONID IN (
SELECT
EMPLOYEEID
FROM
WTKEMPLOYEE
WHERE
PAYRULEID IN (
SELECT
PAYRULEID
FROM
PAYRULEIDS
WHERE
NAME = 'XXXX'OR
NAME = 'YYYY'
)
)
GROUP BY
P.PERSONID,
P.FIRSTNM,
P.LASTNM,
LABACCT.LABORLEV1NM,
ACT.ACTIVITYNM,
SPAN.EVENTDTM
) DATA
GROUP BY
DATA.EMPID,
DATA.FIRST_NAME,
DATA.LAST_NAME,
DATA.LOCATION,
DATA.ACTY_NAME
)MAIN_DATA
GROUP BY
MAIN_DATA.EMPID,
MAIN_DATA.FIRST_NAME,
MAIN_DATA.LAST_NAME,
MAIN_DATA.LOCATION,
MAIN_DATA.ACTY_NAME;
RETURN ACTY_DATA;
END ACTY_LOAD_DATA;
您可以创建自己的函数来解决此问题。e、 g:
CREATE FUNCTION to_number_or_null (text IN VARCHAR2) RETURN NUMBER IS
BEGIN
RETURN TO_NUMBER(text);
EXCEPTION
WHEN VALUE_ERROR THEN
RETURN NULL;
END to_number_or_null;
现在,更改您的查询:
SUM(NVL(to_number_or_null(RES.REPTXT),0)) AS "ACTY_COUNT",
您可以创建自己的函数来解决此问题。e、 g:
CREATE FUNCTION to_number_or_null (text IN VARCHAR2) RETURN NUMBER IS
BEGIN
RETURN TO_NUMBER(text);
EXCEPTION
WHEN VALUE_ERROR THEN
RETURN NULL;
END to_number_or_null;
现在,更改您的查询:
SUM(NVL(to_number_or_null(RES.REPTXT),0)) AS "ACTY_COUNT",
你真的不能把
ACTY\u COUNT
aNUMBER
列?这样做会容易得多,而且更好我不能更改列的数据类型。。。我需要另一个解决方案你真的不能把活动计数aNUMBER
列?这样做会容易得多,而且更好我不能更改列的数据类型。。。我需要一个替代的解决方案,但是这里我使用一个游标从查询中获取值。如果我使用上面的函数,我只需要传递那个特定的值,我猜。这不是很复杂吗?请给我一些建议this@Remya表示“这不是很复杂吗?”使用VARCHAR2列存储数值会导致任何复杂情况。糟糕的数据模型总是让我们的生活更加复杂。在这种情况下,只有一个合乎逻辑的地方可以解决问题——正如杰弗里指出的,最内在的问题。事实上,只要引用NVL(MAIN\u DATA.ACTY\u COUNT,0)
,您就可以去掉所有其他NVL()
函数,因此查询实际上稍微不那么复杂。嗨,Jeffrey和APC感谢您的宝贵建议。我可以实现该功能及其工作。非常感谢…但我在这里使用游标从查询中获取值..如果我使用上述函数,我只需要传递特定的值,我猜。这不是很复杂吗?请给我一些建议this@Remya表示“这不是很复杂吗?”使用VARCHAR2列存储数值会导致任何复杂情况。糟糕的数据模型总是让我们的生活更加复杂。在这种情况下,只有一个合乎逻辑的地方可以解决问题——正如杰弗里指出的,最内在的问题。事实上,只要引用NVL(MAIN\u DATA.ACTY\u COUNT,0)
,您就可以去掉所有其他NVL()
函数,因此查询实际上稍微不那么复杂。嗨,Jeffrey和APC感谢您的宝贵建议。我可以实现该功能及其工作。非常感谢你。。。