Oracle 存储过程编译错误

Posted

技术标签:

【中文标题】Oracle 存储过程编译错误【英文标题】:Oracle Stored Procedure compilation error 【发布时间】:2017-04-05 03:41:09 【问题描述】:

我是 PL/SQL 新手。任何人都可以帮助修复我的编译错误吗?非常感谢您的帮助。另外,在我想调用这个程序来检查并添加一个新用户之后。

create or replace procedure CheckAddUser ( userid in varchar2(20))
as
declare vartmp number;
begin
    SELECT nvl((SELECT distinct 1 FROM crm_admin.LTY_USER_STORE WHERE usr_nm = userid  ), 0) INTO :varTmp FROM dual;    
    IF (:varTmp = 0) THEN
       dbms_output.put_line('the user ' || ':userid' || ' does not exist');

    elsif (:varTmp = 1) THEN
       dbms_output.put_line('the user ' || ':userid' || '  already exist');
    End if;
end;

【问题讨论】:

您看到的编译错误是什么? @Chetan 在 sqldeveloper 中,我得到了几个: 1. 错误(2,44):PLS-00103:在期望以下之一时遇到符号“(”::=。), @ % 默认字符符号 ":=" 被替换为 "(" 以继续。 2. 错误 (4,1): PLS-00103: 在期望以下之一时遇到符号 "DECLARE": begin function pragma procedure subtype type 当前光标删除存在先前的外部语言符号“begin”被替换为“DECLARE”以继续。 【参考方案1】:

试试这个:

create or replace procedure checkadduser(userid in varchar2)
as
    vartmp number;
begin
    select coalesce(max(1), 0) into vartmp
    from dual
    where exists (
            select 1
            from crm_admin.lty_user_store
            where usr_nm = userid
            );
    if vartmp = 0 then
        dbms_output.put_line('the user ' || userid || ' does not exist');
    elsif vartmp = 1 then
       dbms_output.put_line('the user ' || userid || '  already exist');
    end if;
end;
/

所做的更改:

    从参数中删除了大小 删除了 declare 关键字 - 不是过程语法的一部分

    修改了查询,只要找到一行就停止搜索,否则返回 1。

    select coalesce(max(1), 0) into varTmp
    from dual
    where exists (
            select 1
            from crm_admin.lty_user_store
            where usr_nm = userid
            );
    

    如果 usr_nm 在您的表中是唯一的,这也可以很好地工作(即使它不是唯一的,也可以使用,但如果每个 usr_nm 的行数可以任意大,则性能可能会稍差一些):

    select coalesce(max(1), 0)
    into varTmp
    from crm_admin.lty_user_store
    where usr_nm = userid
    

    不要将: 与变量和参数一起使用。

【讨论】:

@GurV 现在可以正常工作了。感谢您的帮助!开始 2 checkadduser('MikeC'); 3 结束; 4 / 用户 MikeC 已经存在【参考方案2】:

不要将 ":" 与 var 一起使用。 我做了一些更改,我可能会用到:

--I recommended to change procedure to function, then you can use it in SQL
create or replace 
procedure CheckAddUser ( userid in varchar2)
as
  --Best practics, use self-describing variables
    isuserexist number(1,0); -- vartmp
    message_suff varchar2(30):=' does not exist';
begin
  --Best practics, first check the parameters
  if trim(userid) is null then
    raise_application_error(-20000, 'Param userid is empty');
  end if;

    select count(*) into isuserexist
  from crm_admin.lty_user_store 
  where usr_nm = userid;

  --only one if, reads easier
  if isUserExist > 0 then
    message_suff:= ' already exist';
  end if;

  dbms_output.put_line('the user ' || ':userid' || message_suff);
end;

【讨论】:

感谢您的回答和良好做法的提示。它有助于! @Farkhat trim(userid)='' 永远不会是真的。此外,如果我们在谈论最佳实践,我们可以避免在 if 条件和 count(*) 周围使用不必要的括号,而不是 count(1) (加上它的输入更少)。

以上是关于Oracle 存储过程编译错误的主要内容,如果未能解决你的问题,请参考以下文章

oracle存储过程报937错误

oracle存储过程,如何获得详细的错误信息

oracle 如何终止存储过程的运行!

oracle 创建存储过程部分表编译错误是不是表空间、权限不足?

Netezza 存储过程错误

oracle 存储过程 执行、调用不成功 求高手指导?