Multiple "execute immediately" queries in Oracle - oracle9i

I have this sequence of queries:
begin
execute immediate 'drop table mytable1';
exception when others then null;
end;
begin
execute immediate 'drop table mytable2';
exception when others then null;
end;
begin
execute immediate 'drop table mytable3';
exception when others then null;
end;
but when I try to execute it in SQL Scratchpad it says "encountered the symbol begin" which pointed me that all the queries must be in one begin...
if I remove all the begin end exept for the first begin and last end it gives me
"invalid SQL statement" how to perform multiple drop table or multiple create table with the upper pattern and to check if the tables exist? I know that my style with exception when others then null; is considered bad practice similar to empty catch()'es in other languages but thats the easiest way for me to check if a table exists/not exists in oracle

BEGIN
EXECUTE IMMEDIATE 'drop table mytable1';
EXECUTE IMMEDIATE 'drop table mytable2';
EXECUTE IMMEDIATE 'drop table mytable3';
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
Works fine.
If you ask me, exception when others then null - should be be avoided. If you want to check if a table exists - query USER_TABLES
DECLARE
V_EXISTS NUMBER;
BEGIN
SELECT 1 INTO V_EXISTS FROM USER_TABLES WHERE TABLE_NAME = 'TEST';
IF V_EXISTS = 1 THEN
EXECUTE IMMEDIATE 'DROP TABLE TEST';
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Table not found');
END;
Regd: your comment, if you still want to go about using the method in your question, wrap it in a outside anonymous block
BEGIN
BEGIN
EXECUTE IMMEDIATE 'drop table mytable1';
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
BEGIN
EXECUTE IMMEDIATE 'drop table mytable2';
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
BEGIN
EXECUTE IMMEDIATE 'drop table mytable3';
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
END;
Result:
SQL> BEGIN
2
3 BEGIN
4 EXECUTE IMMEDIATE 'drop table mytable1';
5 EXCEPTION
6 WHEN OTHERS THEN
7 NULL;
8 END;
9
10 BEGIN
11 EXECUTE IMMEDIATE 'drop table mytable2';
12 EXCEPTION
13 WHEN OTHERS THEN
14 NULL;
15 END;
16
17 BEGIN
18 EXECUTE IMMEDIATE 'drop table mytable3';
19 EXCEPTION
20 WHEN OTHERS THEN
21 NULL;
22 END;
23
24 END;
25
26 /
PL/SQL procedure successfully completed.
SQL>

Related

Set a variable value in stored procedure and use in following query

How can I set a variable in stored procedure and use it in following query to be executed.
create or replace procedure sp1()
returns table (dealer_id varchar, dealershipgroup_name varchar)
language sql
as
$$
declare
create_query varchar;
res resultset;
MISSING_DEALER NUMBER(38,0) default 0;
begin
MISSING_DEALER := 100;
select_query := 'WITH CTE AS(
SELECT dealer_id,
CASE WHEN dealer_id=:MISSING_DEALER then \'Abc\'
WHEN dealershipgroup IS NULL then \'\'
ELSE dealershipgroup end as dealershipgroup FROM TBL )
select * from CTE';
res:= (execute immediate : select_query);
return table(res);
end;
$$;
call sp1();
Could someone please suggest how can I use MISSING_DEALER in the query. I am currently getting the following error
Uncaught exception of type 'STATEMENT_ERROR' on line 28 at position 9 : SQL compilation error: error line 8 at position 26 Bind variable :MISSING_DEALER not set
You need to concatenate the string parts of your SQL statement with the variable. This is covered in the documentation if you look at the end of the section here

How to write multi line query in snowflake scripting in stored procedure

create or replace procedure create_src_table()
returns table (name varchar, age number(10,0),dob date)
language sql as
$$
declare
create_query varchar;
res resultset;
begin
create_query := `CREATE TEMPORARY TABLE SRC_TEMP_TBL AS SELECT * FROM
(WITH CTE_1 AS (SELECT * FROM "DB"."DW"."USER_TBL" WHERE name='rahul'),
CTE_2 AS (SELECT * FROM CTE_1 WHERE CAST(DOB AS DATE)<2000-05-01)
SELECT name,age,dob FROM CTE_2 limit 10)`;
res := (execute immediate : create_query);
return table(res);
end;
$$;
call create_src_table();
Could someone please help in how to write multiline sql query. I found few answers that indicate using backtick in javascript but not sure how to achieve it in sql.
Multi-statement SQL should be wrapped inside BEGIN ... END block:
EXECUTE IMMEDIATE 'BEGIN
statement1;
statement2;
...
END;';
Sample:

