Why am I receiving "not enough values" when running an INSERT? - sql

Couldn't get the right approach to automatically set the id value in my table with Oracle. Here's my trigger:
create or replace trigger themes_on_insert
before insert on THEME
for each row
begin
:new.ID := THEMES_SEQ.nextval;
end;
I have two columns: id, description. But when i call insert
insert into theme values('Sport');
it gives me
Error report:
SQL Error: ORA-00947: not enough values
00947. 00000 - "not enough values"

You do not specify the columns you are supplying values for, so the database expects a value for every column in your table.
Assuming you have a column name in that table, you need to do this:
insert into theme (name) values('Sport');
Not listing the target columns in an INSERT statement is bad coding style.

Just make sure to name the columns you're specifying the values for.
insert into theme (description) values('Sport');

Well if you do not specify the colnames, in your insert statement, the databse will assume that you give the values for all the column.
So :
insert into theme (col_name) values ('Sport');

In case Trigger is not mandatory,You can simply use the following
insert into theme values(THEMES_SEQ.nextval,'Sport');

Check the columns count while inserting.

Related

Can SQL before insert triggers access the values of an INSERT statement? [duplicate]

I am trying to create a trigger in mysql that will insert in to another table when an insert on a table occurs.
CREATE TRIGGER addCardForNewUser AFTER INSERT ON swiped.Users
FOR EACH ROW
BEGIN
INSERT INTO swiped.Card (userid) VALUES (get value from original insert here);
END
In the values part of the insert statement how would i get a value from the original insert to use here?
Thanks
You can use those values with new.columnname. If the name of the column is userid too, then you can use:
CREATE TRIGGER addCardForNewUser AFTER INSERT ON swiped.Users
FOR EACH ROW
BEGIN
INSERT INTO swiped.Card (userid) VALUES (new.userid);
END
From the official documentation:
Within the trigger body, the OLD and NEW keywords enable you to access
columns in the rows affected by a trigger. OLD and NEW are MySQL
extensions to triggers; they are not case sensitive.
In an INSERT trigger, only NEW.col_name can be used

Advance Replace in insert scripts

I have below 2 insert statements which i took the export from sql developer from dev environment. I have delete those records from dev afterwards. Now i want to run this insert statement again in dev because those are my back up but i am getting error as virtual column which is ORD_DAYID cannot be used inside insert script. So i want to exclude this column and also the respective values using replace function or any tools which i dont know. I didnt know previously that i have virtual column for this table. I would like to know is there any tool or function where i can select ORD_DAYID and also the respective values get selected and then i can delete those and then i can be able to run this insert statement again in test enviornment.
P.S i have mentioned only 2 sample insert statements but there are 1000 insert statements. So its very difficult to manually delete this ORD_DAYID from this insert statements with respective values.
Insert into test_ord (IS_GRP,ORD_DAYID,REF_CAMPA_CODE) values (1,20150813,null);
Insert into test_ord (IS_GRP,ORD_DAYID,REF_CAMPA_CODE) values (1,20150828,null);
You can edit your INSERT statements using regular expressions, in an editor such as Notepad++.
So to change this ...
Insert into test_ord (IS_GRP,ORD_DAYID,REF_CAMPA_CODE) values (1,20150813,null);
... into this ...
Insert into test_ord (IS_GRP,REF_CAMPA_CODE) values (1,null);
You need a search pattern of:
Insert into test_ord \(IS_GRP,ORD_DAYID,REF_CAMPA_CODE\) values \(([0-9]+),([0-9]+),null\);
and a replace pattern of:
Insert into test_ord \(IS_GRP,REF_CAMPA_CODE\) values \(\1,null\);
Obviously you will need to refine the search pattern to cater for all the different values of IS_GRP, and REF_CAMPA_CODE in your 1000 statements.
" is there any way where we can count the place of column and value and replace it with null"
No. The snag with virtual columns is that they cannot be referenced in INSERT or UPDATE statements. So you need to totally exclude it from the projection.
"i am not able to find those option in notepad++"
Really? Search and replace is not an exotic option:
From the menu: Search > Find > Replace [tab] (or [ctrl]+h)
As the search mode select the regular expression radio button
create an auxiliary table without virtual columns.
Restore your data to this auxiliary table.
Transfer the data from the auxiliary table to the original table.
-- this is your table
create table mytab(A number, b number, s as (a+b));
--fill it with data
insert into mytab(a,b) values(1,1);
insert into mytab(a,b) values(1,2);
insert into mytab(a,b) values(2,1);
insert into mytab(a,b) values(2,2);
commit;
-- check its content
select * from mytab;
-- now delete the rows
delete from mytab;
commit;
-- restore your data
--------------------
-- create a table similar the table you want to restore
-- but the virtual colums as regular columns.
create table ctas as
select * from mytab where 1!=0;
-- insert your backup data
insert into ctas(a,b,s) values(1,1,2);
insert into ctas(a,b,s) values(1,2,3);
insert into ctas(a,b,s) values(2,1,3);
insert into ctas(a,b,s) values(2,2,4);
commit;
-- transfer the data to the table you want to restore
insert into mytab(a,b) select a,b from ctas;

ORACLE TRIGGER INSERT INTO ... (SELECT * ...)

