How to run multiple statements in one sqlscript for Oracle - oracle

I'm trying to run a few statements in one sql file but it does not work.
declare
new_sequence INTEGER;
begin
select LAST_NUMBER + 1
into new_sequence
from user_sequences
where SEQUENCE_NAME = 'MLTS_SEQUENCE';
execute immediate 'Create sequence Table_SEQ start with '
|| new_sequence ||' increment by 1';
end;
If i run this block with the option 'execute as one statement' in the eclipse database plugin it works.
How can i mark the sqlscript to run each of these blocks as one statement, to execute the script later with sqlplus or something different than eclipse?
I tried GO in front and / at the end but that also didn't work.

As long as it's on its own line and left aligned, it should be ok in sql*plus:
SQL> create sequence MLTS_SEQUENCE start with 1 cache 20;
Sequence created.
SQL> select MLTS_SEQUENCE.nextval from dual;
NEXTVAL
----------
1
SQL> declare
2 new_sequence INTEGER;
3 begin
4 select LAST_NUMBER + 1
5 into new_sequence
6 from user_sequences
7 where SEQUENCE_NAME = 'MLTS_SEQUENCE';
8
9 execute immediate 'Create sequence Table_SEQ start with '
10 || new_sequence ||' increment by 1';
11 end;
12 /
PL/SQL procedure successfully completed.
SQL> select Table_SEQ.nextval from dual;
NEXTVAL
----------
22

The proper format for sqlplus is the following:
declare
...
begin
...
end;
/

Related

How to execute Dynamic sql with insert statement in Oracle

