【问题标题】:Oracle PL/SQL Compare Strings in ProcedureOracle PL/SQL 比较过程中的字符串
【发布时间】:2017-11-13 21:54:18
【问题描述】:

有了这张桌子:

CREATE TABLE HR.MSG_USER ( 
ID                   number(38)  NOT NULL,
NAME                 varchar2(100)  NOT NULL,
PASS                 varchar2(10)  NOT NULL,
LOGIN                varchar2(20)  NOT NULL,
CONSTRAINT IDX_USER_LOGIN_UNIQUE UNIQUE ( LOGIN ) ,
CONSTRAINT PK_USER PRIMARY KEY ( ID ) ,
CONSTRAINT IDX_USER_NAME_UNIQUE UNIQUE ( NAME ) 
);

我创建了这个程序:

create or replace procedure new_user ( login IN VARCHAR, name IN VARCHAR, pass IN VARCHAR) is

rowsFound number;
ERR_NULL            exception;
ERR_NAME_TOO_LONG   exception;
ERR_NAME_DUPLICATED exception;
ERR_UNIQUE          exception;

PRAGMA EXCEPTION_INIT(ERR_NULL,            -20001);
PRAGMA EXCEPTION_INIT(ERR_NAME_TOO_LONG,   -20002);
PRAGMA EXCEPTION_INIT(ERR_NAME_DUPLICATED, -20003);
PRAGMA EXCEPTION_INIT(ERR_UNIQUE,          -20013);

begin

  if (login is null) or (name is null) or (pass is null) then
    raise_application_error(-20001, 'Datos de Usuario Nulos');
  end if; 

  if (LENGTH(name) > 100) then
    raise_application_error(-20002, 'Nombre Usuario Demasiado Largo');
  end if; 

  select count(*) into rowsFound from MSG_USER where NAME = name;
  if rowsFound >= 1 then
        raise_application_error(-20013, 'Usuario Ya Existe: Name');
  end if;

  select count(*) into rowsFound from MSG_USER where LOGIN = login;
  if rowsFound >= 1 then
        raise_application_error(-20013, 'Usuario Ya Existe: Login');
  end if;

  INSERT INTO MSG_USER ( "ID", "NAME", "PASS", "LOGIN") VALUES ( seq_MSG_USER_id.nextval, name, pass,login );

  dbms_output.put_line('Usuario Creado: '||name);
  commit;

end;
/

当我使用 exec 插入用户时:

   exec new_user('testL1','testN1','testP1');
   exec new_user('testL2','testN2','testP2');

第二个失败,出现 ORA-20013;这意味着 (testL1 = testL2)=True。但是使用:

select count(*) from MSG_USER where NAME = 'testN2';

计数等于0。我不知道为什么;有人可以帮我纠正我的程序吗?

【问题讨论】:

    标签: oracle stored-procedures plsql procedure


    【解决方案1】:

    您的绑定变量和列具有相同的名称。将绑定变量更改为不同的名称。

    create or replace procedure new_user (
      i_login IN VARCHAR2, -- Use VARCHAR2 not VARCHAR
      i_name  IN VARCHAR2,
      i_pass  IN VARCHAR2
    )
    is
      rowsFound number;
      ERR_NULL            exception;
      ERR_NAME_TOO_LONG   exception;
      ERR_NAME_DUPLICATED exception;
      ERR_UNIQUE          exception;
    
      PRAGMA EXCEPTION_INIT(ERR_NULL,            -20001);
      PRAGMA EXCEPTION_INIT(ERR_NAME_TOO_LONG,   -20002);
      PRAGMA EXCEPTION_INIT(ERR_NAME_DUPLICATED, -20003);
      PRAGMA EXCEPTION_INIT(ERR_UNIQUE,          -20013);
    begin
      if (i_login is null) or (i_name is null) or (i_pass is null) then
        raise_application_error(-20001, 'Datos de Usuario Nulos');
      end if; 
    
      if (LENGTH(i_name) > 100) then
        raise_application_error(-20002, 'Nombre Usuario Demasiado Largo');
      end if; 
    
      select count(*) into rowsFound from MSG_USER where NAME = i_name;
      if rowsFound >= 1 then
            raise_application_error(-20013, 'Usuario Ya Existe: Name');
      end if;
    
      select count(*) into rowsFound from MSG_USER where LOGIN = i_login;
      if rowsFound >= 1 then
            raise_application_error(-20013, 'Usuario Ya Existe: Login');
      end if;
    
      INSERT INTO MSG_USER ( "ID", "NAME", "PASS", "LOGIN") VALUES ( seq_MSG_USER_id.nextval, i_name, i_pass, i_login );
    
      dbms_output.put_line('Usuario Creado: '||i_name);
    end;
    /
    

    另外,您 should not put a COMMIT statement in the procedure - 在过程之后调用它,因为它允许您将多个过程调用捆绑到一个事务中并同时回滚它们。

    【讨论】:

      【解决方案2】:

      您认为NAME = name 的(逻辑)值是多少?

      我知道你怎么会犯这个错误......也许你是用 C 或类似语言编码长大的,在这些语言中,大写很重要。在 SQL 和 PL/SQL 中并非如此。

      不要对表列和过程参数使用相同的名称。并理解 PL/SQL 对象名称不区分大小写。对于过程,例如更改为 p_namep_login 等。

      【讨论】:

        猜你喜欢
        • 2011-11-09
        • 1970-01-01
        • 1970-01-01
        • 2015-06-17
        • 2015-11-19
        • 2011-09-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多