Pl-sql Procedure to print table details - plsql

SQL. I have created 1 procedure but I am not getting the desired output. My procedure is below:
--/
CREATE OR REPLACE procedure Update_TB_INTERACTLOG
IS
BEGIN
FOR records in (select TNAME from tab where TNAME like 'TB_INTERACTLOG%' and TABTYPE = 'TABLE')
LOOP
dbms_output.put_line(records.TNAME||' modified');
END LOOP;
END;
/
There are 7 records I am getting from select query.
This I am getting in Log Output.
13:10:02 [CREATE - 0 row(s), 0.031 secs] Command processed. No rows were affected
... 1 statement(s) executed, 0 row(s) affected, exec/fetch time: 0.031/0.000 sec [0 successful, 1 warnings, 0 errors]

It looks as if you have created the procedure but not executed it. To execute it, run the following code:
exec Update_TB_INTERACTLOG;
Furthermore, you will need to turn on DBMS output in the tool you're using to run it (unless it's SQL*plus).
And please not that the procedure wasn't properly compiled (1 warnings). The procedure should probably end with:
END Update_TB_INTERACTLOG;
instead of:
END;

Related

Column sizes sometimes do not fit when I move data from table 'TABLE_1' to table 'TABLE_2'. oracle is sending an error as follows

I want to move data from one table to a table.
I wrote one plsql code for this process.
Column sizes sometimes do not fit when I move data from table 'TABLE_1' to table 'TABLE_2'.
oracle is sending an error as follows.
I have identified one exception to get rid of this error.
but this exception is in a static state.
I want to make this exception part dynamic.
that is, if this error occurs in other columns, I want to automatically increase the size of the column in those columns.
the following is the plsql code I wrote.
for example, an oracle insert operation may give the same error in the 'explanation' column.
I want to modify the size of the 'explanation' column.
if this error occurs,
I want to perform these operations automatically for each column.
DECLARE
SAYAC INTEGER;
SAYAC_2 INTEGER;
extension_already_exists EXCEPTION;
PRAGMA EXCEPTION_INIT(extension_already_exists, -12899);
BEGIN
SAYAC:=0;
FOR XX IN (SELECT
FILE_NO,
NAME,
EV_ADRESI,
explanation
FROM TABLE_1
WHERE NOT EXISTS (SELECT *
FROM TABLE_2
WHERE TABLE_2.FILE_NO = TABLE_1.FILE_NO )
)LOOP
BEGIN
SAYAC:=SAYAC+1;
EXECUTE IMMEDIATE 'INSERT INTO
TABLE_2(
FILE_NO,
NAME,
EV_ADRESI,
explanation
)
VALUES
(
:A,
:B,
:C,
:D
) '
using XX.FILE_NO,XX.NAME,XX.EV_ADRESI,xx.explanation
;
IF MOD(SAYAC,1000)=0 THEN
COMMIT;
END IF;
EXCEPTION WHEN extension_already_exists THEN
dbms_output.put_line('seviye cok buyuk = '||sqlcode||' FILE_NO = '||XX.FILE_NO||','||xx.EV_ADRESI);--this error may occur in other columns
EXECUTE IMMEDIATE 'ALTER TABLE TABLE_2 MODIFY EV_ADRESI,explanation VARCHAR2(100)'; --forexample xx.explanation
NULL; --I want to make this place dynamic
end;
END LOOP;
COMMIT;
END;
ORA-12899: value too large for column "HOSPITAL"."table_2"."EV_ADRESI" (actual: 34, maximum: 20)
ORA-06512: at line 20
That won't work anyway. Even if you capture the error and enlarge the column, you'd miss the offending row as you should repeat the previous insert (which failed).
From my point of view, you should first match columns' datatpyes and then move data from here to there in a simple manner.
By the way, why did you use dynamic SQL for insert? There's nothing dynamic there.

How to conditionally exit SQL Plus from PL/SQL

