How do you update a SQL record with ORDSYS.ORDImage in a procedure - sql

I'm trying to create a procedure that will update a column in my table with an ORDSYS.ORD Image. The code I have is bellow and it keeps telling me errors when I'm trying to use it. Can some please help? Thank you
Procedure code:
create or replace
PROCEDURE Inserting_Images (REST_ID NUMBER, RESTImage ORDSYS.ORDImage) AS
ctx RAW(64):=NULL;
BEGIN
UPDATE restaurant_table
Set RESTImage = RESTImage
WHERE REST_id = REST_ID;
COMMIT;
EXCEPTION
WHEN others THEN
BEGIN
ROLLBACK;
dbms_output.put_line(sqlerrm);
END;
--Error Handling.
END;
--Ends the procedure.
Using Procedure:
BEGIN
inserting_images(52, 'YUSKIN.jpeg');
END;

The function Inserting_Images accepts an argument of ORDSYS.ORDImage, whereas what you are actually sending it is a VARCHAR, to get the behaviour you want, you need to initialize the ORDImage object first like so:
CREATE OR REPLACE DIRECTORY FILE_DIR as '/mydir/work';
GRANT READ ON DIRECTORY FILE_DIR TO 'user';
inserting_images(52, ORDSYS.ORDImage.init('FILE', 'FILE_DIR','speaker.jpg'));
(Quoted from docs.oracle.com)

Related

Invalid identifier error while running plsql block

Since my school does not allow me to post the code, hence i had to come back home and put up an example to show the issue i am facing. My school asked me to do a homework on dynamic sql to create a table and later insert one dummy record to it. But while doing it I am facing the below issue. Please find the code below for your reference. Thank you.
Procedure:
create or replace procedure table_creation(table_name in varchar2,col1 varchar2,col2 varchar2)
is
l_stat varchar2(3000);
v_stat varchar2(1000);
a varchar2(10):='1';
b varchar2(10):='Dummy';
begin
l_stat:='create table '||table_name||' ("'||col1||'" varchar2(10),"'||col2||'" varchar2(10))';
execute immediate l_stat;
execute immediate 'insert into '||table_name||'('||col1||','||col2||') values (:x,:y)' using a,b;
end;
/
Plsql Block to call the procedure:
set serveroutput on;
declare
a varchar2(10);
b varchar2(10);
c varchar2(10);
begin
a:='Example';
b:='id';
c:='nm';
table_creation(a,b,c);
dbms_output.put_line('Yes');
end;
/
The procedure is getting created perfectly and while running the above block i am getting the below error .
declare
*
ERROR at line 1:
ORA-00904: "NM": invalid identifier
ORA-06512: at "SYS.TABLE_CREATION", line 9
ORA-06512: at line 9
But when I checked the created table. The table exists with 0 records. The structure of the table is as follows.
Name Null? Type
----------------------------------------- -------- ---------------
ID VARCHAR2(10)
NM VARCHAR2(10)
Any help from your end is much appreciated.
Nick,
Please note that the above procedure will create the column with a double qoutes ("ID","NM") hence the error occurred. Please find the updated code and check if the issue has resolved.
According to oracle=>
Oracle is case sensitive in column and table names. It just converts everything to upper case by default. But if you use names in double quotes, you tell Oracle to create the column in the exact spelling you provided (lower case in the CREATE statement).
Code:
create or replace procedure table_creation(table_name in varchar2,col1 varchar2,col2 varchar2)
is
l_stat varchar2(3000);
v_stat varchar2(1000);
a varchar2(10):='1';
b varchar2(10):='Dummy';
begin
l_stat:='create table '||table_name||' ('||col1||' varchar2(10),'||col2||' varchar2(10))';
execute immediate l_stat;
execute immediate 'insert into '||table_name||'('||col1||','||col2||') values (:x,:y)' using a,b;
end;
/
Note: I have not touched any other logic of the code. Please try and let us know the result.
Only change is
From :
l_stat:='create table '||table_name||' ("'||col1||'" varchar2(10),"'||col2||'" varchar2(10))';
to :
l_stat:='create table '||table_name||' ('||col1||' varchar2(10),'||col2||' varchar2(10))';

