Define Select statement as variable - oracle

is it possible to define a select statement as variable, somethings like this:
Define (Select t1.id, t1.var1, t1.var2, t2.id, t2.var1, t2.var2 From
table1 t1, table2 t2 Where t1.id = t2.id) as namevariable
Thanks for your help,
Andrea

Define (Select t1.id, t1.var1, t1.var2, t2.id, t2.var1, t2.var2 From
table1 t1, table2 t2 Where t1.id = t2.id) as namevariable
You can do it as :
DECLARE
var VARCHAR2 (100);
v_emp_id number;
BEGIN
--Defining as a variable in PLSQL
var := 'Select employee_id from employee where employee_id = :1';
EXECUTE IMMEDIATE var into v_emp_id using 1 ;
--Showing the result
DBMS_OUTPUT.PUT_LINE(v_emp_id);
END;

simply with select ... into ...
DECLARE
my_id NUMBER;
my_val VARCHAR2(32);
BEGIN
SELECT t1.id, t1.val into my_id, my_val from my_table t1 where... ;
END;

Related

ORA-01403: No Data found?

when i try this PL/SQL to execute i have the error Oracle PL/SQL - ORA-01403 "No data found" in first select in for loop
declare
CURSOR
tempRow IS SELECT t2.*
FROM TABLE2 t2
JOIN TABLE3 t3 on t3.ID = t2.ID_FB;
updateId integer;
B TABLE1.A%TYPE;
BEGIN
FOR item IN tempRow
LOOP
select t1.A, t1.ID
into B, updateId
from TABLE2 t2
JOIN TABLE1 t1 on t2.ID = t1.ID_R
WHERE t2.ID = item.ID;
-- more conditions
--- more code
dbms_output.put_line(B);
END LOOP;
END;
i can't found the wrong in the statement.
can someone help me?
It says that for ID (in tempRow cursor), which is acquired via join of table2 and table3, no rows exist in table1 which is joined to table2 in select statement within the cursor FOR loop.
To check it, include additional (nested) begin-exception-end block and display such a value, e.g.
BEGIN
FOR item IN temprow
LOOP
BEGIN
SELECT t1.a, t1.id
INTO b, updateid
FROM table2 t2 JOIN table1 t1 ON t2.id = t1.id_r
WHERE t2.id = item.id;
-- more conditions
--- more code
DBMS_OUTPUT.put_line (b);
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.put_line ('error on ID = ' || item.id);
END;
END LOOP;
END;
Then decide what to do; will you handle it somehow, ignore it, fix WHERE clause(s), ...

How to change alias to table name automatically in case of oracle?

We are currently analyzing hundreds of queries.
E.g
SELECT a.id,
a.name,
a.hobby,
b.desc
FROM tablename a,
table2 b
WHERE a.id = b.id;
or
SELECT id,
NAME,
hobby
FROM tablename;
above these can be change like below?
SELECT tablename.id,
tablename.name,
tablename.hobby,
table2.desc
FROM tablename tablename,
table2 table2
WHERE tablename.id = table2.id;
or
SELECT tablename.id,
tablename.name,
tablename.hobby
FROM tablename tablename;
Do you know any tools or methods that have the ability to change them?
Here is the Ananymous block for another query :
declare
v_query varchar2(4000) :='SELECT a.id,
a.name,
a.hobby,
b.desc
FROM tablename a,
table2 b
WHERE a.id = b.id';
tab_list varchar2(4000);
v_newquery varchar2(4000);
v_tab_alias varchar2(100);
v_tabname varchar2(500);
v_alias varchar2(40);
tab_cnt NUMBER :=0;
begin
-- table list
select replace(REGEXP_SUBSTR(regexp_replace(v_query,'FROM|WHERE','#'),'[^#]+',1,2)||chr(10),chr(10),null)
into tab_list
from dual;
-- no of tables
select REGEXP_COUNT(TRIM(REGEXP_SUBSTR(regexp_replace(v_query,'FROM|WHERE','#'),'[^#]+',1,2)),',')+1
into tab_cnt
from dual;
For i in 1..tab_cnt
LOOP
select TRIM(REGEXP_SUBSTR(tab_list,'[^,]+',1,i))
into v_tab_alias
from dual;
-- replace alias tablename for the column list
select TRIM(REGEXP_SUBSTR(v_tab_alias,'[^ ]+',1,1))
into v_tabname
from dual;
select TRIM(REGEXP_SUBSTR(v_tab_alias,'[^ ]+',1,2))
into v_alias
from dual;
select regexp_replace(v_query,v_alias||'\.',v_tabname||'.')
into v_newquery
from dual;
v_query:= v_newquery;
-- replace alias tablename in FROM clause
select regexp_replace(v_query,v_alias||'\,',v_tabname||',')
into v_query
from dual;
END LOOP;
-- replace alias last tablename before WHERE clause
select regexp_replace(v_query,v_tab_alias,v_tabname||' '||v_tabname)
into v_query
from dual;
DBMS_OUTPUT.PUT_LINE(v_query);
END;

