SQL Duplicate Key Help - sql

I have a statement that looks something like this:
insert table_name(...)
select .... from ... join ...
How can I use where not exists or something of that effect with this insert and select statement so that if this exact code is reran with the same values, it won't throw an error. I don't want to have to copy and paste the select/joins in a check as it is a pretty big block of code, so is there any way to do something like
if not exists (insert table_name(...)
select ... from...join)
or would it be something else like
insert table_name(...)
if not exists(select ... from ... join)

Try using the sql server MERGE command.
http://technet.microsoft.com/en-us/library/bb510625.aspx

Trying to keep this as generic as you did and still have it make sense. Hopefully, this is understandable.
insert table_name(...)
select .... from ... join ...
WHERE NOT EXISTS(SELECT NULL
FROM table_name
WHERE PKColumn = YourOuterSelectTable.PKColumn)
To try to put some more meat on it:
/* Assume Column1 is primary key */
INSERT INTO table_name
(Column1, Column2)
SELECT a.Column1, b.Column2
FROM TableA a
INNER JOIN TableB b
ON a.Column1 = b.FKColumn1
WHERE NOT EXISTS (SELECT NULL
FROM table_name
WHERE Column1 = a.Column1)

You may be able to just put it in a TRY CATCH block to just eat an exception if this insert fails.
http://geekswithblogs.net/ram/archive/2006/10/12/93829.aspx
On that note I must say that this is considered BAD PRACTICE to use exceptions to control logic flow.
I am more concerned about why this situation exists, I am having a hard time thinking of a legitimate situation in a GOOD DESIGN where this problem would occur?

In your
select .... from ... join ...
do a left join to the table you are inserting to with the new values you want to insert
if those joined values are null then you can safely insert without error.

Related

empty oracle global temporary table for where clause

I have some GTTs that are filled with data and later used for WHERE clauses (WHERE x in (SELECT * FROM gtt)). However sometimes I don't have data for a temporary table or don't want to filter by it.
If I understand it correctly, GTTs are instantiated when I insert something and are there for the session. Is there a way to instantiate an empty table so when I use the WHERE IN SELECT it doesn't throw an error (which it does now)?
Or do I have to create the SELECT statement with IFs to selectively only include a WHERE for the gtts that should be used?
Currently the structure looks like this:
IF(data)
INSERT INTO GTT1 SELECT ...
END IF;
(for several gtts)
SELECT x.data, x.more, a.a, a.b
FROM table1 x, table2 a
WHERE x.key in (SELECT * From gtt1) AND x.a = a.a;
You could change the WHERE clause of your INSERT INTO GTT such that no rows are found.

IF-Statement in SQLite: update or insert?

