Variables in PLSQL - oracle

I want to get the value defined in my Procedure as mentioned below.
declare
city varchar2(50) := 'XYZ';
TYPE table_type is table of table_name%rowtype;
var table_type;
begin
select * bulk collect into var from table_name;
DBMS_OUTPUT.PUT_LINE(var(1).field); -- Output is City
I want the output of
DBMS_OUTPUT.PUT_LINE(var(1).field); -- Output is XYZ
How can I achieve this?

First of all, your code does not work. Second, if you are going to recover a variable, you don't need bulk collect
Example
create table mytest ( c1 varchar2(50) ;
insert into mytest values ( 'XYZ' );
commit;
Then
SQL> set serveroutput on
declare
vcity mytest.c1%type := 'XYZ';
var mytest.c1%type;
begin
select c1 into var from mytest where c1=vcity;
DBMS_OUTPUT.PUT_LINE('vcity is '||vcity||' ');
DBMS_OUTPUT.PUT_LINE('var is '||var||' ');
end;
/SQL> 2 3 4 5 6 7 8 9
vcity is XYZ
var is XYZ
PL/SQL procedure successfully completed.
SQL>
vcity is just a variable defined with the type of the column c1, but
assigned to a constant, in this case 'XYZ'
var is the variable which I use to recover the value of c1 in the
table, whatever that value is.
You don't need bulk collect here at all.

Assuming you have several cities to list, you need to define a collection to house them once selected, then a variable of that collection. So for example:
--setup
create table table_name ( id integer
, city varchar2(10)
);
insert into table_name(id, city)
select level, 'City #' || trunc(dbms_random.value( 10, 75 ))
from dual connect by level <= 10;
-- process
declare
type city_list is table of table_name%rowtype;
var city_list;
begin
select *
bulk collect
into var
from table_name;
for r in 1 .. var.count
loop
dbms_output.put_line(var(r).city); -- Output is City
end loop;
end;

Let's keep remain mystery about why you want like this,
If I understood you , to achieve what you want you have to specify columns instead of '*' and replace the variable city with column field.
Dbfiddle link for your reference (unable to provide via link through mobile device)
https://dbfiddle.uk/?rdbms=oracle_18&fiddle=20f1a1fff11d4acda7acc701ad120d32
DECLARE
city varchar2(50) := 'XYZ';
TYPE table1_type is table of table1%rowtype;
var table1_type;
BEGIN
select city,field2,field3,field4
bulk collect into var
from table1;
DBMS_OUTPUT.PUT_LINE(var(1).field);
END;
/

Related

How to insert into oracle custom object from select result?

I have a obj like below
CREATE TYPE SOME_CUSTOM_OBJ FORCE AS OBJECT(
ID number,
Name varchar(30)
)
and want to insert value in that, I read the document for oracle database, but only way that I found is use initial function.
DECLARE
SOME_OBJ SOME_CUSTOM_OBJ;
BEGIN
SOME_OBJ := SOME_CUSTOM_OBJ(1,'PETER');
DBMS_OUTPUT.PUT_LINE(SOME_OBJECT.ID);
END;
// OUTPUT : 1
I want to insert those value from another table, the imagine like below
DECLARE
SOME_OBJECT SOME_CUSTOM_OBJECT;
BEGIN
SOME_OBJECT := SOME_CUSTOM_OBJECT(
SELECT ID,NAME FROM ANTHER_TABLE WHERE {SOME CONDITIONS} AND rownum = 1
);
DBMS_OUTPUT.PUT_LINE(SOME_OBJECT.ID);
END;
// OUTPUT : 1
The value who select from table would be only 1 row.
If use Object_table could be easy to solve my question, but I don't want to add too much things in the database.
You can use the object constructor in the SELECT clause:
DECLARE
SOME_OBJECT SOME_CUSTOM_OBJ;
BEGIN
SELECT some_custom_obj(ID,NAME)
INTO some_object
FROM another_table
WHERE rownum = 1;
DBMS_OUTPUT.PUT_LINE(SOME_OBJECT.ID);
END;
/
Which, for the sample data:
CREATE TABLE another_table (id, name) AS
SELECT 1, 'Alice' FROM DUAL;
Outputs:
1
db<>fiddle here

looping through an array for the where condition pl/sql

Is it possible in pl/sql to loop through a number of id's that need to go in the WHERE clause of the pl/sql statement. The sql statement itself is pretty simple, but I need to iterate over a number of id's:
SELECT x_name
FROM table_x
WHERE x_id = {array of 90 id's};
How can I insert the 90 id's here so that sql iterates over them? I tried using the cursor For Loop, but I'm stuck. The code below is erroneous, but it might give an indication what Im trying to achieve here
DECLARE
TYPE x_id_array IS VARRAY(3) OF NUMBER;
CURSOR cur_x_id (x_ondz_id NUMBER) IS
SELECT x_name
FROM table_x
WHERE x_id = var_ondz_id;
loop_total integer;
x_id x_id_array;
name VARCHAR;
BEGIN
x_id_new := x_id_array(8779254, 8819930, 8819931); --3 for testing
loop_total := x_id_new.count;
FOR i in 1 .. loop_total LOOP
dbms_output.put_line('x_id: ' || x_id_new(i) || '= Name: ' || x_name );
END LOOP;
END;
/
The expected out put would be
x_id: 8779254= Name: Name_1
x_id: 8819930= Name: Name_2
x_id: 8819931= Name: Name_3
...
... etc for all 90 id's in the array
Any help is appreciated
We can use TABLE function on a collection to get a list of numbers / character.
SELECT *
FROM TABLE ( sys.odcinumberlist(8779254,8819930,8819931) );
8779254
8819930
8819931
Here I'm using Oracle's internal VARRAY with a limit of 32767. You may use your own NESTED TABLE type.
create OR REPLACE TYPE yourtype AS TABLE OF NUMBER;
and then select it.
SELECT *
FROM TABLE ( yourtype(8779254,8819930,8819931) );
So, your query can simply be written as
SELECT x_name
FROM table_x
WHERE x_id IN ( SELECT * FROM
TABLE ( yourtype(8779254,8819930,8819931) ) );
12.2 and above, you won't even need to specify TABLE.
SELECT * FROM yourtype(8779254,8819930,8819931) works.

how to look up another field in Oracle Function

Table 1
ID
----------
1
2
3
4
5
Table 2
ID Desc
------------------------------
A1 Apple
A2 Pear
A3 Orange
I am trying to create a Function in Oracle, so that it add the prefix 'A' in Table 1, and after that I want to look up in Table 2 to get the DESC returned. It has to be a function.
Thank you!!!
You may use the following for creation of such a function :
Create or Replace Function Get_Fruit( i_id table2.description%type )
Return table2.description%type Is
o_desc table2.description%type;
Begin
for c in ( select description from table2 where id = 'A'||to_char(i_id) )
loop
o_desc := c.description;
end loop;
return o_desc;
End;
where
no need to include exception handling, because of using cursor
instead of select into clause.
using table_name.col_name%type for declaration of data types for
arguments or variables makes the related data type of the columns
dynamic. i.e. those would be able to depend on the data type of the
related columns.
the reserved keywords such as desc can not be used as column names
of tables, unless they're expressed in double quotes ("desc")
To call that function, the following might be preferred :
SQL> set serveroutput on
SQL> declare
2 i_id pls_integer := 1;
3 o_fruit varchar2(55);
4 begin
5 o_fruit := get_fruit( i_id );
6 dbms_output.put_line( o_fruit );
7 end;
8 /
Apple
PL/SQL procedure successfully completed
I am not sure with your question- Are you trying to achieve something like this:-
CREATE OR REPLACE FUNCTION Replace_Value
(
input_ID IN VARCHAR2
) RETURN VARCHAR2
AS
v_ID varchar(2);
BEGIN
begin
SELECT distinct a.ID into v_id from Table 2 a where a.ID in (select 'A'||b.id from table1 b where b.id=input_ID);
exception
when others then
dbms_output.put_line(sqlcode);
end;
RETURN v_id;
END Replace_Value;
Are you trying for something like this?
CREATE OR replace FUNCTION replace_value (table_name IN VARCHAR2,
input_id IN INTEGER)
RETURN VARCHAR2
AS
v_desc VARCHAR(20);
BEGIN
SELECT descr
INTO v_desc
FROM table2
WHERE id = 'A' || input_id
AND ROWNUM = 1; -- only needed if there are multiple rows for each id.
RETURN v_desc;
END replace_value;
You may also add an exception handling for NO_DATA_FOUND or INVALID_NUMBER

Oracle PL/SQL - Show results of declared table

I am using Toad. I have a declaration of a table in a package as follows:
TYPE MyRecordType IS RECORD
(ID MyTable.ID%TYPE
,FIELD1 MyTable.FIELD1%TYPE
,FIELD2 MyTable.FIELD2%TYPE
,FIELD3 MyTable.FIELD3%TYPE
,ANOTHERFIELD VARCHAR2(80)
);
TYPE MyTableType IS TABLE OF MyRecordType INDEX BY BINARY_INTEGER;
There is a procedure (lets say MyProcedure), that is using an object of this table type as input/output. I want to run the procedure and see the results (how the table is filled). So I am thinking I will select the results from the table:
declare
IO_table MyPackage.MyTableType;
begin
MyPackage.MyProcedure (IO_table
,parameter1
,parameter2
,parameter3);
select * from IO_table;
end;
I get the message:
Table or view does not exist (for IO_table). If I remove the select line, the procedure runs successfully, but I cannot see its results. How can I see the contents of IO_table after I call the procedure?
You cannot see the results for a PL/SQL table by using Select * from IO_table
You will need to loop through the collection in the annonymous block.
do something like, given in pseudo code below...
declare
IO_table MyPackage.MyTableType;
l_index BINARY_INTEGER;
begin
MyPackage.MyProcedure (IO_table
,parameter1
,parameter2
,parameter3);
l_index := IO_table.first;
While l_index is not null
loop
dbms_output.put_line (IO_table(l_index).id);
.
.
.
.
l_index :=IO_table.next(l_index_id);
end loop;
end;
You have to do it like this:
select * from TABLE(IO_table);
and, of course you missed the INTO or BULK COLLECT INTO clause
1) You can not use associated arrays in SELECT statement, Just nested tables or varrays declared globally.
2) You should use TABLE() expression in SELECT statement
3) You can't simply use SELECT in PL/SQL code - cursor FOR LOOP or REF CURSOR or BULK COLLECT INTO or INTO must be used.
4) The last but not least - please study the manual:
http://docs.oracle.com/cd/B28359_01/appdev.111/b28371/adobjcol.htm#ADOBJ00204
Just an example:
SQL> create type t_obj as object( id int, name varchar2(10));
2 /
SQL> create type t_obj_tab as table of t_obj;
2 /
SQL> var rc refcursor
SQL> declare
2 t_var t_obj_tab := t_obj_tab();
3 begin
4 t_var.extend(2);
5 t_var(1) := t_obj(1,'A');
6 t_var(2) := t_obj(2,'B');
7 open :rc for select * from table(t_var);
8 end;
9 /
SQL> print rc
ID NAME
---------- ----------
1 A
2 B

