How to display output in Pl/SQL - sql

I was wondering if someone can help me figure out how to code so that it will display the output without me having to use the command select * from month_days when I run the program.
set serveroutput on
--- Drop Table
DROP TABLE MONTH_DAYS;
--- Create Table
CREATE TABLE MONTH_DAYS(cnt number(2), Month_ Varchar(9),Days_ Number(2));
Declare
mons varchar2(10);
dats varchar2(10);
i Binary_integer := 0;
Begin
loop
i:= i+1;
if i = 13 then
exit;
end if;
insert into month_days(cnt, month_, days_)`enter code here`
values
(i, to_char(add_months(to_date('20200112', 'YYYYDDMM'), i), 'Month'),
to_char(last_day(add_months(to_date('20200112', 'YYYYDDMM'), i)), 'DD'));
end loop;
DBMS_Output.Put_Line('The Month and Days for the year 2020'||Month_|| ''||Days_);
end;

Create or Replace function insert_date (mons varchar2, dats varchar2)
return varchar2
as
i Binary_integer := 0;
Begin
loop
i:= i+1;
if i = 13 then
exit;
end if;
insert into month_days(cnt, month_, days_)
//enter code here Didn't understood what you are trying to do here
values
(i, to_char(add_months(to_date('20200112', 'YYYYDDMM'), i), 'Month'), to_char(last_day(add_months(to_date('20200112', 'YYYYDDMM'), i)), 'DD'));
end loop;
return 'The Month and Days for the year 2020'||Month_|| ''||Days_;
end;
select insert_date(12,2) from dual;
Is this what you are looking for ??
I haven't tested this. I think it should work.

Use:
select
rownum cnt,
to_char(add_months(date '2020-12-01', rownum), 'Month') month_,
to_char(last_day(add_months(date '2020-12-01', rownum)), 'DD')) days_
from
dual
connect by
level <= 12;

If you're using sqlplus, try turning serveroutput on by using the following command.
set serveroutput on
if using another client program, look up the documentation for enabling server output.

Related

Error: Table or view does not exist in PL SQL package

