How to apply wildcard to column list in SQL - sql

I would like to know How to use wildcard in select
For example, I would like to extract columns which contains for example test.
How can I extract this?
Select
From T2
My desired result is like this
test1 test2 test3
1 2 3
4 5 6
Thanks

You need to use the dynamic query as follows:
SQL> var lv_cur refcursor;
SQL>
SQL> DECLARE
2 LV_COLS VARCHAR2(32000);
3 LV_TABLE_NAME VARCHAR2(128) := 'STUDENTS';
4 LV_SCHEMA_NAME VARCHAR2(128) := 'TEJASH';
5 LV_COLUMN_STARTWITH VARCHAR2(10) := 'S';
6 --LV_CUR SYS_REFCURSOR;
7 BEGIN
8 SELECT
9 LISTAGG(COLUMN_NAME, ',') WITHIN GROUP(
10 ORDER BY
11 COLUMN_ID
12 )
13 INTO LV_COLS
14 FROM
15 ALL_TAB_COLUMNS
16 WHERE
17 TABLE_NAME = LV_TABLE_NAME
18 AND COLUMN_NAME LIKE LV_COLUMN_STARTWITH || '%'
19 AND OWNER = LV_SCHEMA_NAME;
20
21 IF LV_COLS IS NOT NULL THEN
22 OPEN :LV_CUR FOR 'SELECT '
23 || LV_COLS
24 || ' FROM '
25 || LV_SCHEMA_NAME
26 || '.'
27 || LV_TABLE_NAME;
28
29 ELSE
30 OPEN :LV_CUR FOR 'SELECT ''NO DATA'' FROM DUAL';
31 END IF;
32 END;
33 /
PL/SQL procedure successfully completed.
SQL> PRINT LV_cUR;
S_ID S_NAME S_ADDRESS S_LEVEL S_RECORDS_POINTS S_MAJOR S_CLASS
---------- ---------- ---------- ---------- ---------------- ---------- ----------
1 TEJASH A2 1 15.972 1 1
SQL>
I have used this block to fetch the data of the column having S as the starting character in the STUDENTS table(TEJASH schema). If there is no column satisfying the condition then NO DATA will be displayed.

You can do something like this
SQL Server
select *
from information_schema.columns
where column_name like 'test%'
order by
table_name
Oracle
select
table_name,
column_name
from all_tab_columns
where column_name like 'test%'
and owner in ('your_schema_name')

Related

Row wise comparisons between two Oracle table

I'm a beginner & trying to find a solution for the below issue
I have two table with same number of column, same names and same datatype.
I'm sorting both the table by time and trying to do row wise comparison (including data in each row) using not exist operation to identify the mismatch of records. If all the rows in both table are same then I need to return True else False.
Note: No relationship between the tables to do Join.
This is how I understood the question.
Sample tables: they have the same number of columns, with same names, same datatypes - but, you didn't say whether they contain the same number of rows. Mine don't:
SQL> select * from t1 order by id;
ID NAME COUNTRY
---------- ------ -------
1 Little Croatia
2 Foot Hungary
3 Scott UK
SQL> select * from t2 order by id;
ID NAME COUNTRY
---------- ------ -------
1 Little Croatia
2 Michel France
SQL>
The idea is to compare SHA1 hash values computed on concatenated values from both tables for comparative rows (which ones? Those that share the same row number).
SQL> set serveroutput on
SQL> declare
2 l_cnt_1 number;
3 l_cnt_2 number;
4 l_cnt number;
5 --
6 cursor c1 is
7 select id, name, country
8 from (select id, name, country,
9 row_number() over (order by id) rn
10 from t1)
11 order by rn;
12 cursor c2 is
13 select id, name, country
14 from (select id, name, country,
15 row_number() over (order by id) rn
16 from t2)
17 order by rn;
18 c1r c1%rowtype;
19 c2r c2%rowtype;
20 h1 raw(20);
21 h2 raw(20);
22 begin
23 -- which table is smaller (by number of rows)?
24 select count(*) into l_cnt_1 from t1;
25 select count(*) into l_cnt_2 from t2;
26 l_cnt := least(l_cnt_1, l_cnt_2);
27
28 open c1;
29 open c2;
30 -- loop as many times as there are rows in a smaller table; it doesn't make
31 -- sense comparing rows that don't have a "pair"
32 for i in 1 .. l_cnt loop
33 fetch c1 into c1r;
34 fetch c2 into c2r;
35
36 -- SHA1 hash
37 select sys.dbms_crypto.hash(utl_raw.cast_to_raw
38 (c1r.id || c1r.name || c1r.country), sys.dbms_crypto.hash_sh1),
39 sys.dbms_crypto.hash(utl_raw.cast_to_raw
40 (c2r.id || c2r.name || c2r.country), sys.dbms_crypto.hash_sh1)
41 into h1, h2
42 from dual;
43
44 dbms_output.put_line('Comparing');
45 dbms_output.put_line('- T1: ' || c1r.id ||', '|| c1r.name ||', '|| c1r.country);
46 dbms_output.put_line('- T2: ' || c2r.id ||', '|| c2r.name ||', '|| c2r.country);
47
48 if h1 = h2 then
49 dbms_output.put_line('- Result: match');
50 else
51 dbms_output.put_line('- Result: no match');
52 end if;
53 end loop;
54
55 close c1;
56 close c2;
57 end;
58 /
Result is:
Comparing
- T1: 1, Little, Croatia
- T2: 1, Little, Croatia
- Result: match
Comparing
- T1: 2, Foot, Hungary
- T2: 2, Michel, France
- Result: no match
PL/SQL procedure successfully completed.
SQL>

