2017-06-12 55 views
0

比較字符串有了這張表:的Oracle PL/SQL的過程

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。我不知道爲什麼;有人可以幫我糾正我的程序嗎?

回答

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 - 稱它爲手術後,因爲它可以讓你捆綁多個過程調用到一個單一的交易和背部同時推出了他們。

3

您認爲NAME = name的(邏輯)值是多少?

我可以看到你是如何犯這個錯誤的......也許你是用C語言或類似語言編寫的,那裏的大寫字母很重要。在SQL和PL/SQL中不是這樣。

不要對錶列和過程參數使用相同的名稱。並瞭解PL/SQL對象名稱不區分大小寫。對於該過程,例如更改爲p_name,p_login等。