Trigger with Insert into (select * ...)
I'm trying it.
INSERT INTO T_ USERS SELECT * FROM USERS WHERE ID = :new.ID;
not working...
this work.
INSERT INTO T_USERS(ID) VALUES(:new.ID);
Trigger
create or replace trigger "TRI_USER"
AFTER
insert on "USER"
for each row
begin
INSERT INTO T_USER SELECT * FROM USER WHERE ID = :new.ID;
end;​
this work.
INSERT INTO T_USERS(ID) VALUES(:new.ID);
So if it fits to you then try this:
INSERT INTO T_USER(ID) SELECT ID FROM USER WHERE ID = :new.ID;
If you want to select one or more rows from another table, you have to use this syntax:
insert into <table>(<col1>,<col2>,...,<coln>)
select <col1>,<col2>,...,<coln>
from ...;
Perhaps you could post the actual error you are experiencing?
Also, I suggest that you rethink your approach. Triggers that contain DML introduce all sorts of issues. Keep in mind that Oracle Database may need to restart a trigger, and could therefore execute your DML multiple times for a particular row.
Instead, put all your related DML statements together in a PL/SQL procedure and invoke that.
Its not about your trigger but because of INSERT statement
here insert statement works as below
INSERT INTO <TABLE>(COL1,COL2,COL3) VALUES (VAL1,VAL2,VAL3); --> If trying to populate value 1 by one.
INSERT INTO <TABLE>(COL1,COL2,COL3) --> If trying to insert mult vales at a time
SELECT VAL1,VAL2,VAL3 FROM <TABLE2>;
The number of values should match with number of columsn mentioned.
Hope this helps you to understand

Keyword 'Values' absent Oracle 9i

I'm trying to execute the following trigger when inserting some data in my table :
CREATE OR REPLACE TRIGGER AJOUTER_NEW_CONSISTANCE
AFTER INSERT OR UPDATE OF
CONSISTANCE_LIBELLE_1,CONSISTANCE_LIBELLE_2,CONSISTANC_LIBELLE_3
ON DB.ETAT_PARCELLAIRE
BEGIN
insert into DB.CONSISTANCE.LIBELLE
select consistance_libelle_1
from DB.ETAT_PARCELLAIRE
where DB.ETAT_PARCELLAIRE.consistance_libelle_1 not in (
select LIBELLE from DB.CONSISTANCE.LIBELLE);
END;
But it keeps giving me the following error :
PL/SQL : ORA00926 : Keyword Values absent.
How can I fix this ?
Thank you for help in advance :)
If CONSISTANCE is a table with a column called LIBELLE then you're referring to it incorrectly.
your insert is including the column, which I assume means the table has other columns and you only want to insert a value into that one, but your syntax is wrong (DB.CONSISTANCE.LIBELLE should be DB.CONSISTANCE(LIBELLE)). it is this line that's generating the ORA-00926.
your sub-select is including the column in the table name (DB.CONSISTANCE.LIBELLE should be just DB.CONSISTANCE)
So it should be:
CREATE OR REPLACE TRIGGER AJOUTER_NEW_CONSISTANCE
AFTER INSERT OR UPDATE OF
CONSISTANCE_LIBELLE_1,CONSISTANCE_LIBELLE_2,CONSISTANC_LIBELLE_3
ON DB.ETAT_PARCELLAIRE
BEGIN
insert into DB.CONSISTANCE(LIBELLE)
select consistance_libelle_1
from DB.ETAT_PARCELLAIRE
where consistance_libelle_1 not in (
select LIBELLE from DB.CONSISTANCE);
END;
I'm also not sure if CONSISTANC_LIBELLE_3 is a typo and it should be CONSISTANCE_LIBELLE_3.
You could also do a not exists instead of a not in:
insert into DB.CONSISTANCE(LIBELLE)
select CONSISTANCE_LIBELLE_1
from DB.ETAT_PARCELLAIRE
where not exists (
select 1
from DB.CONSISTANCE
where LIBELLE = DB.ETAT_PARCELLAIRE.CONSISTANCE_LIBELLE_1
);
Or use a merge:
merge into DB.CONSISTANCE c
using (select CONSISTANCE_LIBELLE_1 from DB.ETAT_PARCELLAIRE) ep
on (c.LIBELLE = ep.CONSISTANCE_LIBELLE_1)
when not matched then
insert (LIBELLE) values (ep.CONSISTANCE_LIBELLE_1);
Using a trigger to (partially) maintain that table looks odd though - it would be simpler to have a view which selects distinct values from ETAT_PARCELLAIRE:
create or replace view CONSISTANCE_VIEW as
select distinct CONSISTANCE_LIBELLE_1
from ETAT_PARCELLAIRE;
But they would have different content - once a value has appeared in CONSISTANCE_LIBELLE_1 it will always remain in CONSISTANCE as you are not removing defunct values, only inserting new ones; whereas CONSISTANCE_VIEW would only show values currently in the table. It isn't clear which behaviour you want.

Can I access values from where clauses in SQLite triggers?

I would like to trigger an update to a table based on the where clause of an insert to a different table. For example:
CREATE TRIGGER update_key_table
BEFORE INSERT ON value_table
BEGIN
INSERT OR IGNORE INTO key_table (key_name) VALUES ('new_key_name');
END;
This would update key_table with the value 'new_key_name' when the following query is run:
INSERT INTO value_table (key_id, value)
SELECT key_table.key_id, 'new_value'
FROM key_table
WHERE key_table.key_name = 'new_key_name';
However, I have not been able to find any way to get access to the 'new_key_name' value from the triggering query's WHERE clause.
I understand that I can just run the following two queries in sequence, it would just be inconvenient in this particular application:
INSERT OR IGNORE INTO key_table (key_name) VALUES ('new_key_name');
INSERT INTO value_table (key_id, value)
SELECT key_table.key_id, 'new_value'
FROM key_table
WHERE key_table.key_name = 'new_key_name';
An INSERT trigger can access only the values in the new record to be inserted.
You have to execute the two queries separately.
Alternatively, if you can modify all your applications, you could create a view with all three columns (key_id, value, and key_name), and create an INSTEAD OF trigger that executes both the 'real' INSERTs.