Return ID in insert oracle - oracle

I have a package with a INSERT in a sp, and I want to return the id of that insert. The table have a sequence and a trigger for the identity, but in the sp I don't know how can I return the id of the insert that i'm doing, because in the code java I need to use it.
CREATE OR REPLACE PACKAGE BODY PLUSALT.INSERTAR
IS
PROCEDURE INSERTAR_ESTRATEGIA(
P_USUARIO IN VARCHAR2,
P_CAMPAÑA IN NUMBER,
P_FKPLANTILLA IN NUMBER,
P_NOMBRE IN VARCHAR2)
IS
BEGIN
INSERT
INTO ESTRATEGIA VALUES
(
NULL,
P_CAMPAÑA,
P_USUARIO,
P_FKPLANTILLA,
P_NOMBRE,
NULL,
SYSDATE,
1,
'Y'
);
END;
END;
/
Ths is the table
CREATE TABLE ESTRATEGIA
(
ESID NUMBER(25) NOT NULL,
FK_CAMPAÑA NUMBER(5) NOT NULL,
FK_USUARIO NUMBER(8) NOT NULL,
FK_PLANTILLAESTRA NUMBER(8),
ESNOMBRE VARCHAR2(100),
ESDESCRIPCION VARCHAR2(300),
ESFCHCREACION DATE,
FKESTADO NUMBER(3) NOT NULL,
ESACTIVA CHAR(1)
)
;
The sequence
CREATE SEQUENCE ESTRATEGIA_SEC
START WITH 1
INCREMENT BY 1
NOMAXVALUE;
The trigger
CREATE TRIGGER TRIG_ESTRATEGIA
BEFORE INSERT ON ESTRATEGIA
FOR EACH ROW
BEGIN
SELECT ESTRATEGIA_SEC.nextval INTO :new.ESID FROM dual;
END
;

USE RETURNING INTO in the insert with an OUT parameter. Use this parameter P_ESID in your java code.
CREATE OR REPLACE PACKAGE BODY PLUSALT.INSERTAR
IS
PROCEDURE INSERTAR_ESTRATEGIA(
P_USUARIO IN VARCHAR2,
P_CAMPAÑA IN NUMBER,
P_FKPLANTILLA IN NUMBER,
P_NOMBRE IN VARCHAR2,
P_ESID OUT NUMBER)
IS
BEGIN
INSERT
INTO ESTRATEGIA VALUES
(
NULL,
P_CAMPAÑA,
P_USUARIO,
P_FKPLANTILLA,
P_NOMBRE,
NULL,
SYSDATE,
1,
'Y'
) RETURNING ESID INTO P_ESID ;
END;
END;
/

http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/returninginto_clause.htm
Quick demonstration.
SQL> create table t (id int);
Table created.
SQL> create sequence s;
Sequence created.
SQL> var x number
SQL> insert into t values(s.nextval) returning id into :x;
1 row created.
SQL> print x
X
----------
1

Related

How define AUTONOMOUS_TRANSACTION in oracle?

How to define the autonomous pragma for error logging in oracle with the help of procedure.My table structure is like below.
CREATE TABLE error_logs (
id NUMBER(10) NOT NULL,
log_timestamp TIMESTAMP NOT NULL,
error_message VARCHAR2(4000),
CONSTRAINT error_logs_pk PRIMARY KEY (id)
);
CREATE SEQUENCE error_logs_seq
start with 1
nocycle
nocache;
i tried below code for my requirement.
CREATE OR REPLACE PROCEDURE log_errors (p_error_message IN VARCHAR2) AS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO error_logs (id, log_timestamp, error_message)
VALUES (error_logs_seq.NEXTVAL, SYSTIMESTAMP, p_error_message);
COMMIT;
END;
/

how to fetch plsql table type values into refcursor

