PL/SQL CURRENT_DATE if NULL - oracle

I need some help for figuring out how to use the CURRENT_DATE if the p_start_time is NULL when doing an insert.
The code below is what I have figured out so far (except for the insert statement). The code I need help for is the last code block.
Using PL/SQL btw.
create or replace procedure BEGIN_TRIP_SP (
p_trip_id OUT INTEGER, -- an output parameter
p_bicycle_id IN INTEGER, -- Must not be NULL. Must match value value in BC_BICYCLE and BC_DOCK tables.
p_start_time IN DATE, -- If NULL, use CURRENT_DATE system date value
p_membership_id IN INTEGER -- Must not be NULL. Must match value in BC_MEMBERSHIP table.
)
IS
lv_membership_id_exist INTEGER;
lv_bicycle_id_exist INTEGER;
lv_Error_Message VARCHAR2(200);
ex_Exception EXCEPTION;
BEGIN
IF p_bicycle_id IS NULL THEN
lv_Error_Message := 'Missing mandatory value for bicycle id in BEGIN_TRIP_SP. No trip added.';
RAISE ex_Exception;
END IF;
IF p_start_time IS NULL THEN
NVL(trip_start_time, '08-03-2022')
END IF;
INSERT INTO bc_trip (
Trip_id,
Bicycle_id,
Trip_start_time,
Membership_id
)
VALUES (
p_trip_id,
p_bicycle_id,
NVL(p_start_time, current_date),
p_membership_id
);

See if this helps; I presumed trip_id is somehow automatically generated so you'll be just returning its value to the caller.
Sample table:
SQL> CREATE TABLE bc_trip
2 (
3 trip_id NUMBER GENERATED ALWAYS AS IDENTITY,
4 bicycle_id NUMBER,
5 trip_start_time DATE,
6 membership_id NUMBER
7 );
Table created.
Procedure:
SQL> CREATE OR REPLACE PROCEDURE begin_trip_sp
2 (p_trip_id OUT INTEGER, -- an output parameter
3 p_bicycle_id IN INTEGER, -- Must not be NULL. Must match value value in BC_BICYCLE and BC_DOCK tables.
4 p_start_time IN DATE, -- If NULL, use CURRENT_DATE system date value
5 p_membership_id IN INTEGER -- Must not be NULL. Must match value in BC_MEMBERSHIP table.
6 )
7 IS
8 BEGIN
9 IF p_bicycle_id IS NULL
10 THEN
11 raise_application_error (
12 -20000,
13 'Missing mandatory value for bicycle id in BEGIN_TRIP_SP. No trip added.');
14 ELSE
15 INSERT INTO bc_trip (bicycle_id, trip_start_time, membership_id)
16 VALUES (p_bicycle_id,
17 NVL (p_start_time, CURRENT_DATE),
18 p_membership_id)
19 RETURNING trip_id
20 INTO p_trip_id;
21 END IF;
22 END;
23 /
Procedure created.
Testing:
SQL> SET SERVEROUTPUT ON
SQL> DECLARE
2 l_trip_id NUMBER;
3 BEGIN
4 begin_trip_sp (l_trip_id,
5 1,
6 NULL,
7 100);
8 DBMS_OUTPUT.put_line ('Inserted trip ID = ' || l_trip_id);
9 END;
10 /
Inserted trip ID = 1
PL/SQL procedure successfully completed.
What if there's no P_BICYCLE_ID?
SQL> l5
5* 1,
SQL> c/1/null/
5* null,
SQL> /
DECLARE
*
ERROR at line 1:
ORA-20000: Missing mandatory value for bicycle id in BEGIN_TRIP_SP. No trip
added.
ORA-06512: at "DP_4005.BEGIN_TRIP_SP", line 11
ORA-06512: at line 4
SQL>
Result is
SQL> SELECT * FROM bc_trip;
TRIP_ID BICYCLE_ID TRIP_START MEMBERSHIP_ID
---------- ---------- ---------- -------------
1 1 08.03.2022 100
SQL>

