PL/SQL and date intervals - oracle

I have a date and I'd like to print the offset from that date. I can do this:
dbms_output.put_line(to_char(g_startDate - interval '4' month ,'YYYY-MM-DD'));
and it works fine. The problem is that the interval is variable. When I try this:
dbms_output.put_line(to_char(g_startDate - interval g_dateOffsetAmt month ,'YYYY-MM-DD'));
I get a compiler error.
I thought it might be because g_dateOffsetAmt is an integer so I tried this:
dbms_output.put_line(to_char(g_startDate - interval to_char(g_dateOffsetAmt) month ,'YYYY-MM-DD'));
Though I still get compiler errors saying:
Error: PLS-00103: Encountered the symbol "TO_CHAR" when expecting one of the following:
. ) , * # & | = - + at in is mod remainder not rem =>
.. or != or ~= >= and or like
LIKE2_ LIKE4_ LIKEC_ as between from using || member
SUBMULTISET_
The symbol "," was substituted for "TO_CHAR" to continue.
Line: 704
Error: PLS-00103: Encountered the symbol "MONTH" when expecting one of the following:
. ( ) , * % & | = - + at in is mod remainder not range
rem => .. or != or ~= >= and or
like LIKE2_ LIKE4_ LIKEC_ between || multiset member
SUBMULTISET_
The symbol "." was substituted for "MONTH" to continue.
Line: 704
Is there some other way to do this?

You would probably want to use the NumToYMInterval function
declare
v_interval pls_integer := 4;
begin
dbms_output.put_line( sysdate - NumToYMInterval( v_interval, 'month' ) );
end;
/

There are a couple ways to do this.. Either type your variable being passed in as an interval, or use the function add_months instead:
declare
v_interval INTERVAL YEAR TO MONTH := interval '4' month;
begin
dbms_output.put_line(to_char((sysdate - v_interval), 'MM/DD/YYYY'));
end;
declare
v_interval PLS_INTEGER := 4;
begin
dbms_output.put_line(to_char(add_months(sysdate, -v_interval), 'MM/DD/YYYY'));
end;

Related

PLS-00103 Encountered symbol ">" error while executing stored prcedure

I am having below stored procedure, when I try to execute it throws error. All the things are proper but don't know why this error it throws. can anybody help me to sort out this.
create or replace PROCEDURE FR_Notes_Mng (
P_STR_ID IN VARCHAR2,
p_Ref_no in VARCHAR2,
P_UserId in VARCHAR2,
P_Note IN VARCHAR2,
P_datestamp IN VARCHAR2,
p_Request_ID in varchar2,
p_WrittenDate IN VARCHAR2
) AS
numSqlCode Number := 0;
RecCounter Number :=0;
strTable varchar2(30) := 'FR_Notes';
strAction varchar2(30) := 'Insert';
vSQLERM VARCHAR2(200) :=SUBSTR(SQLERRM, 1, 85);
BEGIN
Select Count(*) into RecCounter From FR_Notes where str_id=P_str_ID and ref_no=P_Ref_No and user_id=P_UserId and notes=P_note and datestamp=P_Datestamp and to_date(writtendate,'YYYYMMDDHH24MISS')=to_Date(p_WrittenDate,'YYYYMMDDHH24MISS') and request_id=p_request_id;
If RecCounter=0 then
insert into Fr_Notes Values
(p_str_ID,p_ref_no,p_UserId,P_note,p_Datestamp,to_date(p_WrittenDate,'YYYYMMDDHH24MISS'),p_Request_ID,'FR',sysdate);
commit;
end if;
EXCEPTION
WHEN OTHERS THEN
numSqlCode := SQLCODE;
INSERT INTO FR_UNEXPECTED_ERRORS (TABLE_NAME, KEY, ACTION, ERR_CODE)
VALUES (strTable, vSQLERM, strAction, numSqlCode);
END;
Error Thrown:
ORA-06550: line 1, column 47: PLS-00103: Encountered the symbol ">" when expecting one of the following: . ( ) , * # % & = - + < / > at in is
mod remainder not rem <> or != or ~= >= <= <>
and or like like2 like4 likec between || multiset member submultiset
When I execute it at database level its executed properly but failed in vbscript code. Below is the vb-script code I used to execute and which is throwing this error
function InsertNotes(str_id,ref_no,userId,Note,strdatestamp,writtenDates)
Dim strcon2: set strcon2=server.CreateObject("ADODB.Connection")
Dim sql2
Dim strcmd2
strcon2.open "Provider=MSDAORA;Data Source="&Application("DBDsn")&";User Id="&Application("DBUserName")&"; Password="&Application("DBPassword")&";"
sql2 = "rep2.FR_Notes_Mng"
Set strcmd2 = Server.CreateObject("ADODB.Command")
Set strcmd2.ActiveConnection = strCOn2
strcmd2.CommandText = sql2
strcmd2.CommandType = 4
strcmd2.Parameters.Append strcmd2.CreateParameter("p_str_id", 200,1,50,str_id)
strcmd2.Parameters.Append strcmd2.CreateParameter("p_ref_no", 200,1,50,ref_no)
strcmd2.Parameters.Append strcmd2.CreateParameter("p_UserId", 200,1,50,userId)
strcmd2.Parameters.Append strcmd2.CreateParameter("p_note", 200,1,200,Note)
strcmd2.Parameters.Append strcmd2.CreateParameter("p_Datestamp", 200,1,50,strdatestamp)
strcmd2.Parameters.Append strcmd2.CreateParameter("p_Request_id", 200,1,50,"012")
strcmd2.Parameters.Append strcmd2.CreateParameter("p_WrittenDate", 200,1,50,writtenDates)
strcmd2.Execute
end function
Actually I have checked what values are getting passed in VB script call to that stored procedure and found that value for str_id is not getting passed hence the procedure execution was getting failed and throwing above error.
ORA-06550: line 1, column 47: PLS-00103: Encountered the symbol ">" when expecting one of the following: . ( ) , * # % & = - + < / > at in is
mod remainder not rem <> or != or ~= >= <= <>
and or like like2 like4 likec between || multiset member submultiset
I have assigned one value to str_id variable and rechecked by executing the code and it worked properly.
One thing I came to know here by this error which is, when we don't pass required parameter value or we pass the parameter as null even if it is mandatory that time this type of error get generated.
Thanks for all who helped me over this ask.

