ora-00933:SQL command not properly ended - sql

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;

Related

Trigger created with compiling errors on unique value

I'm trying to create a trigger that checks the value of a column whenever I have an insert or an update on the table, the value of columnX must be unique:
tableX(ID, ..., columnX)
CREATE or replace TRIGGER tableX_uk
BEFORE INSERT OR UPDATE ON tableX
FOR EACH ROW
BEGIN
if(:new.columnX in (select T.columnX from tableX T)) then
Raise_Application_Error(-20001, 'Already existing');
end if;
End;
It shows that the trigger is created with compiling errors.
I couldn't find any error here, can someone help me please ? Thank you !
It shows that the trigger is created with compiling errors. I couldn't find any error here
Errors for stored PL/SQL can be found in user/all/dba_errors. Desktop tools such as SQL Developer, Toad, PL/SQL Developer etc will display them automatically but that's where they get the details from.
DBFiddle
In this case the first error is from
if(:new.columnX in (select t.columnX from tableX t))
which gives
PLS-00405: subquery not allowed in this context
because if x in (select...) isn't valid PL/SQL syntax. You have to do the select as a separate step. Fixing that will give you code that at least compiles, but still isn't ideal:
create or replace trigger tablex_uk_trg
before insert or update on tablex
for each row
declare
l_columnx_check number := 0;
begin
select count(*) into l_columnx_check
from tablex t
where t.columnx = :new.columnx
and rownum = 1;
if l_columnx_check > 0 then
raise_application_error(-20001, 'Value '||:new.columnx||' already exists');
end if;
end;
It's not ideal because firstly, a unique constraint is a far more efficient and self-documenting way to enforce uniqueness.
create table tablex (columnx number unique);
or better still
create table tablex (columnx number constraint tablex_uk unique);
or if it's the primary key
create table tablex (columnx number constraint tablex_pk primary key);
Now, anyone checking the table definition will see the unique constraint, the optimiser will use it in queries, it has a standard error code ORA-00001: unique constraint (WILLIAM.TABLEX_UK) violated and so on.
Secondly, the update part of the trigger won't work anyway. Oracle won't let a row-level update trigger query its own table:
insert into tablex (columnx) values (1);
update tablex set columnx = 1;
ORA-04091: table WILLIAM.TABLEX is mutating, trigger/function may not see it
ORA-06512: at "WILLIAM.TABLEX_UK_TRG", line 4
ORA-04088: error during execution of trigger 'WILLIAM.TABLEX_UK'
DBFiddle
And in any case the logic is missing some checks, because the update in my example should be valid. But I won't go into how you might fix that because the unique constraint is all you need.

Trigger in Oracle giving error

This is my sql code:
CREATE OR REPLACE TRIGGER PLACE_NO_TRIGGER
BEFORE INSERT or UPDATE ON UHA_LEASE
FOR EACH ROW BEGIN
INSERT INTO UHA_TEMPVAL SELECT PLACE_NO FROM UHA_RESHALL;
INSERT INTO UHA_TEMPVAL SELECT PLACE_NO FROM UHA_GENERAL;
IF(:NEW.PLACE_NO NOT IN UHA_TEMPVAL.TEMP_VALUE AND :NEW.PLACE_NO IS NOT NULL) THEN
RAISE_APPLICATION_ERROR(-10001, 'PLACE_NO MUST BE IN UHA_RESHALL OR IN UHA_GENERAL OR NULL');
END IF;
DELETE FROM UHA_TEMPVAL;
END;
This is giving these errors:
Error(4,27): PLS-00103: Encountered the symbol "UHA_TEMPVAL" when expecting one of the following: ( The symbol "(" was substituted for "UHA_TEMPVAL" to continue.
Error(4,69): PLS-00103: Encountered the symbol "THEN" when expecting one of the following: ) , and or as The symbol ")" was substituted for "THEN" to continue.
Can someone help me understand why these errors are occurring? It's especially odd because row 4 ends at column 60.
Thanks!
It looks like you're trying to enforce referential integrity from a child table to either of two parent tables. You don't really need to insert and delete from a temporary table; you can count how many rows match in either table:
CREATE OR REPLACE TRIGGER PLACE_NO_TRIGGER
BEFORE INSERT or UPDATE ON UHA_LEASE
FOR EACH ROW
DECLARE
CNT NUMBER;
BEGIN
SELECT COUNT(*)
INTO CNT
FROM (
SELECT PLACE_NO FROM UHA_RESHALL
WHERE PLACE_NO = :NEW.PLACE_NO
UNION ALL
SELECT PLACE_NO FROM UHA_GENERAL
WHERE PLACE_NO = :NEW.PLACE_NO
);
IF :NEW.PLACE_NO IS NOT NULL AND CNT = 0 THEN
RAISE_APPLICATION_ERROR(-10001,
'PLACE_NO MUST BE IN UHA_RESHALL OR IN UHA_GENERAL OR NULL');
END IF;
END;
/
You could choose to only run the query if the :NEW.PLACE_NO is not null but it probably won't make much difference if the columns are indexed.

