oracle select * from variable table name - oracle

ORACLE: So far nothing I have tried has worked. I wish to display on the screen the results of select * from my_table. In this case my_table = select table_name from all_tables where owner='ABC' and name like 'ABC%'. Table name would be a plus, but column name is a necessity. I can do this in seconds with DB2, but can't quite translate for Oracle.
My attempt:
variable refcur refcursor;
declare
my_select varchar2(64);
cursor c_tables is
select table_name
from all_tables
where owner='ABC' and table_name like 'ABC%';
begin
for x in c_tables
loop
dbms_output.put_line(x.table_name);
my_select := 'select * from ' || x.table_name;
open :refcur for my_select;
end loop;
exception
when no_data_found
then dbms_output.put_line('Nothing is found');
end;
/
In all of my attempts, the best I have gotten is table does not exist
Thanks

I don't know how you're logged on, but if you're NOT logged on as ABC you'll need to include the schema along with the table name, e.g.
my_select := 'select * from ' || x.owner || '.' || x.table_name;
Also, opening a cursor doesn't fetch anything from it, or display the data anywhere. You'll need to add logic to fetch data from the cursor, display the data, and close the cursor. And because the table name isn't fixed the database can't tell ahead a time what your row looks like so you'll need to get familiar with the DBMS_SQL package, which is used for handling dynamic SQL like this.
Best of luck.

you can user below example:
create or replace procedure app_test(v_tab varchar2) is
type cur_type is ref cursor;
my_cur cur_type;
v_name varchar2(20);
dyna_sql varchar2(4000);
begin
dyna_sql := 'select username from ' || v_tab || ' where rownum=1';
open my_cur for dyna_sql;
fetch my_cur
into v_name;
while my_cur%found LOOP
fetch my_cur
into v_name;
DBMS_output.put_line(v_name);
end loop;
close my_cur;
end app_test;

Related

Oracle query logic to identify email addresses across the dwh schemas

