Check inputs of Stored Procedure in HANA - sql

In stored procedure i would like to give a set of inputs, in which i also have some tables.
i could use if condition to handle empty scalar inputs but i dont know how to handle empty table or if the input is left empty.
I would like to have some thing like this
count = select count(*) from input_table;
if :count = 0 or not given(~) --how to check if the input is not given?
then
tab = select * from table;
else
tab = input_table;
end if;
Thank you!

select * from Table t1
where exists(
select 1 from ChildTable t2
where t1.id = t2.parentid)
procedure
if exists(select 1 from table)
begin
-- do stuff
end

Related

Nested cursor performance tuning

I have 2 cursors , one to fetch records from a table of 50 columns and 10,000 + data and another to check if a particular column exists in another big table (2 million data). I should write to a file all the records from cursor 1 for a year , if that column exists in cursor 2 then i should print an error message as exists and not delete them . If it does not exist then i should delete the row and write it to the same file and message as record deleted.
I used a nested cursor , the performance is too bad as it is processing each row from cursor 1 against cursor 2 , every time .
CURSOR cursor1
IS
select a.* ,a.rowid
FROM table1 a
WHERE a.table1.year = p_year;
CURSOR check_c2(lv_cd )
IS
Select DISTINCT 'Y'
from table2
where table2 ='R'
AND table2.year= p_year
and table2_code= lv_cd ;
BEGIN :
FOR r in cursor1 LOOP
EXIT WHEN cursor1%NOTFOUND;
OPEN check_c2(r.cd);
FETCH check_c2 INTO lv_check;
IF check_c2%NOTFOUND THEN
lv_check :='N';
END IF;
CLOSE check_c2;
IF lv_check ='Y' THEN
lv_msg =(r.col1,r.col2....r.col50, R code exists do not delete)
utl_file.put_line(lv_log_file, lv_msg, autoflush=>TRUE);
ELSE
DELETE from table1 where rowid= r.rowid
lv_msg =(r.col1,r.col2....r.col50, delete row)
utl_file.put_line(lv_log_file, lv_msg, autoflush=>TRUE);
END IF;
END LOOP;
Don't have enough reputation to write comments som will write as an answer.
Didn't you try to add some time marks to understand which parts are the most time spending?
Does table2 have index by year and code? What's the explain plan of cursor2 query? If yes - how many rows are there average for year+code combination?
If the amount of data selected overall from table 2 is huge - then it probably can be faster to do a single query with full scan/index range scan by year on table2, grouping and hash left outer join from table1 to table2 like
select a.*, a.rowid, nvl2(c.code, 'Y', 'N') check_col
from table1 a,
(
select distinct code
from table2 b
where b.year = p_year
) c
where a.year = p_year
and c.code(+) = a.cd
How about this? A 3-steps-operation:
Step 1: "save" rows you'll later delete
create table log_table as
select *
from table1 a
where exists (select null
from table2 b
where b.year = a.year
and b.code = a.code
);
Step 2: delete rows:
delete from table1 a
where exists (select null
from table2 b
where b.year = a.year
and b.code = a.code
);
Step 3: if you must, store rows saved in the LOG_TABLE into that file of yours. If not, leave them in LOG_TABLE.
utl_file.put_line in the loop will be an overhead.Try appending to lv_msg till length of the string is 32767 bytes and write just once.
This will definitely reduce the I/O and performance should be improved.

PROC SQL - Case when with multiple tables

I need to create a dataset (TABLE3) in order to check if some variables from other two tables are equals. If so, the code must return 0, otherwise 1. But, as I'm a new user of SAS and SQL I'm struggling to figure out how to do that.
I'm trying something like that but it's not working.
PROC SQL;
CREATE TABLE TABLE3 AS
SELECT A.*, B.*
CASE WHEN B.VARIABLE1 = A.VARIABLE2 THEN 0 ELSE 1 END AS VARIABLE_1_2,
CASE WHEN B.VARIABLE3 = A.VARIABLE4 THEN 0 ELSE 1 END AS VARIABLE_3_4
FROM TABLE1 AS A
LEFT JOIN TABLE2 AS B;
P.S.: Variables 1, 2, 3 and 4 are all character variables.
In addition to the tables relation you must add after the join, You miss a coma "," just before the first case.
For a JOIN condition to work, there must a ON clause
PROC SQL;
CREATE TABLE TABLE3 AS
SELECT A.*, B.*,
CASE WHEN B.VARIABLE1 = A.VARIABLE2 THEN 0 ELSE 1 END AS VARIABLE_1_2,
CASE WHEN B.VARIABLE3 = A.VARIABLE4 THEN 0 ELSE 1 END AS VARIABLE_3_4
FROM TABLE1 AS A LEFT JOIN TABLE2 AS B
**ON TABLE1.SOME_COLUMN_NAME = TABLE2.SOME_COLUMN_NAME**
;