Issue with PL-SQL: ORA-06550

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';

sql - insert if not exists

I am having trouble with a sql query. I need to insert a row if the same row does not exist already. This is what I have so far:
DECLARE
BEGIN
FOR FOLDER_ROW IN (SELECT FOLDERID, USERID FROM DATA1.FOLDERS)
LOOP
IF NOT EXISTS (SELECT * FROM DATA1.FOLDER_USER WHERE FOLDER_ID = FOLDER_ROW.FOLDERID AND USER_ID = FOLDER_ROW.USERID)
INSERT INTO DATA1.FOLDER_USER (FOLDER_ID, USER_ID) VALUES (FOLDER_ROW.FOLDERID, FOLDER_ROW.USERID);
END LOOP;
COMMIT;
END;
I would not be very familiar with sql particularly the not exists syntax so when I execute I get the following error:
ORA-06550: line 37, column 11: PLS-00103: Encountered the symbol
"INSERT" when expecting one of the following:
then and or
The symbol "then" was substituted for "INSERT" to continue.
ORA-06550: line 38, column 10:
PLS-00103: Encountered the symbol "LOOP" when expecting one of the following:
if
ORA-06550: line 40, column 5:
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
Do it all in SQL rather than context switching into PL/SQL:
INSERT INTO DATA1.FOLDERS
(folder_id,
user_id)
SELECT f1.folder_id,
f1.user_id
FROM DATA1.FOLDERS f1
WHERE NOT EXISTS (SELECT 1
FROM DATA1.FOLDERS f2
WHERE f1.folder_id = f2.folder_id
AND f1.user_id = f2.user_id);
A better (Oracle specific?) solution may be the MERGE statement.
See here for a nice explanation, with examples:
http://www.oracle-base.com/articles/10g/MergeEnhancements10g.php
Hope that helps.
You forgot the THEN
IF condition THEN
...
ELSE
...
END IF;
DECLARE
N_COUNTS NUMBER;
BEGIN
select count(ID) into N_COUNTS from TABLE_NAME where ID = 1;
IF N_COUNTS=0 THEN
INSERT QUERY....
ELSE
UPDATE QUERY....
END IF;
END;
Needed Similar for Sqlite
I need to insert into a sqlite db but only if the key doesn't already exist.
id is the primary key autoincremented.
key is a unique string.
MainToken Table
id | key | created | active
1 | test | 2022-01-07 | 1
2 | 2ndOne | 2021-12-19 | 1
Finally, if the item already exists then I want that id but if it was just inserted then I want that new id.
Query That Works -- based on answer
insert into maintoken (key)
select $key
where not exists
(select key from maintoken where key=$key);
select id from maintoken where key=$key and active=1;
This will insert the $key value into the maintoken table
only if the $key doesn't already exist.
After the new unique key is inserted it will select and get the new ID value and return it.
If the new key isn't unique it will return the value of that existing key's id.

error ORA-06550 ORA-00933

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 ?