error:PL/SQL: ORA-00904: : invalid identifier - oracle

CREATE OR REPLACE PACKAGE pls_check2 AS
PROCEDURE check_proc(p_item_cat NUMBER,
p_sub_cat NUMBER,
p_pack_is NUMBER,
p_pack_name NUMBER,
v1 OUT NUMBER,
v2 OUT NUMBER,
v3 OUT NUMBER,
v4 OUT NUMBER);
PROCEDURE package_info1(param1 NUMBER, param2 NUMBER, param3 NUMBER);
END pls_check2;
CREATE OR REPLACE PACKAGE BODY pls_check2 AS
v1 NUMBER;
v2 NUMBER;
v3 NUMBER;
v4 NUMBER;
PROCEDURE check_proc(p_item_cat NUMBER,
p_sub_cat NUMBER,
p_pack_is NUMBER,
p_pack_name NUMBER,
v1 OUT NUMBER,
v2 OUT NUMBER,
v3 OUT NUMBER,
v4 OUT NUMBER) IS
CURSOR c1 IS
SELECT ic.id
FROM itemcategory ic
WHERE ic.id = p_item_cat;
BEGIN
v1 := p_item_cat;
v2 := p_sub_cat;
v3 := p_pack_is;
v4 := p_pack_name;
FOR c_p IN c1 LOOP
INSERT INTO master_product_table
(SELECT NULL,
NULL,
package_info1(c_p.id, v2, v3)
FROM package);
END LOOP;
DBMS_OUTPUT.put_line('hello');
END;
PROCEDURE package_info1(param1 NUMBER, param2 NUMBER, param3 NUMBER) IS
v_is_incentivized VARCHAR2(20);
BEGIN
SELECT is_incentivized
INTO v_is_incentivized
FROM package pk
WHERE pk.id = 1;
DBMS_OUTPUT.put_line('hi');
END;
END pls_check2;
On compilation following error comes:
Error(18,1): PL/SQL: SQL Statement ignored
Error(33,7): PL/SQL: ORA-00904: : invalid identifier