I Can't run this query with SQLite
if 0<(select COUNT(*) from Repetition where (Word='behnam' and Topic='mine'))
begin
update Repetition set Counts=1+ (select Counts from Repetition where (Word='behnam' and Topic='mine'))
end
else
begin
insert Repetition(Word,Topic,Counts)values('behnam','mine',1)
end
It says "Syntax error near IF"
How can I solve the problem
SQLite does not have an IF statement (see the list of supported queries)
Insetad, check out out ERIC B's suggestion on another thread. You're effectively looking at doing an UPSERT (UPdate if the record exists, INSERT if not). Eric B. has a good example of how to do this in SQLite syntax utilizing the "INSERT OR REPLACE" functionality in SQLite. Basically, you'd do something like:
INSERT OR REPLACE INTO Repetition (Word, Topic, Counts)
VALUES ( 'behnam', 'mine',
coalesce((select Counts + 1 from Repetition
where Word = 'behnam', AND Topic = 'mine)
,1)
)
Another approach is to INSERT ... SELECT ... WHERE ... EXISTS [or not] (SELECT ...);
I do this sort of thing all the time, and I use jklemmack's suggestion as well. And I do it for other purposes too, such as doing JOINs in UPDATEs (which SQLite3 does not support).
For example:
CREATE TABLE t(id INTEGER PRIMARY KEY, c1 TEXT NOT NULL UNIQUE, c2 TEXT);
CREATE TABLE r(c1 TEXT NOT NULL UNIQUE, c2 TEXT);
INSERT OR REPLACE INTO t (id, c1, c2)
SELECT t.id, coalesce(r.c1, t.c1), coalesce(r.c2, t.c2)
FROM r LEFT OUTER JOIN t ON r.c1 = t.c1
WHERE r.c2 = #param;
The WHERE there has the condition that you'd have in your IF. The JOIN in the SELECT provides the JOIN that SQLite3 doesn't support in UPDATE. The INSERT OR REPLACE and the use of t.id (which can be NULL if the row doesn't exist in t) together provide the THEN and ELSE bodies.
You can apply this over and over. If you'd have three statements (that cannot somehow be merged into one) in the THEN part of the IF you'd need to have three statements with the IF condition in their WHEREs.
This is called an UPSERT (i.e. UPdate or inSERT). It has its forms in almost every type of database. Look at this question for the SQLite version: SQLite - UPSERT *not* INSERT or REPLACE
One way that I've found is based on SQL WHERE clause true/false statement:
SELECT * FROM SOME_TABLE
WHERE
(
SELECT SINGLE_COLUMN_NAME FROM SOME_OTHER_TABLE
WHERE
SOME_COLUMN = 'some value' and
SOME_OTHER_COLUMN = 'some other value'
)
This actually means execute some QUERIES if some other QUERY returns 'any' result.

query insert and select explaination

I am confused about this query where it uses insert statement and then ignore and then select. Can someone explain me this? Thanks
INSERT IGNORE INTO
myTable
SELECT
$var1 AS `CMMNCTID`,
$var2 AS `ENCID`,
variableID,
ProductID,
CustomerID,
Age,
"" AS `myJ`,
"" AS `myI`
FROM
table2
JOIN
table3
ON
table2.ID= table3.ID
INSERT IGNORE in a keyword mysql: If the insert will cause a Primary key or Unique key error, it should skip that row.
INSERT ... SELECT: is used to copy data from another table.
http://dev.mysql.com/doc/refman/5.1/en/insert.html
The SELECT is a subquery. What the INSERT is doing is inserting whatever is contained in the join of table2 and table3, into myTable. The IGNORE tells it to ignore any entries for keys that already exist in myTable and to just insert whatever doesn't yet exist.
It seems the purpose of the query is to combine the data that is associated between table2 and table3 and dump it into myTable.
It takes results from the SELECT query on tables table2 and table3 and inserts the results into table myTable. IGNORE keyword simply tells mysql to ignore any errors that occur while executing the INSERT query.

Using tuples in SQL in clause

Given a database like this:
BEGIN TRANSACTION;
CREATE TABLE aTable (
a STRING,
b STRING
);
INSERT INTO aTable VALUES('one','two');
INSERT INTO aTable VALUES('one','three');
CREATE TABLE anotherTable (
a STRING,
b STRING
);
INSERT INTO anotherTable VALUES('one','three');
INSERT INTO anotherTable VALUES('two','three');
COMMIT;
I would like to do something along the lines of
SELECT a,b FROM aTable
WHERE (aTable.a,aTable.b) IN
(SELECT anotherTable.a,anotherTable.b FROM anotherTable);
To get the answer 'one','three', but I'm getting "near ",": syntax error"
Is this possible in any flavour of SQL? (I'm using SQLite)
Am I making a gross conceptual error? Or what?
your code works if you do it in PostgreSQL or Oracle. on MS SQL, it is not supported
use this:
SELECT a,b FROM aTable
WHERE
-- (aTable.a,aTable.b) IN -- leave this commented, it makes the intent more clear
EXISTS
(
SELECT anotherTable.a,anotherTable.b -- do not remove this too, perfectly fine for self-documenting code, i.e.. tuple presence testing
FROM anotherTable
WHERE anotherTable.a = aTable.a AND anotherTable.b = aTable.b
);
[EDIT]
sans the stating of intent:
SELECT a,b FROM aTable
WHERE
EXISTS
(
SELECT *
FROM anotherTable
WHERE anotherTable.a = aTable.a AND anotherTable.b = aTable.b
);
it's somewhat lame, for more than a decade, MS SQL still don't have first-class support for tuples. IN tuple construct is way more readable than its analogous EXISTS construct. btw, JOIN also works (tster's code), but if you need something more flexible and future-proof, use EXISTS.
[EDIT]
speaking of SQLite, i'm dabbling with it recently. yeah, IN tuples doesn't work
you can use a join:
SELECT aTable.a, aTable.b FROM aTable
JOIN anotherTable ON aTable.a = anotherTable.a AND aTable.b = anotherTable.b
Another alternative is to use concatenation to make your 2-tuple into a single field :
SELECT a,b FROM aTable
WHERE (aTable.a||'-'||aTable.b) IN
(SELECT (anotherTable.a || '-' || anotherTable.b FROM anotherTable);
...just be aware that bad things can happen if a or b contain the delimiter '-'

Using SQl Server CE; Possible to Insert Only If Not Exists?

I'm trying to verify a simple 1 field table to determine if a record exists before inserting a duplicate.
if not exists (select * from url where url = ...)
insert into url...
Can someone Help?
Your code example will run in the full version of SQL, or you could rearrange to the following:
insert into url
select 'myvalue'
where not exists (select * from url where url = 'myvalue')
Just reverse it and add the condition as a where clause predicate
Insert Into Table ....
Where Not Exists
(Select * From table where ...)
... But your basic problem sounds like it might be better solved by putting a alternate key (unique) constraint on the insert table, referencing the url column (I assume Sql CE does Referential Integrity (RI) constraints?)
You might want to read this thread. performing-insert-or-update-upsert-on-sql-server-compact-edition
In a nutshell a sqlce specific solution (using SqlCeResultSet) will provide the maximum performance.
Use an Outer Join
Insert into X(...)
select blah, blah, blah
from
table t left outer join
X on t.id=x.id
where
x.id is null
Granted, this is way past the posting date, but since I've not seen this answered elsewhere in my quick Google search, I thought I'd share how I solved this with SQL CE so others searching might find an answer.
-- Update existing record's value
UPDATE myTable SET myValue = 'Hello World' WHERE keyField = 'MyKey';
-- Insert new record if existing record doesn't exist`
INSERT INTO myTable (keyField, myValue)
SELECT I.keyField, I.myValue
FROM (
SELECT 'Hello World' AS myValue, 'MyKey' AS keyField
) I
LEFT JOIN myTable T ON I.keyField = T.keyField
WHERE T.keyField IS NULL;
You are on the right path with IF NOT EXISTS. It is better to use IF NOT EXISTS() or IF EXISTS() than a Sub Query because SQL Server will stop scanning rows in the table when it finds the first instance that matches the EXISTS() condition your looking for. With a Sub Query written in the examples above it will scan the whole table.
A Classic example is the Insert or Update aka the SAVE.
IF EXISTS(SELECT * FROM Table_A WHERE Column_1 = #Parameter)
BEGIN
--Update Statement here.
END
ELSE
BEGIN
--Insert Statement here.
END
What about something like this:
UPDATE Table1 SET (...) WHERE Column1='SomeValue'
IF ##ROWCOUNT=0
INSERT INTO Table1 VALUES (...)
Source