Stored procedure is not getting complied

I am trying to run the below stored procedure in Oracle pl/sql. I am trying to fetch data from join in cursor using table 1 and table 2 and update the output in Table 3, however its giving me compliation error near declare. The queries are working fine.
create or replace PACKAGE BODY PKG_LOAD_BY_ROWID AS
PROCEDURE PRC_LOAD_BY_ROWID AS
DECLARE
N1 NUMBER;
VAR_ROWID_OBJECT VARCHAR2(255);
VAR_PRTY_FK VARCHAR2(255);
V_OUT_ERROR_MSG VARCHAR2(1000);
v_out_return_code number;
CURSOR C1 IS
SELECT PX.ROWID_OBJECT , A.PRTY_FK
FROM TABLE_1 PX
INNER JOIN
TABLE_2 A
ON
substr(PX.PKEY_SRC_OBJECT,8,INSTR(PX.PKEY_SRC_OBJECT,'|')+8)=A.ALT_ID_VAL
WHERE A.ALT_ID_TYP='DUMMY1' AND PX.ROWID_SYSTEM='SRC';
BEGIN
SELECT COUNT(1) INTO N1 FROM TABLE_3 WHERE SRC_SYSTEM='SRC2' AND ROWID_OBJECT IS NULL;
BEGIN
OPEN C1;
FOR i in 1..n1
LOOP
FETCH C1 INTO VAR_ROWID_OBJECT, VAR_PRTY_FK;
UPDATE TABLE3 SET ROWID_OBJECT= VAR_ROWID_OBJECT WHERE
SRC_KEY=VAR_PRTY_FK;
COMMIT;
END LOOP;
CLOSE C1;
v_out_return_code :=0;
DBMS_OUTPUT.put_line('Rowid_object updated successfully for VVA');
EXCEPTION
when others then
out_error_msg := 'Updation Error';
DBMS_OUTPUT.put_line (out_error_msg);
END;
END;
END PKG_LOAD_BY_ROWID;
However, I am getting compilation error:
Error(2,1): PLS-00103: Encountered the symbol "DECLARE" when expecting one of the following: begin function pragma procedure subtype type current cursor delete exists prior external language
Oracle Version:
You don't need Declare keyword for the procedure, it is only for anonymous block. Just remove declare and try it.

TADOQuery Including blank rows

