Read SQL procedure from script file, Oracle - oracle

How can I read a stored procedure from a .sql file? Example of this file's content:
create or replace procedure insert(p_t varchar(20), p_e varchar(10), out p_id number)
as begin
insert into instrument(type, status) values (p_t, p_e);
commit;
select max(id) from instrument into p_id;
end /
...other procedures...
I want this procedure to be created when I use the command #"filepath", but instead of doing so, Oracle executes the content of the procedure.
I would like to create all my procedures reading the file I made, any ideas?.

Firstly, please don't call your procedure INSERT. I'd be horrified if this actually compiled.
Secondly, you seem to be missing a semi-colon after end; and you need to put the / on a new line:
create or replace procedure insert_instrument (
p_t varchar(20), p_e varchar(10), out p_id number ) as
begin
insert into instrument(type, status) values (p_t, p_e);
commit;
select max(id) from instrument into p_id;
end;
/
You could simplify this using the RETURNING INTO clause; it saves an extra SELECT and so will operate quicker:
create or replace procedure insert_instrument (
p_t varchar(20), p_e varchar(10), out p_id number ) as
begin
insert into instrument(type, status)
values (p_t, p_e)
returning id into p_id;
commit;
end;
/

Related

stored procedure compiled with errors

I have a stored procedure where I am trying to take 2 input age and name
That will update the record in employee table.
But when I am compiling getting - compiled with errors
Code :
CREATE OR REPLACE PROCEDURE update_emp_age
(
v_age in number;
v_ename in varchar2(255 char);
) AS
BEGIN
UPDATE employee
SET
eage = v_age
WHERE
ename = v_ename;
ROLLBACK;
END;
Remove the size from the data types in the signature.
Use commas and not semi-colons between arguments in the signature.
Don't ROLLBACK (else your query will perform the update and then immediately ROLLBACK the change doing lots of work for no effect and potentially rolling back prior chages).
Like this:
CREATE OR REPLACE PROCEDURE update_emp_age
(
v_age in NUMBER,
v_ename in VARCHAR2
) AS
BEGIN
UPDATE employee
SET eage = v_age
WHERE ename = v_ename;
END;
/
You could also use %TYPE in the signature:
CREATE OR REPLACE PROCEDURE update_emp_age
(
v_age in EMPLOYEE.EAGE%TYPE,
v_ename in EMPLOYEE.ENAME%TYPE
) AS
BEGIN
UPDATE employee
SET eage = v_age
WHERE ename = v_ename;
END;
/
db<>fiddle here

provide Select statement in procedure parameter

Hi i'm working on this query in oracle and i need to provide many id to a procedure from a table. how can i provide each id from a table to my procedure. sory i'm kinda new at this im completely lost i dont know what to search.
here's
Procedure
PROCEDURE procedname(in_id in VARCHAR2)
select id from mytable
Here's what i tryed
execute procedname(select id from mytable);
but did no work
Is there a way to achive this?
Hope somone help me out with this
You can pass a collection of numbers. Here is an example on how to pass.
--sys.odcinumberlist is a collection which can hold numbers..
create procedure sp_test(i_id in sys.odcinumberlist)
as
l_cnt int;
begin
select count(*)
into l_cnt
from TABLE(i_id); /* the TABLE keyword is used to unfold the collection of numbers as rows..*/
dbms_output.put_line(l_cnt);
end;
/
--calling the stored procedure
begin
dbms_output.enable;
sp_test(sys.odcinumberlist(1,2,3,4,5,6)); /* here i am passing a list of numbers from 1 to 6*/
--the procedure will count the number of elements in the input collection which is 6
end;
/
You cannot directly use a SQL statement as an argument for a procedure or function. Since that needs an INTO clause in order to return the content of the SELECT statement. Your case suggests a CURSOR as needs to return all the records at a time. For this, a possible sample solution using SYS_REFCURSOR as an IN/OUT(or just OUT) type of parameter would be ;
SQL> CREATE TABLE mytable( id VARCHAR2(1) );
SQL> INSERT INTO mytable VALUES('A');
SQL> INSERT INTO mytable VALUES('B');
SQL> CREATE OR REPLACE PROCEDURE Convert_ID(p_myrecordset IN OUT SYS_REFCURSOR) AS
BEGIN
OPEN p_myrecordset FOR
SELECT id, ASCII( id )
FROM mytable
ORDER BY id;
END;
/
SQL> SET SERVEROUTPUT ON;
SQL> DECLARE
l_cursor SYS_REFCURSOR;
l_value1 mytable.id%TYPE;
l_value2 INT;
BEGIN
Convert_ID(p_myrecordset => l_cursor);
LOOP
FETCH l_cursor
INTO l_value1, l_value2;
EXIT WHEN l_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(l_value1 || ' - ' || l_value2 );
END LOOP;
CLOSE l_cursor;
END;
/
A - 65
B - 66
Demo
To take each id from some table and call sometable(id), a PL/SQL loop would be something like this:
begin
for r in (
select id from sometable
)
loop
procedname(r.id);
end loop;
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);