Copying value to actual parameter

I have a pckage plch_pkg as follows
create type plch_number_nt is table of number;
create or replace package plch_pkg
authid definer
is
g_numbers plch_numbers_nt:=plch_numbers_nt(1);
procedure empty_the_nt_fail(numbers_io IN OUT plch_numbers_nt);
procedure empty_the_nt(numbers_io IN OUT plch_numbers_nt);
end plch_pkg;
create or replace package body plch_pkg
is
procedure empty_the_nt_fail(numbers_io in out plch_numbers_nt)
is
begin
dbms_output.put_line('empty_the_nt_fail');
numbers_io.delete;
raise program_error;
end empty_the_nt_fail;
procedure empty_the_nt(numbers_io in out plch_numbers_nt)
is
begin
dbms_output.put_line('empty_the_nt');
numbers_io.delete;
end empty_the_nt;
end plch_pkg;
Later I created this procedure.
create or replace procedure plch_proc
authid definer
is
l_numbers plch_numbers_nt := plch_numbers_nt(1);
procedure show_numbers
is
begin
dbms_output.put_line('count='||l_numbers.count);
end;
begin
plch_pkg.empty_the_nt_fail(l_numbers);
show_numbers;
exception
when others then
show_numbers;
end plch_proc;
Now when i call this procedure as follows
declare
begin
plch_proc;
end;
I get the output as count=0.
This is my understanding. My procedure plch_proc the empty_the_nt_fail procedure in the plch_pkg.After deleting all the elements from numbers_io nested table,it raises an error.
The oracle documentation says that "Only when the procedure has finished without exception is the result value copied back to the formal parameter".
This copying of numbers_io to my actual parameter l_numbers should not happen as the error occured. But when I called the procedure plch_proc,it printed the count as 0,which means that formal parameter value was copied to actual parameter. Could somebody please explain
I found the explaination for copying actual parameters and formal parameters here
https://docs.oracle.com/cd/B10500_01/appdev.920/a96624/08_subs.htm#895
https://docs.oracle.com/cd/B13789_01/appdev.101/b10807/08_subs.htm#i23202
http://www.dba-oracle.com/t_pl_sql_nocopy_data_structures.htm

executing a stored proc with output parameter

I am using SQLDEVELOPER TO make a stored procedure. this is my procedure
create or replace PROCEDURE SPP
(
inpt IN VARCHAR2,
opt OUT VARCHAR2
)
AS
BEGIN
SELECT U_ID
INTO opt
FROM TABLE_NAME
WHERE U_ID=inpt;
END;
so it should return the value in opt which i can then print or whatever.
i dont know how to execute it i tried running this script
var opt VARCHAR2;
exec SPP('test_user') := opt
but it doesnt work this is my first time doing stored procs and I'm really confused any help is appreciated
how do i make it run? i can make a stored proc run with input variables but with an output variable i mess up and I cant do it without using the SELECT (item) INTO format.
In order to call the procedure, you'd need to pass in a variable that the procedure can populate. Something like
DECLARE
l_output table_name.u_id%type;
BEGIN
spp( 'test_user', l_output );
END;
Now, that being said, declaring a stored procedure whose only purpose is to query the database and return a value is generally the wrong architectural choice. That's why functions exist.
CREATE OR REPLACE FUNCTION some_function( p_input IN table_name.u_id%type )
RETURN table_name.u_id%type
IS
l_uid table_name.u_id%type;
BEGIN
SELECT u_id
INTO l_uid
FROM table_name
WHERE u_id = p_input;
RETURN l_uid;
END;
which you can then call either in a PL/SQL block
DECLARE
l_output table_name.u_id%type;
BEGIN
l_output := some_function( 'test_user' );
END;
or in a SQL statement
SELECT some_function( 'test_user' )
FROM dual;

Sending multiple sets of parameters to procedure

