我是存储过程的新手。
我正在尝试运行存储过程并得到以下错误:
我正在获取PLS-00103:遇到以下情况之一时遇到符号" SELECT":开始函数编译指示过程...
PLS-00103:预期以下其中一项时遇到符号" RETURN":*&=-+ > at in is mod剩下的不是rem然后...
我曾尝试寻找导致这些错误的原因以及与此类似的示例,但结果不足。 关于为什么会发生这些错误的任何线索?
这是代码:
CREATE OR REPLACE PROCEDURE LIST_ACTIONS_CHECK_ADD
(
LISTNAME IN VARCHAR2
) AS
BEGIN
DECLARE CNT NUMBER;
SELECT COUNT(LIST_NAME) INTO CNT FROM LISTS_MASTER WHERE LIST_NAME = LISTNAME;
IF (CNT > 0)
RETURN 1
ELSE
RETURN 0
END IF;
END LIST_ACTIONS_CHECK_ADD;
新代码:
CREATE OR REPLACE PROCEDURE LIST_ACTIONS_CHECK_ADD
(
P_LISTNAME IN VARCHAR2
)
AS
L_CNT NUMBER;
BEGIN
SELECT COUNT(LIST_NAME)
INTO L_CNT
FROM LISTS_MASTER
WHERE LIST_NAME = P_LISTNAME;
IF (L_CNT > 0)
RETURN 1;
ELSE
RETURN 0;
END IF;
END LIST_ACTIONS_CHECK_ADD;
(更正#1)您不能在过程中返回值。应该删除LIST_ACTIONS_CHECK_ADD并将其声明为函数,以便返回NUMBER
(更正#2)您需要按以下方式移动CNT的声明(请参见下文)
(更正#3)您需要在return语句上使用分号:
(更正#4)您需要在IF(CNT> 0)之后输入THEN(请参见下文):
DROP PROCEDURE LIST_ACTIONS_CHECK_ADD;
CREATE OR REPLACE FUNCTION LIST_ACTIONS_CHECK_ADD
(
LISTNAME IN VARCHAR2
)
RETURN NUMBER AS
CNT NUMBER;
BEGIN
SELECT COUNT(LIST_NAME) INTO CNT FROM LISTS_MASTER WHERE LIST_NAME = LISTNAME;
IF (CNT > 0) THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END LIST_ACTIONS_CHECK_ADD;
可以从SQLPLUS执行以下操作:
SET SERVEROUTPUT ON SIZE 100000;
DECLARE
V_RESULT NUMBER;
BEGIN
V_RESULT := LIST_ACTIONS_CHECK_ADD('X');
DBMS_OUTPUT.PUT_LINE('RESULT: ' || V_RESULT);
END;
谢谢!我正在尝试调用此功能。我尝试致电LIST_ACTIONS_CHECK_ADD(NAME);我尝试执行相同的东西
这工作:从双选择LISTS_ACTIONS_CHECK_ADD(BLACKLIST);
SQLPLUS不会使用LIST_ACTIONS_CHECK_ADD(NAME);如果LIST_ACTIONS_CHECK_ADD是一个函数-您需要一个匿名PLSQL块-请修改上面的帖子,好吗?
是。非常感谢您的建议
存储过程声明的框架是
CREATE OR REPLACE PROCEDURE procedure_name( <> )
AS
<>
BEGIN
<>
END procedure_name;
在您发布的代码中,
您将BEGIN放在变量声明之前
您有一个无关紧要的DECLARE -仅在声明不涉及CREATE的PL / SQL块时才使用。
RETURN语句后,缺少分号。
过程无法返回值。如果要返回1或0,则可能需要一个函数而不是一个过程。如果需要过程,可以声明OUT参数。
您在IF之后缺少THEN
听起来你想要类似的东西
CREATE OR REPLACE FUNCTION LIST_ACTIONS_CHECK_ADD
(
LISTNAME IN VARCHAR2
)
RETURN NUMBER
AS
CNT NUMBER;
BEGIN
SELECT COUNT(LIST_NAME)
INTO CNT
FROM LISTS_MASTER
WHERE LIST_NAME = LISTNAME;
IF (CNT > 0)
THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END LIST_ACTIONS_CHECK_ADD;
请注意,通常,最好使用某种命名约定来确保参数和局部变量不共享列名。试图弄清楚LISTNAME是参数还是列名以及LIST_NAME和LISTNAME之间的区别通常会使将来的程序员困惑。就个人而言,我对参数使用p_前缀,对局部变量使用l_前缀。我也建议使用锚定类型-lists_master.list_name%type
CREATE OR REPLACE FUNCTION LIST_ACTIONS_CHECK_ADD
(
P_LIST_NAME IN lists_master.list_name%TYPE
)
RETURN NUMBER
AS
L_CNT NUMBER;
BEGIN
SELECT COUNT(LIST_NAME)
INTO L_CNT
FROM LISTS_MASTER
WHERE LIST_NAME = P_LIST_NAME;
IF (L_CNT > 0)
THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END LIST_ACTIONS_CHECK_ADD;
非常感谢你的帮助。除了使用锚定类型外,我已经使用了您的所有建议。根据我对锚定类型的了解,这是您的in参数是从list_name列的lists_master表中获取的吗?实际上,我只是希望它是一个我希望输入的in参数,例如:CALL LIST_ACTIONS_CHECK_ADD(BLACKLIST);
现在,当我按照您的建议编译代码时,我得到了Error(13,4):PLS-00103:在期望以下情况之一时遇到了符号" RETURN":*&=-+ > ...知道为什么吗?我编辑了原始问题以包含新代码
@jon-锚定类型仅指定您要传入的参数是当前定义的lists_master.list_name类型。即使您的表中没有该字符串,也不会阻止您传递该字符串。这确实意味着,如果list_name列的数据类型发生更改,则参数的数据类型将发生更改,并且为下一开发人员提供了有关所需数据类型的文档。
哦,那绝对是正确的。谢谢会用这个。
@jon-请注意,我更新了答案。我错过了A B在他的回答中发现的几个问题。
看见了。非常感谢你。