I am trying to create a procedure in which another procedure is being called and it returns pl/sql table type. How to collect values of plsql table into ref cursor and return as OUT type refcursor. Please help.
Thanks!
I have this piece of Code : p_rec is table type
DECLARE
p_rec PORTAL_LOAD_PKG.header_tab#test_link;
p_status VARCHAR2(200);
BEGIN
DASHBOARD_PRC#test_link('XYZ LIMITED', p_rec, p_status);
END;
Above code is working fine but my requirement is to create a procedure which returns the values of p_rec in refcursor.
Finally resolved.
First we have to create a Object and table type locally. Object definition should
be same as your record type which is declared on remote DB.
CREATE OR REPLACE TYPE dashboard_obj AS OBJECT (
i_num VARCHAR2(500),
desc VARCHAR2(1000),
od_num VARCHAR2(200),
i_amount NUMBER,
amount_paid NUMBER,
status VARCHAR2(200),
terms_date DATE,
i_id NUMBER,
v_id NUMBER
);
After that create table type of that object.
CREATE OR REPLACE TYPE tab1 IS
TABLE OF dashboard_obj;
Now Create procedure :
CREATE OR REPLACE PROCEDURE proc_test (
recordset OUT SYS_REFCURSOR
) IS
p_rec portal_load_pkg.header_tab#test_link;
p_status VARCHAR2(200);
obj dashboard_obj;
v_tab tab1 := tab1 ();
BEGIN
dashboard_prc#test_link ( 'XYZ LIMITED',p_rec,p_status );
FOR i IN 1.._rec.count LOOP
v_tab.extend;
v_tab(v_tab.count) := dashboard_obj(p_rec(i).i_num,
p_rec(i).desc,
p_rec(i).od_num,
p_rec(i).i_amount,
p_rec(i).amount_paid,
p_rec(i).status,
p_rec(i).terms_date,
p_rec(i).i_id,
p_rec(i).v_id
);
END LOOP;
OPEN recordset FOR SELECT
*
FROM
TABLE ( v_tab );
END;
If there is any other solution, please let me know. Thanks!

Trying to assign a value in a variable and used it in proc in Oracle

i am trying to assign a value in a variable "slno" use it to insert value in table "Par_conn" . but it is giving error while executing the Procedure with parameter.Any help would be appreciated.
Table
create table PAR_CONN
(
CUSTOMER_ID NUMBER(10) not null,
CUSTOMER_NAME VARCHAR2(50) not null,
CITY VARCHAR2(50)
)
Store Procedure
CREATE OR REPLACE PROCEDURE sp_insert(CUSTOMER_NAME IN VARCHAR2,CITY IN VARCHAR2)
IS
Declare slno number;
BEGIN
select count(*) into slno from Par_conn;
insert into Par_conn values(slno,CUSTOMER_NAME,CITY);
commit;
END;
Executing SP:
Begin
sp_insert('ramesh','dispur');
end;
The syntax is wrong. See below comments inline. Not sure what you wanted to achieve but at the first place you need to make all syntatic corrections before implementing any logic.
CREATE OR REPLACE PROCEDURE sp_insert (CUSTOMER_NAME IN VARCHAR2,
CITY IN VARCHAR2)
IS
---Declare slno number; --<this is wrong way of declaration
slno NUMBER;
BEGIN
SELECT COUNT (*) INTO slno FROM Par_conn;
INSERT INTO Par_conn
VALUES (slno, CUSTOMER_NAME, CITY);
COMMIT;
END;
Refer here how to create a procedure .
Procedure
Please do not reinvent wheel.
You probably aimed for:
CREATE OR REPLACE PROCEDURE sp_insert(CUSTOMER_NAME IN VARCHAR2,CITY IN VARCHAR2)
IS
slno number;
BEGIN
select max(id_col_name)+1 into slno from Par_conn;
insert into Par_conn values(slno,CUSTOMER_NAME,CITY);
commit;
END;
to set id value. I would strongly recommend to use SEQUENCE or IDENTITY.
Also you should always specify column list:
insert into Par_conn(col1_name, col2_name, col3_name)
values(slno,CUSTOMER_NAME,CITY);

Selecting elements and inserting them into List of tables in Oracle