I have a package called 'S_PKG' in schema 'A'. I want to migrate it into schema B. What I did was I copied the code and executed in B schema. Then I wanted to execute the following pl sql script in which the 'S_PKG' is used in schema B.
select to_char(sysdate,'YYYYMMDD - HH:MI:SS AM') date_time
from dual
/
insert into zzz_ccc
select zzz_ccc_seq.nextval,to_char(sysdate,'YYYYMMDD - HH:MI:SS AM'),
'Start S Load tab',8,user,(select * from global_name)
from dual
/
commit
/
insert into zzz
select zzz_seq.nextval,to_char(sysdate,'YYYYMMDD - HH:MI:SS AM'),
'Start S Load tab',
(select trim(ruser)||' '||trim(rdbase)
from zzz_ccc where ss = 8
and rr = (select max(rr) from zzz_ccc where ss = 8)),
null,null,null,null,null,null,
(select max(rr) from zzz_ccc where ss = 8)
from dual
/
commit
/
DECLARE
PV_PRD_ID VARCHAR2(5);
BEGIN
PV_PRD_ID := '3';
B.S_PKG.PR_MAIN (PV_PRD_ID);
COMMIT;
END;
/
commit
/
insert into tab_counts(created_dtm,
ora_database,ora_user,ora_table,cc,flg,
subj)
select sysdate,'ccenter','aim10_ccenter','s_package_run - rows',
no_of_rows,1,
'S Load Tab Run'
from s_package_run
where to_char(st_date,'YYYYMM-DD') = to_char(sysdate,'YYYYMM-DD')
and package_name = 'LOAD_TAB'
/
commit
/
insert into tab_counts(created_dtm,
ora_database,ora_user,ora_table,cc,flg,
subj)
select sysdate,'ccenter','aim10_ccenter','s_package_run - dur_min',
dur_min,2,
'S Load Tab Run'
from s_package_run
where to_char(st_date,'YYYYMM-DD') = to_char(sysdate,'YYYYMM-DD')
and package_name = 'LOAD_TAB'
/
insert into hrc_chk_mar14_24_1
select sysdate, 'B', 'COUNT 6 ', 's_load_tab',
null,null,null,null
from dual t1
/
insert into zzz
select zzz_seq.nextval,to_char(sysdate,'YYYYMMDD - HH:MI:SS AM'),
'End S Load tab',
(select trim(ruser)||' '||trim(rdbase)
from zzz_ccc where ss = 8
and rr = (select max(rr) from zzz_ccc where ss = 8)),
null,null,
null,null,null,null,
(select max(rr) from zzz_ccc where ss = 8)
from dual
/
commit
/
Then I got the following error.
ORA-00942: table or view does not exist
ORA-06512: at "B.S_PKG", line 109
ORA-06512: at "B.S_PKG", line 35
ORA-06512: at line 5
Then I searched for the package. But I could not find the exact table which gives me the error. Here is my package.
CREATE OR REPLACE PACKAGE BODY B.S_PKG is
PROCEDURE PR_Main(kseq number) IS
sql_stmnt varchar2(5000);
begin
select s_pkg_seq.nextval into dd from dual;
pkg_st_date := sysdate;
sql_stmnt:='truncate table s_msgs';
execute immediate sql_stmnt;
begin
for c_rec in (select * from s_test_1 where pkg_seq = kseq and
flg = 'as' order by pkg_ord)
loop
if substr(c_rec.run_sql,1,1) != '-' then
pkg_name := c_rec.run_sql;
PR_Msgs('*** '||c_rec.run_sql||' Started...', pkg_name||'.'||'pr_main');
else
PR_Msgs(c_rec.run_sql, pkg_name||'.'||'pr_main');
end if;
insert into s_test_3
values(sysdate,c_rec.run_sql,c_rec.pkg_seq,c_rec.pkg_ord,c_rec.prc_seq);
end loop;
end;
PR_LOAD_PRODUCT3(1,kseq);
PR_LOAD_PRODUCT3(2,kseq);
PR_LOAD_PRODUCT3(3,kseq);
PR_LOAD_PRODUCT3(4,kseq);
PR_LOAD_PRODUCT3(5,kseq);
PR_LOAD_PRODUCT3(6,kseq);
PR_LOAD_PRODUCT3(7,kseq);
PR_LOAD_PRODUCT3(8,kseq);
PR_LOAD_PRODUCT3(9,kseq);
PR_LOAD_PRODUCT3(10,kseq);
PR_LOAD_PRODUCT3(11,kseq);
begin
for c_rec in (select * from s_test_1 where pkg_seq = kseq and
flg = 'ae' order by pkg_ord)
loop
if substr(c_rec.run_sql,1,1) != '-' then
PR_Msgs('*** '||c_rec.run_sql||' End OK...', pkg_name||'.'||'pr_main');
else
PR_Msgs(c_rec.run_sql, pkg_name||'.'||'pr_main');
end if;
insert into s_test_3
values(sysdate,c_rec.run_sql,c_rec.pkg_seq,c_rec.pkg_ord,c_rec.prc_seq);
end loop;
end;
sql_stmnt:='insert into s_msgs_his select * from s_msgs where msg_ord > 0';
execute immediate sql_stmnt;
pkg_en_date := sysdate;
insert into s_package_run values (pkg_st_date,pkg_en_date,floor((pkg_en_date-pkg_st_date)*24*60),
(pkg_en_date-pkg_st_date)*24*60*60 - floor((pkg_en_date-pkg_st_date)*24*60)*60,gv_count,
pkg_name,null,dd);
end;
-- ==============================================================================================
-- ==============================================================================================
PROCEDURE PR_LOAD_PRODUCT3(pseq number, tseq number) is
sql_stmnt VARCHAR2(5000);
begin
prc_st_date := sysdate;
begin
for c_rec in (select * from s_test_1 where pkg_seq = tseq and
prc_seq = pseq and flg = 'bs' order by pkg_ord)
loop
prc_name := c_rec.run_sql;
PR_Msgs(c_rec.run_sql||' Started...', pkg_name||'.'||'pr_main');
insert into s_test_3
values(sysdate,c_rec.run_sql,c_rec.pkg_seq,c_rec.pkg_ord,c_rec.prc_seq);
end loop;
end;
begin
for c_rec in (select * from s_test_1 where pkg_seq = tseq and
prc_seq = pseq and flg = 'aa' order by pkg_ord)
loop
sql_stmnt := c_rec.run_sql;
execute immediate sql_stmnt;
insert into s_test_3
values(sysdate,c_rec.run_sql,c_rec.pkg_seq,c_rec.pkg_ord,c_rec.prc_seq);
end loop;
end;
begin
for c_rec in (select * from s_test_1 where pkg_seq = tseq and
prc_seq = pseq and flg = 'be' order by pkg_ord)
loop
if substr(c_rec.run_sql,1,1) != '-' then
PR_Msgs(c_rec.run_sql||' End OK...', pkg_name||'.'||'pr_main');
else
PR_Msgs(c_rec.run_sql, pkg_name||'.'||'pr_main');
end if;
insert into s_test_3
values(sysdate,c_rec.run_sql,c_rec.pkg_seq,c_rec.pkg_ord,c_rec.prc_seq);
end loop;
end;
select cc into gv_count
from cr2_test_2;
prc_en_date := sysdate;
insert into s_procedure_run values (prc_st_date,prc_en_date,floor((prc_en_date-prc_st_date)*24*60),
(prc_en_date-prc_st_date)*24*60*60 - floor((prc_en_date-prc_st_date)*24*60)*60,gv_count,
prc_name,pkg_name,dd);
end;
-- ==============================================================================================
-- ==============================================================================================
PROCEDURE PR_Msgs(pv_msg varchar2, pv_point varchar2) as
cc number(5);
Begin
select s_pkg2_seq.nextval into cc from dual;
insert into s_msgs values (sysdate, pv_msg, pv_point, user, '','',cc);
commit;
End;
-- ==============================================================================================
-- ==============================================================================================
END S_PKG;
/
Can anyone help me to find the error as I am new to PL SQL packages?
As far as I can tell, if you compiled the package when connected as user B and it was successful, then the only "unknown" information at that time is this:
sql_stmnt:='truncate table s_msgs';
i.e. the table you're truncating using dynamic SQL. sql_stmnt's value is a string, compiler doesn't check what's in there. But, when you actually execute it, then it finds out that there's no table s_msgs in user B's schema.
The same goes for
sql_stmnt:='insert into s_msgs_his select * from s_msgs where msg_ord > 0';
and table s_msgs_his.
As you moved everything from A to B, I guess that you should do the same with those tables. Do that and then try to run your code again.
[EDIT]
This is line 109:
for c_rec in (select * from s_test_1 where pkg_seq = tseq and
prc_seq = pseq and flg = 'aa' order by pkg_ord)
loop
sql_stmnt := c_rec.run_sql;
execute immediate sql_stmnt; --> line 109
Check what's written in S_TEST_1. Looks like some statement that is supposed to be executed dynamically, but - the table involved into it doesn't exist in schema B (or that user doesn't have privileges to use it).

Not able get data for today

I have below procedure MY_PROC.
CREATE PROCEDURE MY_PROC(
IN_VAR_FROM_DATE IN VARCHAR2,
OUT_DATA OUT SYS_REFCURSOR )
AS
TEMP_DATE DATE;
BEGIN
TEMP_DATE : = NVL(TO_DATE(IN_VAR_FROM_DATE,'DD-MON-RRRR'),SYSDATE);
IF(IN_VAR_FROM_DATE='CM') THEN
TEMP_DATE := SYSDATE;
END IF;
OPEN OUT_DATA FOR SELECT * FROM TABLE_NAME WHERE DATE_COLUMN>=TRUNC(TEMP_DATE );
EXCEPTION
WHEN OTHERS THEN
NULL;
END MY_PROC;
Now in above proc, When i am passing null as input param, i am getting values for sysdate. i want same when i will pass "CM" as input param but instead i am getting no data.
Please help. Thanks in advance.
Hmmm. . . I think this is the logic you want:
OPEN OUT_DATA FOR
SELECT *
FROM TABLE_NAME
WHERE DATE_COLUMN >= (CASE WHEN IN_VAR_FROM_DATE IS NULL OR IN_VAR_FROM_DATE = 'CM'
THEN TRUNC(sysdate)
ELSE TO_DATE(IN_VAR_FROM_DATE, 'DD-MON-RRRR')
END);
I think this is due to when you are passing 'CM' as input parameter your procedure tries to convert the CM in to date and you are getting exception in this case.
CREATE PROCEDURE MY_PROC(
IN_VAR_FROM_DATE IN VARCHAR2,
OUT_DATA OUT SYS_REFCURSOR )
AS
TEMP_DATE DATE;
BEGIN
IF(IN_VAR_FROM_DATE='CM') THEN
TEMP_DATE := SYSDATE;
ELSE
TEMP_DATE : = NVL(TO_DATE(IN_VAR_FROM_DATE,'DD-MON-RRRR'),SYSDATE);
END IF;
OPEN OUT_DATA FOR SELECT * FROM TABLE_NAME WHERE DATE_COLUMN>=TRUNC(TEMP_DATE );
EXCEPTION
WHEN OTHERS THEN
NULL;
END MY_PROC;

Trigger compilation error

I need some help in creating a trigger.
create or replace trigger trigger_one
before insert on Funtom_timesheet
for each row
Declare
V_id number;
V_hours number;
Begin
Select max(timesheet_ID)+1 into v_id from Funtom_timesheet
:new.timesheet_ID :=v_id;
select grade_hours into V_hours
from funtom_grade join funtom_employee
on emp_grade = grade_id
where empid = :new.timesheet_emp;
if V_hours >:new.timesheet_hours
else
:new.timesheet_overtime :=
:new.timesheet_hours-V_hours
:new.timesheet_hours:= V_hours;
END IF;
END;
/
please tell me which part of my code is wrong so I could work on it,
Thanks
You have many syntax errors - missing ; and then. There can't be if only with else part and without expression on it.
CREATE OR REPLACE TRIGGER TRIGGER_ONE
BEFORE INSERT ON FUNTOM_TIMESHEET
FOR EACH ROW
DECLARE
V_ID NUMBER;
V_HOURS NUMBER;
BEGIN
SELECT MAX(TIMESHEET_ID) + 1 INTO V_ID FROM FUNTOM_TIMESHEET;
:NEW.TIMESHEET_ID := V_ID;
SELECT GRADE_HOURS
INTO V_HOURS
FROM FUNTOM_GRADE
JOIN FUNTOM_EMPLOYEE
ON EMP_GRADE = GRADE_ID
WHERE EMPID = :NEW.TIMESHEET_EMP;
IF V_HOURS > :NEW.TIMESHEET_HOURS THEN
NULL;
ELSE
:NEW.TIMESHEET_OVERTIME := :NEW.TIMESHEET_HOURS - V_HOURS;
:NEW.TIMESHEET_HOURS := V_HOURS;
END IF;
END;
/
Also better use SEQUENCES instead of:
SELECT MAX(TIMESHEET_ID) + 1 INTO V_ID FROM FUNTOM_TIMESHEET;
:NEW.TIMESHEET_ID := V_ID;
When selecting form the same table as inserting, you can get MUTATING trigger error (http://www.dba-oracle.com/t_avoiding_mutating_table_error.htm)

How to get Numbers in number range by PL-Sql .?

here is my serial table.it has more than 1000 records.its with start number and end number.but between numbers not exist.
i need to add all number [start/between & end numbers] records in another temp table number by number
like below
EXIST TABLE
select concat(CARD_BULK_CODE,start_serial) startserial,concat(CARD_BULK_CODE,end_serial) endserial
from TSR_BULK_CARD_SERIALS
---------------------------
STARTSERIAL ENDSERIAL |
---------------------------
18126944 18126946 |
18141101 18141122 |
15150722 15150729 |
19069303 19069317 |
---------------------------
REQUIRED TABLE
-----------
SERIAL_NO |
-----------
18126944
18126945
18141101
18141102
....
-----------
seem its need pl-sql to implement this.
please help me to sort out this issue
I tried with below query with the help of dual.
but its very slow and not yet got results :-) running more than 1 Hour
select distinct concat(t.CARD_BULK_CODE,t.START_SERIAL)+level-1 SERIAL
from TSR_BULK_CARD_SERIALS t, dual
connect by level-1<=(concat(t.CARD_BULK_CODE,t.END_SERIAL ))-concat(t.CARD_BULK_CODE,t.START_SERIAL)
order by 1
EDIT :
Dear Alen & Dba.i tried with your ones and below error occured.
DECLARE
l_st NUMBER;
l_en NUMBER;
BEGIN
FOR rec IN (select concat(card_bulk_code, start_serial) startserial,concat(card_bulk_code, end_serial) endserial from tsr_bulk_card_serials)
LOOP
l_st := rec.startserial;
l_en := rec.endserial;
FOR rec1 IN l_st..l_en
LOOP
INSERT INTO temp(serial_no) values(rec1);
END LOOP;
END LOOP;
COMMIT;
END;
Error at line 1
ORA-01426: numeric overflow
ORA-06512: at line 9
Script Terminated on line 1.
One way to do it without resorting to plsql
WITH ranges AS
(
SELECT CONCAT(CARD_BULK_CODE, start_serial) startserial,
CONCAT(CARD_BULK_CODE, end_serial) endserial
FROM TSR_BULK_CARD_SERIALS
),
numbers(n) AS (
SELECT 0 n
FROM dual
UNION ALL
SELECT n + 1
FROM numbers
WHERE n <=
(
SELECT MAX(endserial - startserial)
FROM ranges
)
)
SELECT t.startserial + n.n SERIAL_NO
FROM ranges t JOIN numbers n
ON n.n <= t.endserial - t.startserial
ORDER BY SERIAL_NO
Here is SQLFiddle demo
Just write some PL/SQL - iterate through your table and insert rows in the temp table.
declare
l_start number;
l_end number;
begin
for r_rec in (select to_number(concat(card_bulk_code, start_serial)) startserial
, to_number(concat(card_bulk_code, end_serial)) endserial
from tsr_bulk_card_serials )
loop
l_start := r_rec.startserial;
l_end := r_rec.endserial;
for l_i in l_start..l_end loop
insert into your_temp_table;
end loop;
end loop;
end;
Try like this,
WITH t(ST, EN) AS
(
SELECT 18126944, 18126946 FROM dual
UNION
SELECT 18141101, 18141122 FROM dual
UNION
SELECT 15150722, 15150729 FROM dual
UNION
SELECT 19069303 , 19069317 FROM dual
)
SELECT DISTINCT st + LEVEL -1
FROM t
CONNECT BY LEVEL <= (SELECT en - st + 1 FROM DUAL)
ORDER BY 1;
/
Try something like this for PL/SQL,
DECLARE
l_st NUMBER;
l_en NUMBER;
BEGIN
FOR rec IN (SELECT * FROM t)
LOOP
l_st := rec.st;
l_en := rec.en;
FOR rec1 IN l_st..l_en
LOOP
INSERT INTO <your_tab>;
END LOOP;
END LOOP;
COMMIT;
END;
DECLARE
l_st NUMBER (20);
l_en NUMBER (20);
testnum NUMBER (4);
BEGIN
FOR rec IN (SELECT CONCAT (card_bulk_code, start_serial) startserial,CONCAT (card_bulk_code, end_serial) endserial FROM tsr_bulk_card_serials)
LOOP
l_st := TO_NUMBER (rec.startserial);
l_en := TO_NUMBER (rec.endserial);
testnum := l_en - l_st;
DBMS_OUTPUT.put_line (l_st);
DBMS_OUTPUT.put_line (l_en);
IF l_st < l_en
THEN
FOR rec1 IN 0 .. testnum
LOOP
l_st := l_st + 1;
INSERT INTO temp(serial_no) VALUES (l_st);
END LOOP;
END IF;
END LOOP;
COMMIT;
END;
above code helped me to sorted my issue
thanks all :-)

