甲骨文 sql : "get or insert" 存储过程
oracle sql : "get or insert" stored procedure
我想做一个接收输入参数的存储过程,然后
- 如果 targeted table 不包含该值,则会创建一个新行,然后返回所创建行的 ID
- 如果目标table已经包含输入参数,则返回行的id
暂时我只有在输入参数是新的时才设法插入新行:
--exemple of table with a primary id a column with value
create table unique_number_table (
id NUMBER(12) not null,
UNIQUE_NUMBER VARCHAR2(80) not null,
constraint PK_ID primary key (ID)
);
create sequence SEQ_NUMBER
INCREMENT BY 1
START WITH 2
MAXVALUE 999999999
MINVALUE 0;
create or replace procedure insert_or_get_unique_number ( input_number in varchar ) is
begin
insert into unique_number_table (id, UNIQUE_NUMBER)
select SEQ_NUMBER.NEXTVAL ,input_number
from dual
where not exists(select * from unique_number_table
where UNIQUE_NUMBER =input_number);
end insert_or_get_unique_number;
你知道怎么做吗?
在我看来你想要一个存储函数而不是一个过程。
create or replace function insert_or_get_unique_number (input_number varchar2)
return UNIQUE_NUMBER_TABLE.ID%type
is
L_NUM UNIQUE_NUMBER_TABLE.ID%type;
begin
select ID
into L_NUM
from UNIQUE_NUMBER_TABLE
where UNIQUE_NUMBER = input_number;
return L_NUM;
exception
when NO_DATA_FOUND then
insert into unique_number_table (id, UNIQUE_NUMBER)
values (SEQ_NUMBER.NEXTVAL, input_number)
returning ID into L_NUM;
return L_NUM;
end insert_or_get_unique_number;
这是您问题的可能解决方案。
CREATE OR REPLACE PROCEDURE insert_or_get_unique_number (
input_number IN VARCHAR,
c_out out sys_refcursor
) IS
Lv_input_exists INT;
lv_myRowid VARCHAR2(200);
err_code varchar2(600);
err_msg varchar2(500);
BEGIN
--step 1 check if the input param exists. -
select count(*)
INTO Lv_input_exists
FROM unique_number_table
WHERE unique_number = input_number;
--step 2 if it exists than get the rowid of that row and return that value
IF Lv_input_exists > 0
THEN
OPEN c_out for
SELECT ROWID
FROM unique_number_table Uni
WHERE uni.id = input_number ;
RETURN;
ELSE
-- STEP 3 the input number does not exists therefore we need to insert and return the rowid--
INSERT INTO unique_number_table (
id,
unique_number
)
VALUES(
seq_number.NEXTVAL,
input_number)
returning ROWID into lv_myRowid;
----STEP 4 Open the cursor and return get the rowid.
OPEN c_out for
SELECT lv_myRowid
FROM DUAL ;
SYS.dbms_output.put_line( 'Done' );
END IF;
EXCEPTION WHEN OTHERS THEN
err_code := SQLCODE;
err_msg := SUBSTR(SQLERRM, 1, 200);
SYS.dbms_output.put_line( err_code || ' '||': '||err_msg );
END insert_or_get_unique_number;
你可以这样测试程序。
set serveroutput on ;
DECLARE
INPUT_NUMBER VARCHAR2(200);
C_OUT sys_refcursor;
BEGIN
INPUT_NUMBER := '3';
INSERT_OR_GET_UNIQUE_NUMBER(
INPUT_NUMBER => INPUT_NUMBER,
C_OUT => C_OUT
);
DBMS_SQL.return_result(C_OUT);
END;
我想做一个接收输入参数的存储过程,然后
- 如果 targeted table 不包含该值,则会创建一个新行,然后返回所创建行的 ID
- 如果目标table已经包含输入参数,则返回行的id
暂时我只有在输入参数是新的时才设法插入新行:
--exemple of table with a primary id a column with value
create table unique_number_table (
id NUMBER(12) not null,
UNIQUE_NUMBER VARCHAR2(80) not null,
constraint PK_ID primary key (ID)
);
create sequence SEQ_NUMBER
INCREMENT BY 1
START WITH 2
MAXVALUE 999999999
MINVALUE 0;
create or replace procedure insert_or_get_unique_number ( input_number in varchar ) is
begin
insert into unique_number_table (id, UNIQUE_NUMBER)
select SEQ_NUMBER.NEXTVAL ,input_number
from dual
where not exists(select * from unique_number_table
where UNIQUE_NUMBER =input_number);
end insert_or_get_unique_number;
你知道怎么做吗?
在我看来你想要一个存储函数而不是一个过程。
create or replace function insert_or_get_unique_number (input_number varchar2)
return UNIQUE_NUMBER_TABLE.ID%type
is
L_NUM UNIQUE_NUMBER_TABLE.ID%type;
begin
select ID
into L_NUM
from UNIQUE_NUMBER_TABLE
where UNIQUE_NUMBER = input_number;
return L_NUM;
exception
when NO_DATA_FOUND then
insert into unique_number_table (id, UNIQUE_NUMBER)
values (SEQ_NUMBER.NEXTVAL, input_number)
returning ID into L_NUM;
return L_NUM;
end insert_or_get_unique_number;
这是您问题的可能解决方案。
CREATE OR REPLACE PROCEDURE insert_or_get_unique_number (
input_number IN VARCHAR,
c_out out sys_refcursor
) IS
Lv_input_exists INT;
lv_myRowid VARCHAR2(200);
err_code varchar2(600);
err_msg varchar2(500);
BEGIN
--step 1 check if the input param exists. -
select count(*)
INTO Lv_input_exists
FROM unique_number_table
WHERE unique_number = input_number;
--step 2 if it exists than get the rowid of that row and return that value
IF Lv_input_exists > 0
THEN
OPEN c_out for
SELECT ROWID
FROM unique_number_table Uni
WHERE uni.id = input_number ;
RETURN;
ELSE
-- STEP 3 the input number does not exists therefore we need to insert and return the rowid--
INSERT INTO unique_number_table (
id,
unique_number
)
VALUES(
seq_number.NEXTVAL,
input_number)
returning ROWID into lv_myRowid;
----STEP 4 Open the cursor and return get the rowid.
OPEN c_out for
SELECT lv_myRowid
FROM DUAL ;
SYS.dbms_output.put_line( 'Done' );
END IF;
EXCEPTION WHEN OTHERS THEN
err_code := SQLCODE;
err_msg := SUBSTR(SQLERRM, 1, 200);
SYS.dbms_output.put_line( err_code || ' '||': '||err_msg );
END insert_or_get_unique_number;
你可以这样测试程序。
set serveroutput on ;
DECLARE
INPUT_NUMBER VARCHAR2(200);
C_OUT sys_refcursor;
BEGIN
INPUT_NUMBER := '3';
INSERT_OR_GET_UNIQUE_NUMBER(
INPUT_NUMBER => INPUT_NUMBER,
C_OUT => C_OUT
);
DBMS_SQL.return_result(C_OUT);
END;