I have a sales table:
Name Null? Type
SALE_ID NOT NULL NUMBER(4)
SALE_DATE DATE
NO_OF_PRODS NUMBER(4)
PROD_ID NOT NULL NUMBER(4)
CUST_ID NOT NULL NUMBER(4)
DESP_ID NOT NULL NUMBER(4)
SALE_RECEIPT NOT NULL NUMBER(5)
I am trying to insert randomly generated data into the sales table. I am using iSQL plus for oracle. This is just test data that I have to create.
I run the following script to generate the data:
begin
insert into sales
select sale_id_seq.nextval,
sysdate,
trunc(dbms_random.value(000,999)),
p.prod_id, c.cust_id
FROM dba_xy.product p, dba_xy.customer c,
desp_id_seq.nextval,
trunc(dbms_random.value(0000,9999));
end;
/
But when I do, the following error message appears:
trunc(dbms_random.value(0000,9999));
*
ERROR at line 9:
ORA-06550: line 9, column 21:
PL/SQL: ORA-00933: SQL command not properly ended
ORA-06550: line 2, column 2:
PL/SQL: SQL Statement ignored.
What have I done wrong?
I just realised that the DESP_ID is a foreign key within the sales table, but currently the despatch table is empty and when I try to insert data into either tables, I'm not able to cause one table needs the data from the other table. I end up getting this error message:
PL/SQL: ORA-02289: sequence does not exist
You cannot select FROM
FROM dba_xy.product p, dba_xy.customer c,
desp_id_seq.nextval,
trunc(dbms_random.value(0000,9999));
Try:
insert into sales
(select
sale_id_seq.nextval,
sysdate,
trunc(dbms_random.value(000,999)),
p.prod_id,
c.cust_id,
desp_id_seq.nextval,
trunc(dbms_random.value(0000,9999))
FROM dba_xy.product p, dba_xy.customer c;
BTW, are you sure that you want an Cartesian product here, maybe some join is missed ?
Related
I'm learning PL/SQL specifically triggers, and I want to learn how to operate on multiple tables using triggers but I'm having trouble understanding the process. Here's an example:
CREATE TABLE Sess
(code INTEGER NOT NULL,
dateStart DATE NOT NULL,
dateEnd DATE NOT NULL,
CONSTRAINT KeySess PRIMARY KEY(code)
)
CREATE TABLE Ins
(codeIns CHAR(12) NOT NULL,
code INTEGER NOT NULL,
dateIns DATE NOT NULL,
dateAb DATE,
note INTEGER,
CONSTRAINT KeyIns PRIMARY KEY (codeIns, code)
)
1/ I'm trying to build a trigger that will ensure this:
before Insert or Update Ins
dateAb is between dateStart and dateEnd
2/ I want also to ALTER TABLE and lock code, and codeIns in Ins so no one can update them but i don't know the command.
For the first trigger, I tried something like:
CREATE OR REPLACE TRIGGER test
BEFORE INSERT OR UPDATE OF dateAb ON Ins
FOR EACH ROW
DECLARE
start date;
BEGIN
SELECT DISTINCT s.dateStart INTO start
WHERE Ins.code = s.code
IF (:NEW.dateAb < start) THEN
raise_application_error(-20101,'dateAb incorrect');
END IF;
END;
Note: I didn't declare a variable end to check if it's between, my purpose here was to test the correct syntax
Note2: the table are empty.
I had Warning: Trigger created with compilation errors. and 3 errors :
PL/SQL: SQL Statement ignored
4/40 PL/SQL: ORA-00923: key-word FROM absent
9/5 PLS-00103: Encountered the symbol "IF" when expecting one of the
following:
;
And finally like I said I don't know the correct syntax to lock column on table to prevent updates or if it's possible.
I'm learning so if one of you can teach me the correct way to process with my two request, I would apreciate that.
Thank you
Try this:
create or replace trigger test
before insert or update of dateab on ins
for each row
declare
l_sess_start date;
begin
select s.datestart into l_sess_start
from sess s
where s.code = :new.code;
if :new.dateab < l_sess_start then
raise_application_error
( -20101
, 'Start date ' || to_char(:new.dateab,'DD-MON-YYYY') ||
' cannot be before ' || to_char(l_sess_start,'DD-MON-YYYY'));
end if;
end;
Test:
insert into sess values (1, date '2018-04-22', date '2018-04-30');
insert into ins values ('Z', 1, date '2018-04-01', date '2018-04-01', null);
ERROR at line 1:
ORA-20101: Start date 01-APR-2018 cannot be before 22-APR-2018
ORA-06512: at "WILLIAM.TEST", line 10
ORA-04088: error during execution of trigger 'WILLIAM.TEST'
PLS-00103: Encountered the symbol "IF" when expecting one of the
following:
;
This error is because you are missing ; after select statement
I need help to solve this issue. The Driver_ID exists in two tables, Driver and Driver_Deliveries. I need it to display the First_Name, Surname & Driver_ID for the Driver ID's that do not appear in the Driver_Deliveries table. I'm using Oracle SQL Developer with Oracle 11G.
DECLARE
FIRSTNAME VARCHAR2(20);
SUR_NAME VARCHAR2(20);
DRIVERID VARCHAR2(5);
BEGIN
FOR i IN
(
SELECT
FIRST_NAME,
SURNAME,
a.DRIVER_ID
INTO
FIRSTNAME, SUR_NAME, DRIVERID
FROM
DRIVER_DELIVERIES,
DRIVER a,
WHERE NOT EXISTS(SELECT * FROM DRIVER_DELIVERIES WHERE DRIVER_DELIVERIES.DRIVER_ID = a.DRIVER_ID);
)
LOOP
DBMS_OUTPUT.PUT_LINE('FIRST NAME :' ||I.FIRST_NAME);
DBMS_OUTPUT.PUT_LINE('SURNAME :' || I.SURNAME);
DBMS_OUTPUT.PUT_LINE('DELIVERY JOB REQUIRED: YES ');
END LOOP;
END;
Here's the error stack:
Error report -
ORA-06550: line 23, column 9:
PL/SQL: ORA-00903: invalid table name
ORA-06550: line 10, column 5:
PL/SQL: SQL Statement ignored
ORA-06550: line 23, column 106:
PLS-00103: Encountered the symbol ";" when expecting one of the following:
loop
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
You need to select into something with a simple query in a PL/SQL block, but you've taken that rule too far; because your cursor loop variable i is an implicit record type that is already available to take the query results.
You also have an extra comma in your cursor query's select list, and the from clause. And an extra semicolon after the where clause.
So with that loop syntax you need:
...
FOR i IN
(
SELECT
FIRST_NAME,
SURNAME,
a.DRIVER_ID
FROM
DRIVER_DELIVERIES,
DRIVER a
WHERE
...
Though you should really use explicit join syntax, which would make it more obvious that you currently have no link between the two tables in your where clause. But you don't actually want to refer to driver_deliveries there at all - you're getting all the data from the driver table. You only need to refer to that within the exists clause. (And I've just noticed you've spelled the table name incorrectly in that clause too).
So modifying that further:
need:
...
FOR i IN
(
SELECT
FIRST_NAME,
SURNAME,
DRIVER_ID
FROM
DRIVER a
WHERE NOT EXISTS(
SELECT null FROM DRIVER_DELIVERIES
WHERE DRIVER_DELIVERIES.DRIVER_ID = a.DRIVER_ID)
)
LOOP
...
You don't appear to need PL/SQL for this, but if you have to...
I'm trying to learn a bit of PL-SQL using a tutorial by examples book, but one of the suggested codes return the following error when run:
ORA-06550: line 10, column 48: PL/SQL: ORA-00947: not enough values
ORA-06550: line 9, column 1: PL/SQL: SQL Statement ignored
Could you please help me understand what I'm doing wrong?
Many thanks in advance!
Simone.
SQL Fiddle
Oracle 11g R2 Schema Setup:
create table product (code integer primary key, name varchar2 (20), type varchar2(8),price number(4,2),update_dt date);
insert into product values(1,'Mela','Frutta',1,to_date('1-MAY-2015','DD-MON-YYYY'));
insert into product values(2,'Pera','Frutta',2,to_date('2-MAY-2015','DD-MON-YYYY'));
insert into product values(3,'Carota','Ortaggio',3,to_date('3-MAY-2015','DD-MON-YYYY'));
insert into product values(4,'Zucchina','Ortaggio',4,to_date('4-MAY-2015','DD-MON-YYYY'));
insert into product values(5,'Arancia','Frutta',5,to_date('5-MAY-2015','DD-MON-YYYY'));
Query 1:
declare
code_var integer;
type_var varchar2(8);
name_var varchar2(20);
price_var number(4,2);
update_dt_var date;
price_too_high exception;
begin
select code, type,name, price, update_dt
into code_var,type_var,price_var,update_dt_var
from product
where name='Arancia';
if price_var > 4.5 then
raise price_too_high;
end if;
exception
when price_too_high then
dbms_output.put_line('price is too damn high!');
end;
Results:
you are trying to insert 5 values from your select into four variables.
This is correct:
select code, type, name, price, update_dt
into code_var, type_var, name_var, price_var, update_dt_var
from product
where name='Arancia';
I have a table which called Logiciel :
Name Null? Type
---------- -------- -------------
NLOG NOT NULL VARCHAR2(5)
NOMLOG NOT NULL VARCHAR2(20)
DATEACH DATE
VERSION VARCHAR2(7)
TYPELOG VARCHAR2(9)
PRIX NUMBER(6,2)
Using PL/SQL I want to add an entry which has the same data as the entry with NLOG = 'log3', and the value PRIX as the average of PRIX : AVG(PRIX) of all entries.
This is the script I wrote:
DECLARE
unLog LOGICIEL%ROWTYPE;
moy LOGICIEL.PRIX%TYPE;
BEGIN
SELECT AVG(PRIX) INTO moy FROM LOGICIEL;
SELECT * INTO unLog FROM LOGICIEL WHERE NLOG='log5';
unLog.PRIX := moy;
unLog.NLOG := 'logS';
INSERT INTO LOGICIEL SELECT * FROM unLog;
END;
/
The problem is when I execute this script I get this error :
ERROR at line 9:
ORA-06550: line 9, column 37:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 9, column 2:
PL/SQL: SQL Statement ignored
How can I solve this problem ?
Just use insert . . . select:
INSERT INTO LOGICIEL(NLOG, NOMLOG, DATEACH, VERSION, TYPELOG, PRIX)
SELECT NLOG, NOMLOG, DATEACH, VERSION, TYPELOG,
(SELECT AVG(PRIX) FROM LOGICIEL) as PRIX
FROM LOGICIEL
WHERE NLOG = 'log3';
EDIT:
Is this what you mean?
INSERT INTO LOGICIEL(NLOG, NOMLOG, DATEACH, VERSION, TYPELOG, PRIX)
SELECT unlog.NLOG, unlog.NOMLOG, unlog.DATEACH, unlog.VERSION, unlog.TYPELOG, unlog.PRIX
FROM dual;
I have the following code:
begin
for i in 1..2 loop
insert into dba_xy.despatch
select desp_id_seq.nextval,
dbms_random.string('U',5),
trunc(dbms_random.value(0000,9999)),
prod_id from dba_xy.product
prod_name from dba_xy.product;
end loop;
end;
When I run it, oracle gives me the following error message:
prod_name from dba_xy.product;
*
ERROR at line 8:
ORA-06550: line 8, column 29:
PL/SQL: ORA-00933: SQL command not properly ended
ORA-06550: line 3, column 2:
PL/SQL: SQL Statement ignored
What I'm trying to do is link the existing prod_id and prod_name with new data inserted into the despatch table. I have set prod_name as a unique key in the product table and prod_id as the primary key and have set both as foreign key constraints in the despatch table. I need to include the prod_name into the despatch table to allow readers of the table to have more understanding of what prod_name needs to be found etc, rather than just giving the prod_id which will make no sense to them at all. But maybe I was thinking that I don't need prod_id in the despatch table.
Please help.
After dropping the prod_id column from the despatch table, i altered my code:
begin
for i in 1..2 loop
insert into dba_xy.despatch
select desp_id_seq.nextval,
dbms_random.string('U',5),
trunc(dbms_random.value(0000,9999)),
prod_name from dba_xy.product;
end loop;
end;
/
and the following error message came up about the unique constraint:
begin
*
ERROR at line 1:
ORA-00001: unique constraint (DBA_XY.PROD_NAME_UC) violated
ORA-06512: at line 3
Your ORA-00933 error is due to an incorrectly formatted SELECT statement:
SELECT desp_id_seq.nextval,
dbms_random.string('U',5),
TRUNC(dbms_random.value(0000,9999)),
prod_id from dba_xy.product
prod_name from dba_xy.product;
...when it should be:
SELECT DESP_ID_SEQ.nextval,
DBMS_RANDOM.string('U',5),
TRUNC(DBMS_RANDOM.value(0000,9999)),
t.prod_id,
t.prod_name
FROM dba_xy.product t;
You were missing the comma to separate the prod_id and prod_name columns, and additionally had a redundant FROM dba_xy.product declaration in the wrong location.
That said, the dba_xy.despatch table should only contain the prod_id. If you need to provide a human readable version of the data, I recommend you construct a view. Example:
CREATE VIEW despatch_vw AS
SELECT t.prod_id,
p.prod_name
FROM dba_xy.despatch t
JOIN dba_xy.product p ON p.prod_id = t.prod_id
Could you be getting the unique constraint violation because you are inserting the same rows twice? Is "i" supposed to be used in the where clause of the insert statement or do you really want the rows inserted twice?
Your first statement has two FROM clauses, which is why you are getting a syntax error.
select desp_id_seq.nextval,
dbms_random.string('U',5),
trunc(dbms_random.value(0000,9999)),
prod_id, --from dba_xy.product
prod_name from dba_xy.product;