Oracle PL/SQL 比较过程中的字符串
Oracle PL/SQL Compare Strings in Procedure
有了这个table:
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。我不知道为什么;有人可以帮我改正程序吗?
您的绑定变量和列同名。更改绑定变量以具有不同的名称。
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;
/
此外,您 - 在过程之后调用它,因为它允许您将多个过程调用捆绑到一个事务中并同时回滚它们。
您认为 NAME = name
的(逻辑)值是多少?
我知道你怎么会犯这个错误......也许你是用 C 或类似语言长大的,其中大写很重要。在 SQL 和 PL/SQL 中并非如此。
不要对 table 列和您的过程参数使用相同的名称。并了解 PL/SQL 对象名称不区分大小写。对于程序,例如更改为 p_name
、p_login
等
有了这个table:
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。我不知道为什么;有人可以帮我改正程序吗?
您的绑定变量和列同名。更改绑定变量以具有不同的名称。
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;
/
此外,您
您认为 NAME = name
的(逻辑)值是多少?
我知道你怎么会犯这个错误......也许你是用 C 或类似语言长大的,其中大写很重要。在 SQL 和 PL/SQL 中并非如此。
不要对 table 列和您的过程参数使用相同的名称。并了解 PL/SQL 对象名称不区分大小写。对于程序,例如更改为 p_name
、p_login
等