使用用户定义的表类型sql server插入时检查记录是否存在

时间:2014-11-13 04:57:15

标签: sql-server constraints sql-insert user-defined-types

我正在尝试批量插入sql server中的记录。我使用用户定义表类型来传递我的.net应用程序中的记录集合。请查看下面的插入查询。

INSERT INTO MachineItems([Name],[Price],[Quantity],[ItemGroupID],[SubGroup] ,[IsDefault],
    [IsRemovable],[MachineTypeID],[ItemType],[CreatedBy],[CreatedOn] )

    SELECT mi.Name
    ,mi.Price
    ,mi.Quantity
    ,(SELECT ID from ItemGroups WHERE NAME=mi.ItemGroup) as ID
    ,mi.SubGroup,
    CASE 
      WHEN mi.IsDefault ='Yes' THEN 1 
      WHEN mi.IsDefault ='No' THEN 0 
      WHEN mi.IsDefault IS NULL THEN 0
     END ,
     CASE 
      WHEN mi.IsRemovable ='Yes' THEN 1 
      WHEN mi.IsRemovable ='No' THEN 0 
     END ,
    (SELECT ID from MachineTypes WHERE Name=mi.MachineType),
    (SELECT ID from MachineItemTypes WHERE Name=mi.ItemType),
    mi.CreatedBy 
    ,mi.CreatedOn       
    FROM @MachineItems mi

我想要做的是在插入记录之前进行检查,表中是否已存在[MachineTypeID]和[Name]的记录。如果它不存在,则插入Eles更新记录。

如何使用用户定义的表格类型?

2 个答案:

答案 0 :(得分:2)

  1. 您应该使用MERGE命令而不是直接插入。您想要做的并不是特定于用户定义的表类型。

  2. 如果您加入3个子表而不是为每行执行的列子查询,那将会更好/更有效。

  3. 示例:

    MERGE MachineItems AS Target
    USING (SELECT mi.Name,
                  mi.Price,
                  mi.Quantity,
                  ig.ID, -- ItemGroupID
                  mi.SubGroup,
                  CASE 
                     WHEN mi.IsDefault ='Yes' THEN 1 
                     WHEN mi.IsDefault ='No' THEN 0 
                     WHEN mi.IsDefault IS NULL THEN 0
                  END, -- IsDefault
                  CASE 
                     WHEN mi.IsRemovable ='Yes' THEN 1 
                     WHEN mi.IsRemovable ='No' THEN 0 
                  END, -- IsRemovable
                  mt.ID, -- MachineTypeID
                  mit.ID, -- ItemType
                  mi.CreatedBy,
                  mi.CreatedOn
           FROM   @MachineItems mi
           INNER JOIN ItemGroups ig
                   ON ig.[Name] = mi.ItemGroup
           INNER JOIN MachineTypes mt
                   ON mt.[Name] = mi.MachineType
           INNER JOIN MachineItemTypes mit
                   ON mit.[Name] = mi.ItemType) AS Source (
                       [Name],[Price],[Quantity],[ItemGroupID],[SubGroup],[IsDefault],
                       [IsRemovable],[MachineTypeID],[ItemType],[CreatedBy],[CreatedOn])
    ON (
             Target.[MachineTypeID] = Source.[MachineTypeID]
        AND  Target.[Name] = Source.[Name]
        )
    WHEN MATCHED THEN 
         UPDATE SET Price = Source.Price,
                    Quantity = Source.Quantity,
                    ItemGroupID = Source.ItemGroupID,
                    SubGroup = Source.SubGroup,
                    IsDefault = Source.IsDefault,
                    IsRemovable = Source.IsRemovable,
                    MachineTypeID = Source.MachineTypeID,
                    ItemType = Source.ItemType,
                    CreatedBy = Source.CreatedBy,
                    CreatedOn = Source.CreatedOn
    WHEN NOT MATCHED BY TARGET THEN
         INSERT ([Name],[Price],[Quantity],[ItemGroupID],[SubGroup] ,[IsDefault],
                 [IsRemovable],[MachineTypeID],[ItemType],[CreatedBy],[CreatedOn])
         VALUES (Source.[Name], Source.[Price], Source.[Quantity], Source.[ItemGroupID],
                 Source.[SubGroup], Source.[IsDefault], Source.[IsRemovable],
                 Source.[MachineTypeID], Source.[ItemType], Source.[CreatedBy],
                 Source.[CreatedOn]);
    

答案 1 :(得分:1)

您可以使用Merge此处

使用Merge

  1. 如果不存在,您可以插入
  2. 如果已存在,您可以删除
  3. 如果已存在,您可以更新

  4. MERGE MachineItems
    USING @MachineItems ON MachineItems.id = @MachineItems.id
    and MachineItems.Name=@MachineItems.Name
    WHEN NOT MATCHED THEN
    INSERT INTO MachineItems([Name],[Price],[Quantity],[ItemGroupID],[SubGroup]         
    ,[IsDefault],
    [IsRemovable],[MachineTypeID],[ItemType],[CreatedBy],[CreatedOn] )
    
        SELECT mi.Name
        ,mi.Price
        ,mi.Quantity
        ,(SELECT ID from ItemGroups WHERE NAME=mi.ItemGroup) as ID
        ,mi.SubGroup,
        CASE 
          WHEN mi.IsDefault ='Yes' THEN 1 
          WHEN mi.IsDefault ='No' THEN 0 
          WHEN mi.IsDefault IS NULL THEN 0
         END ,
         CASE 
          WHEN mi.IsRemovable ='Yes' THEN 1 
          WHEN mi.IsRemovable ='No' THEN 0 
         END ,
        (SELECT ID from MachineTypes WHERE Name=mi.MachineType),
        (SELECT ID from MachineItemTypes WHERE Name=mi.ItemType),
        mi.CreatedBy 
        ,mi.CreatedOn       
        FROM @MachineItems mi