Just write default value for that parameter:
create or replace procedure BEGIN_TRIP_SP (
p_trip_id OUT INTEGER,
p_bicycle_id IN INTEGER,
p_start_time IN DATE DEFAULT sysdate,--if the parameter is not given it will take sysdate (current date)
p_membership_id IN INTEGER
)...

Related

How can i correct this error(The package is configured with translation errors)?

This is the question
-Create customers table and add these columns:
Id
Name
AGE
ADDRESS
SALARY
-Add 10 rows.
-Create a package with three procedures:
one that add a customer to the table.
one that removes a customer from the table.
one that lists all the customers.
-Create customers table and add these columns:
Id
Name
AGE
ADDRESS
SALARY
-Add 10 rows.
-Create a package with three procedures:
one that add a customer to the table.
one that removes a customer from the table.
one that lists all the customers.
CREATE TABLE customer(
customer_id NUMBER NOT NULL,
customer_name VARCHAR2(50) NOT NULL,
customer_age NUMBER NOT NULL,
customer_address VARCHAR2(50) NOT NULL,
customer_salary NUMBER NOT NULL,
PRIMARY KEY(customer_id)
);
INSERT INTO customer
VALUES
(1,'Ahemed',22,'wq1',2500);
INSERT INTO customer
VALUES
(2,'salem',24,'wq2',2000);
INSERT INTO customer
VALUES
(3,'Aboud',26,'wq3',2200);
INSERT INTO customer
VALUES
(4,'Tarek',27,'wq4',2100);
INSERT INTO customer
VALUES
(5,'Hazem',33,'wq5',3000);
INSERT INTO customer
VALUES
(6,'Hayder',32,'wq6',2300);
INSERT INTO customer
VALUES
(7, 'Sammy',35,'wq7',2700);
INSERT INTO customer
VALUES
(8,'Mohammed',20,'wq8',4000);
INSERT INTO customer
VALUES
(9,'Tayseer',18,'wq9',3600);
INSERT INTO customer
VALUES
(10,'Hamoud',40,'wq10',3100);
CREATE OR REPLACE PACKAGE mypackage AS
PROCEDURE add_customer(c_id customer.customer_id%type,
c_name customer.customer_name%type,
c_age customer.customer_age%type,
c_address customer.customer_address%type,
c_salary customer.customer_salary%type);
PROCEDURE remove_customer(c_id customer.customer_id%type);
PROCEDURE list_customer;
END mypackage ;
CREATE OR REPLACE PACKAGE BODY mypackage AS
PROCEDURE add_customer(c_id customer.customer_id%type,
c_name customer.customer_name%type,
c_age customer.customer_age%type,
c_address customers.address%type,
c_salary customer.customer_salary%type)
IS
BEGIN
INSERT INTO customer (customer_id ,customer_name,customer_age ,customer_address ,customer_salary)
VALUES(c_id, c_name, c_age, c_address, c_salary);
END add_customer;
PROCEDURE remove_customer(c_id customer.customer_id%type) IS
BEGIN
DELETE FROM customer
WHERE customer_id= c_id;
END remove_customer;
PROCEDURE list_customer(customer_id ,customer_name,customer_age ,customer_address ,customer_salar) IS
BEGIN
select * from customer;
END list_customer;
If i create this package the error is(The package is configured with translation errors) how can i solve it?
Table and package specification are OK (kind of):
SQL> CREATE TABLE customer(
2 customer_id NUMBER NOT NULL,
3 customer_name VARCHAR2(50) NOT NULL,
4 customer_age NUMBER NOT NULL,
5 customer_address VARCHAR2(50) NOT NULL,
6 customer_salary NUMBER NOT NULL,
7 PRIMARY KEY(customer_id)
8 );
Table created.
SQL> CREATE OR REPLACE PACKAGE mypackage AS
2 PROCEDURE add_customer(c_id customer.customer_id%type,
3 c_name customer.customer_name%type,
4 c_age customer.customer_age%type,
5 c_address customer.customer_address%type,
6 c_salary customer.customer_salary%type);
7
8 PROCEDURE remove_customer(c_id customer.customer_id%type);
9 PROCEDURE list_customer;
10 END mypackage ;
11 /
Package created.
But then, for some reason, you didn't follow the same recipe for package body:
SQL> CREATE OR REPLACE PACKAGE BODY mypackage AS
2 PROCEDURE add_customer(c_id customer.customer_id%type,
3 c_name customer.customer_name%type,
4 c_age customer.customer_age%type,
5 c_address customers.address%type,
6 c_salary customer.customer_salary%type)
7 IS
8 BEGIN
9 INSERT INTO customer (customer_id ,customer_name,customer_age ,customer_address ,customer_salary)
10 VALUES(c_id, c_name, c_age, c_address, c_salary);
11 END add_customer;
12
13 PROCEDURE remove_customer(c_id customer.customer_id%type) IS
14 BEGIN
15 DELETE FROM customer
16 WHERE customer_id= c_id;
17 END remove_customer;
18
19 PROCEDURE list_customer(customer_id ,customer_name,customer_age ,customer_address ,customer_salar) IS
20 BEGIN
21 select * from customer;
22 END list_customer;
23 end mypackage;
24 /
Warning: Package Body created with compilation errors.
What's wrong?
SQL> show err
Errors for PACKAGE BODY MYPACKAGE:
LINE/COL ERROR
-------- -----------------------------------------------------------------
19/41 PLS-00103: Encountered the symbol "," when expecting one of the
following:
in out <an identifier> <a double-quoted delimited-identifier>
table ... columns long double ref char standard time
timestamp interval date binary national character nchar
20/4 PLS-00103: Encountered the symbol "BEGIN" when expecting one of
the following:
not null of nan infinite dangling a empty json
SQL>
Line #19 is wrong:
19 PROCEDURE list_customer(customer_id ,customer_name,customer_age ,customer_address ,customer_salar) IS
So: if - apparently - you do know how to use parameters while declaring procedures, why didn't you do the same for list_customer? Besides, it wouldn't work anyway - in PL/SQL, a SELECT must have an INTO (and your procedure doesn't). I guess that at customer_id should be passed as a parameter (so I'm doing that in my example).
Moreover, all procedures you declare in package specification must exist in package body, with exactly the same description (you've used customer.address%type but that column doesn't exist in the table).
So, when fixed: specification:
SQL> CREATE OR REPLACE PACKAGE mypackage AS
2 PROCEDURE add_customer(c_id customer.customer_id%type,
3 c_name customer.customer_name%type,
4 c_age customer.customer_age%type,
5 c_address customer.customer_address%type,
6 c_salary customer.customer_salary%type);
7
8 PROCEDURE remove_customer(c_id customer.customer_id%type);
9 PROCEDURE list_customer (p_customer_id customer.customer_id%type);
10 END mypackage ;
11 /
Package created.
Body:
SQL> CREATE OR REPLACE PACKAGE BODY mypackage AS
2 PROCEDURE add_customer(c_id customer.customer_id%type,
3 c_name customer.customer_name%type,
4 c_age customer.customer_age%type,
5 c_address customer.customer_address%type,
6 c_salary customer.customer_salary%type)
7 IS
8 BEGIN
9 INSERT INTO customer (customer_id ,customer_name,customer_age ,customer_address ,customer_salary)
10 VALUES(c_id, c_name, c_age, c_address, c_salary);
11 END add_customer;
12
13 PROCEDURE remove_customer(c_id customer.customer_id%type) IS
14 BEGIN
15 DELETE FROM customer
16 WHERE customer_id= c_id;
17 END remove_customer;
18
19 PROCEDURE list_customer(p_customer_id in customer.customer_id%type)
20 --,customer_name,customer_age ,customer_address ,customer_salar) IS
21 is
22 l_row customer%rowtype;
23 BEGIN
24 select * into l_row from customer where customer_id = p_customer_id;
25 END list_customer;
26 end mypackage;
27 /
Package body created.
SQL>
This, at least, compiles. Does it do what you wanted it, I didn't try - I'll leave it to you.

