Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Insert record only if record does not already exist in table

I'm wondering if there is a way to insert a record into a table only if the table does not already contain that record?

Is there a query that will do this, or will I need a stored procedure?

like image 912
MegaMatt Avatar asked Jul 16 '10 21:07

MegaMatt


People also ask

Which command insert rows that do not exist and update the rows that exist?

The alternative (and generally preferred) method for INSERTING into rows that may contain duplicate UNIQUE or PRIMARY KEY values is to use the INSERT ... ON DUPLICATE KEY UPDATE statement and clause.

How do you insert value if not exists SQL?

The basic syntax for INSERT IF NOT EXISTS is as follows. Copy INSERT INTO name_of_the_table (column_name) SELECT * FROM (SELECT value_name) AS val WHERE NOT EXISTS (<conditonal expression>); In the name_of_the_table we insert the value_name in the column_name if the conditional expression is met.

How do you find out if a record already exists in a database if it doesn't insert a new record in Python?

You can either do this with a stored procedure or from ASP. SELECT 'This record already exists!' First, we check if the record exists with the EXISTS keyword. EXISTS executes the query we tell it to (the SELECT ) and returns a boolean value.


2 Answers

You don't say what version of SQL Server. If SQL Server 2008 you can use MERGE

NB: It is usual to use Merge for an Upsert which is what I originally thought the question was asking but it is valid without the WHEN MATCHED clause and just with a WHEN NOT MATCHED clause so does work for this case also. Example Usage.

CREATE TABLE #A(  [id] [int] NOT NULL PRIMARY KEY CLUSTERED,  [C] [varchar](200) NOT NULL)       MERGE #A AS target     USING (SELECT 3, 'C') AS source (id, C)     ON (target.id = source.id)     /*Uncomment for Upsert Semantics        WHEN MATCHED THEN          UPDATE SET C = source.C */     WHEN NOT MATCHED THEN             INSERT (id, C)         VALUES (source.id, source.C); 

In terms of execution costs the two look roughly equal when an Insert is to be done...

Link to plan images for first run

but on the second run when there is no insert to be done Matthew's answer looks lower cost. I'm not sure if there is a way of improving this.

Link to plan images for second run

Test Script

select *  into #testtable from master.dbo.spt_values  CREATE UNIQUE CLUSTERED INDEX [ix] ON #testtable([type] ASC,[number] ASC,[name] ASC)   declare @name nvarchar(35)= 'zzz' declare @number int = 50 declare @type nchar(3) = 'A' declare @low int declare @high int declare @status int = 0;    MERGE #testtable AS target USING (SELECT @name, @number, @type, @low, @high, @status) AS source (name, number, [type], low, high, [status]) ON (target.[type] = source.[type] AND target.[number] = source.[number] and target.[name] = source.[name] ) WHEN NOT MATCHED THEN     INSERT (name, number, [type], low, high, [status]) VALUES (source.name, source.number, source.[type], source.low, source.high, source.[status]);  set @name = 'yyy'  IF NOT EXISTS      (SELECT *     FROM #testtable     WHERE [type] = @type AND [number] = @number and name = @name)     BEGIN INSERT INTO #testtable (name, number, [type], low, high, [status]) VALUES (@name, @number, @type, @low, @high, @status); END 
like image 116
Martin Smith Avatar answered Sep 22 '22 12:09

Martin Smith


IF NOT EXISTS      (SELECT {Columns}      FROM {Table}      WHERE {Column1 = SomeValue AND Column2 = SomeOtherVale AND ...})  INSERT INTO {Table} {Values} 
like image 22
Matthew Jones Avatar answered Sep 19 '22 12:09

Matthew Jones