How to store a result set of a ORACLE sql query?

Example : There is a table "ID_NAME" with one column "ID" which has 2000 entries like 1,2,3.. 2000.
I've have a query
select id from ID_NAME where id < 1001;
> Result : 1 2 3 4 . .1000
My PL SQL block looks like this,
SET SERVEROUTPUT ON;
declare
var1 number;
var2 number;
var3 number;
var4 number;
var5 number;
var6 number;
var7 number;
var8 number;
var9 number;
var10 number;
begin
with set1 as (select id from ID_NAME where id < 1001)
select count(*) into var1 from table1 where id in (select * from set1);
select count(*) into var2 from table2 where id in (select * from set1);
select count(*) into var3 from table3 where id in (select * from set1);
select count(*) into var4 from table4 where id in (select * from set1);
select count(*) into var5 from table5 where id in (select * from set1);
select count(*) into var6 from table6 where id in (select * from set1);
select count(*) into var7 from table7 where id in (select * from set1);
select count(*) into var8 from table8 where id in (select * from set1);
select count(*) into var9 from table9 where id in (select * from set1);
select count(*) into var10 from table10 where id in (select * from set1);
DBMS_OUTPUT.PUT_LINE('var1,var2,var3,var4,var5,var6,var7,var8,var9,var10');
DBMS_OUTPUT.PUT_LINE(var1||','||var2||','||var3||','||var4||','||var5||','||var6||','||var7||','||var8||','||var9||','||var10);
end;
but I'm getting
PL/SQL: ORA-00942: table or view does not exist
in my sql developer.
I want to use the SET1 from my below query so that I don't have to run it again and again in the count(*) sub queries
with set1 as (select id from ID_NAME where id < 1001)
SET SERVEROUTPUT ON;
declare
var1 number;
var2 number;
var3 number;
var4 number;
var5 number;
var6 number;
var7 number;
var8 number;
var9 number;
var10 number;
begin
with set1 as (select id from ID_NAME where id < 1001)
select
(select count(*) from table1 where id in (select * from set1)),
(select count(*) from table2 where id in (select * from set1)),
..............
(select count(*) from table9 where id in (select * from set1)),
(select count(*) from table10 where id in (select * from set1))
into var1,var2,.....,var9,var10
from dual;
DBMS_OUTPUT.PUT_LINE('var1,var2,var3,var4,var5,var6,var7,var8,var9,var10');
DBMS_OUTPUT.PUT_LINE(var1||','||var2||','||var3||','||var4||','||var5||','||var6||','||var7||','||var8||','||var9||','||var10);
end;
You are building a CTE so it goes like this: For each select statement you need to join with CTE.
declare
var1 number;
var2 number;
var3 number;
var4 number;
var5 number;
var6 number;
var7 number;
var8 number;
var9 number;
var10 number;
begin
with set1 as (select emp_id from employee where emp_id < 1001)
select count(*) into var1 from employee
where emp_id in (select eno from emp_sal);
with set1 as (select emp_id from employee where emp_id < 1001)
select count(*) into var2 from employee
where emp_id in (select eno from emp_sal);
.
.
.
.
and so on
-- select count(*) into var2 from table2 where id in (select * from set1);
-- select count(*) into var3 from table3 where id in (select * from set1);
-- select count(*) into var4 from table4 where id in (select * from set1);
-- select count(*) into var5 from table5 where id in (select * from set1);
-- select count(*) into var6 from table6 where id in (select * from set1);
-- select count(*) into var7 from table7 where id in (select * from set1);
-- select count(*) into var8 from table8 where id in (select * from set1);
-- select count(*) into var9 from table9 where id in (select * from set1);
-- select count(*) into var10 from table10 where id in (select * from set1);
DBMS_OUTPUT.PUT_LINE('var1,var2,var3,var4,var5,var6,var7,var8,var9,var10');
DBMS_OUTPUT.PUT_LINE(var1||','||var2||','||var3||','||var4||','||var5||','||var6||','||var7||','||var8||','||var9||','||var10);
end;
In SQL, a with clause or Common Table Expression is part of a query. It doesn't set a program variable.
with xyz as (select blah from blahblah where something = somethingelse)
select blah from xyz;
You can't refer to xyz in other queries - it is just a clause within a single query.