Fetching data from tables whose names are stored in a table?

I have a table lets say table_names which contains some table names ( table1 , table2 ,table3 etc ). Now I want to fetch the data from table1 , table2 , table3 etc by going through the table table_names.
I am unable to achieve this task. Could anyone please help me out of this situation ?
I am using Oracle DB.
Thank you in advance.
If from TableA you have to get value from Single table then use this,
SELECT * FROM (SELECT table_name FROM tableA WHERE id=3)AS b
Otherwise from getting from multiple table, I prefer below PHP-
while($a=mysql_fetch_assoc(mysql_query((SELECT table_name FROM tableA)))
{ $tablename=$a[table_name];
while($b=mysql_fetch_assoc(mysql_query((SELECT * FROM $tablename))))
{
echo $b[column_name];
}
}
try this query:
DECLARE
str VARCHAR2(30);
num number(5);
BEGIN
SELECT count(*) into num FROM table_names;
FOR i in 1..num loop
SELECT name into str FROM
(SELECT ROWNUM r,t.name FROM table_names t) where r = i;
EXECUTE IMMEDIATE 'SELECT * FROM '||str;
str:='';
end loop;
END;
Select t1.,t2.,t3.* from table1 t1,table2 t2, table3 t3 where (select name from tables)

sql case statement update based on other table

I want to update a table (table1) based on the values of one or more fields in another table (table2). I believe this should be a case statement but I'm unsure how to incorporate a case statement and an update clause based on another table in one statement. Here's what I have so far which I know does not work:
update table1 i, table2 s
set i.sales = 'F'
where s.payment = 'Y'
and i.order_no = s.order_no;
I know how to do a select based on two tables but that's not very helpful since I don't want to create a new database object - I just want to update an existing object (table1):
create or replace view merge as
select
i.order_no
, case when s.payment = 'Y'
then 'F'
end as sales
from table1 i, table2 s
where i.order_no = s.order_no;
And I know how to update WITHIN a case statement:
UPDATE table1
SET sales = (
SELECT CASE
WHEN foo = 'X'
THEN 'F'
ELSE null
END
FROM table1
)
;
I considered a where clause instead of a case statement but it ends up selecting EVERY record and the 2nd table definitely has different values in the payment field:
update t1
set sales = 'F'
where exists (select table2.payment
from table2
where table2.order_no = table1.order_no
and table2.payment = 'Y');
try this:
update table1 i
set i.sales = (select case when x.payment = 'Y'
then 'F'
else i.sales end
from table2 x
where x.order_no = i.order_no);
I don't have an oracle running right now (so I cannot check the syntax propertly), but I think you can try something like this:
update table1 i
set i.sales = 'F'
where i.order_no IN (select s.order_no from table2 s where s.payment = 'Y')
Hope it helps!

Determine if a row for an fk exists in any one of 20 tables

I was trying to determine a better way than so many IF/THEN statements to determine if ONE OR MORE tables contain a ref to a forign key. I simply need to know (true/false) if a row exists in any one of 20 tables. All tables have the same fk field.
I hope this makes sense, if not i'll try to explain further.
I'm not sure I understand the question. Would the following improve your situation?
if exists(select * from Table1 where ForeignKeyColumn = searchValue)
or exists(select * from Table2 where ForeignKeyColumn = searchValue)
or exists(select * from Table3 where ForeignKeyColumn = searchValue)
or ...
Assuming that the 20 tables remains consistant then what about using a left outer join to each of the tables. probably inefficient way of doing it but should work
select Id from
(Select PK.id, isnull(tbl1.fk,0) as fk1, isnull(tbl2.fk,0) as fk2 ... etc
from pk left join tbl1 on pk.id = tbl1.fk left join
tbl2 on pk.id = tbl2.fk ... etc) as VirtualTable
Where fk1>0 or fk2>0 ... etc
So you're trying to work out if you can remove a particular row?
So... perhaps try:
begin tran;
delete tablename
where id = 3;
rollback tran;
Then see what error you get (if any), and how many rows are affected.
What about something like:
if exists (
select * from Table1 where MyKey = #key
union
select * from Table2 where MyKey = #key
union
select * from Table3 where MyKey = #key
...
)
I don't have a SQL server instance open in front of me so I'm sure that's got a syntax error somewhere, but you get the idea =)