I would like to set variable for date of first monday from sysdate and return this day in put_line but it's not working. I working on oracle database
SET serveroutput on;
DECLARE
first_monday DATE;
BEGIN
first_monday := select NEXT_DAY(sysdate, 'MONDAY') from dual;
DBMS_OUTPUT.PUT_LINE(first_monday);
END;
/
result should be 06-04-20
what is wrong?
my error below
ERROR at line 4:
ORA-06550: line 4, column 29:
PLS-00103: Encountered the symbol "SELECT" when expecting one of the following:
( - + case mod new not null <an identifier>
<a double-quoted delimited-identifier> <a bind variable>
continue avg count current exists max min prior sql stddev
sum variance execute forall merge time timestamp interval
date <a string literal with character set specification>
<a number> <a single-quoted SQL string> pipe
<an alternatively-quoted string literal with character set specification>
<an alternat
ORA-06550: line 4, column 73:
PLS-00103: Encountered the symbol ")" when expecting one of the following:
. , # ; for <an identifier>
<a double-quoted delimited-identifier> group having intersect
minus order partition start subpartition union where connect
ORA-06550: line 8, column 0:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
end not pragma final instantiable order overriding static
member constructor map
You can directly call next_day in PL/SQL (no need for a query). This is desirable because it doesn't cause a context switch between the PL/SQL engine and the SQL engine. Most, but not all, scalar functions can be used this way.
If you need to use it as part of a query then INTO is used to send a query result value into a variable.
Here are both in action.
DECLARE
first_monday DATE;
BEGIN
first_monday := next_day(SYSDATE,
'MONDAY');
dbms_output.put_line(first_monday);
SELECT next_day(SYSDATE,
'MONDAY')
INTO first_monday
FROM dual;
dbms_output.put_line(first_monday);
END;
/
The way to assign the result of a single row query to a variable in PL/SQL is via the INTO keyword. You need to change your code as follows:
DECLARE
first_monday DATE;
BEGIN
select NEXT_DAY(sysdate, 'MONDAY')
INTO first_monday
from dual;
DBMS_OUTPUT.PUT_LINE(first_monday);
END;
Related
I want to send a collection to a Function, but I keep getting an error.
I defined the RECORD and TYPES in my Package Header and Implemented the body aswell. I dont understand why I cant send a simple collection as a parameter, the idea is for me to loop through the collection and do some comparisation then return a char within a sql statement.
Been struggling with this for a week now, any help is appreciated.
Exact error:
ORA-06550: line 9, column 45:
PLS-00382: expression is of wrong type
ORA-06550: line 9, column 40:
PLS-00306: wrong number or types of arguments in call to 'TEST_F'
ORA-06550: line 9, column 23:
PL/SQL: ORA-00904: "PACKAGE_SS"."TEST_F": invalid identifier
ORA-06550: line 9, column 3:
PL/SQL: SQL Statement ignored
Header:
create or replace
PACKAGE PACKAGE_SS AS
type t_itemnumber is table of varchar2(100) index by BINARY_INTEGER;
type t_alternative_rec is record
(
itemnumber t_itemnumber
);
type t_alternative_prev is table of t_alternative_rec INDEX BY BINARY_INTEGER;
type t_procestype_rec is record
(
procestype char
);
TYPE result_table IS TABLE OF t_procestype_rec;
FUNCTION test_f(p_items_prev IN t_alternative_prev) RETURN result_table PIPELINED;
END AOPA_VALIDATE_SS;
The package body looks like this:
create or replace
PACKAGE BODY PACKAGE_SS AS
FUNCTION test_f(p_items_prev IN t_alternative_prev) RETURN result_table PIPELINED IS
processType char(1) := 'U';
rec t_procestype_rec :=null;
BEGIN
DBMS_OUTPUT.PUT_LINE('ENTERD ');
if (processType= 'U') then
select 'U' into rec from dual;
end if;
if (processType='C') then
select 'C' into rec from dual;
end if;
if (processType='D') then
select 'D' into rec from dual;
end if;
pipe row (rec);
return;
END test_f;
END PACKAGE_SS;
Usage plsql script:
DECLARE
prev_rev_alternatives PACKAGE_SS.t_alternative_prev;
BEGIN
prev_rev_alternatives(1).itemnumber(10) := 'PR454545';
prev_rev_alternatives(1).itemnumber(20) := 'PR333333';
SELECT * FROM table(PACKAGE_SS.test_f(prev_rev_alternatives));
END;
There are two things which my eyes fall upon:
Usage of SELECT without INTO in an anonymous PLSQL block is not supposed to work.
Usage of types in an SQL statement requires the type defined as an object, not within a package specification.
Try
CREATE TYPE
https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_8001.htm
and
SELECT * INTO ... FROM ...
This might help.
I have written below procedure to delete records from table and record old and new rowcount in another table.
create or replace procedure delete_old_records_job as
DECLARE
COUNTER PLS_INTEGER:=1;
drop table SIEBEL.RETAILORDER_DETAILS_COUNT;
CREATE TABLE SIEBEL.RETAILORDER_DETAILS_COUNT (TABLE_COUNT_OLD varchar(64) NOT NULL,TABLE_COUNT_NEW varchar(64) NOT NULL);
insert into SIEBEL.RETAILORDER_DETAILS_COUNT( TABLE_COUNT_OLD )SELECT COUNT(*) FROM SIEBEL.Z_VIEWS_BACKUP;
BEGIN
WHILE COUNTER>0 LOOP
DELETE FROM SIEBEL.Z_VIEWS_BACKUP WHERE LAST_UPD < add_months(sysdate, -3) AND ROWNUM<25000;
COUNTER:=SQL%ROWCOUNT;
COMMIT;
END LOOP
insert into SIEBEL.RETAILORDER_DETAILS_COUNT( TABLE_COUNT_NEW )
SELECT COUNT(*) FROM SIEBEL.Z_VIEWS_BACKUP;
END;
I am getting below error while executing
SQL> show errors procedure delete_old_records_job;
Errors for PROCEDURE DELETE_OLD_RECORDS_JOB:
LINE/COL ERROR
-------- -----------------------------------------------------------------
2/1 PLS-00103: Encountered the symbol "DECLARE" when expecting one of
the following:
begin function pragma procedure subtype type <an identifier>
<a double-quoted delimited-identifier> current cursor delete
exists prior external language
The symbol "begin" was substituted for "DECLARE" to continue.
4/1 PLS-00103: Encountered the symbol "DROP" when expecting one of
the following:
begin function pragma procedure subtype type <an identifier>
<a double-quoted delimited-identifier> current cursor delete
LINE/COL ERROR
-------- -----------------------------------------------------------------
exists prior
What I need to do is I want to create a trigger which raises an error if both the proficiencies of the programmer are equal. Please tell me the errors I have done.
SQL> get f:/sqlprog/trigger_3;
1 create or replace trigger t2 before insert or update on programmer for each
row
2 declare
3 cursor c1 is select prof1, prof2 from programmer;
4 begin
5 for r1 in c1 loop
6 if r1.pname=:new.pname then
7 if :new.prof1=: new.prof2 then
8 raise_application_error(-20091,'prof1 and prof2 should not be same');
9 end if;
10 end if;
11 end loop;
12* end;
SQL> /
Warning: Trigger created with compilation errors.
SQL> show errors
Errors for TRIGGER T2:
LINE/COL ERROR
-------- -----------------------------------------------------------------
4/1 PLS-00103: Encountered the symbol "FOR" when expecting one of the
following:
constant exception <an identifier>
<a double-quoted delimited-identifier> table long double ref
char time timestamp interval date binary national character
nchar
6/15 PLS-00103: Encountered the symbol ":" when expecting one of the
following:
( - + all case mod new null <an identifier>
<a double-quoted delimited-identifier> <a bind variable>
LINE/COL ERROR
-------- -----------------------------------------------------------------
continue any avg count current max min prior some sql stddev
sum variance execute forall merge time timestamp interval
date <a string literal with character set specification>
<a number> <a single-quoted SQL string> pipe
<an alternatively-quoted string literal with character set
specification>
<an alternative
these are the errors which i encountered and the table regarding programmer is given below
prof1=proficieny 1
prof2= proficieny 2
SQL> desc programmer;
Name Null? Type
----------------------------------------- -------- ----------------------------
PNAME VARCHAR2(20)
DOB DATE
DOJ DATE
SEX CHAR(1)
PROF1 VARCHAR2(10)
PROF2 VARCHAR2(10)
SALARY NUMBER(5)
I don't have any idea why I am getting them please help me out.
Thank you in advance.
Get rid of the cursor, lose the loop, and get rid of the first if statement. Only the innermost if statement makes sense
create or replace trigger t2
before insert or update on programmer
for each row
begin
if :new.prof1 = :new.prof2
then
raise_application_error(-20091,'prof1 and prof2 should not be same');
end if;
end;
In a row-level trigger, you generally cannot query the table that the trigger is defined on. You can only make decisions based on the data in the :new and :old pseudo-records.
I create a type:
CREATE OR REPLACE TYPE NAGULIVE.DEPOSIT_DATA_TYPE AS OBJECT (
DEPOSIT_NO VARCHAR2 (16 Byte),
ACCT_NAME VARCHAR2 (128 Byte),
DEPOSIT_DT DATE,
EPOSIT_AMT NUMBER (16,2)
);
If I execute the function it will show error. I don't know where I'm wrong.
CREATE OR REPLACE FUNCTION NAGULIVE.GET_DEPOSIT_DETAIL (IN_F_DATE DATE,IN_T_DATE DATE)
RETURN(NAGULIVE.DEPOSIT_DATA_TYPE) AS
BEGIN
RETURN QUERY(SELECT D.DEPOSIT_NO, ACCT_NAME, DEPOSIT_DT, DEPOSIT_AMT
FROM DEPOSIT_ACINFO D
INNER JOIN ACT_MASTER A ON D.CUST_ID=A.CUST_ID
INNER JOIN DEPOSIT_SUB_ACINFO DS ON D.DEPOSIT_NO=DS.DEPOSIT_NO WHERE DS.DEPOSIT_DT>=IN_F_DATE AND DS.DEPOSIT_DT<=IN_F_DATE);
END;
/
The error is
2/7 PLS-00103: Encountered the symbol "(" when expecting one of the following:
<an identifier> <a double-quoted delimited-identifier> self
long double ref char time timestamp interval date binary
national character nchar
4/1 PLS-00103: Encountered the symbol "BEGIN" when expecting one of the following:
<an identifier> <a double-quoted delimited-identifier>
As little as you understand about PL/SQL I doubt you coded the above all by yourself. The error messages refers to the non existing function QUERY.
CREATE OR REPLACE FUNCTION NAGULIVE.GET_DEPOSIT_DETAIL (IN_F_DATE DATE,IN_T_DATE DATE)
RETURN(NAGULIVE.DEPOSIT_DATA_TYPE) AS
BEGIN
RETURN QUERY(SELECT D.DEPOSIT_NO, ACCT_NAME, DEPOSIT_DT, DEPOSIT_AMT
^^^^^
FROM DEPOSIT_ACINFO D
INNER JOIN ACT_MASTER A ON D.CUST_ID=A.CUST_ID
INNER JOIN DEPOSIT_SUB_ACINFO DS ON D.DEPOSIT_NO=DS.DEPOSIT_NO WHERE DS.DEPOSIT_DT>=IN_F_DATE AND DS.DEPOSIT_DT<=IN_F_DATE);
END;
/
The opening bracket indicates that you want to pass parameters to the function but there is no variable called SELECT etc. etc. This of course looks like a SELECT statement. You mention Postgres in your comments. I know nothing about postgres but if that is something you can do in postgres I can attest you that there is no such thing in Oracle PL/SQL.
I guess all this does not bring you further but I must agree with a_horse_with_no_name you must start at square one and start learning PL/SQL.
create or replace function nagulive.get_deposit_detail(
in_f_date date,
in_t_date date
) return deposit_data_type
as
v_deposit_data deposit_data_type;
begin
select deposit_data_type(d.deposit_no, acct_name, deposit_dt, deposit_amt)
into v_deposit_data
from deposit_acinfo d
inner join act_master a on d.cust_id=a.cust_id
inner join deposit_sub_acinfo ds on d.deposit_no=ds.deposit_no
where ds.deposit_dt>=in_f_date
and ds.deposit_dt<=in_f_date;
return v_deposit_data;
end;
/
Although SQL and PL/SQL work well together they are not completely seamless. Unlike PostgreSQL, A SQL statement cannot be used as a native PL/SQL expression. Instead, a variable must be declared, the statement must SELECT INTO that variable, and then the variable is returned.
Also there was a minor syntax problem with the return declaration - there should not be parentheses around the return type. This is different than the return statement, which does optionally allow parentheses.
Those both look like understandable mistakes to me, I'm not sure why this question is getting so much hate.
if i write procedure creating code like this
declare
salary number :=20000;
employee_id number :=36325;
procedure give_bonus(emp_id in number,bonus in number) is
begin
dbms_output.put_line(emp_id);
dbms_output.put_line(bonus);
end;
begin
case
when salary >=10000 and salary <=20000 then
give_bonus(employee_id,1500);
when salary >= 20000 and salary <=40000 then
give_bonus(employee_id,1000);
when salary>40000 then
give_bonus(employee_id,500);
else
give_bonus(employee_id,0);
end case ;
end;
it writes on output
anonymous block completed
but if i write a head of procedure word this one
create or replace procedure give_bonus ,it writes errors,please help me why?
error is this
Error starting at line 1 in command:
declare
salary number :=20000;
employee_id number :=36325;
create or replace procedure give_bonus(emp_id in number,bonus in number) is
begin
dbms_output.put_line(emp_id);
dbms_output.put_line(bonus);
end;
begin
case
when salary >=10000 and salary <=20000 then
give_bonus(employee_id,1500);
when salary >= 20000 and salary <=40000 then
give_bonus(employee_id,1000);
when salary>40000 then
give_bonus(employee_id,500);
else
give_bonus(employee_id,0);
end case ;
end;
Error report:
ORA-06550: line 4, column 3:
PLS-00103: Encountered the symbol "CREATE" when expecting one of the following:
begin function pragma procedure subtype type <an identifier>
<a double-quoted delimited-identifier> current cursor delete
exists prior
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
CREATE OR REPLACE only works for top-level objects. If you are declaring a procedure inside of another PL/SQL block, there is, by definition, nothing to replace. You aren't creating a procedure that will exist once the anonymous block finishes so there is nothing to replace. You're simply declaring a procedure that has the same scope as a local variable.
You could create a standalone procedure
create or replace procedure give_bonus(emp_id in number,bonus in number)
is
begin
dbms_output.put_line(emp_id);
dbms_output.put_line(bonus);
end;
and then reference that procedure in your anonymous PL/SQL block
declare
salary number :=20000;
employee_id number :=36325;
begin
case
when salary >=10000 and salary <=20000 then
give_bonus(employee_id,1500);
when salary >= 20000 and salary <=40000 then
give_bonus(employee_id,1000);
when salary>40000 then
give_bonus(employee_id,500);
else
give_bonus(employee_id,0);
end case ;
end;