Oracle procedure to increment string data type and store it as one of the column in table

I need to take the max value of the column id which starts with AB from Table A
I have a Table B where I need to update the column values max value +1 for all the rows present in Table B.
For example If I get the max value from Table A as AB1500, and Table B has 20 records and various columns, I need to populate from AB1501 to AB1520 for the records in Table B for the ORG_ID column.
Issue: For loop not able to write data into the TABLE B
Table A:
ORG_ID
ORG_NAME
AE500
Google
AB1500
Amazon
AB1200
Apple
Table B: Here For the available records i need to increment from max of AB from Table A
Country
Country_ID
ORG_ID
US
10
AB1501
UK
11
AB1502
FRANCE
12
AB1503
Create or replace procedure proc_incr(
v_org_id IN TableB.org_id%TYPE
)
v_max_number NUMBER;
v_max_org_id VARCHAR2(20);
v_max_var VARCHAR2(20);
v_temp VARCHAR2(20);
v_count NUMBER;
begin
select max(Table A.org_id)
into v_max_org_id
from TableA where org_id like 'AB%';
select count(*)
into v_count
from Table B;
select regexp_substr(v_max_org_id, '\d+')
into v_max_number
from dual;
select regexp_substr(v_max_org_id, '\D+')
into v_max_var
from dual;
// For Loop to write data to Table B
for i in 1 .. (v_count) LOOP
v_temp := v_max_number+i;
v_max_org_id := v_max_var||v_temp;
v_org_id := v_max_org_id;
End LOOP;
commit;
END proc_incr;
Sample data:
SQL> SELECT * FROM tablea;
ORG_ID
------
AB1500
CD1234
SQL> SELECT * FROM tableb;
ORG_ID NAME
------ ------
xxxxxx Little
Foot
Mahe
Your code, slightly fixed; you didn't perform any update, so I presume that's why you had an "issue"
For loop not able to write data into the TABLE B
Note the cursor for the tableb table; it is used to update current row fetched by it.
SQL> DECLARE
2 v_max_number NUMBER;
3 v_max_org_id VARCHAR2 (20);
4 v_max_var VARCHAR2 (20);
5
6 CURSOR curb IS
7 SELECT org_id, name
8 FROM tableb
9 FOR UPDATE;
10
11 cbr curb%ROWTYPE;
12 i NUMBER := 1;
13 BEGIN
14 SELECT MAX (tablea.org_id)
15 INTO v_max_org_id
16 FROM tablea
17 WHERE org_id LIKE 'AB%';
18
19 SELECT REGEXP_SUBSTR (v_max_org_id, '\d+') INTO v_max_number FROM DUAL;
20
21 SELECT REGEXP_SUBSTR (v_max_org_id, '\D+') INTO v_max_var FROM DUAL;
22
23 -- For Loop to write data to Table B
24 OPEN curb;
25
26 LOOP
27 FETCH curb INTO cbr;
28
29 EXIT WHEN curb%NOTFOUND;
30
31 v_max_org_id := v_max_var || TO_CHAR (v_max_number + i);
32
33 UPDATE tableb
34 SET org_id = v_max_org_id
35 WHERE CURRENT OF curb;
36
37 i := i + 1;
38 END LOOP;
39 END;
40 /
PL/SQL procedure successfully completed.
SQL> SELECT * FROM tableb;
ORG_ID NAME
------ ------
AB1501 Little
AB1502 Foot
AB1503 Mahe
SQL>