table name in loop oracle pl/sql

declare
v_cnt NUMBER;
C SYS_REFCURSOR;
TMP_TBL_NM VARCHAR2(100);
stmt VARCHAR2(1000);
the_name varchar2 (50);
cursor c_table is
(SELECT a.table_name
--, a.column_name, a.constraint_name, c.owner,
--c.r_owner , c_pk.table_name r_table_name, c_pk.constraint_name r_pk
FROM all_cons_columns a
JOIN all_constraints c ON a.owner = c.owner AND a.constraint_name = c.constraint_name
JOIN all_constraints c_pk ON c.r_owner = c_pk.owner AND c.r_constraint_name = c_pk.constraint_name
WHERE c.owner like '%LTR' and c_pk.table_name like '%EnumerationValue%');
begin
stmt := 'SELECT table_name FROM ' || TMP_TBL_NM || ' ORDER BY 1';
OPEN C FOR stmt;
for t in C
loop
FETCH C INTO the_name;
EXIT WHEN C%NOTFOUND;
--my query for each table goes here
end loop;
end;
i want to use table names in loop as to check the records as per my query.
it is giving me error only by getting table name in the loop.
how can i get table name in a loop so that i can fetch rows as per my requirement from each table in a loop.
thanks in advance.
I'm not entirely sure what you want to achieve here, but if it's just the table names you're interested in, you can make your code a lot less complicated doing it this way:
declare
cursor c_table is
SELECT a.table_name
--, a.column_name, a.constraint_name, c.owner,
--c.r_owner , c_pk.table_name r_table_name, c_pk.constraint_name r_pk
FROM all_cons_columns a
JOIN all_constraints c ON a.owner = c.owner AND a.constraint_name = c.constraint_name
JOIN all_constraints c_pk ON c.r_owner = c_pk.owner AND c.r_constraint_name = c_pk.constraint_name
begin
for t in c_table loop
--do something with the table name
dbms_output.put_line(t.table_name);
end loop;
end;
This kind of for loop also handles the opening and closing of the cursor and is the recommended way to do these kind of operations.

How to pass cursor values into variable?

I am trying to read values from two column1, column2 from table1 using cursor. Then I want to pass these values to another cursor or select into statement
so my PL/Sql script will use the values of these two columns to get data from another table called table2
Is this possible? And what's the best and fastest way to do something like that?
Thanks :)
Yes, it's possible to pass cursor values into variables. Just use fetch <cursor_name> into <variable_list> to get one more row from a cursor. After that you can use the variables in where clause of some select into statement. E.g.,
declare
cursor c1 is select col1, col2 from table1;
l_col1 table1.col1%type;
l_col2 table1.col2%type;
l_col3 table2.col3%type;
begin
open c1;
loop
fetch c1 into l_col1, l_col2;
exit when c1%notfound;
select col3
into l_col3
from table2 t
where t.col1 = l_col1 --Assuming there is exactly one row in table2
and t.col2 = l_col2; --satisfying these conditions
end loop;
close c1;
end;
If you use an implicit cursor, then it's even simpler:
declare
l_col3 table2.col3%type;
begin
for i in (select col1, col2 from table1)
loop
select col3
into l_col3
from table2 t
where t.col1 = i.col1 --Assuming there is exactly one row in table2
and t.col2 = i.col2; --satisfying these conditions
end loop;
end;
In these examples, it's more efficient to use a subquery
begin
for i in (select t1.col1
, t1.col2
, (select t2.col3
from table2 t2
where t2.col1 = t1.col1 --Assuming there is atmost one such
and t2.col2 = t1.col2 --row in table2
) col3
from table1 t1)
loop
...
end loop;
end;

Resources