I have a main SQL script (say main.sql) which includes other files like so:
-- Contents of main.sql
##init.sql
##body.sql
This template is fixed and I have no control over it. I can only put any code into the included files. Init.sql consists of PL/SQL code. Main.sql is run using SQL Plus. Now I want the following behavior of init.sql:
if cond1 is true then init.sql should terminate the execution of main.sql with an error such that body.sql doesn't run
if cond2 is true then init.sql should terminate the execution of main.sql with success such that body.sql doesn't run either
if cond3 is true then init.sql should successfully exit and the execution of body.sql should start
I am trying to get this behaviour using RAISE_APPLICATION_ERROR together with WHENEVER SQLERROR EXIT as I've learned that this is the only way of terminating an execution in SQL Plus completely, but I have troubles in achieving the bullet No.2 as
I can't make init.sql exit to the operating system with 0 code. I've tried to set a bind variable and use WHENEVER SQLERROR EXIT :retcode but :retcode appears to be empty when EXIT is called even if dbms_output.put_line outputs the correct value of this variable immediately before calling RAISE_APPLICATION_ERROR
This situation is normal and I'd rather not have an Oracle exception appearing
Could you help me to accomplish the bullet No.2 or maybe suggest a totally different approach overall.
You could handle different return codes by conditionally calling one or another sql file containing the return code you like:
cond1.sql:
WHENEVER SQLERROR EXIT 1
cond2.sql:
WHENEVER SQLERROR EXIT 0
Then here is how your init.sql starts:
--> Variable for init condition
col the_cond New_value the_cond noprint
--> select into condition variable
Select decode(smthg, 1, 'cond1', 2, 'cond2') the_cond
From table Where (whatever);
-- call to the host for the file:
#/path/to/the_file/&the_cond
begin
-- then here an exception will cause exit, with return code set right before in file the_cond
end;
/
Not very satisfying, but hopping it helps :)
This should work:
init.sql:
WHENEVER SQLERROR EXIT 0
BEGIN
IF COND2 THEN
RAISE_APPLICATION_ERROR(-20001, 'Cant continue');
END IF;
END;
/
WHENEVER SQLERROR EXIT 1
BEGIN
IF COND1 THEN
RAISE_APPLICATION_ERROR(-20001, 'Cant continue');
END IF;
END;
/

ORA-00900: invalid SQL statement when using loop to insert rows

I'm trying to insert multiple rows into an Oracle 11g table by running the following in Aqua Data Studio (version 15.0.11), using this:
BEGIN
FOR i IN 1..700 LOOP
INSERT INTO lims.stock_template (
stock_template_id,
name,
group_id,
version,
version_status,
workflow_id,
amount,
stock_type_id,
aliquot_template_id,
auto_authorise,
reorder_amount
)
VALUES (
lims.sq_stock_template.nextval,
lims.sq_stock_template.currval,
21,
1,
'A',
51881,
0,
103,
2362,
'F',
0
);
END LOOP;
END;
/
but I get the following error:
>[Error] Script lines: 30-30 ------------------------
ORA-00900: invalid SQL statement
Script line 30, statement line 1, column 0
If I run just the INSERT statement by itself, it works just fine, but I want to be able to insert multiple rows in one operation.
I'm sure that I've run something similar in the past, but I can't see what the problem is.
Any help much appreciated.
Thanks
In your example, you included a BEGIN and END clause, which turns this into a "Anonymous PL/SQL Block"
http://docstore.mik.ua/orelly/oracle/prog2/ch15_03.htm
Within a PL/SQL block you can't execute a SQL statement directly. You have to use only PL/SQL. See attached example.
Now you can create a stored procedure to execute your insert and use Script Object to Window As -> Execute or Execute Bind. See below screenshot.
In a stored procedure or a stored procedure within a package you can do whatever you like!
create or replace procedure testMe as
begin
FOR i IN 1..700 LOOP
INSERT INTO lims.stock_template (
stock_template_id,
name,
group_id,
version,
version_status,
workflow_id,
amount,
stock_type_id,
aliquot_template_id,
auto_authorise,
reorder_amount
)
VALUES (
lims.sq_stock_template.nextval,
lims.sq_stock_template.currval,
21,
1,
'A',
51881,
0,
103,
2362,
'F',
0
);
END LOOP;
end;
This is EXACTLY analogous to typing every line in at the SQL prompt form the word begin to the word end;.
What is more then likely tripping you up is the slash at the bottom. In the CLI sqlPlus the end of the line with the semicolon ( ; ) causes it to run the process, hence :
select 'A' from dual;
The semicolon tells it to execute.
IF on the other hand you type in the word begin then it shifts mode and will accept semicolons anywhere and just keep adding your strings to the buffer. ON A BLANK LINE the type the / and return and it will try and execute your code.
I think if you remove the slash it will execute quite nicely.