Oracle SQL to Check a value against a specific list of columns

I got the SQLfiddle link copied below for my required.
CREATE TABLE TAB1
(COL1 NUMBER,
COL2 NUMBER,
COL3 NUMBER,
COL4 NUMBER);
INSERT INTO TAB1 VALUES(1,2,3,2);
INSERT INTO TAB1 VALUES(1,2,1,2);
INSERT INTO TAB1 VALUES(1,2,2,2);
INSERT INTO TAB1 VALUES(1,2,2,2);
I want to check if columns col2, col3,col4 has the value 2. I have the below sql to achieve my requirement. But the problem is I have to check the same for 300 columns. Table is already designed like this by the developer as per incoming data file and I can't change anything now. Is there a better way of doing this other than using the below SQL with 300 column names in ALL(col1..col300)?
SELECT *
FROM TAB1
WHERE 2 = ALL (COL2,COL3,COL4);
SQLfiddle link is below with expected output
http://www.sqlfiddle.com/#!4/fbc00/3/0
Appreciate the responses. Thank you
As The Impaler said, dynamic SQL could help. If you can't fix that design, see if something like this helps: function accepts search value as a parameter, uses query you already wrote and returns refcursor.
SQL> create or replace function f_ok (par_search_value in number)
2 return sys_refcursor
3 is
4 l_str varchar2(32000) := 'select * From tab1 where ' || par_search_value ||' = all(';
5 l_rc sys_refcursor;
6 begin
7 for cur_r in (select column_name
8 from user_tab_columns
9 where table_name = 'TAB1'
10 and column_id > 1
11 order by column_id
12 )
13 loop
14 l_str := l_str || cur_r.column_name || ', ';
15 end loop;
16 l_str := rtrim(l_str, ', ') || ')';
17 open l_rc for l_str;
18 return l_rc;
19 end;
20 /
Function created.
Testing:
SQL> select * from tab1;
COL1 COL2 COL3 COL4
---------- ---------- ---------- ----------
1 2 3 2
1 2 1 2
1 2 2 2
1 2 2 2
SQL> var rc refcursor
SQL> exec :rc := f_ok(2);
PL/SQL procedure successfully completed.
SQL> print rc
COL1 COL2 COL3 COL4
---------- ---------- ---------- ----------
1 2 2 2
1 2 2 2
SQL>

Print counts from multiple tables in one SQL

