How to insert conditionally in Oracle? - sql

I've read here that the syntax looks like this:
INSERT
WHEN ([Condition]) THEN
INTO [TableName] ([ColumnName])
VALUES ([VALUES])
ELSE
INTO [TableName] ([ColumnName])
VALUES ([VALUES])
SELECT [ColumnName] FROM [TableName];
But I don't want to provide values from another table. I just want to type them, so I've got:
INSERT
WHEN EXISTS (SELECT 1 FROM FOO WHERE NAME = 'JOE')
THEN
INTO BAR (NAME, AGE)
VALUES ('JOE', 50)
and this produces exception: ORA-00928: missing SELECT keyword.
I want to perform an insert if given value is found in another table.

Using with select works. Your query wasn't working because there is a problem with values keyword when inserting conditionally.
INSERT
WHEN EXISTS (SELECT 1 FROM FOO WHERE NAME = 'JOE')
THEN
INTO BAR (NAME, AGE)
SELECT 'JOE', 50 FROM DUAL

So, I've found an indirect way here and solution for my question would be:
INSERT INTO BAR (NAME, AGE)
SELECT 'JOE', 50
FROM DUAL
WHERE EXISTS (SELECT 1 FROM FOO WHERE NAME = 'JOE')
but it doesn't explain why I have to use SELECT statement in INSERT WHEN

Related

PostgreSQL bulk update

In my PostgreSQL database I have the following schema:
CREATE TABLE atc_codes (
id bigint NOT NULL,
name character varying,
atc_code character varying
);
INSERT INTO atc_codes (id, name, atc_code) VALUES (1, 'granisetron', 'A04AA02');
INSERT INTO atc_codes (id, name, atc_code) VALUES (2, '', 'A04AA02');
INSERT INTO atc_codes (id, name, atc_code) VALUES (3, '', 'A04AA02');
INSERT INTO atc_codes (id, name, atc_code) VALUES (4, 'metoclopramide', 'A03FA01');
INSERT INTO atc_codes (id, name, atc_code) VALUES (5, '', 'A03FA01');
INSERT INTO atc_codes (id, name, atc_code) VALUES (6, '', 'A03FA01');
SELECT * FROM atc_codes;
id
name
atc_code
1
granisetron
A04AA02
2
A04AA02
3
A04AA02
4
metoclopramide
A03FA01
5
A03FA01
6
A03FA01
View on DB Fiddle
Now I want to do the following things:
Update all records with act_code equal to A04AA02 to have granisetron value in the name column.
Update all records with act_code equal to A03FA01 to have metoclopramide value in the name column.
In the real database there will be much more scenarios like that so using something like CASE statement is impossible in that case.
Can I do that in one query instead of two?
I found the solution with using view:
WITH act_codes_name AS (
SELECT
name,
atc_code
FROM
atc_codes
WHERE
name IS NOT NULL
)
UPDATE
atc_codes
SET
name = act_codes_name.name
FROM act_codes_name
WHERE act_codes_name.atc_code = atc_codes.atc_code;
Yes you could use a CASE WHEN (standard SQL "switch case") in the SET clause:
UPDATE atc_codes
SET name = CASE
WHEN atc_code = 'A04AA02' THEN 'granisetron'
WHEN atc_code = 'A03FA01' THEN 'metoclopramide'
ELSE name
END
WHERE atc_code IN('A04AA02', 'A03FA01');
To avoid mistakes, I added a ELSE (equivalent to a default case) and a WHERE clause to prevent updating rows that don't match. Both do the same thing and I think you could just use one or the other.

Inserting data into Oracle table (SQL)

I already have a table built in oracle.
Im trying to insert some data like this:
INSERT INTO movies_actor('name','id')
VALUES ('Nuno','2'), ('Pedro','3'), ('Jose','1');
select * from movies_actor;
I always get this error
ORA-00928: missing SELECT keyword
What am I doing wrong?
I don't think you need the single quote around your field names.
You need to do:
INSERT INTO TableName(Column1, Column2)
VALUES('Nuno', '2');
In your example, it would be:
INSERT INTO movies_actor(name, id)
VALUES ('Nuno','2');
INSERT INTO movies_actor(name, id)
VALUES ('Pedro','3');
INSERT INTO movies_actor(name, id)
VALUES ('Jose','1');
select * from movies_actor;
Another way.
insert into table
(field1, field2)
select value1, value2
from dual
union
select value3, value4
from dual
etc
You cannot insert multiple records in one statement using VALUES. You can either use Tenzin's solution or use INSERT ALL :
INSERT ALL
INTO movies_actor(name, id) VALUES ('Nuno', '2')
INTO movies_actor(name, id) VALUES ('Pedro', '3')
INTO movies_actor(name, id) VALUES ('Jose', '1')
SELECT * FROM dual;

Sql insert multiple rows if not exists

