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
Related
I'm trying to return the number of rows per invoice_id using a function and procedure. Some invoice_id's have more than one row and I'm not sure how to fetch the count when I execute my procedure. As an example invoice_id(7) has just one row, but invoice_id(100) has four rows of information.
Create or replace function return_num_rows_function(invoice_id_text in varchar2)
Return varchar2
Is inv_id varchar2(20);
Begin
Select count(*)invoice_id into inv_id from invoice_line_items where invoice_id=invoice_id_text;
Return inv_id;
End;
Create or replace procedure return_num_rows (invoice_id_text in varchar2)
Is inv_id varchar(20);
line_item_desc invoice_line_items.line_item_description%type;
Begin
inv_id := return_num_rows_function(invoice_id_text);
If inv_id is not null then
Select count(*)invoice_id, line_item_description into inv_id,line_item_desc
From invoice_line_items where invoice_id = inv_id;
dbms_output.put_line('The number of rows returned:'|| inv_id);
dbms_output.put_line('Item description(s):'|| line_item_desc);
End if;
End;
set serveroutput on;
execute return_num_rows(7);
First of all do not use a string type variable for a numeric one
(invoice_id_text).
For your case it's better to use a procedure instead of called
function ( return_num_rows_function ), since you need two out
arguments returned.
A SQL Select statement cannot be used without Group By with aggegated and non-aggregated columns together ( i.e. don't use this one :
Select count(*) invoice_id, line_item_description
into inv_id,line_item_desc
From invoice_line_items
Where invoice_id = inv_id;
)
So, Try to create below procedures :
SQL> CREATE OR REPLACE Procedure
return_num_rows_proc(
i_invoice_id invoice_line_items.invoice_id%type,
inv_id out pls_integer,
line_item_desc out invoice_line_items.line_item_description%type
) Is
Begin
for c in
(
Select line_item_description
into line_item_desc
From invoice_line_items
Where invoice_id = i_invoice_id
)
loop
line_item_desc := line_item_desc||' '||c.line_item_description;
inv_id := nvl(inv_id,0) + 1;
end loop;
End;
/
SQL> CREATE OR REPLACE Procedure
return_num_rows(
i_invoice_id pls_integer
) Is
inv_id pls_integer;
line_item_desc invoice_line_items.line_item_description%type;
Begin
return_num_rows_proc(i_invoice_id,inv_id,line_item_desc);
If inv_id is not null then
dbms_output.put_line('The number of rows returned:' || inv_id);
dbms_output.put_line('Item description(s):' || line_item_desc);
End if;
End;
/
and call as in your case :
SQL> set serveroutput on;
SQL> execute return_num_rows(7);
Replace inv_id varchar2(20) with inv_id number;
and also if you want to get two outputs from procedure better to use refcursor.
I am trying to execute a simple proc Like this in oracle 10g but not able to do getting error PLS-00905: object dbnew.sp_TDCCountry is invalid any idea would be appreciated
Table
CREATE TABLE TDCCountry
( CountryID number(10) NOT NULL,
CountryName varchar2(50) NOT NULL
);
Procedure
CREATE OR REPLACE PROCEDURE SP_TDCCountry
IS
BEGIN
select * from tdcCountry;
COMMIT;
END SP_TDCCountry;
Execution
1.
begin
SP_TDCCountry;
end;
2.exec SP_TDCCountry;
Because you do not have an into clause by which you return values to some variables. It may be proper to return your variable as a rowtype [ By the way a commit is not needed for a non-DDL( in this case, there's a SELECT) statement ].
So, You may use in the following way :
SQL> set serveroutput on;
SQL> CREATE OR REPLACE PROCEDURE SP_TDCCountry IS
v_row tdcCountry%rowtype;
BEGIN
select * into v_row from tdcCountry;
dbms_output.put(v_row.countryid||' - ');
dbms_output.put_line(v_row.countryname);
END;
/
SQL> exec SP_TDCCountry;
If your SELECT statement brings more than one row, then it's proper to return data by means of cursor :
SQL> CREATE OR REPLACE PROCEDURE SP_TDCCountry IS
v_row tdcCountry%rowtype;
BEGIN
for c in ( select * from tdcCountry )
loop
dbms_output.put(c.countryid||' - ');
dbms_output.put_line(c.countryname);
end loop;
END;
/
SQL> exec SP_TDCCountry;
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);
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 ?
I need to write a procedure to input let's say a rep_id and then output the rep_name that corresponds to the rep_id.
After that, I need to use another procedure to call the above procedure.
Here is what I have for the first procedure.
create or replace procedure p_inout
(v_rep_id in number)
As
v_first_name varchar2(20);
v_last_name varchar2(20);
begin
select first_name,last_name into v_first_name, v_last_name
from rep
where rep_id = v_rep_id;
dbms_output.put_line(v_first_name||' '||v_last_name);
end p_inout;
/
Execute p_inout(100);
And here is my procedure to call the above procedure
create or replace procedure p_call
is
v_first_name varchar2(20);
v_last_name varchar2(20);
begin
p_inout(100);
dbms_output.put_line(v_first_name||' '||v_last_name);
end p_call;
/
execute p_call
I was able to get the result but one guy told me that my call procedure should be like this
Create or replace procedure p_call
Is
V_name varchar2(20);
Begin
P_inout(100,v_name); --100 is a rep id
Dbms_output.Put_line(v_name);
End;
/
Execute p_call
Doesn't my procedure to call and his call procedure produce the same result?
CREATE TABLE minions (
rep_id DATE CONSTRAINT minions__rep_id__pk PRIMARY KEY,
rep_name NUMBER CONSTRAINT minions__rep_name__nn NOT NULL
CONSTRAINT minions__rep_name__u UNIQUE
)
/
CREATE OR REPLACE PROCEDURE myCatWasSick (
p_rep_id IN minions.rep_id%TYPE,
p_rep_name OUT minions.rep_name%TYPE
)
IS
BEGIN
SELECT rep_name
INTO p_rep_name
FROM minions
WHERE rep_id = p_rep_id;
EXCEPTION
WHEN NO_DATA_FOUND THEN
p_rep_name := NULL;
END myCatWasSick;
/
CREATE OR REPLACE PROCEDURE releaseTheBadgers
IS
the_badger NUMBER(10);
BEGIN
myCatWasSick( SYSDATE + 1, the_badger );
// Do something with the_badger.
END releaseTheBadgers;
/