PL/SQL trouble at create trigger

CREATE TABLE INVENTORY(
INVENTORY_ID NUMBER(6) PRIMARY KEY,
ITEM_NAME VARCHAR2(255),
QUANTITY NUMBER,
PRICE NUMBER,
ITEM_SIZE VARCHAR(255),
INVENTORY_VALUE NUMBER);
===
CREATE TABLE INVENTORY_AUDIT(
DATE_CHANGED DATE,
USER_NAME VARCHAR2(30),
INV_ID NUMBER(6),
OLD_QUANTITY NUMBER,
NEW_QUANTITY NUMBER,
CONSTRAINT fk_INV_ID
FOREIGN KEY (INV_ID)
REFERENCES INVENTORY (INVENTORY_ID));
===
CREATE OR REPLACE TRIGGER INV_CHG
BEFORE UPDATE OF QUANTITY
ON INVENTORY
FOR EACH ROW
BEGIN
IF :NEW.QUANTITY <> :OLD.QUANTITY THEN
INSERT INTO INVENTORY_AUDIT
VALUES (GETDATE(), v('APP_USER'), :NEW.INVENTORY_ID, :OLD.QUANTITY, :NEW.QUANTITY)
END IF;
END;
===
ORA-24344: success with compilation error
ORA-06512: at "SYS.WWV_DBMS_SQL_APEX_190200", line 592
ORA-06512: at "SYS.DBMS_SYS_SQL", line 1658
ORA-06512: at "SYS.WWV_DBMS_SQL_APEX_190200", line 578
ORA-06512: at "APEX_190200.WWV_FLOW_DYNAMIC_EXEC", line 2057
3. ON INVENTORY
4. FOR EACH ROW
5. BEGIN
6. IF :NEW.QUANTITY <> :OLD.QUANTITY THEN
7. INSERT INTO INVENTORY_AUDIT
===
I tried to create trigger that triggered by inventory table's quantity change.
But it throws an error and syntax looks fine for me.
I tried without IF whole statement but still had same problem.
That means my create trigger statement has problem right?
But I cannot find it.
Two things:
missing semi-colon at the end of the INSERT statement
use sysdate instead of getdate
Here's how:
SQL> CREATE OR REPLACE TRIGGER INV_CHG
2 BEFORE UPDATE OF QUANTITY
3 ON INVENTORY
4 FOR EACH ROW
5 BEGIN
6 IF :NEW.QUANTITY <> :OLD.QUANTITY THEN
7 INSERT INTO INVENTORY_AUDIT
8 VALUES (sysdate, --> sysdate instead of getdate()
9 v('APP_USER'),
10 :NEW.INVENTORY_ID,
11 :OLD.QUANTITY,
12 :NEW.QUANTITY
13 ); --> missing semi-colon here
14 END IF;
15 END;
16 /
Trigger created.
SQL>