I have a sql table that has two columns id and name. I have list of names about 20 and I need to write a query that checks if name exists before insert.
Is there a better way of doing this rather then just having the below query 20 times but with different names (I need do this in t-sql):
IF NOT EXISTS(SELECT*
FROM mytable
WHERE name = 'Dan')
BEGIN
INSERT INTO mytable
(name)
VALUES ('dan')
END
INSERT INTO MyTable (Name)
SELECT NewNames.Name
FROM ( VALUES ('Name1'), ('Name2'), ('Name3') ) AS NewNames (Name)
WHERE NOT EXISTS ( SELECT 1
FROM MyTable AS MT
WHERE MT.Name = NewNames.Name );
I think you could use a merge statement:
MERGE INTO myTable AS Target
USING (VALUES ('name1'),('name2'),('...')) AS source (NAME)
ON Target.NAME = Source.NAME
WHEN NOT MATCHED BY TARGET THEN
INSERT (NAME) VALUES (name)
You can filter values with NOT EXISTS
INSERT INTO myTable (
Name
)
SELECT DISTINCT
Name
FROM (
VALUES ('Name 1'),
('Name 2')
) AS NewNames(Name)
WHERE
NOT EXISTS (SELECT 1 FROM TargetTable WHERE myTable.Name = NewNames.Name)
If your new names are in another table, you can change the select query in the above one.
Please note, that the DISTINCT keyword is necessary to filter out the duplications in the source data.
I would do this using insert:
with names as (
select 'Dan' as name union all
select 'name2' union all
. . .
)
insert into myTable(name)
select distinct name
from myTable
where not exists (select 1 from mytable t2 where t2.name = t.name);
Note: you may want to create a unique index on mytable(name) so the database does the checking for duplicates.
untested so there might be some minor errors:
merge into mytable x
using (
values ('name1')
, ('name2')
, ...
, ('namen')
) as y (name)
on x.name = y.name
when not matched then
insert (name)
values (y.name)
INSERT INTO MyTable (Name)
SELECT Name FROM
(
VALUES ('Name 1'),
('Name 2')
) AS Names(Name)
WHERE Name NOT IN
(
SELECT Name FROM MyTable
)
INSERT IGNORE INTO myTable (column1, column2) VALUES (val1, val2),(val3,val4),(val5,val6);
INSERT IGNORE will allow skip on duplicate values

equivalent of if exists in isqlplus?

I'm new to sql and trying to find out if there is a way to say something like this in isqlplus? I'm trying to insert a row with values if a certain value exists on another table.
IF EXISTS (SELECT ID FROM SOMETABLE WHERE ID = 1)
BEGIN
INSERT INTO ANOTHERTABLE (NBR, FNAME, LNAME) VALUES ( 2, 'John', 'Smith');
END
Any help appreciated.
You can add WHERE EXISTS in your query
INSERT INTO ANOTHERTABLE (NBR, FNAME, LNAME)
SELECT 2, 'John', 'Smith'
FROM DUAL
WHERE EXISTS (SELECT ID FROM SOMETABLE WHERE ID = 1)

Why this oracle query returning empty result set?

I have two database tables with some demo data like shown below
Create table demo(uuid int, addressname varchar(50));
insert into demo values(1, 'intersportprofi');
insert into demo values(2, 'intersportprofi');
insert into demo values(3, 'intersportprofi');
insert into demo values(4, 'intersportmarket');
insert into demo values(5, 'intersportmarket');
insert into demo values(6, 'intersportmarket');
create table demo_av(uuid int, testid int, name varchar(50), value varchar(50));
insert into demo_av values(1, 1, 'sport','football basketball cricket');
insert into demo_av values(2, 1, 'brand','reebok addidas nike');
insert into demo_av values(3, 2, 'sport','football basketball ');
insert into demo_av values(4, 2, 'brand','reebok addidas ');
I wrote the following query to get the results from those tables, but oracle returning empty result set.
SELECT d.addressname FROM demo d, demo_av dv
WHERE d.uuid = dv.testid AND d.addressname='intersportprofi'
AND REGEXP_LIKE( dv.value, 'reebok') AND REGEXP_LIKE( dv.value, 'cricket')
Why? where i am doing wrong ? Any help will be greatly appriciated
Change this:
AND REGEXP_LIKE( dv.value, 'reebok') AND REGEXP_LIKE( dv.value, 'cricket')
To this:
AND (REGEXP_LIKE( dv.value, 'reebok') OR REGEXP_LIKE( dv.value, 'cricket'))
Because:
You have no record in the "demo_av" table that matches with "reebok" AND "cricket". The operator you need is "OR" and the parantheses are necessary because of existing of the first condition.
UPDATE
Here is the capture screen of the results:
Cheers
Based on your comments, I think you want a query that will search over multiple rows with same testid. This can be done with joins or like this:
SELECT DISTINCT d.addressname
FROM demo AS d
WHERE d.addressname = 'intersportprofi'
AND EXISTS
( SELECT *
FROM demo_av AS dv
WHERE d.uuid = dv.testid
AND dv.value LIKE '%reebok%'
)
AND EXISTS
( SELECT *
FROM demo_av AS dv
WHERE d.uuid = dv.testid
AND dv.value LIKE '%cricket%'
) ;