When using the 'while not TADOQuery.Eof' with an microsoft Excel Workbook, it's including rows which are completely empty. Is there a way to stop including any rows that are completely blank as I don't need them?
You could exclude blank lines in the SQL used to open the spreadsheet. If the first row contains column headings like 'Column1', 'Column2', etc then the following SQL will not return rows where the value in the first column is blank
select * from [sheet1$]
where Column1 <> ''
Obviously the SQL could be a bit more specific (in terms of column values) about what you regard as constituting a blank row.
You'll have gathered that there are various ways to deal with variations in the contents of the column headers, but as the other answer shows, these are likely to be far more verbose than simply skipping blank rows inside the body of your main while not EOF loop to read the table contents, so I can't really see any benefit to not doing it by just skipping the blank rows.
Btw, ime the Excel data accessible via SQL behaves as though the query is automatically restricted to the UsedRange range in the Excel COM interface.
Original answer:
If I understand you correctly and you want to exclude empty rows after the query is opened, then next approach may help (but I think, that you should exclude these rows with SQL statement, as in #MartynA's answer). Here, empty rows are all rows, which have Null value for all fields.
procedure TForm1.btnDataClick(Sender: TObject);
var
i: Integer;
empty: Boolean;
begin
qry.First;
while not qry.Eof do begin
// Check for empty row. Row is empty if all fields have NUull value.
empty := True;
for i := 0 to qry.FieldCount - 1 do begin
if not qry.Fields[i].IsNull then begin
empty := False;
Break;
end{if};
end{for};
// Read record data if record is not empty
if not empty then begin
// Your code here ...
end{if};
// Next record
qry.Next;
end{while};
end;
Update:
It's an attempt to improve my answer. If the table structure is not known, you can query the table with always false WHERE clause to get this structure and generate an SQL statement dynamically:
procedure TForm1.btnDataClick(Sender: TObject);
var
i: Integer;
where: string;
begin
// Get column names
qry.Close;
qry.SQL.Clear;
qry.SQL('SELECT * FROM [SheetName] WHERE 1 = 0');
try
qry.Open;
except
ShowMessage('Error');
end{try};
where := '';
for i := 0 to qry.FieldCount - 1 do begin
where := where + '(' + qry.Fields[i].FieldName + ' <> '''') AND ';
end{for};
where := 'WHERE ' + Copy(where, 1, Length(where) - 5);
// Read data without "empty" rows
qry.Close;
qry.SQL.Clear;
qry.SQL('SELECT * FROM [SheetName] ' + where);
try
qry.Open;
except
ShowMessage('Error');
end{try};
end;

Create table with stored procedure in Teradata

I want to create a stored procedure where I can pass in variable to the WHERE clause below.
DROP TABLE fan0ia_mstr.Store_List;
CREATE TABLE fan0ia_mstr.Store_List AS(
SELECT
a11.ANA_Code,
a11.Premise_Name_Full,
a11.Store_Code,
a11.Estates_Segment,
a12.Post_Code
FROM Store_Dimension_Hierarchy a11
JOIN Location a12
ON a11.ANA_Code = a12.ANA_Code
WHERE a11.Area_Desc = 'VARIABLE' ) WITH DATA
PRIMARY INDEX (ANA_Code)
The VARIABLE will be a character string. I don't need to display the results, I just want the table to be created.
Also how do I trap any errors e.g. if the table doesn't exist for some reason I still want it to be created
thanks
As you don't have variable database/table/column names you simply need to wrap your existing code (slightly modified) into a Stored Procedure:
replace procedure myproc(IN variable varchar(100))
begin
BEGIN
-- simply try dropping the table and ignore the "table doesn't exist error"
DECLARE exit HANDLER FOR SQLEXCEPTION
BEGIN -- 3807 = table doesn't exist
IF SQLCODE <> 3807 THEN RESIGNAL; END IF;
END;
DROP TABLE fan0ia_mstr.Store_List;
END;
CREATE TABLE fan0ia_mstr.Store_List AS(
SELECT
a11.ANA_Code,
a11.Premise_Name_Full,
a11.Store_Code,
a11.Estates_Segment,
a12.Post_Code
FROM Store_Dimension_Hierarchy a11
JOIN Location a12
ON a11.ANA_Code = a12.ANA_Code
WHERE a11.Area_Desc = :variable ) WITH DATA
PRIMARY INDEX (ANA_Code);
end;
Of course a DELETE/INSERT or a Temporary table might be more efficient.
Edited... second option needs a execute immediate too...
CREATE PROCEDURE PROCEDURE1(
V_AREA_DESC IN VARCHAR2 )
AS
BEGIN
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE fan0ia_mstr.Store_List';
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
EXECUTE IMMEDIATE 'CREATE TABLE fan0ia_mstr.Store_List AS
(SELECT a11.ANA_Code,
a11.Premise_Name_Full,
a11.Store_Code,
a11.Estates_Segment,
a12.Post_Code
FROM Store_Dimension_Hierarchy a11
JOIN Location a12
ON a11.ANA_Code = a12.ANA_Code
WHERE a11.Area_Desc = ''' || v_area_desc || '''
) WITH DATA PRIMARY INDEX (ANA_Code)';
END PROCEDURE1;
but you can avoid drop / create with truncate / insert
CREATE PROCEDURE PROCEDURE1(
V_AREA_DESC IN VARCHAR2 )
AS
BEGIN
execute immediate 'truncate TABLE fan0ia_mstr.Store_List';
insert into fan0ia_mstr.Store_List (SELECT a11.ANA_Code,
a11.Premise_Name_Full,
a11.Store_Code,
a11.Estates_Segment,
a12.Post_Code
FROM Store_Dimension_Hierarchy a11
JOIN Location a12
ON a11.ANA_Code = a12.ANA_Code
WHERE a11.Area_Desc = v_area_desc
);
commit;
END PROCEDURE1;

Resources