Domanda

I have the following code: the problem is, when I run the insert into, it would insert into the food table even the result are already inserted, how could I write an if statement that would check if the records in NEWfoods already exist in food table, if they exist in food, just don't do an insert, if they don't then do the insert. Thank you.

CREATE TABLE food (FoodName NVARCHAR(200), FoodType NVARCHAR(200));

CREATE TABLE NEWfoods (FoodName NVARCHAR(200), FoodType NVARCHAR(200));

-- populate base table (existing database table)
INSERT INTO food (FoodName, FoodType) VALUES 
 ('Apples', 'Fruit')
,('Avocado','Fruit')
,('Bananas', 'Fruit')
,('Mangos', 'Fruit')
,('Bread', 'Grain')
,('Cottage Cheese', 'Dairy')
,('Tacos', 'Meals')
,('Carrots', 'Vegetables')
,('Celery', 'Vegatables')

-- populate NEW table of foods which we will use ti import into;
INSERT INTO NEWfoods ( FoodName, FoodType ) VALUES  
 ('Avocado','Vegetables')
,('Apples','Fruit')
,('Salt','Preservative')
,('Turkey','Protein')
,('Bread','Grain')
,('Bread','Grain')
,('Tacos','Meals')


-- add in this list of foods if the pair does not exist;
-- this will become an INSERT INTO when said and done;

INSERT INTO food
SELECT
         f.FoodName
        ,f.FoodType 
    FROM food AS f
    WHERE NOT EXISTS (
        SELECT * FROM NEWfoods AS g
        where g.FoodName = f.FoodName
        AND g.FoodType = f.FoodType
        )
È stato utile?

Soluzione

I can think of a couple of ways if you are using SQL Server 2008 or later:

Insert Food ( FoodName, FoodType )
Select FoodName, FoodType
From NewFood
Except
Select FoodName, FoodType
From Food

Another is to use the Merge statement:

Merge Food As target
Using NewFoods As source
    On source.FoodName = target.FoodName
            And source.FoodType = target.FoodType
When Not Matched Then
    Insert ( FoodName, FoodType )
    Values( source.FoodName, source.FoodType );

Altri suggerimenti

First thing, you'd need to check against some kind of ID about the presence of a row, what you are trying to do is an "UPSERT", just that you won't like to do an update operation in case a row exists already.

How to upsert (update and insert) in SQL Server 2005

you can just skip the "update" part, and carry on; or you can also make the foodname and food type as primary key, if the row is already present for a couplet, it won't let you insert another row, and will give you an exception; try either ways.

You want to do IF EXISTS to check if it is there already. If not then do the insert. Otherwise if no new records exist, then it will not do anything, like this:

    IF EXISTS(
    SELECT 1 FROM NEWfoods AS g 
    INNER JOIN food f ON g.FoodName = f.FoodName
      AND g.FoodType = f.FoodType)
   INSERT INTO food
   SELECT
     f.FoodName
    ,f.FoodType 
   FROM food AS f
   WHERE NOT EXISTS (
    SELECT * FROM NEWfoods AS g
    where g.FoodName = f.FoodName
    AND g.FoodType = f.FoodType
    )

One option is to put a DELETE statement before your INSERT INTO statement, for example...

DELETE FROM food
WHERE FoodName IN (SELECT FoodName FROM NEWfoods)

..., and simplify your INSERT INTO statement:

INSERT INTO food
SELECT -- Also, consider SELECT DISTINCT here unless you truly want repeat records like 'Bread'|'Grain', 'Bread'|'Grain'.
     nf.FoodName
    ,nf.FoodType 
FROM NEWfoods AS nf

Whereas the results of SELECT * FROM food is...

FoodName                                           FoodType
-------------------------------------------------- --------------------------------------------------
Apples                                             Fruit
Avocado                                            Fruit
Bananas                                            Fruit
Mangos                                             Fruit
Bread                                              Grain
Cottage Cheese                                     Dairy
Tacos                                              Meals
Carrots                                            Vegetables
Celery                                             Vegatables

(9 row(s) affected)

...and SELECT * FROM NEWfoods is...

FoodName                                           FoodType
-------------------------------------------------- --------------------------------------------------
Avocado                                            Vegetables
Apples                                             Fruit
Salt                                               Preservative
Turkey                                             Protein
Bread                                              Grain
Bread                                              Grain
Tacos                                              Meals

(7 row(s) affected)

...prior to the DELETE and revised INSERT INTO, the result of the SELECT * FROM food becomes the following after the DELETE and revised INSERT INTO statements are run:

FoodName                                           FoodType
-------------------------------------------------- --------------------------------------------------
Avocado                                            Vegetables
Apples                                             Fruit
Bananas                                            Fruit
Mangos                                             Fruit
Salt                                               Preservative
Cottage Cheese                                     Dairy
Turkey                                             Protein
Carrots                                            Vegetables
Celery                                             Vegatables
Bread                                              Grain
Bread                                              Grain
Tacos                                              Meals

(12 row(s) affected)

Of course, if a lot of NEWfoods records will perfectly match food records, this will produce a lot of unnecessary deletes as-is. You could enhance the DELETE (and INSERT INTO) statement(s) to avoid this, but it really depends on the particulars of the data('s life cycle).

Also, you could of course wrap the DELETE and INSERT INTO statements in a transaction to make them all-or-nothing.

As @Thomas points out, EXCEPT and MERGE are great ways to do what you want as well if you are using SQL Server 2008 or later; both are frankly more elegant; but distinct DELETE and INSERT INTO statements are an option.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top