IF else condition in sql stored procedure

I'm trying to compile the stored procedure:
create
procedure checkFroud2(code IN varchar2, p_recordset OUT SYS_REFCURSOR)
AS
BEGIN
OPEN p_recordset FOR
if code='C' then
select * from emp
//dbms_output.putline('this is if block')
else if code='F' then
dbms_output.putline('this is else block')
else
dbms_output.putline('last else')
end if;
end checkFroud2;
but this is showing compile time errors. Can anybody suggest where the problem is?
CREATE
PROCEDURE checkFroud2(
code IN VARCHAR2,
p_recordset OUT SYS_REFCURSOR)
AS
BEGIN
IF code='C' THEN
dbms_output.put_line('this is if block');
OPEN p_recordset FOR
SELECT * FROM emp;
ELSIF code='F' THEN
--you can open p_recordset with dummy as
/*open p_recordset for select * from dual where 1 = 0; */
dbms_output.put_line('this is else block');
ELSE
/*open p_recordset for select * from dual where 1 = 0; */
dbms_output.put_line('last else');
END IF;
END checkFroud2;
/
var o refcursor;
BEGIN
CHECKfroud2
('C',:o);
END;
/
PRINT O;
The correct code is as follows:
create procedure checkFroud2(code IN varchar2, p_recordset OUT SYS_REFCURSOR)
AS
BEGIN
OPEN p_recordset FOR
if code='C' then
select * from emp
//dbms_output.putline('this is if block');
elsif code='F' then
dbms_output.putline('this is else block');
else
dbms_output.putline('last else');
end if;
end checkFroud2;
ELSE IF doesn't exist use ELSIF, also remove // before dbms_output.putline('this is if block').
This is an example in oracle 11g
CREATE OR REPLACE PROCEDURE PROC_EMP_CHECK
(
EMPNO1 IN NUMBER
, EMPNO2 IN NUMBER
)
AS
EMPONE_NOT_EXISTS EXCEPTION;
EMPTWO_NOT_EXISTS EXCEPTION;
BOTHEMP_NOT_EXISTS EXCEPTION;
EMPCOUNT1 NUMBER;
EMPCOUNT2 NUMBER;
BEGIN
SELECT COUNT(1) INTO EMPCOUNT1 FROM EMPLOYEES WHERE EMPLOYEE_ID=EMPNO1;
SELECT COUNT(1) INTO EMPCOUNT2 FROM EMPLOYEES WHERE EMPLOYEE_ID=EMPNO2;
BEGIN
IF( EMPCOUNT1=0 AND EMPCOUNT2=0)THEN
RAISE BOTHEMP_NOT_EXISTS;
ELSIF ( EMPCOUNT1=0) THEN
RAISE EMPONE_NOT_EXISTS;
ELSIF ( EMPCOUNT2=0) THEN
RAISE BOTHEMP_NOT_EXISTS;
dbms_output.put_line('ELSE BLOCK');
END IF;
END;
EXCEPTION
WHEN EMPONE_NOT_EXISTS THEN
dbms_output.put_line('EMP One not exit');
WHEN EMPTWO_NOT_EXISTS THEN
dbms_output.put_line('EMP two not exit');
WHEN BOTHEMP_NOT_EXISTS THEN
dbms_output.put_line('both not exit');
WHEN OTHERS THEN
dbms_output.put_line(SQLERRM);
END PROC_EMP_CHECK;
Use ELSIF instead of ELSE IF. By using ELSE IF you're opening up a new nested IF-block, which you're not closing.
Couple of errors:
1. Open record set for ??? For what??
2. ELSIF and no ELSE IF
3. where is ;
CREATE PROCEDURE CHECKFROUD2 ( CODE IN VARCHAR2,
P_RECORDSET OUT SYS_REFCURSOR )
AS
BEGIN
OPEN P_RECORDSET FOR SELECT * FROM DUAL;
IF CODE = 'C'
THEN
SELECT * FROM EMP;
ELSIF CODE = 'F'
THEN
DBMS_OUTPUT.PUTLINE ( 'this is else block' );
ELSE
DBMS_OUTPUT.PUTLINE ( 'last else' );
END IF;
END CHECKFROUD2;