ora-06575 package or function is in an invalid state pl sql

I am new to pl sql and i am trying to call a procedure but i am getting the error ora-06575 package or function is in an invalid state.
What do you think i am doing wrong? Thanks
select * from NB_tfr_USERS; --previous table created
create or replace procedure nb_tfr_add_user
(
i_user_name in nb_tfr_users.name%type,
i_address in nb_tfr_users.address%type,
i_birthdate in nb_tfr_users.birthdate%type,
o_userid out nb_tfr_users.id%type,
o_errm out varchar2
) AS
--Variables
l_user_id number;
--Parameters invalid exception
error_params exception;
BEGIN
--validate parameters
--- name can not be empty
--- birthdate can be empty
if i_user_name is null or length(i_user_name) = 0 then
raise error_params;
end if;
--initialize variables
l_user_id := nb_seq_tfr_user_id.nextval;
--insert new user
insert into NB_tfr_USERS (id, name, address, birthdate)
values (l_user_id, i_user_name, i_address, i_birthdate);
--deal with exceptions
exception
when error_params then
o_errm := 'Invalid Parameters!';
dbms_output.put_line(o_errm);
when others then
dbms_output.put_line('Error: '||sqlerrm);
o_errm:=substr(1,150,sqlerrm);
raise;
END NB_tfr_ADD_USER;
call
nb_tfr_add_user(54,'tf','lx',12121989);
So when i try to call the procedure i get the error.
Well, it looks OK - apart from the fact that you incorrectly called the procedure.
Here's a test case.
SQL> create table nb_tfr_users
2 (id number, name varchar2(10), address varchar2(10), birthdate date);
Table created.
SQL> create sequence nb_seq_tfr_user_id;
Sequence created.
The procedure:
SQL> create or replace procedure nb_tfr_add_user
2 (
3 i_user_name in nb_tfr_users.name%type,
4 i_address in nb_tfr_users.address%type,
5 i_birthdate in nb_tfr_users.birthdate%type,
6 o_userid out nb_tfr_users.id%type,
7 o_errm out varchar2
8 ) AS
9 --Variables
10 l_user_id number;
11 --Parameters invalid exception
12 error_params exception;
13 BEGIN
14 --validate parameters
15 --- name can not be empty
16 --- birthdate can be empty
17 if i_user_name is null or length(i_user_name) = 0 then
18 raise error_params;
19 end if;
20
21 --initialize variables
22 l_user_id := nb_seq_tfr_user_id.nextval;
23
24 --insert new user
25 insert into NB_tfr_USERS (id, name, address, birthdate)
26 values (l_user_id, i_user_name, i_address, i_birthdate);
27
28 --deal with exceptions
29 exception
30 when error_params then
31 o_errm := 'Invalid Parameters!';
32 dbms_output.put_line(o_errm);
33
34 when others then
35 dbms_output.put_line('Error: '||sqlerrm);
36 o_errm:=substr(1,150,sqlerrm);
37 raise;
38 END NB_tfr_ADD_USER;
39 /
Procedure created.
SQL>
Testing - it shows how you should have called it. As there are 3 IN and 2 OUT parameters, that's what you should have done as well.
SQL> set serveroutput on
SQL> declare
2 l_userid nb_tfr_users.id%type;
3 l_Errm varchar2(200);
4 begin
5 nb_tfr_add_user(i_user_name => 'tf',
6 i_address => 'lx',
7 i_birthdate => sysdate,
8 o_userid => l_userid,
9 o_errm => l_errm);
10 dbms_output.put_Line(l_userid ||' '||l_errm);
11 end;
12 /
PL/SQL procedure successfully completed.
SQL> select * from nb_tfr_users;
ID NAME ADDRESS BIRTHDAT
---------- ---------- ---------- --------
1 tf lx 09.09.19
SQL>
If you got the error, it - obviously - means that there's something wrong. I don't know what, but - maybe you forgot to create the sequence.
Anyway: after creating stored procedures, check whether everything is OK by running (in SQL*Plus) show err, e.g.
SQL> create or replace procedure p_test is
2 begin
3 insert into abc (id) values (seq_does_not_exist.nextval);
4 end;
5 /
Warning: Procedure created with compilation errors.
SQL> show err
Errors for PROCEDURE P_TEST:
LINE/COL ERROR
-------- -----------------------------------------------------------------
3/3 PL/SQL: SQL Statement ignored
3/15 PL/SQL: ORA-00942: table or view does not exist
SQL>
Or, query user_source:
SQL> select line, text, attribute from user_errors where name = 'P_TEST';
LINE TEXT ATTRIBUTE
----- -------------------------------------------------- ---------
3 PL/SQL: ORA-00942: table or view does not exist ERROR
3 PL/SQL: SQL Statement ignored ERROR
SQL>
I suggest you do the same and see what's wrong with the procedure.

