How to Create Stored procedure in DB2 - sql

Can you please help me to create a below Oracle procedure in DB2? Same table name with columns are available in DB2 also but below script is not working
CREATE OR REPLACE PROCEDURE sample_proc (ACCT_NO in CHAR,p_cursor out SYS_REFCURSOR)
is
BEGIN
OPEN p_cursor FOR
select sampl1,sample2,sample3
from
table_test b
where
rec_id='A'
and sample3=ACCT_NO ;
END;

If you want a return better use function here are some example to get collection
CREATE TABLE table_test
(
sample1 VARCHAR2 (1000),
sample2 VARCHAR2 (1000),
sample3 VARCHAR2 (1000)
);
insert into table_test ( sample1,sample2 ,sample3)
values ('daftest1','dsdtest1','sstsest3');
insert into table_test ( sample1,sample2 ,sample3)
values ('FAStest1','fstest1','sstsest3');
insert into table_test ( sample1,sample2 ,sample3)
values ('sdtest1','asdtest1','fstest3');
insert into table_test ( sample1,sample2 ,sample3)
values ('test2','test2','test123');
CREATE OR REPLACE TYPE TEST_REC
AS OBJECT (
sample1 VARCHAR2(1000)
,sample2 VARCHAR2(1000)
,sample3 VARCHAR2(1000)
);
CREATE OR REPLACE TYPE TEST_REPORT_TABLE
AS TABLE OF TEST_REC;
CREATE OR REPLACE FUNCTION testing (p_acct_no IN varchar2)
RETURN test_report_table
IS
v_rec test_rec;
v_test_report_table test_report_table := test_report_table();
BEGIN
FOR i IN (SELECT sample1,sample2,sample3
FROM table_test b
--where rec_id='A'
where sample3=p_acct_no)
LOOP
v_rec:=test_rec(NULL,NULL,NULL);
dbms_output.put_line(i.sample1);
v_rec.sample1:=i.sample1;
v_rec.sample2:=i.sample2;
v_rec.sample3:=i.sample3;
v_test_report_table.EXTEND;
v_test_report_table(v_test_report_table.COUNT) :=v_rec;
END LOOP;
RETURN v_test_report_table;
END;
select * from table(testing(p_acct_no=>'sstsest3'))
Or better use bulk collect if you don't need to add rows dynamically
CREATE OR REPLACE FUNCTION JSTRAUTI.testing (p_acct_no IN varchar2)
RETURN test_report_table
IS
v_test_report_table test_report_table := test_report_table();
BEGIN
SELECT test_rec(sample1,sample2,sample3)
bulk collect into v_test_report_table
FROM table_test b
--where rec_id='A'
where sample3=p_acct_no;
RETURN v_test_report_table;
END;
result the same.

Related

oracle sql : "get or insert" stored procedure

I would like to do a stored procedure that receive an input param and then
if targeted table does not contains that value, a new row is created and then the id of the created row is returned
if targeted table already contain input param, the id of the row is returned
For moment I only manage to insert new row only if input param is new:
--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;
Do you know how to do this?
Seems to me like you want a stored function and not a procedure.
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;
This is a possible solution to your problem.
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;
you can test the procedure like so.
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;

Procedure to Insert into table and its columns by given parameters?