Define Procedures inside Packages

I have created some Procedures in SQL Developer, and they are working fine. However I am now creating a Package to include all those Procedures, and can't seem to figure out the right way to code the Package as it returns the following error (refering to the PACKAGE BODY's CREATE):
PLS-00103: Encountered the symbol "CREATE"
Here is my code:
CREATE OR REPLACE PACKAGE package_test AS
PROCEDURE copy_object;
END package_test;
CREATE OR REPLACE PACKAGE BODY package_test AS
PROCEDURE copy_object IS
CURSOR object_cursor IS
SELECT COD_OBJECT, OBJECT_NAME FROM OBJECT;
object_rec object_cursor%rowtype;
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE DATABASE2.D_OBJECT';
FOR object_rec IN object_cursor
LOOP
INSERT INTO DATABASE2.D_OBJECT (COD_OBJECT,OBJECT_NAME) VALUES (object_rec.OOD_OBJECT,object_rec.OBJECT_NAME);
END LOOP;
COMMIT;
END copy_object;
END package_test;
I have done some searching and the only thing I can think of is maybe some problem related to the definition on the CURSOR...not sure though. Thanks in advance
I successfully ran this in sqlplus and sqldeveloper (F5 in sqldeveloper: "Run Script"). I changed the two dml statements since my schema is different.
SQL> CREATE OR REPLACE PACKAGE package_test AS
2
3 PROCEDURE copy_object;
4
5 END package_test;
6 /
Package created.
SQL>
SQL> CREATE OR REPLACE PACKAGE BODY package_test AS
2
3 PROCEDURE copy_object IS
4 CURSOR object_cursor IS
5 SELECT * from dual;
6
7 object_rec object_cursor%rowtype;
8
9 BEGIN
10 EXECUTE IMMEDIATE 'TRUNCATE TABLE DATABASE2.D_OBJECT';
11 FOR object_rec IN object_cursor
12 LOOP
13 NULL; --INSER INTO DATABASE2.D_OBJECT (COD_OBJECT,OBJECT_NAME) VALUES (object_rec.OOD_OBJECT,object_rec.OBJECT_
NAME);
14 END LOOP;
15 COMMIT;
16 END copy_object;
17 END package_test;
18 /
Package body created.
SQL>

Accessing Bind Variable in PL/SQL

I am trying to run a program in the Oracle express edition editor. When I execute the program, I get an error
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
Can anyone help me understand why I am getting an error and how to fix the code?
VARIABLE gvn_total_salary NUMBER;
DECLARE
vn_base_salary NUMBER := 3000;
vn_bonus NUMBER := 1000;
BEGIN
:gvn_total_salary := vn_base_salary + vn_bonus;
END;
The output I'm getting
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
Run By SYSTEM
Parsing Schema SYSTEM
Script Started Thursday, April 26, 2012
3 seconds ago
Elapsed time 0.01 seconds
Statements Processed 1
Successful 0
With Errors 1
With the declaration of the bind variable, that code works fine for me in SQL*Plus
SQL> VARIABLE gvn_total_salary NUMBER;
SQL> DECLARE
2 vn_base_salary NUMBER := 3000;
3 vn_bonus NUMBER := 1000;
4 BEGIN
5 :gvn_total_salary := vn_base_salary + vn_bonus;
6 END;
7 /
PL/SQL procedure successfully completed.
SQL> print gvn_total_salary
GVN_TOTAL_SALARY
----------------
4000
Can you connect to the database using SQL*Plus and run the same thing?
What are you actually trying to accomplish? This script won't execute in sqlplus or Oracle Developer or any PL/SQL execution environment I can think of. In fact, I don't understand how you are passing the bind variable :gvn_total_salary and how you can get the error you are describing. You should get something like "bind variable gvn_total_salary" not declared.

Resources