Sql PLS-00103遇到了符号“QUOTE”;完";
我遇到了问题PL-00103:在以下过程的倒数第二行遇到了符号“END”。此过程的目的是查看发送新电子邮件时是否存在以前版本的电子邮件。。。并使旧电子邮件过期。(电子邮件在创建时默认设置为一个遥远的过期日期,因此我检查过期日期是否超过当前日期) 我试着在两端移动,但开始无效 由于保密协议的原因,我已经更改了物品的名称,所以如果有任何混淆,我很乐意澄清,因为我可能遗漏了一些东西Sql PLS-00103遇到了符号“QUOTE”;完";,sql,oracle,plsql,Sql,Oracle,Plsql,我遇到了问题PL-00103:在以下过程的倒数第二行遇到了符号“END”。此过程的目的是查看发送新电子邮件时是否存在以前版本的电子邮件。。。并使旧电子邮件过期。(电子邮件在创建时默认设置为一个遥远的过期日期,因此我检查过期日期是否超过当前日期) 我试着在两端移动,但开始无效 由于保密协议的原因,我已经更改了物品的名称,所以如果有任何混淆,我很乐意澄清,因为我可能遗漏了一些东西 提前感谢您的帮助 编写存储过程的理想方法是处理每个块/语句的所有异常。您还有一个必须删除的附加端,另外,我还添加了当第一
提前感谢您的帮助 编写存储过程的理想方法是处理每个块/语句的所有异常。您还有一个必须删除的附加端,另外,我还添加了当第一个和最后一个块进入任何异常时要返回的消息。 块在某种意义上是逻辑分组的DML操作,它可以是单个选择或DML操作组。根据业务逻辑做出决策
PROCEDURE EXPIRE_STUFF_PRC
(
PI_EMAIL_NBR_STR IN VARCHAR2,
PO_SUCCESS_FLG OUT VARCHAR2,
PO_OUT_MSG OUT VARCHAR2
) AS
L_SUCCESS VARCHAR2(1) := 'N';
L_EMAIL_ID NUMBER;
L_PREV_EMAIL_VER_ID NUMBER := 0;
L_PREV_EMAIL_EXP_DT DATE;
BEGIN
BEGIN
SELECT
ITEM.EMAIL_ID
INTO L_EMAIL_ID
FROM HR_EMAIL ITEM
WHERE ITEM.EMAIL_NBR_STR = PI_EMAIL_NBR_STR;
EXCEPTION WHEN OTHERS THEN
PO_SUCCESS_FLG := 'Y';
PO_OUT_MSG := 'COULD NOT FETCH EMAIL_ID';
END;
BEGIN
SELECT
VER_ID.EMAIL_VER_ID
INTO L_PREV_EMAIL_VER_ID
FROM (
SELECT
EMAIL_VER_ID
FROM HR_EMAIL_VER
WHERE EMAIL_ID = L_EMAIL_ID
ORDER BY EMAIL_VER_ID DESC
) VER_ID
WHERE ROWNUM = 2;
EXCEPTION
WHEN NO_DATA_FOUND
THEN PO_SUCCESS_FLG := 'Y';
PO_OUT_MSG := 'LESS THAN 2 VERSIONS';
END;
BEGIN
IF (L_PREV_EMAIL_VER_ID > 0) THEN
SELECT
VER.EXP_DT
INTO L_PREV_EMAIL_EXP_DT
FROM HR_EMAIL_VER VER
WHERE VER.EMAIL_VER_ID = L_PREV_EMAIL_VER_ID;
IF (L_PREV_EMAIL_EXP_DT > SYSDATE) THEN
UPDATE HR_EMAIL_VER
SET EXP_DT = SYSDATE
WHERE EMAIL_VER_ID = L_PREV_EMAIL_VER_ID;
END IF;
PO_SUCCESS_FLG := 'Y';
PO_OUT_MSG := 'SUCCESS';
END IF;
EXCEPTION
WHEN OTHERS THEN
PO_SUCCESS_FLG := 'Y';
PO_OUT_MSG := 'UNABLE TO UPDATE HR_EMAIL_VER';
END;
END EXPIRE_STUFF_PRC;
编写存储过程的理想方法是处理每个块/语句的所有异常。您还有一个必须删除的附加端,另外,我还添加了当第一个和最后一个块进入任何异常时要返回的消息。 块在某种意义上是逻辑分组的DML操作,它可以是单个选择或DML操作组。根据业务逻辑做出决策
PROCEDURE EXPIRE_STUFF_PRC
(
PI_EMAIL_NBR_STR IN VARCHAR2,
PO_SUCCESS_FLG OUT VARCHAR2,
PO_OUT_MSG OUT VARCHAR2
) AS
L_SUCCESS VARCHAR2(1) := 'N';
L_EMAIL_ID NUMBER;
L_PREV_EMAIL_VER_ID NUMBER := 0;
L_PREV_EMAIL_EXP_DT DATE;
BEGIN
BEGIN
SELECT
ITEM.EMAIL_ID
INTO L_EMAIL_ID
FROM HR_EMAIL ITEM
WHERE ITEM.EMAIL_NBR_STR = PI_EMAIL_NBR_STR;
EXCEPTION WHEN OTHERS THEN
PO_SUCCESS_FLG := 'Y';
PO_OUT_MSG := 'COULD NOT FETCH EMAIL_ID';
END;
BEGIN
SELECT
VER_ID.EMAIL_VER_ID
INTO L_PREV_EMAIL_VER_ID
FROM (
SELECT
EMAIL_VER_ID
FROM HR_EMAIL_VER
WHERE EMAIL_ID = L_EMAIL_ID
ORDER BY EMAIL_VER_ID DESC
) VER_ID
WHERE ROWNUM = 2;
EXCEPTION
WHEN NO_DATA_FOUND
THEN PO_SUCCESS_FLG := 'Y';
PO_OUT_MSG := 'LESS THAN 2 VERSIONS';
END;
BEGIN
IF (L_PREV_EMAIL_VER_ID > 0) THEN
SELECT
VER.EXP_DT
INTO L_PREV_EMAIL_EXP_DT
FROM HR_EMAIL_VER VER
WHERE VER.EMAIL_VER_ID = L_PREV_EMAIL_VER_ID;
IF (L_PREV_EMAIL_EXP_DT > SYSDATE) THEN
UPDATE HR_EMAIL_VER
SET EXP_DT = SYSDATE
WHERE EMAIL_VER_ID = L_PREV_EMAIL_VER_ID;
END IF;
PO_SUCCESS_FLG := 'Y';
PO_OUT_MSG := 'SUCCESS';
END IF;
EXCEPTION
WHEN OTHERS THEN
PO_SUCCESS_FLG := 'Y';
PO_OUT_MSG := 'UNABLE TO UPDATE HR_EMAIL_VER';
END;
END EXPIRE_STUFF_PRC;
您在代码中使用了不必要的
BEGIN/END
。如果您想处理某个特定部分中的异常
,可能有必要。格式化和检查语法的最好方法是使用一个好的代码编辑器
我已经删除了所有不需要的开始/结束,这应该很好:
CREATE OR REPLACE PROCEDURE expire_stuff_prc (
pi_email_nbr_str IN VARCHAR2,
po_success_flg OUT VARCHAR2,
po_out_msg OUT VARCHAR2
) AS
l_success VARCHAR2(1) := 'N';
l_email_id NUMBER;
l_prev_email_ver_id NUMBER := 0;
l_prev_email_exp_dt DATE;
BEGIN
SELECT
item.email_id
INTO l_email_id
FROM
hr_email item
WHERE
item.email_nbr_str = pi_email_nbr_str;
BEGIN
SELECT
ver_id.email_ver_id
INTO l_prev_email_ver_id
FROM
(
SELECT
email_ver_id
FROM
hr_email_ver
WHERE
email_id = l_email_id
ORDER BY
email_ver_id DESC
) ver_id
WHERE
ROWNUM = 2;
EXCEPTION
WHEN no_data_found THEN
po_success_flg := 'Y';
po_out_msg := 'LESS THAN 2 VERSIONS';
END;
IF ( l_prev_email_ver_id > 0 ) THEN
SELECT
ver.exp_dt
INTO l_prev_email_exp_dt
FROM
hr_email_ver ver
WHERE
ver.email_ver_id = l_prev_email_ver_id;
IF ( l_prev_email_exp_dt > sysdate ) THEN
UPDATE hr_email_ver
SET
exp_dt = sysdate
WHERE
email_ver_id = l_prev_email_ver_id;
END IF;
po_success_flg := 'Y';
po_out_msg := 'SUCCESS';
END IF;
END expire_stuff_prc;
/
您在代码中使用了不必要的
BEGIN/END
。如果您想处理某个特定部分中的异常
,可能有必要。格式化和检查语法的最好方法是使用一个好的代码编辑器
我已经删除了所有不需要的开始/结束,这应该很好:
CREATE OR REPLACE PROCEDURE expire_stuff_prc (
pi_email_nbr_str IN VARCHAR2,
po_success_flg OUT VARCHAR2,
po_out_msg OUT VARCHAR2
) AS
l_success VARCHAR2(1) := 'N';
l_email_id NUMBER;
l_prev_email_ver_id NUMBER := 0;
l_prev_email_exp_dt DATE;
BEGIN
SELECT
item.email_id
INTO l_email_id
FROM
hr_email item
WHERE
item.email_nbr_str = pi_email_nbr_str;
BEGIN
SELECT
ver_id.email_ver_id
INTO l_prev_email_ver_id
FROM
(
SELECT
email_ver_id
FROM
hr_email_ver
WHERE
email_id = l_email_id
ORDER BY
email_ver_id DESC
) ver_id
WHERE
ROWNUM = 2;
EXCEPTION
WHEN no_data_found THEN
po_success_flg := 'Y';
po_out_msg := 'LESS THAN 2 VERSIONS';
END;
IF ( l_prev_email_ver_id > 0 ) THEN
SELECT
ver.exp_dt
INTO l_prev_email_exp_dt
FROM
hr_email_ver ver
WHERE
ver.email_ver_id = l_prev_email_ver_id;
IF ( l_prev_email_exp_dt > sysdate ) THEN
UPDATE hr_email_ver
SET
exp_dt = sysdate
WHERE
email_ver_id = l_prev_email_ver_id;
END IF;
po_success_flg := 'Y';
po_out_msg := 'SUCCESS';
END IF;
END expire_stuff_prc;
/
其他人时的异常几乎总是一个bug。您只是将所有异常转储到一个位置并将其隐藏。看到你的博客是指异常时,其他人则为空,我同意这是一个错误,但不是当你妥善处理它。在这种情况下,它会向调用者返回一个错误。OP可以适当修改。您正在比较苹果和香蕉。我不知道如果没有
RAISE
它会如何返回错误?这不是错误处理,应该避免。要么处理错误,要么离开它。THEN NULL
只是一个例子,当其他人没有RAISE
时,bug就是。我不知道处理异常的用例,它取决于如何处理它。PO_OUT_MSG返回一条消息,这样打电话的人就知道遇到了错误。没关系,我在这里不是吹毛求疵。我只是在帮助你,因为很多开发者都犯了这个错误。我已经向你解释过了,也给你提供了一本好书。如果你不同意,那由你决定。但是你不能不同意汤姆的观点,保持安全<代码>当其他人
时的异常几乎总是一个bug。您只是将所有异常转储到一个位置并将其隐藏。看到你的博客是指异常时,其他人则为空,我同意这是一个错误,但不是当你妥善处理它。在这种情况下,它会向调用者返回一个错误。OP可以适当修改。您正在比较苹果和香蕉。我不知道如果没有RAISE
它会如何返回错误?这不是错误处理,应该避免。要么处理错误,要么离开它。THEN NULL
只是一个例子,当其他人没有RAISE
时,bug就是。我不知道处理异常的用例,它取决于如何处理它。PO_OUT_MSG返回一条消息,这样打电话的人就知道遇到了错误。没关系,我在这里不是吹毛求疵。我只是在帮助你,因为很多开发者都犯了这个错误。我已经向你解释过了,也给你提供了一本好书。如果你不同意,那由你决定。但是你不能不同意汤姆的观点,保持安全!!!如果第一个select语句返回no_Data_found/too_many_rows select item.email_id到l_email_id FROM hr_email item,该怎么办?调用方在此上下文中没有任何线索。代码将引发错误,要处理它,OP需要有一个适当的异常。我会让OP来决定,我当然不会在他的代码中添加bug并在这里发布。我将坚持问题的范围,这是编译问题。这一个对我有用。正在从另一个创建并传递新项目的进程调用my proc。如果找不到数据,那是其他人的错:)LOL如果第一个select语句返回找不到数据/太多行select item.email\U id到l\U email\U id从hr\U email item?调用方在此上下文中没有任何线索。代码将引发错误,要处理它,OP需要有一个适当的异常。我会让OP来决定,我当然不会在他的代码中添加bug并在这里发布。我将坚持问题的范围,这是编译问题。这一个对我有用。正在从另一个创建并传递新项目的进程调用my proc。如果找不到任何数据,那是其他人的错:)LOL缩进代码,使嵌套块缩进得比其包含的父块更深。若您有多个嵌套块,并且一眼就看不到它们属于哪一级代码,那个么您将花费额外的时间来调试这样的问题。花点时间把你的代码格式化好。。。这看起来可能需要花费很多时间,但实际上从长远来看,这将为您节省大量的时间和精力,因为您需要调试的时间更少。@MT0我做得很好