i`ll start this with some code...
CREATE OR REPLACE PROCEDURE LOAD_IMAGE_INTO_TABLE (
imgDir varchar2
, imgName varchar2
, destTable varchar2
, destIndex varchar2
, destBlob varchar2)
AS
fHnd bfile;
b blob;
srcOffset integer := 1;
dstOffset integer := 1;
BEGIN
dbms_lob.CreateTemporary( b, true );
fHnd := BFilename( imgDir, imgName );
dbms_lob.FileOpen( fHnd, DBMS_LOB.FILE_READONLY );
dbms_lob.LoadFromFile( b, fHnd, DBMS_LOB.LOBMAXSIZE, dstOffset, srcOffset );
--insert into (Select * From user_tables Where table_name = destTable) values(imgName,b);
--insert into destTable (destIndex, destBlob) values( imgName, b );
commit;
dbms_lob.FileClose( fHnd );
END LOAD_IMAGE_INTO_TABLE;
As you might see, I am trying to create a procedure which puts an image into a table. Target table name and column names (for imgname and blobfile) will be given as parameters.
Both ways I tried didn't work. (see --insert(...) in code)
Maybe you have any idea how to solve this?
Thanks in advance.

Oracle: dynamic SQL statement based on a mapping table

Take the following statements in order to create the context in this page:
BEGIN TRANSACTION;
CREATE TABLE TABLEA (COLUMN_A VARCHAR2(30));
CREATE TABLE TABLEB (COLUMN_B VARCHAR2(30));
CREATE TABLE MAPPING_TABLE (TABLEA_COL VARCHAR2(30), TABLEB_COL VARCHAR2(30));
INSERT INTO MAPPING_TABLE (TABLEA_COL, TABLEB_COL) VALUES ('COLUMN_A', 'COLUMN_B');
COMMIT;
I want to make a select from TABLEB using the mapping value setted in the MAPPING_TABLE.
In other words, knowing the name of the column of the TABLEA (for example 'COLUMN_A'), I want to make a SELECT directly in the TABLEB.
Something like:
SELECT /*a statement to recover the COLUMN_B based on the 'COLUMN_A' value*/
FROM TABLEB
It is possible to do in SQL statement, or I'm forced to use PL/SQL context (with procedures, etc...)?
Try this,
declare
v_col varchar(30);
v_val varchar(30);
sql_stmt varchar(255);
begin
select tableb_col into v_col
from mapping_table
where tablea_col = 'COLUMN_A';
sql_stmt := 'select '||v_col||' from tableb';
dbms_output.put_line ( sql_stmt ) ;
execute immediate sql_stmt into l_val;
dbms_output.put_line ( v_val) ;
end;

Create and populate Varray in Oracle SQL

I'm trying to créate a Varray of beans type and populate it, but I'm in a hurry and don't find any usefull example.
arr=[[1,'A'],[2,'B'],[3,'C']]
This is my code:
create table my_table (NUM_OPERACIO NUMBER,TITULS varchar2(3)) ;
insert into my_table values(1,'A');
insert into my_table values(2,'B');
insert into my_table values(3,'C');
create TYPE item IS object( NUM_OPERACIO NUMBER, TITULS varchar2(3));
/
create TYPE arr IS VARRAY(10) OF item;
/
insert into arr values( select NUM_OPERACIO, TITULS from my_table);
FOR i IN 1..3 loop
dbms_output.put_line(arr (i));
END loop;
Help me achive this, please.
Thanks in advance
Oracle Setup:
create table my_table (NUM_OPERACIO NUMBER,TITULS varchar2(3)) ;
insert into my_table values(1,'A');
insert into my_table values(2,'B');
insert into my_table values(3,'C');
CREATE TYPE item IS object( NUM_OPERACIO NUMBER, TITULS varchar2(3));
/
CREATE TYPE item_array IS VARRAY(10) OF item;
/
PL/SQL:
DECLARE
arr item_array;
BEGIN
SELECT item( NUM_OPERACIO,TITULS )
BULK COLLECT INTO arr
FROM my_table;
FOR i IN 1..arr.COUNT loop
dbms_output.put_line(arr(i).NUM_OPERACIO || ', ' || arr(i).TITULS);
END loop;
END;
/

select forall array in sql statement(PL/SQL)

Type tabArray IS TABLE OF TABLE%ROWTYPE;
tableArray tabArray ;
--fill array
SELECT *
BULK COLLECT INTO tableArray
FROM TABLE
WHERE TABLE.field = ....
--work
FOR pos IN 1..tableArray .count
LOOP
dbms_output.put_line(pos||' '||audArray(pos).field);
end loop;
--doesn't work
SELECT * TABLE2
WHERE TABLE2.field in (SELECT filed FROM FORALL tableArray );
Main question: how can I use my array in sql statement (in) ?
First you have to create a type in SQL then can use as given below
CREATE TYPE FRUIT_TT AS TABLE OF VARCHAR2(100)
SELECT column_value AS val
FROM TABLE(FRUIT_TT('Apple','Banana','Apricot'))
WHERE column_value NOT LIKE 'A%';
Here a type FRUIT_TT is created and using it in SQL query.
Here is an example, you just need to adjust your SQL statement.
CREATE TYPE col_ntt IS TABLE OF NUMBER;
CREATE TABLE num_tab
(
col NUMBER
);
INSERT INTO num_tab VALUES(1);
INSERT INTO num_tab VALUES(2);
INSERT INTO num_tab VALUES(4);
DECLARE
l_col1 col_ntt := col_ntt(1, 2, 3);
l_col2 col_ntt;
BEGIN
SELECT *
BULK COLLECT INTO l_col2
FROM num_tab
WHERE col IN (SELECT column_value FROM TABLE(l_col1));
FOR indx IN 1..l_col2.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(l_col2(indx));
END LOOP;
END;
/*
1
2
*/