oracle pl/sql issue on procedure way of execution

I have a scenario I have a table t1 which has two table names they are san and man. And now the two tables san, man each table has multiple table filenames like table san has two file names (audi.txt ,mercedes.txt) and the second table man has one file name (hundai.txt). I wrote a procedure where it can return number of rows in the which are present in the respective table with the respective file name. Here is the procedure:
:sql queries
-- for creating t1 table--
CREATE TABLE HR.T1
(
NAMES VARCHAR2(20 BYTE),
MAPPING_ID VARCHAR2(10 BYTE)
);
SET DEFINE OFF;
Insert into HR.T1
(NAMES, MAPPING_ID)
Values
('san', '1');
Insert into HR.T1
(NAMES, MAPPING_ID)
Values
('man', '1');
COMMIT;
-----------sql query for 'san' table----
CREATE TABLE HR.SAN
(
SRC_FILENAME VARCHAR2(20 BYTE)
);
SET DEFINE OFF;
Insert into HR.SAN
(SRC_FILENAME)
Values
('audi.txt');
Insert into HR.SAN
(SRC_FILENAME)
Values
('mercedes.txt');
COMMIT;
------sql query for man table ----
CREATE TABLE HR.MAN
(
SRC_FILENAME VARCHAR2(20 BYTE)
);
SET DEFINE OFF;
Insert into HR.MAN
(SRC_FILENAME)
Values
('hundai.txt');
COMMIT;
-------package spec -----
CREATE OR REPLACE PACKAGE HR.file_entry
AS
PROCEDURE PKG_PROC_FILES(L_MAPPING_ID NUMBER);
procedure insert_proc (l_object_name VARCHAR2);
END;
-----package body -----
CREATE OR REPLACE PACKAGE BODY HR.file_entry
AS
PROCEDURE PKG_PROC_FILES (L_MAPPING_ID NUMBER)
AS
V_TABLE_NAME VARCHAR2 (50);
V_SCHEMA_NAME VARCHAR2 (50);
TYPE CURTYPE IS REF CURSOR;
V_SCHEMA_NAME VARCHAR2 (50);
----
CURSOR TARGET_OBJ_CUR
IS
SELECT DISTINCT names
FROM t1
WHERE MAPPING_ID = L_MAPPING_ID;
BEGIN
FOR I IN TARGET_OBJ_CUR
LOOP
INSERT_PROC (I.names);
DBMS_OUTPUT.PUT_LINE ('TARGET_TABLE_NAME= ' || I.names);
END LOOP;
END;
PROCEDURE INSERT_PROC (L_OBJECT_NAME VARCHAR2)
AS
V_TABLE_NAME VARCHAR2 (50);
V_SCHEMA_NAME VARCHAR2 (50);
V_QUERY VARCHAR2 (50);
TYPE CURTYPE IS REF CURSOR;
V_SRC_FILE_NAMES VARCHAR2 (200);
CUR CURTYPE;
BEGIN
V_QUERY := 'select distinct src_filename from ' || L_OBJECT_NAME;
OPEN CUR FOR V_QUERY;
LOOP
FETCH CUR INTO V_SRC_FILE_NAMES;
DBMS_OUTPUT.PUT_LINE ('SOURCE FILE NAMES 1 = ' || V_SRC_FILE_NAMES);
COMMIT;
EXIT WHEN CUR%NOTFOUND;
END LOOP;
CLOSE CUR;
END;
END;
/
After executing the procedure I have multiple names from DB:
O/P
SOURCE FILE NAMES = mercedes.txt
SOURCE FILE NAMES = audi.txt
SOURCE FILE NAMES = audi.txt
TARGET_TABLE_NAME= san
SOURCE FILE NAMES = hundai.txt
SOURCE FILE NAMES = hundai.txt
TARGET_TABLE_NAME= man
In the below O/P I need to get only distinct source file names from table butI am unable to understand why am I getting the audi.txt and hundai.txt multiple times. Can anyone help me out to solve this issue? I need a file name once to be printed in the output like mercedes.txt which has been printed only once in the output.
EXIT WHEN CUR%NOTFOUND; exit statement needs to be checked after fetch in the INSERT_PROC procedure, not before end loop . And why you use commit after dbms_output.put_line ?

Resources