PL/SQL procedures same row

Table before solve:
ID NAME DATA
1 zhang 9
1 zhang 12
2 wang 1
2 wang 2
/this is the table before solved/
Table after solve:
ID NAME DATA
1 DIY 13
2 DIY 3
/this is what I want to get result/
There is the procedure:
update A a
set a.date=(select max(f_get(f.id,f.date,g.date))
from A f,A g
where f.date!=g.date
and f.id=a.id);
--function f_get()
create or replace function f_get
(id in varchar2,date in varchar,date2 in varchar )
return varchar is
Result varchar
date3 varchar(4);
begin
select nvl(date,date2) into date3
from dual;
Result:=date3;
delete from A a
where a.ID=id
and a.date=date2;--there is error
return(Result);
end f_get;
Your question does its best to hide itself, but this is the point:
"--there is error "
The error you get is (presumably) ORA-14551: cannot perform a DML operation inside a query, which you are getting because you are calling a FUNCTION which includes a DELETE command from a SELECT statement.
Oracle's transactional model doesn't allow queries to change the state of the database. Instead of a FUNCTION you need to write a procedure.
Although, if you want to remove duplicate rows, a straight SQL solution will suffice. Something like
delete from a
where (id, date) not in
( select id, max(date) from a
group by id)
/
You really should pay attention how to write questions. It would help us to help you. This is my guess what you are looking for. Unfortunately I don't have 9i available, but hope this helps !
create table so7t (
id number,
name varchar2(10),
data number -- date is a reserved word and can't be used as identifier
);
-- 1001
insert into so7t values (1, 'zhang', 9);
-- 1100
insert into so7t values (1, 'zhang', 12);
-- 0001
insert into so7t values (2, 'wang', 1);
-- 0010
insert into so7t values (2, 'wang', 2);
select * from so7t;
/* from http://www.dbsnaps.com/oracle/bitwise-operators-in-oracle/ */
create or replace function bitor (x number, y number)
return number
is
begin
return (x+y)-bitand(x,y);
end;
/
show errors
create or replace procedure solve (
p_id in number
) as
type ids_t is table of number;
v_ids ids_t;
v_result number := 0;
begin
select data bulk collect into v_ids from so7t where id = p_id;
for i in v_ids.first .. v_ids.last loop
v_result := bitor(v_result, v_ids(i));
end loop;
delete from so7t where id = p_id;
insert into so7t values (p_id, 'DIY', v_result);
end;
/
begin
solve(1);
commit;
solve(2);
commit;
end;
/
Table before solve:
ID NAME DATA
---------- ---------- ----------
1 zhang 9
1 zhang 12
2 wang 1
2 wang 2
Table after solve:
ID NAME DATA
---------- ---------- ----------
1 DIY 13
2 DIY 3