You're trying to call a PROCEDURE from SQL. That's not allowed (because it doesn't really make sense). Change package_info1 to
function package_info1(param1 NUMBER, param2 NUMBER, param3 NUMBER)
return number;
in the package header and to
function package_info1(param1 NUMBER, param2 NUMBER, param3 NUMBER)
return number IS
v_is_incentivized VARCHAR2(20);
BEGIN
SELECT is_incentivized
INTO v_is_incentivized
FROM package pk
WHERE pk.id = 1;
DBMS_OUTPUT.put_line('hi');
RETURN 1;
END;
in the package body, and it will compile. Nevertheless, I'd really recommend you rename your PACKAGE table - that name is going to cause you pain without 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

How to make recursive a pl/sql code block which one work with several selects sentences?

I have a pl/sql code block I'd like to improve. It's the next:
SELECT REPLACE(v_tx_cuerpo, '${param1}', rec.param1)
INTO v_tx_cuerpo
from DUAL;
SELECT REPLACE(v_tx_cuerpo, '${param2}', rec.param2)
INTO v_tx_cuerpo
from DUAL;
SELECT REPLACE(v_tx_cuerpo, '${param3}', rec.param3)
INTO v_tx_cuerpo
from DUAL;
SELECT REPLACE(v_tx_cuerpo, '${param4}', rec.param4)
INTO v_tx_cuerpo
from DUAL;
SELECT REPLACE(v_tx_cuerpo, '${param5}', rec.param5)
INTO v_tx_cuerpo
from DUAL;
As you see, it's repetitive. I'll explain it. v_tx_cuerpo is a text block which has some similar parameters. I want to replace them for some specific values. Each one of this parameters have names ${param#} and each one must be replace by one specific value .
What I'd like is, can run it in a loop, make it recursive. Can someone helpme whit this?
You haven't described your rec type, so I'll show an example how to make it more independent:
declare
type t_rec is record(
param1 varchar2(30),
param2 varchar2(30),
param3 varchar2(30),
param4 varchar2(30),
param5 varchar2(30)
);
rec t_rec;
v_tx_cuerpo varchar2(4000);
function f_subst(str varchar2, template varchar2, subst ora_name_list_t) return varchar2
as
res varchar2(32767):=str;
begin
for i in 1..subst.count loop
res:=replace(res, replace(template,'%d',i), subst(i));
end loop;
return res;
end;
begin
v_tx_cuerpo:='p1:${param1};p2:${param2};p3:${param3};p4:${param4};p5:${param5};';
v_tx_cuerpo:=f_subst(
v_tx_cuerpo,
'${param%d}',
ora_name_list_t('str1','str2','str3','str4','str5')
);
dbms_output.put_line(v_tx_cuerpo);
end;
/
as you can see I've created function f_subst that takes 3 arguments:
str varchar2 - input string for replacement
template varchar2 - string mask for replacement, in your example it's ${param%d}
subst ora_name_list_t - that is a collection defined as TYPE ora_name_list_t IS TABLE OF VARCHAR2(2*(ORA_MAX_NAME_LEN+2)+1), so you can specify any number of string for replacement. In this example, I've put str1 to str5.
So this function iterates input collection elements and replaces any substrings that match an input template mask with the value from this collection.
Results:
p1:str1;p2:str2;p3:str3;p4:str4;p5:str5;
And finally using your original rec:
declare
type t_rec is record(
param1 varchar2(30),
param2 varchar2(30),
param3 varchar2(30),
param4 varchar2(30),
param5 varchar2(30)
);
rec t_rec;
v_tx_cuerpo varchar2(4000);
function f_subst(str varchar2, template varchar2, subst ora_name_list_t) return varchar2
as
res varchar2(32767):=str;
begin
for i in 1..subst.count loop
res:=replace(res, replace(template,'%d',i), subst(i));
end loop;
return res;
end;
begin
v_tx_cuerpo:='p1:${param1};p2:${param2};p3:${param3};p4:${param4};p5:${param5};';
rec.param1:='str1';
rec.param2:='str2';
rec.param3:='str3';
rec.param4:='str4';
rec.param5:='str5';
v_tx_cuerpo:=f_subst(
v_tx_cuerpo,
'${param%d}',
ora_name_list_t(
rec.param1,
rec.param2,
rec.param3,
rec.param4,
rec.param5
)
);
dbms_output.put_line(v_tx_cuerpo);
end;
/

how to pass object type as a parameter in oracle

below abstarct type created
create or replace TYPE callbck as table of callback_t;
abstract table
create or replace TYPE CALLBACK_T as object
(
url varchar2(50),
uri_key number,
);
below is the procedure used,
procedure get_callback_info
(
pi_clbk callbck := callbck (),
requestor varchar2,
msg varchar2)
how to pass the parameter for the abstract object type to the procedure get_callback_info.
i have the abstract values 'http://test.com', and 1345 as the url and uri_key
Say you have these types and procedure:
CREATE OR REPLACE TYPE CALLBACK_T AS OBJECT
(
url VARCHAR2(50),
uri_key NUMBER
);
CREATE OR REPLACE TYPE callbck AS TABLE OF callback_t;
CREATE OR REPLACE PROCEDURE get_callback_info(
pi_clbk IN callbck := callbck(),
requestor IN VARCHAR2,
msg OUT VARCHAR2
) IS
BEGIN
/* whatever your code is */
msg := requestor || ' asked information on callbck with ' || pi_clbk.COUNT || ' elements';
END;
You can test your procedure with something like:
declare
vCallbck callbck;
vRequestor varchar2(20) := 'a requestor';
vMsg varchar2(100);
begin
/* populate the vCallbck with 10 records */
select CALLBACK_T ('url ' || level, level)
bulk collect into vCallbck
from dual
connect by level <= 10;
--
get_callback_info(vCallbck, vRequestor, vMsg);
--
dbms_output.put_line(vMsg);
end;
/
If you want to test with a single value, you can use:
declare
vCallbck callbck;
vRequestor varchar2(20);
vMsg varchar2(100);
begin
vCallbck := callbck();
vCallbck.extend(1);
vCallbck(1) := CALLBACK_T('http://test.com', '1345');
--
get_callback_info(vCallbck, vRequestor, vMsg);
--
dbms_output.put_line(vMsg);
end;
/

Procedure to input number and output varchar2

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;
/

Number of args for stored procedure PLS-00306

I have problem with calling for my procedure. Oracle scrams
PLS-00306 Error: Wrong number of types of arguments in call to procedure.
With my type declaration procedure has exact the same declaration like in header below. If I run it as separate procedure it works, when i work in ODCI interface for extensible index creation, it throws PLS-00306.
MEMBER PROCEDURE FILL_TREE_LVL
(target_column VARCHAR2, cur_lvl NUMBER, max_lvl NUMBER,
parent_rect NUMBER,start_x NUMBER, start_y NUMBER,
end_x NUMBER, end_y NUMBER)
IS
stmt VARCHAR2(2000);
rect_id NUMBER;
diff_x NUMBER;
diff_y NUMBER;
new_start_x NUMBER;
new_end_x NUMBER;
i NUMBER;
j NUMBER;
BEGIN
{...}
END FILL_TREE_LVL;
STATIC FUNCTION ODCIINDEXCREATE
(ia SYS.ODCIINDEXINFO, parms VARCHAR2, env SYS.ODCIEnv) RETURN NUMBER
IS
stmt VARCHAR2(2000);
stmt2 VARCHAR2(2000);
min_x NUMBER;
max_x NUMBER;
min_y NUMBER;
max_y NUMBER;
lvl NUMBER;
rect_id NUMBER;
pt_tab VARCHAR2(50);
rect_tab VARCHAR2(50);
cnum NUMBER;
TYPE point_rect is RECORD(
point_id NUMBER,
rect_id NUMBER
);
TYPE point_rect_tab IS TABLE OF point_rect;
pr_table point_rect_tab;
BEGIN
{...}
FILL_TREE_LVL('any string', 0, lvl,0, min_x, min_y, max_x, max_y);
{...}
END;
I have no experience in PL/SQL OOP, but I guess the problem occurs because you try to call a member procedure from a static function. A member procedure always needs an object context, which is lacking in the call.
Looks like you're missing a parameter, probably parent_rect I'm guessing:
FILL_TREE_LVL(target_column VARCHAR2,
cur_lvl NUMBER,
max_lvl NUMBER,
parent_rect NUMBER,
start_x NUMBER,
start_y NUMBER,
end_x NUMBER,
end_y NUMBER)
FILL_TREE_LVL('any string', --target_column
0, --cur_lvl
lvl, --max_lvl
min_x, --parent_rect
min_y, --start_x
max_x, --start_y
max_y --end_x
--end_y ???
);

Resources