I'm trying to insert the selected value of columns into List of Tables, Here is my code:
First I've Created an Object:
CREATE OR REPLACE TYPE ordersinf as OBJECT(orderDate DATE, orderName VARCHAR2(20), orderPrice NUMBER)
Then
CREATE OR REPLACE orders_tab IS TABLE OF ordersinf
and Finally my Function:
create or replace function execImmFunc(orderName in VARCHAR2, orderPrice in NUMBER) return orders_tab is
Result orders_tab := orders_tab();
myName orders_table.orders_name%type;
myPrice orders_table.orders_price%type;
begin
RESULT.extend();
SELECT orders_name, orders_price
**INTO RESULT(1).ordersInf('NULL',orders_name, orders_price)**
--I'm Having trouble with the above code..
FROM orders_table
WHERE orders_name = orderName AND orders_price = orderPrice;
--result.extend();
--result(result.last) := ordersinf(NULL,orderName, orderPrice);
return(Result);
end execImmFunc;
How Can I accomplish this? I'm sorry if this is a dumb question but I'm very new into this..
Hey just an alternative approach can be implemented by using PIPELINED
function as mentioned below. Hope it also helps
CREATE OR REPLACE TYPE ordersinf
AS
OBJECT
(
orderDate DATE,
orderName VARCHAR2(20 CHAR),
orderPrice NUMBER);
CREATE OR REPLACE TYPE orders_tab IS TABLE OF ordersinf;
CREATE OR REPLACE FUNCTION execImmFunc(
orderName IN VARCHAR2,
orderPrice IN NUMBER)
RETURN orders_tab pipelined
IS
Rsult orders_tab := orders_tab();
myName orders_table.orders_name%type;
myPrice orders_table.orders_price%type;
BEGIN
SELECT NULL,
orders_name,
orders_price BULK COLLECT
INTO Rsult
FROM orders_table
WHERE orders_name = orderName
AND orders_price = orderPrice;
FOR i IN Rsult.FIRST..Rsult.LAST
LOOP
PIPE ROW(I);
END LOOP;
RETURN ;
END execImmFunc;
You can use BULK COLLECT to retrieve data:
create or replace function execImmFunc(orderName in VARCHAR2, orderPrice in NUMBER)
return orders_tab is
Result orders_tab := orders_tab();
begin
SELECT ordersinf(null, orders_name, orders_price)
bulk collect INTO RESULT
FROM orders_table
WHERE orders_name = orderName AND orders_price = orderPrice;
return(Result);
end execImmFunc;
Test:
create or replace type ordersinf
as object(orderdate date, ordername varchar2(20), orderprice number);
create or replace type orders_tab is table of ordersinf;
create table orders_table (orders_name varchar2(20), orders_price number);
insert into orders_table values ('ORD1', 101);
insert into orders_table values ('ORD2', 102);
insert into orders_table values ('ORD3', 103);
select * from table(execImmFunc('ORD1', 101))
Output:
ORDERDATE ORDERNAME ORDERPRICE
----------- -------------------- ----------
ORD1 101

can any solve what is wrong with this please?

create table account_type
(
acct_type number(3) primary key,
acct_desc Varchar2(30) not null CHECK (acct_desc IN('savings','salary','current','credit')),
acct_wd_limit number(10)
);
create sequence acct_seq;
CREATE OR REPLACE TRIGGER acct_pk
BEFORE INSERT ON account_type
FOR EACH ROW
WHEN (new.acct_type IS NULL)
BEGIN
SELECT acct_seq.NEXTVAL
INTO :new.acct_type
FROM account_type;
END;
i am getting an error on the line before insert on account_type. no idea why
I also tried doing
CREATE OR REPLACE TRIGGER acct_pk
BEFORE INSERT ON account_type
FOR EACH ROW
WHEN (new.id IS NULL)
BEGIN
SELECT acct_seq.NEXTVAL
INTO :new.id
FROM account_type;
END;
Even doing this is giving me an error
create sequence acct_pk
start with 1
increment by 1
max value 999
min value 1
no cycle;
Thanks
Since the author tagged the question with oracle10g, she can't use sequence_name.nextVal in PL/SQL. Solution:
CREATE OR REPLACE TRIGGER acct_pk
BEFORE INSERT ON account_type
FOR EACH ROW
DECLARE
v_acct_type NUMBER;
BEGIN
IF :new.acct_type IS NULL THEN
SELECT acct_seq.NEXTVAL
INTO v_acct_type
FROM dual;
:new.acct_type := v_acct_type;
END IF;
END;

Resources