DB version: 11.1.2.3.0
I am using the below SQL:
SELECT tab_nam, cnt
FROM
(
SELECT 'Tab1' "tab_nam", COUNT(1) "cnt" FROM Tab1
UNION
SELECT 'Tab2' "tab_nam", COUNT(1) "cnt" FROM Tab2
);
TAB_NAM CNT
------- ------
Tab1 23
Tab2 10
CREATE TABLE Tab1 (id NUMBER, name VARCHAR2(100));
CREATE TABLE Tab2 (id NUMBER, name VARCHAR2(100));
Is there any other way to get the output in the above form?
I would like to get the resultset in above format only and not horizontally..
Reason for different SQL: I am not able to print the SQL output to HTML. Format used:
PRO <h3>Table Count</h3>
PRO <table>
PRO <tr>
PRO <th>Table Name</th>
PRO <th>Count</th>
PRO </tr>
SELECT '<tr>'||
'<td class="left">'||"tab_name"||'</td>'||
'<td class="center">'||"cnt"||'</td>'||
'</tr>'
FROM (
SELECT 'Tab1' "tab_name", COUNT(1) "cnt" FROM Tab1
UNION
SELECT 'Tab2' "tab_name", COUNT(1) "cnt" FROM Tab2);
PRO </table>
Tia..
There are several ways of finding the count of SOME/ALL tables in a single query. For example, let's say I want to get the count of rows from all tables in the schema 'SCOTT'.
1.Using SQL
SQL> column table_name format A15;
SQL> SELECT table_name,
2 to_number(extractvalue(xmltype(dbms_xmlgen.getxml('select count(*) c from '
3 ||owner
4 ||'.'
5 ||table_name)),'/ROWSET/ROW/C')) AS COUNT
6 FROM all_tables
7 WHERE owner = 'SCOTT'
8 /
TABLE_NAME COUNT
--------------- ----------
DEPT 4
EMP 14
BONUS 0
SALGRADE 5
SQL>
2.With 100% statistics gathered
SQL> EXEC DBMS_STATS.gather_schema_stats('SCOTT', estimate_percent => 100);
PL/SQL procedure successfully completed.
SQL> column owner format A10;
SQL> select owner, table_name, num_rows, sample_size, last_analyzed from all_tables where owner = 'SCOTT';
OWNER TABLE_NAME NUM_ROWS SAMPLE_SIZE LAST_ANAL
---------- --------------- ---------- ----------- ---------
SCOTT DEPT 4 4 12-OCT-14
SCOTT EMP 14 14 12-OCT-14
SCOTT BONUS 0 0 12-OCT-14
SCOTT SALGRADE 5 5 12-OCT-14
SQL>
3.Using PL/SQL
SQL> SET serveroutput ON;
SQL> DECLARE
2 var_count NUMBER;
3 BEGIN
4 FOR i IN
5 (SELECT table_name, owner FROM all_tables WHERE owner = 'SCOTT'
6 )
7 LOOP
8 EXECUTE IMMEDIATE 'select count(*) from ' || i.table_name INTO var_count;
9 dbms_output.put_line(i.table_name ||' - '|| var_count);
10 END LOOP;
11 END;
12 /
DEPT - 4
EMP - 14
BONUS - 0
SALGRADE - 5
PL/SQL procedure successfully completed.
SQL>
But the SQL approach is simpler, isn't it?

PL/SQL Help to check for specific values in specific tables

I have query. I have 1 column user_auto with 234 value.
I want to find which table is using this Column and with specific value.
I have done how many table is using this column.
SELECT t.name AS table_name
FROM sys.tables AS t
INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE c.name LIKE '%user_auto%'
ORDER BY table_name;
Now I want this table with user_auto = 234 have change the value.
Means User_auto value is 234. want all detail about this user?
do you want something like this?
SQL> desc foo1
Name Null? Type
----------------------------------------- -------- ----------------------------
USER_AUTO NUMBER
SQL> desc foo2
Name Null? Type
----------------------------------------- -------- ----------------------------
USER_AUTO NUMBER
SQL> select * From foo1;
USER_AUTO
----------
123
1234
SQL> select * From foo2;
USER_AUTO
----------
234
SQL> set serverout on
SQL> declare
2 v_val varchar2(3) := '234';
3 v_cnt pls_integer;
4 begin
5 for r_tab in (select table_name, column_name
6 from all_tab_columns
7 where column_name = 'USER_AUTO'
8 order by 1)
9 loop
10 dbms_output.put_line('Found table ' || r_tab.table_name || ' with column '||r_tab.column_name);
11 execute immediate 'begin select count(*) into :b0 from '
12 || r_tab.table_name
13 || ' where rownum = 1 and ' || r_tab.column_name || ' = :b1;'
14 || 'end;' using out v_cnt, v_val;
15 if (v_cnt = 1)
16 then
17 dbms_output.put_line(chr(9)||'row found for ' || v_val);
18 else
19 dbms_output.put_line(chr(9)||'no row found for ' || v_val);
20 end if;
21 end loop;
22 end;
23 /
Found table FOO1 with column USER_AUTO
no row found for 234
Found table FOO2 with column USER_AUTO
row found for 234
PL/SQL procedure successfully completed.