SQL Server插入 - 更新语句

时间:2014-04-15 05:24:00

标签: sql-server tsql insert upsert

我有以下代码: 问题是,当我运行插入时,它会插入到食物表中,即使结果已经插入,我怎么能写一个if语句来检查NEWfoods中的记录是否已经存在于食物表中,如果它们存在于食物,只是不做插入,如果他们不做插入。谢谢。

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
        )

4 个答案:

答案 0 :(得分:2)

如果您使用的是SQL Server 2008或更高版本,我可以考虑几种方法:

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

另一种方法是使用Merge语句:

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 );

答案 1 :(得分:1)

首先,你需要检查某种关于存在行的ID,你要做的是“UPSERT”,只是你不想做一个更新操作以防万一已存在一行。

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

你可以跳过“更新”部分,然后继续;或者您也可以将foodname和food类型作为主键,如果该行已经存在,则不会让您插入另一行,并且会给您一个例外;尝试两种方式。

答案 2 :(得分:0)

一个选项是在DELETE语句之前添加INSERT INTO语句,例如......

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

...,并简化您的INSERT INTO声明:

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

SELECT * FROM food的结果是......

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)

...... SELECT * FROM NEWfoods是......

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

(7 row(s) affected)

...在DELETE和修订版INSERT INTO之前,SELECT * FROM food的结果在DELETE和修订后的INSERT INTO语句之后变为以下内容运行:

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)

当然,如果很多NEWfoods条记录与food条记录完全匹配,则会产生大量不必要的删除。您可以增强DELETE(和INSERT INTO)语句以避免这种情况,但这实际上取决于数据的详细信息(生命周期)。

此外,您当然可以在事务中包装DELETEINSERT INTO语句,以使它们全有或全无。

正如@Thomas指出的那样,如果您使用的是SQL Server 2008或更高版本,EXCEPTMERGE也是您想要的理想方式。两者都坦率地说更优雅;但是可以选择不同的DELETEINSERT INTO语句。

答案 3 :(得分:0)

你想做IF EXISTS来检查它是否已存在。如果没有,那么插入。否则,如果不存在新记录,那么它将不会执行任何操作,如下所示:

    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
    )