Oracle stored procedure OUT parameters

I have a stored procedure with an IN OUT parameter declared like follows:
create or replace PROCEDURE RIFATT_SEGN0_INS(pIdRifattSegn0 in OUT NUMBER,
pNumDossier IN VARCHAR2 ,
pNumConsegna IN NUMBER,
pDtConsegna IN DATE,
[..]
) AS
[..]
Whenever i call it from another procedure, how do i get the pIdRifattSegn0 parameter that is also out?
Your question isn't entirely clear. An IN OUT parameter is passed both ways, as its name implies. This means it has to be passed a variable, not a literal and you need a declare block to do that. For example:
declare
l_segn number;
begin
l_segn := 1;
-- procedure will have received value = 1
rifatt_segn0_ins(l_segn, 'x', 2, sysdate);
-- procedure may have changed value of l_segn from 1 to something else
dbms_output.put_line(l_segn);
end;
Here is an example:
SQL> create or replace PROCEDURE RIFATT_SEGN0_INS
2 ( pIdRifattSegn0 IN OUT NUMBER
3 , pNumDossier IN VARCHAR2
4 , pNumConsegna IN NUMBER
5 , pDtConsegna IN DATE
6 )
7 as
8 begin
9 dbms_output.put_line(pNumDossier);
10 dbms_output.put_line(to_char(pNumConsegna));
11 dbms_output.put_line(to_char(pDtConsegna,'yyyy-mm-dd'));
12 pIdRifattSegn0 := sqrt(pIdRifattSegn0);
13 end;
14 /
Procedure is aangemaakt.
SQL> create or replace procedure another_procedure
2 as
3 l_IdRifattSegn0 number := 4;
4 begin
5 rifatt_segn0_ins
6 ( pIdRifattSegn0 => l_IdRifattSegn0
7 , pNumDossier => '1A'
8 , pNumConsegna => 42
9 , pDtConsegna => sysdate
10 );
11 dbms_output.put_line('from another_procedure: l_IdRifattSegn0 = ' || to_char(l_IdRifattSegn0));
12 end;
13 /
Procedure is aangemaakt.
SQL> exec another_procedure
1A
42
2009-05-21
from another_procedure: l_IdRifattSegn0 = 2
PL/SQL-procedure is geslaagd.
Regards,
Rob.

Resources