How we can 1 MONTH in a DateType variable in Oracle Stored Procedure

I want to add 1 Month in v_TempEffectiveDate. What will be the correct statement?
WHILE v_TempEffectiveDate <= v_EndDate LOOP
v_TempEffectiveDate := ADD_MONTHS('v_TempEffectiveDate' + 1); --v_TempEffectiveDate + 1 MONTH
v_MonthsElapsed := v_MonthsElapsed + 1;
END LOOP; --WHILE v_TempEffectiveDate <= v_EndDate
v_MonthsElapsed := v_MonthsElapsed - 1;
I got the following error:
PL/SQL : statement is ignored PLS-00306: worng number or type of argument in call to "ADD_Months()

Error(31,64): PLS-00103: Encountered the symbol "(" when expecting one of the following

I have below function in oracle,
create or replace FUNCTION CALINTEREST
( DNumber IN VARCHAR2,
IRate IN NUMBER
) RETURN NUMBER IS
AInterest NUMERIC(17,8):=0;
PDue NUMERIC(11,2);
IDue NUMERIC(17,8);
INTRate NUMERIC(5,2);
IntDate DATE;
IntDATEDIFF NUMERIC(6):=0;
BEGIN
BEGIN
SELECT
DBRD_PRI_DUE,
DBRD_INT_DUE,
DBRD_INT_RATE,
DBRD_INT_DATE INTO
PDue
,IDue
,INTRate
,IntDate
FROM
DBRD
WHERE
DBRNO = DNumber;
IF(INTRate = 999)
THEN
INTRate := IRate;
END IF;
IntDATEDIFF:=Cast((Sysdate-IntDate) AS NUMBER(11,0));
AInterest := IDue + (PDue * INTRate * IntDATEDIFF / 365 / 100);
END;
RETURN AInterest;
END;
I am getting below two error,
Error(31,64): PLS-00103: Encountered the symbol "(" when expecting one of the following: . ) # % The symbol ")" was substituted for "(" to continue.
Error(31,70): PLS-00103: Encountered the symbol ")" when expecting one of the following: . ( * % & = - + ; < / > at in is mod remainder not rem <> or != or ~= >= <= <> and or like like2 like4 likec between || multiset member submultiset The symbol "(" was substituted for ")" to continue.
Not sure if this will work for you. On my machine the only errors I get on compilation have to do with the table DBRO (because I don't have a table by that name), but that doesn't mean this does the computations you want it to do. Anyway, play with it and write back if you have more questions.
I changed NUMERIC to NUMBER (the correct name of the Oracle data type for numbers), I changed the computation for IntDATEDIFF in a way that will be immediately obvious when you look at it (Trunc changes the time portion of an Oracle DATE to 00:00:00, and taking the arithmetic "minus" between two dates returns the difference as a number of days), and I removed BEGIN and END; for the inner block- there was no need for an inner block.
create or replace FUNCTION CALINTEREST
( DNumber IN VARCHAR2,
IRate IN NUMBER
) RETURN NUMBER IS
AInterest NUMBER(17,8):=0;
PDue NUMBER(11,2);
IDue NUMBER(17,8);
INTRate NUMBER(5,2);
IntDate DATE;
IntDATEDIFF NUMBER(6):=0;
BEGIN
SELECT
DBRD_PRI_DUE,
DBRD_INT_DUE,
DBRD_INT_RATE,
DBRD_INT_DATE INTO
PDue
,IDue
,INTRate
,IntDate
FROM
DBRD
WHERE
DBRNO = DNumber;
IF(INTRate = 999)
THEN
INTRate := IRate;
END IF;
IntDATEDIFF:=trunc(Sysdate) - trunc(IntDate);
AInterest := IDue + (PDue * INTRate * IntDATEDIFF / 365 / 100);
RETURN AInterest;
END;
/
create or replace FUNCTION CALINTEREST(
DNumber IN VARCHAR2,
IRate IN NUMBER
) RETURN NUMBER
IS
PDue NUMERIC(11,2);
IDue NUMERIC(17,8);
INTRate NUMERIC(5,2);
IntDate DATE;
BEGIN
SELECT DBRD_PRI_DUE, DBRD_INT_DUE, DBRD_INT_RATE, DBRD_INT_DATE
INTO PDue, IDue, INTRate, IntDate
FROM DBRD
WHERE DBRNO = DNumber;
IF (INTRate = 999) THEN
INTRate := IRate;
END IF;
RETURN IDue + (PDue * INTRate * TRUNC(SYSDATE - IntDate) / 365 / 100);
END;
/
SHOW ERRORS;
Or moving the logic into SQL:
create or replace FUNCTION CALINTEREST(
DNumber IN VARCHAR2,
IRate IN NUMBER
) RETURN NUMBER
IS
p_interest NUMBER(17,8);
BEGIN
SELECT DBRD_INT_DUE
+ ( DBRD_PRI_DUE
* CASE DBRD_INT_RATE
WHEN 999 THEN IRate
ELSE DBRD_INT_RATE
END
* TRUNC( SYSDATE - DBRD_INT_DATE )
/ 365
/ 100
)
INTO p_interest
FROM DBRD
WHERE DBRNO = DNumber;
RETURN p_interest;
END;
/
SHOW ERRORS;

PLSQL-Expected One of The Following

I have created following query. However, I got error below. I think that error is related to TO_CHAR(' AND MARITAL_STATUS in ('Married-civ-spouse') ') line. How can I define this other ways?
Thanks in advance.
Error:
PLS-00103: Encountered the symbol ") " when expecting one of the following:
. ( ) , * # % & = - + < / > at in is mod remainder not rem =>
<an exponent (**)> <> or != or ~= >= <= <> and or like like2
like4 likec between || member
06550. 00000 - "line %s, column %s:\n%s"
This is my code:
SET SERVEROUTPUT ON;
DECLARE
KATSAYI1 VARCHAR2(1000):=TO_CHAR('CREATE TABLE DQ_DNM2 AS SELECT * FROM DQ_TEST_DATA WHERE YEARMONTH=');
KATSAYI2 varchar2(100) := TO_CHAR(sysdate,'YYYY');
KATSAYI3 VARCHAR2(100) := TO_CHAR(KATSAYI2-2);
KATSAYI4 varchar2(100) := to_char(sysdate, 'MM');
KATSAYI7 varchar2(100) := to_char(KATSAYI4 + 11);
KATSAYI5 varchar2(100) := to_char(CONCAT(KATSAYI3,KATSAYI7));
KATSAYI6 VARCHAR2(1000):=TO_CHAR(CONCAT(KATSAYI1,KATSAYI5));
KATSAYI8 VARCHAR2(100) :=TO_CHAR(' AND MARITAL_STATUS in ('Married-civ- spouse') ');
KATSAYI9 varchar2(100) := to_char(CONCAT(KATSAYI6,KATSAYI8));
BEGIN
dbms_output.put_line( KATSAYI5);
DBMS_OUTPUT.PUT_LINE('İlgili tablo yaratıldı.');
EXECUTE IMMEDIATE KATSAYI9;
END;
/code here
Use chr(39) instead of '
select 'That'||chr(39)||'s the right way' from dual
will give you
That's the right way
You can use q'[ ]' to escape all characters and new lines
Example:
select q'[That's the right way also "" '' !##$%^&*()_=+
anything you want... ]' from dual
That's the right way also "" '' !##$%^&*()_=+
anything you want...
This approach is good for dynamic code execution, where you don't need to worry about escaping variables and concatenations; you just write your code in the same format of what will be executed. better in readability of your code.
You appear to be taking 2 off the years and adding 11 to the months (so in effect taking off 13 months):
SET SERVEROUTPUT ON;
DECLARE
p_yyyymm char(6) := TO_CHAR( ADD_MONTHS( SYSDATE, -13 ), 'YYYYMM');
BEGIN
DBMS_OUTPUT.PUT_LINE( p_yyyymm );
DBMS_OUTPUT.PUT_LINE('İlgili tablo yaratıldı.');
EXECUTE IMMEDIATE 'CREATE TABLE DQ_DNM2 AS SELECT * FROM DQ_TEST_DATA WHERE YEARMONTH=''' || p_yyyymm || ''' AND MARITAL_STATUS in (''Married-civ- spouse'')';
END;
Thanks for your answers. Using double quotes worked in this case. Before opening this thread, I tried to use (") . Dont use that. Use double quotes.

Oracle Database PLSQL Error: PLS-00103

I'm writing simple function in Oracle Database 11g that count summary salary for employee. For this we need to count days with specific status. Days is present as fields in table (Day_1, Day_2, ..., Day_30).
But i have got error during compilation:
Error(50,9): PLS-00103: Encountered the symbol ";" when expecting one of the following: :=.(#%;
Code of my package (a place where there is an error marked in code of function f2):
CREATE OR REPLACE PACKAGE pack IS
FUNCTION f1 (id IN NUMBER) return t2 PIPELINED;
FUNCTION f2 (id IN NUMBER) return number;
end pack;
/
CREATE OR REPLACE PACKAGE BODY pack IS
FUNCTION f1 (id IN NUMBER) return t2 PIPELINED IS
name VARCHAR2(50);
num number;
BEGIN
FOR i IN 1 .. id LOOP
SELECT отдел
into name
from отдел
where ид_отдела = i;
select sum(КОЛИЧЕСТВО)
into num
from Таблица_3
join Таблица_2
on Таблица_3.КТО_ПРОДАЛ = Таблица_2.ЧЛВК_ИД
where отдел = i;
PIPE ROW( t1(i, name, num) );
END LOOP;
RETURN;
END f1;
FUNCTION f2 (id IN NUMBER) return NUMBER AS
WorkingDays NUMBER := 0;
CurrentDay VARCHAR2(50);
Salary NUMBER := 120;
Total NUMBER := 0;
BEGIN
FOR i IN 1 .. 30 LOOP
EXECUTE IMMEDIATE 'SELECT День_' || i || ' FROM Таблица_2 WHERE ЧЛВК_ИД = id INTO CurrentDay';
IF WorkingDays IN ('КОМАНДИРОВКА','ВЫХОДНОЙ','ПРАЗДНИК') THEN -- <--- Here
WorkingDays := WorkingDays + 1;
END IF;
END LOOP;
Total : = Salary * WorkingDays;
RETURN Total;
END f2;
end pack;
/
How can i solve this? Maybe the problem is in the logic of the program?
That is an error on parsing, and be aware that it often does not accurately show the error itself, but where the next symbol error occurred. For example:
declare
x number;
y number;
begin
if x = 1 then
y := 1 --I forget to put on the semi-colon to end the line
end if;
end;
You'd expect an error on the missing semi-colon. What you get is:
ORA-06550: line 7, column 2:
PLS-00103: Encountered the symbol "END" when expecting one of the following:
* & = - + ; < / > at in is mod remainder not rem
<an exponent (**)> <> or != or ~= >= <= <> and or like like2
like4 likec between || multiset member submultiset
The symbol ";" was substituted for "END" to continue.
Since in your comments you talk about changing things - perhaps to make it more readable for us (and thank you!), it may be obscuring the actual syntax glitch.
Two things I notice:
Total : = Salary * WorkingDays;
That has a space between the : and = that shouldn't be there
and:
FUNCTION f2 (id IN NUMBER) return NUMBER AS
which is normally
FUNCTION f2 (id IN NUMBER) return NUMBER IS

Resources