Below sql command is not working in procedure
PROCEDURE P_EMPDETAIL
AS
V_WHERE := 'E.EMP_ID = 123'B
BEGIN
EXECUTE IMMEDIATE 'INSERT INTO EMPLOYEE E ' || V_WHERE || ;
END;
It seems to me there are various issues with your syntax and approach (you shouldn't be using dynamic SQL this way), perhaps you should learn PL/SQL and reference the manuals. The insert statement is also wrong. Below is the correct syntax.
CREATE OR REPLACE PROCEDURE P_EMPDETAIL as
V_WHERE varchar2(100);
BEGIN
V_WHERE := 'E.EMP_ID = 123';
EXECUTE IMMEDIATE 'INSERT INTO EMPLOYEE E (colname) values (1) ' || V_WHERE;
END;
Well, not exactly like that (obviously; otherwise, you wouldn't be asking for help).
It is unclear what you want to do because syntax is really strange. If you wanted to insert a row into the table, then:
SQL> CREATE TABLE employees
2 (
3 emp_id NUMBER
4 );
Table created.
SQL> CREATE OR REPLACE PROCEDURE p_empdetail (par_emp_id IN NUMBER)
2 AS
3 l_str VARCHAR2 (200);
4 BEGIN
5 l_str := 'insert into employees (emp_id) values (:1)';
6
7 EXECUTE IMMEDIATE l_str
8 USING par_emp_id;
9 END;
10 /
Procedure created.
Testing:
SQL> EXEC p_empdetail(123);
PL/SQL procedure successfully completed.
SQL> SELECT * FROM employees;
EMP_ID
----------
123
SQL>

executing select statement stored in table column by replacing variable value dynamically

I have simple PL/SQL block with below code
declare
rule1 varchar2(100 char);
begin
for i in (select table_name from all_tables where table_owner='EqEDI') loop
execute immediate 'select rule_stmt from rulebook ' into rule1 ;
execute immediate rule1 into result;
dbms_output.put_line('Result is '||result);
end loop;
end;
the rule statement stored in table rulebook is :
"'select count(1) from '|| tablename"
I want this above statement to be executed for all tables present for given owner
but while executing, it does not replace tablename in query with actual tables.
How can I achieve this with simple PL/SQL block.
Regards
rulebook table's contents is kind of wrong. Not that you can NOT do it the way you stored select statement into it - it is just impractical as you have to remove single quotes, remove tablename (as you can't even bind it, but concatenate what cursor returned) ... too much unnecessary jobs to be done.
Also, check all_tables and names of its columns - there's no table_owner, just owner.
Therefore, I'd suggest you to store such a statement:
SQL> SELECT * FROM rulebook;
RULE_STMT
--------------------------------------------------------------------------------
select count(*) from
Fix your PL/SQL script:
SQL> SET SERVEROUTPUT ON
SQL>
SQL> DECLARE
2 rule1 VARCHAR2 (100 CHAR);
3 l_str VARCHAR2 (100);
4 result NUMBER;
5 BEGIN
6 FOR i IN (SELECT table_name
7 FROM all_tables
8 WHERE owner = 'SCOTT'
9 AND table_name = 'EMP')
10 LOOP
11 EXECUTE IMMEDIATE 'select rule_stmt from rulebook '
12 INTO rule1;
13
14 l_str := rule1 || i.table_name;
15
16 EXECUTE IMMEDIATE l_str
17 INTO result;
18
19 DBMS_OUTPUT.put_line ('Result is ' || result);
20 END LOOP;
21 END;
22 /
Result is 14
PL/SQL procedure successfully completed.
SQL>

Is it possible to take a stored procedure name as input parameter in another stored procedure and execute it?

I have a set of stored procedures with the same interface and one of these stored procedures will be passed to a runner stored procedure as an input parameter. How can I execute this stored procedure within the runner proc.
I tried this by using dynamic SQL. The code snippet I wrote for this:
v_proc_query := ':1(:2, :3)';
execute immediate v_proc_query using p_proc_name, p_param1, p_param2;
But the above statement give error: ORA-00900: invalid SQL statement
I'm using Oracle 12c.
What is the right approach to achieve the goal?
Something like this, perhaps?
SQL> set serveroutput on
SQL> create or replace procedure p_test (par_deptno in number)
2 is
3 l_cnt number;
4 begin
5 select count(*)
6 into l_cnt
7 from emp
8 where deptno = par_deptno;
9 dbms_output.put_line('count = ' || l_cnt);
10 end;
11 /
Procedure created.
SQL> create or replace procedure p_test_2 (par_proc_name in varchar2, par_deptno in number)
2 is
3 l_str varchar2(200);
4 begin
5 l_str := 'begin ' ||
6 dbms_assert.sql_object_name(par_proc_name) ||
7 '(' || par_deptno || ');' ||
8 'end;';
9 execute immediate l_str;
10 end;
11 /
Procedure created.
SQL> exec p_test_2('p_test', 10);
count = 3
PL/SQL procedure successfully completed.
SQL>

PL/SQL: How to enable all triggers in the schema?

I'm trying to make a procedure that uses a cursor that enables all triggers in my schema to be enabled. However, I'm getting this Error at line 16: PL/SQL: SQL Statement ignored which is the line that I use fetch for.
CREATE OR REPLACE PROCEDURE enable_trigg_proc
IS
v_trigger_name trigger_name.user_triggers%TYPE;
CURSOR enable_trigg_cur
IS
SELECT TRIGGER_NAME INTO v_trigger_name
FROM user_triggers
WHERE STATUS = 'DISABLED';
BEGIN
OPEN enable_trigg_cur;
LOOP
FETCH enable_trigg_cur INTO v_trigger_name ;
EXIT WHEN enable_trigg_cur%NOTFOUND;
EXECUTE IMMEDIATE 'ALTER TRIGGER v_trigger_name ENABLE';
END LOOP;
close enable_trigg_cur;
END;
You don't need that much code:
SQL> begin
2 for cur_r in (select trigger_name from user_triggers) loop
3 execute immediate 'alter trigger ' || cur_r.trigger_name || ' enable';
4 end loop;
5 end;
6 /
PL/SQL procedure successfully completed.
SQL>
What's wrong with your code? INTO is required in PL/SQL's SELECT statement, but not within the cursor declaration. Also, you declared the variable in the wrong manner; should be
SQL> CREATE OR REPLACE PROCEDURE enable_trigg_proc
2 IS
3 CURSOR enable_trigg_cur
4 IS
5 SELECT TRIGGER_NAME
6 FROM user_triggers
7 WHERE STATUS = 'DISABLED';
8
9 v_trigger_name user_triggers.trigger_name%TYPE;
10 BEGIN
11 OPEN enable_trigg_cur;
12 LOOP
13 FETCH enable_trigg_cur INTO v_trigger_name ;
14 EXIT WHEN enable_trigg_cur%NOTFOUND;
15
16 EXECUTE IMMEDIATE 'ALTER TRIGGER ' || v_trigger_name || ' ENABLE';
17 END LOOP;
18 close enable_trigg_cur;
19 END;
20 /
Procedure created.
SQL> exec enable_trigg_proc;
PL/SQL procedure successfully completed.
SQL>

Execute Immediate?

Why do we use execute immediate command in PL/SQL?
I'm looking at some procedures written by a previous colleague, and I see that the person has used execute immediate a lot many time to log the progress of the procedure and also when truncating the tables.
My question is why would he do so? Can we not just truncate tables just like that in pl/sql proc?
Oracle wouldn't allow execution of DDL inside executable block. This is not allowed
begin
alter table . . .
end;
Originally Oracle had SYS.DBMS_DDL package to do this job. But it was cumbersome to use, so oracle introduced execute immediate circa v9.
Apart from executing DDL from PL/SQL (which you've already been told), execute immediate is used to run dynamic SQL. What would that be? Creating statements that depend on information that is not known at the time you're creating the PL/SQL procedure. For example, selecting from several tables in your schema:
SQL> set serveroutput on
SQL> declare
2 l_str varchar2(1000);
3 l_cnt number;
4 begin
5 for cur_r in (select table_name from user_tables
6 where table_name in ('EMP', 'DEPT', 'BONUS')
7 )
8 loop
9 l_str := 'select count(*) from ' || cur_r.table_name;
10 execute immediate l_str into l_cnt;
11 dbms_output.put_line(cur_r.table_name ||': '|| l_cnt);
12 end loop;
13 end;
14 /
BONUS: 0
DEPT: 4
EMP: 14
PL/SQL procedure successfully completed.
SQL>
Similarly, you might create a function that uses table (or column) names dynamically, e.g.
SQL> create or replace function f_cnt (par_table_name in varchar2)
2 return number
3 is
4 l_str varchar2(1000);
5 l_cnt number;
6 begin
7 l_str := 'select count(*) from ' || dbms_assert.sql_object_name(par_table_name);
8 execute immediate l_str into l_cnt;
9 return l_cnt;
10 end;
11 /
Function created.
SQL> select f_cnt('emp') from dual;
F_CNT('EMP')
------------
14
SQL>

Resources