I'm using vb.net and oracle db, and currently I have a stored-procedure that is called from my code. Right now it looks similar to this:
CREATE OR REPLACE PROCEDURE MYPROCEDURE(
param1 table.field1%TYPE,
param2 table.field2%TYPE,
param3 table.field3%TYPE,
param4 varchar2,
output OUT number) AS
BEGIN
DO STUFF
END;
I want to ask if it is possible to change this to send multiple sets of parameters at once, so I could use a FOR LOOP inside my procedure to minimize the number of calls. I want to achieve something like this:
CREATE OR REPLACE PROCEDURE MYPROCEDURE(
param myArray
output OUT number) AS
BEGIN
FOR i IN 1..myArray.COUNT LOOP
UPDATE FIELD FROM TABLE WHERE ID = myArray(i).field1;
END LOOP;
END;
Or if there's anything else that would work the same it would be great.
Many thanks.
Yes you can pass a list of objects as parameter in oracle procedure. First you must create the datatype of this list of objects, but you can't do this inside a procedure you have to define it as an oracle object. For example:
CREATE OR REPLACE TYPE TEST."MY_TYPE" AS OBJECT
(PARAM1 VARCHAR (20), PARAM2 NUMBER);
Unfortunately you can define dynamic datatypes inside objects (table.field1%TYPE), but I think you know what datatype this field have.
Second, create a package that have the list of parameter and procedure definition like this:
CREATE OR REPLACE PACKAGE ARRAY_EXAMPLE2
AS
TYPE COL IS TABLE OF MY_TYPE;
PROCEDURE PROCESS_ARRAY (ArrayIn IN COL);
END;
And finally the package implementation
CREATE OR REPLACE PACKAGE BODY ARRAY_EXAMPLE2
AS
PROCEDURE PROCESS_ARRAY (ArrayIn IN COL)
IS
BEGIN
FOR i IN 1 .. ArrayIn.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE ('Hello ' || ArrayIn (i).PARAM1);
END LOOP;
END;
END;
You can try it using this lines of code:
BEGIN
ARRAY_EXAMPLE2.
PROCESS_ARRAY (
array_example2.
COL (MY_TYPE ('Peter', 12),
MY_TYPE ('Jorge', 4),
MY_TYPE ('Bryan', 5)));
END;

Calling a stored procedure in Oracle with IN and OUT parameters

I have this procedure:
CREATE OR REPLACE PROCEDURE PROC1(invoicenr IN NUMBER, amnt OUT NUMBER)
AS BEGIN
SELECT AMOUNT INTO amnt FROM INVOICE WHERE INVOICE_NR = invoicenr;
END;
So when I run it like this it returns absolutely nothing:
DECLARE
amount NUMBER;
BEGIN
PROC1(1000001, amount);
dbms_output.put_line(amount);
END;
BTW I use DreamCoder for Oracle. Is there a problem with the procedure itself or with the way I call it? There is an entry in the INVOICE table with INVOICE_NR equal to 1000001.
If you set the server output in ON mode before the entire code, it works, otherwise put_line() will not work. Try it!
The code is,
set serveroutput on;
CREATE OR REPLACE PROCEDURE PROC1(invoicenr IN NUMBER, amnt OUT NUMBER)
AS BEGIN
SELECT AMOUNT INTO amnt FROM INVOICE WHERE INVOICE_NR = invoicenr;
END;
And then call the function as it is:
DECLARE
amount NUMBER;
BEGIN
PROC1(1000001, amount);
dbms_output.put_line(amount);
END;
I had the same problem. I used a trigger and in that trigger I called a procedure which computed some values into 2 OUT variables. When I tried to print the result in the trigger body, nothing showed on screen. But then I solved this problem by making 2 local variables in a function, computed what I need with them and finally, copied those variables in your OUT procedure variables. I hope it'll be useful and successful!
Go to Menu Tool -> SQL Output, Run the PL/SQL statement,
the output will show on SQL Output panel.
As per my knowledge, a colon (":") should precede any output variable while executing stored procedures, so invocation should look like this: PROC1(1000001, :amount);
DECLARE
amount NUMBER;
BEGIN
PROC1(1000001, :amount);
dbms_output.put_line(amount);
END;
/
hope this helps