What is the simplest way to define a local variable in Oracle?

In the SQL Server, I can define local variables like this.
declare #id number := 1000
select * from tbl_A where id = #id;
select * from tbl_B where id = #id;
It is very convenient.
I tried to do same thing in PL/SQL but it doesn't work.
DECLARE id number;
select 1000 into id from dual;
Do you know how to do something similar? The simplest method is my objective.
If you want to define a local variable in PL/SQL, you need a complete PL/SQL block
DECLARE
id NUMBER;
BEGIN
SELECT 1000
INTO id
FROM dual;
END;
or just
DECLARE
id NUMBER := 1000;
BEGIN
<<do something that uses the local variable>>
END;
If you want to declare a variable in SQL*Plus
SQL> variable id number
SQL> begin
select 1000 into :id from dual;
end;
/
SQL> print id
ID
----------
1000
SQL> SELECT * FROM tbl_a WHERE id = :id
An alternative to DECLARE Block is to use a WITH Clause:
WITH my_params AS (
SELECT 123 AS min_id FROM DUAL
)
SELECT *
FROM some_table
WHERE id > (SELECT min_id FROM my_params)
It is more portable as many vendors support the WITH clause and you can change seamless from parameter to dynamic value. For example:
WITH my_params AS (
SELECT min(id) AS min_id FROM some_id_table
)
SELECT *
FROM some_table
WHERE id > (SELECT min_id FROM my_params)
Solution for Oracle SQL
DEF x = foo
SELECT '&x' FROM dual;
The result will be : foo
NB: The variable will keep the value even after execution. To clear variable run UNDEFINE x.
General syntax to declare variable in PL/SQL is
var_nm datatype [NOT NULL := var_value ];
var_nn is the name of the variable.
datatype is a valid PL/SQL datatype.
NOT NULL is an optional specification on the variable which this variable cannot be assigned null value.
var_value or DEFAULT value is also an optional specification, where you can initialize a variable with some specific value.
Each variable declaration is a separate statement and must be terminated by a semicolon.
We can assign value to variables in one of the following two ways -
direct assignment (Eg. var_nm:= var_value;)
Using select from (Eg. SELECT col_nm INTO var_nm FROM tbl_nm [WHERE clause];)
In you case as Justin Cave has already mentioned it can be
DECLARE
id number;
BEGIN
SELECT 1000 into id from dual;
dbms_output.put_line('id : '|| id );
END;
/
OR
DECLARE
id number := 1000;
BEGIN
dbms_output.put_line('id : '|| id );
END;
/
NOTE: '/' i.e Back slash after END keyword indicates to execute the above PL/SQL Block.
(Just stumbled across this thread.) Beginning with SQL*Plus 12.2, you can declare and assign a value at the same time:
SQL> var id number = 1000
SQL> select * from tbl_A where id = :id;
Oracle calls it input binding.
If you must do it in PL/SQL, the answer was given by others.

Resources