I was performing an activity to identify eMail addresses based on certain pattern (#xyz.de). I initially tried checking the DBA_TAB_COLS [data dictionary] view but this just finds email column names and I manually need to check the big list of tables. Instead of doing that, is there is a more effective way to just fetch the the pattern value #xyz.de ?
Database - oracle 11g
Query used
SET SERVEROUTPUT ON 100000
DECLARE
lv_count number(10):=0;
l_str varchar2 (1000);
lv_col_name varchar2(255) :='EMAIL';
BEGIN
FOR V1 IN
(select distinct table_name
from dba_tab_columns
where column_name = lv_col_name
order by table_name)
LOOP
dbms_output.put_line(lv_col_name||' '||v1.table_name);
END LOOP;
END;
Please note that
I don't exactly know the table or column names.
The value #xyz.de can be in any schema and any table and any column. This has to be identified but in an effective way.
Any suggestions?
i have used the above block query to fetch the email column along with the table name , but how can i achieve by searching certain value #xyz.de using the dynamic sql ?
I don't know what you want to do with the values that you are trying to extract, so the below code just prints them. Refer to PL/SQL Dynamic SQL from the Oracle documentation.
declare
type EMAILS is ref cursor;
L_CURSOR EMAILS;
cursor EMAIL_COLS is
select OWNER
,TABLE_NAME
,COLUMN_NAME
from DBA_TAB_COLS
where COLUMN_NAME like '%EMAIL%'
and OWNER <> 'SYS';
L_SQL varchar2(200);
L_EMAIL varchar2(500);
begin
for REC in EMAIL_COLS
loop
L_SQL := 'select ' || REC.COLUMN_NAME || ' from ' || REC.OWNER || '.' || REC.TABLE_NAME || ' where ' || REC.COLUMN_NAME || ' like ''%xyz.de''';
open L_CURSOR for L_SQL;
loop
fetch L_CURSOR into L_EMAIL;
exit when L_CURSOR%notfound;
DBMS_OUTPUT.PUT_LINE(L_EMAIL);
end loop;
end loop;
end;

Find a Value in Table Using SQL Developer

I inherited a large database and nobody seems to know which table/column a particular data set is coming from. I've spent a lot of time going through table by table in Oracle's SQL Developer, but I can't find it. Is there a way in SQLDeveloper to search the entire table for a single value. Something like:
select table_name from all_tab_columns where column_value='desired value';
The db has around 1K+ tables each with lots of columns so manually combing through this isn't working.
You can use the following script to search for a value in all columns of your schema. The execution time for the script will depend on the number of tables in your schema and the number of rows in each of your table.
Replace 'abc' with the value which you intend to search. Also, right now the script will search all VARCHAR2 columns. You can also insert the table names and counts into a table instead of doing a DBMS_OUTPUT.PUT_LINE.
DECLARE
CURSOR cur_tables
IS
SELECT table_name,
column_name
FROM user_tab_columns
WHERE data_type = 'VARCHAR2';
v_sql VARCHAR2(4000);
v_value VARCHAR2(50);
v_count NUMBER;
BEGIN
v_value := 'abc';
FOR c_tables IN cur_tables LOOP
v_sql := 'SELECT count(1) FROM ' || c_tables.table_name || ' WHERE ' || c_tables.column_name || ' = :val' ;
EXECUTE IMMEDIATE v_sql INTO v_count USING v_value;
IF v_count > 0 THEN
DBMS_OUTPUT.PUT_LINE('Table Name ' || c_tables.table_name || ' Column Name ' || c_tables.column_name || ' Row Count ' || v_count);
END IF;
END LOOP;
END;

Write a PL/SQL Script that fills a table with the help of a cursor

How do I write a PL / SQL program that creates and fills a table for example let's call the table "TABEMP1", it fills it with data from any other table.
What I have so far;
set serveroutput on
set verify off
DECLARE
Cursor cur_emp IS SELECT * FROM EMP;
v_emp EMP%ROWTYPE;
BEGIN
OPEN cur_emp;
LOOP
FETCH cur_emp INTO v_emp;
EXIT WHEN cur_emp%NOTFOUND;
dbms_output.put_line('Ename: ' || v_emp.ename || ' Empno: ' || v_emp.empno);
END LOOP;
CLOSE cur_emp;
END;
/
No need for a cursor, using Native SQL with EXECUTE IMMEDIATE you can achieve that with flexible features:
DECLARE
lv_src_table_name VARCHAR2(30) := 'EMP';
pi_new_table_name VARCHAR2(30) := 'emp_copy';
BEGIN
EXECUTE IMMEDIATE 'CREATE TABLE '||pi_new_table_name||' AS SELECT * FROM '||pi_src_table_name;
END;
/
You can turn that into procedure and pass the two parameters with any original/copy tables names you want
In this case you dont need a PLSQL to achieve. A single SQL statement will be more effective. Hope below snippet helps.
CREATE TABLE TEMP_EMP
AS
SELECT * FROM EMP;

For loop with Table name in Stored Procedures

I am working on Oracle stored procedures.
My requirement is below
IF variable1 := 'true"
THEN
tableName=abr
ELSE
tableName=mvr
END IF;
FOR i IN (select unique(row1) as sc from tableName t where t.row2 = 'name') LOOP
BEGIN
-- required Logic
END
END LOOP;
But here I am not able to pass the table name in tableName parameter. How to do it?
You'll need to use Execute Immediate - it's designed for operations that aren't known until run time.
For normal operations, Oracle must know the tables and columns at compile time. You can't do SELECT * FROM tableName because it has no idea what tableName is and therefore it can't be compiled correctly.
Instead, you can do EXECUTE IMMEDIATE 'SELECT * FROM ' || tableName;
You can select your results INTO a variable, loop the result set, or BULK COLLECT into a structure and then iterate that.
For a simple select into, you can do this:
EXECUTE IMMEDIATE 'SELECT COL1, COL2 FROM ' || tableName INTO V_COL1, V_COL2
V_COL1 & V_COL2 are just local variables, tableName is a string representing your table name, and COL2 and COL2 are columns in the table you're selecting from. You can use the likes of ALL_TAB_COLUMNS to get the structure of a table dynamically.
Here is an example from Oracle docs:
CREATE OR REPLACE PROCEDURE query_invoice(
month VARCHAR2,
year VARCHAR2) IS
TYPE cur_typ IS REF CURSOR;
c cur_typ;
query_str VARCHAR2(200);
inv_num NUMBER;
inv_cust VARCHAR2(20);
inv_amt NUMBER;
BEGIN
query_str := 'SELECT num, cust, amt FROM inv_' || month ||'_'|| year
|| ' WHERE invnum = :id';
OPEN c FOR query_str USING inv_num;
LOOP
FETCH c INTO inv_num, inv_cust, inv_amt;
EXIT WHEN c%NOTFOUND;
-- process row here
END LOOP;
CLOSE c;
END;
/
http://docs.oracle.com/cd/B12037_01/appdev.101/b10795/adfns_dy.htm
You are going to have to build a for loop for each table then use your logic to determine which loop you will execute.

How to select from a parameter (cursor,varchar2, etc)

I have a little problem and if you could help me it would be great.
DECLARE
CURSOR cur1 IS
SELECT table_name
FROM all_tab_columns
WHERE column_name LIKE 'DESCRIPTION';
tableName varchar2(100);
BEGIN
OPEN cur1;
LOOP
FETCH cur1 INTO tableName;
EXIT WHEN cur1%NOTFOUND;
dbms_output.put_line(tablename);
END LOOP;
END;
What I need is to get all the information possible from those tables with the condition:
WEHRE DESCRIPTION LIKE 'Transaction%'
Something like this
SELECT *
FROM tableName ---- from above
WEHRE DESCRIPTION LIKE 'Transaction%'
I would like to select all data from the tables in my cursor.
The tables don't have the same structure, one can have 4 coloumns, one can have 10 coloumns.
Can it be done in an anonymous block?
Can anyone help me, please?
Try this:
DECLARE
CURSOR cur1 IS
SELECT table_name
FROM user_tab_columns
WHERE column_name LIKE 'DESCRIPTION';
tableName varchar2(100);
l_description varchar2(100);
l_str_val varchar2(100) := 'Transaction%';
l_cursor sys_refursor;
BEGIN
OPEN cur1;
LOOP
FETCH cur1 INTO tableName;
EXIT WHEN cur1%NOTFOUND;
open l_cursor for 'select DESCRIPTION from ' || tableName || ' where DESCRIPTION like :description' using l_str_val;
loop
fetch l_cursor into l_description;
exit when l_cursor%NOTFOUND;
dbms_output.put_line(tablename || ' ' || l_description);
end loop;
close l_cursor;
END LOOP;
close cur1;
END;
I extracted only description column, because I am sure this column is in the table, if you want to extract more columns you have to rewrite this like:
WHERE column_name = ('DESCRIPTION', 'ID', NAME)
and then:
execute immediate 'select DESCRIPTION, ID, NAME from ' || tableName || ' where DESCRIPTION like :description' into l_description, l_id, l_name using l_str_val;

Resources