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)
Related
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
Is there a way to insert a new record to a table that has an non-unique id and set this id to the next number in the same SQL statement?
Something like
INSERT INTO T1 (id, fname, lname)
VALUES ([last id + 1], 'Dan', 'Thomson');
this probably works
INSERT INTO T1 (id, fname, lname)
VALUES (ifnull((select max(id) from T1),0) + 1, 'Dan', 'Thomson')
DECLARE #COUNTER INT;
SET #COUNTER = 1;
WHILE(#COUNTER <= XXX)
BEGIN
INSERT INTO T1 (id, fname, lname)
VALUES (#COUNTER, #FNAME , #LNAME);
SET #COUNTER = #COUNTER + 1;
END
Built-in function MAX :
INSERT INTO T1 (id, fname, lname)
SELECT ifnull(MAX(id)+ 1,1), 'Dan', 'Thomson' FROM T1
Insert and set value with max()+1 problems
SELECT MAX(col) +1 is not safe -- it does not ensure that you aren't inserting more than one customer with the same customer_id value, regardless if selecting from the same table or any others.
For performance, add an index:
CREATE INDEX T1_INDEX1 ON T1 (id) DESC
References:
MAX()
CREATE INDEX
Index Advisor, Show Statements
Accelerated analytics - faster aggregations using the IBM DB2 for i encoded vector index (EVI) technology
Unit Test
-- Create Table
SET SCHEMA QTEMP;
CREAT TABLE testtbl (
id integer not null default,
fname char(10) not null default,
lname char(10) not null default)
;
-- Initialize Table with Data
insert into
testtbl ( id , fname, lname)
values
( 1, 'fname1', 'lname_1'),
( 2, 'fname2', 'lname_2'),
( 2, 'fname3', 'lname_3'),
( 3, 'fname4', 'lname_4')
;
-- Test Insert Statement
INSERT INTO
testtbl ( id, fname, lname )
SELECT ifnull(MAX( id ) + 1, 1), 'Dan', 'Thomson' FROM testtbl;
--Confirm Expectation
select * from testtbl;
ID FNAME LNAME
-------------------------------------
1 fname1 lname_1
2 fname2 lname_2
3 fname4 lname_4
4 Dan Thomson
if you want insert all content of table with unique id start with max +1
INSERT INTO T1 (id, fname, lname)
select
rownumber() over() + ifnull((select max(T1.id) from T1), 0),
T2.zone1, T2.zone2
from T2
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
Is it possible to do something like having an IF statement within an INSERT like so;
INSERT INTO #TABLE (ID, NAME, ADDRESS)
VALUES(
IF CONDITION (SELECT DATA)
ELSE (SELECT DATA)
)
Sort of...
INSERT INTO #TABLE (ID, NAME, ADDRESS)
SELECT
CASE condition WHEN result then id else id2 end,
CASE condition WHEN result then name else name2 end,
...
or with a UNION
INSERT INTO #TABLE (ID, NAME, ADDRESS)
SELECT data FROM source WHERE condition
UNION
SELECT data FROM othersource WHERE NOT(condition)
I am having a table Student and i have a set of 20 names.
by using his sql
select name from student st where st.name in (
'abc', 'xyz', . . .
)
i can find out all student names which are in table and in the set.
Now, how can i find out which out of these 20 names are not in Student table.
I'm assuming you want the names themselves.
One option is to create a table with all the available student names, then select from it rows which don't have corresponding rows in the student tables, it will look something like this
select name from student_names
where name not in (select name from students)
CREATE TABLE student(name VARCHAR(255));
INSERT INTO student VALUES('a'), ('abc');
CREATE TABLE temp(x VARCHAR(255));
INSERT INTO temp VALUES('abc'), ('xyz');
SELECT x FROM temp WHERE
NOT EXISTS (SELECT * FROM student st WHERE st.name = x);
Depending on the database you use, there might be an easier way. There is also a way using UNION.
SELECT NOT IN ?
postgresql: http://archives.postgresql.org/pgsql-sql/2002-08/msg00322.php
DECLARE #names table ( name varchar(100) )
INSERT INTO #names VALUES ('abc')
...
INSERT INTO #names VALUES ('xyz')
SELECT name FROM #names WHERE name NOT IN ( SELECT DISTINCT Name FROM Student )
select name from student where name not in (
select name from student st where st.name in (
'abc', 'xyz', . . .
))
EDIT: I might not get what you are looking for. Please run following script and it is giving the results.
declare #student table
(
name varchar(50)
)
insert into #student select 'james'
insert into #student select 'will'
insert into #student select 'bill'
insert into #student select 'adam'
insert into #student select 'jon'
insert into #student select 'white'
insert into #student select 'green'
select name from #student where name in ('james', 'will', 'bill')
select name from #student where name not in (select name from #student where name in ('james', 'will', 'bill'))
Assuming that the tool you are using can generate dynamic sql, try generating an inline view consisting of your set of user names - like so:
select 'abc' check_name union all
select 'xyz' check_name union all
...
(The syntax of the inline view may depend on which version of SQL you are using - some versions of SQL require a from [dummy_table] clause in select statements that are not accessing a table.)
Then construct a query using this inline view with a not exists in student clause, like this:
select check_name from (
select 'abc' check_name union all
select 'xyz' check_name union all
...
) ilv where not exists
(select null from student st where st.name = ilv.check_name)