DELETE By Procedure With String Input - Oracle - sql

I am writing a procedure to delete some records of z_names table by IDs from the input as string (and I need to seprate them by special character (comma ,)).
Sample Input: '1,4'
z_names table:
ID
NAME
1
jim
2
john
3
jack
4
alex
After running this procedure, the record with ID 1 and 4 (jim and alex) must be deleted.
I have lots of errors while was writing this procedure.
create or replace procedure prc_z_names_del (par_string in varchar2)
is
V_del_query varchar2(200);
begin
V_del_query := 'delete from ' || z_names|| 'WHERE ID = ' ||
select to_number(trim(regexp_substr(par_string, '[^,]+', 1, level)))
from dual
connect by level <= regexp_count(par_string, ',') + 1||';';
EXECUTE IMMEDIATE V_del_query;
end;
/

You' don't need dynamic SQL.
Sample data:
SQL> select * from z_names;
ID NAME
---------- ----
1 jim
2 john
3 jack
4 alex
Procedure:
SQL> create or replace procedure prc_z_names_del (par_string in varchar2)
2 is
3 begin
4 delete from z_names
5 where id in (select to_number(trim(regexp_substr(par_string, '[^,]+', 1, level)))
6 from dual
7 connect by level <= regexp_count(par_string, ',') + 1
8 );
9 dbms_output.put_line('Deleted ' || sql%rowcount ||' row(s)');
10 end;
11 /
Procedure created.
Testing:
SQL> set serveroutput on
SQL> exec prc_z_names_del('1, 4');
Deleted 2 row(s)
PL/SQL procedure successfully completed.
SQL> select * from z_names;
ID NAME
---------- ----
2 john
3 jack
SQL>

Related

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>

How to apply wildcard to column list in 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')

Simple Procedure for Printing the count of rows in a table without using COUNT operation ORACLE

Can anyone help me to create Simple Procedure for Printing the count of rows in a table without using COUNT operation in ORACLE ?
You must be looking for the LOOP in the procedure, considering that aggregate functions are not allowed..
Let's say I have an account table with 3 records in it.
SQL> SELECT * FROM ACCOUNT;
ACC_NR SUM_ CUST_ID
---------- ---------- ----------
500 3400 100
600 5000 101
700 5070 102
SQL>
Now, creating the procedure:
SQL> CREATE OR REPLACE PROCEDURE COUNT_ACCOUNT (
2 P_OUT_COUNT OUT NUMBER
3 ) AS
4 BEGIN
5 P_OUT_COUNT := 0;
6 FOR I IN (
7 SELECT
8 1 AS RW
9 FROM
10 ACCOUNT
11 ) LOOP
12 P_OUT_COUNT := P_OUT_COUNT + 1;
13 END LOOP;
14 END COUNT_ACCOUNT;
15 /
Procedure created.
SQL>
Executing the procedure to see the output:
SQL> SET SERVEROUT ON
SQL>
SQL> DECLARE
2 CNT NUMBER := 0;
3 BEGIN
4 COUNT_ACCOUNT(CNT);
5 DBMS_OUTPUT.PUT_LINE('NUMBER OF RECORDS IN ACCOUNT TABLE: ' || CNT);
6 END;
7 /
NUMBER OF RECORDS IN ACCOUNT TABLE: 3
PL/SQL procedure successfully completed.
SQL>
Cheers!!
Now you can/may wrap the below with either
a procedure or a function with or without a return statement
DECLARE
CNT NUMBER;
BEGIN
SELECT MAX(ROWNUM) INTO CNT FROM TABLE_NAME;
DBMS_OUTPUT.PUT_LINE('NUMBER OF ROWS : '||CNT);
END;

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.