รับตารางนี้:
CREATE TABLE dbo.Target (
   TargetId int identity(1, 1) NOT NULL,
   Color varchar(20) NOT NULL,
   Action varchar(10) NOT NULL, -- of course this should be normalized
   Code int NOT NULL,
   CONSTRAINT PK_Target PRIMARY KEY CLUSTERED (TargetId)
);
ในสองสถานการณ์ที่แตกต่างกันเล็กน้อยฉันต้องการแทรกแถวและคืนค่าจากคอลัมน์ข้อมูลประจำตัว
สถานการณ์ 1
INSERT dbo.Target (Color, Action, Code)
OUTPUT inserted.TargetId
SELECT t.Color, t.Action, t.Code
FROM
   (VALUES
      ('Blue', 'New', 1234),
      ('Blue', 'Cancel', 4567),
      ('Red', 'New', 5678)
   ) t (Color, Action, Code)
;
สถานการณ์ที่ 2
CREATE TABLE #Target (
   Color varchar(20) NOT NULL,
   Action varchar(10) NOT NULL,
   Code int NOT NULL,
   PRIMARY KEY CLUSTERED (Color, Action)
);
-- Bulk insert to the table the same three rows as above by any means
INSERT dbo.Target (Color, Action, Code)
OUTPUT inserted.TargetId
SELECT t.Color, t.Action, t.Code
FROM #Target
;
คำถาม
ฉันสามารถพึ่งพาค่าเอกลักษณ์ที่ส่งคืนจากการdbo.Targetแทรกตารางเพื่อส่งคืนตามลำดับที่มีอยู่ใน 1) VALUESส่วนคำสั่งและ 2) #Targetตารางเพื่อให้ฉันสามารถเชื่อมโยงพวกเขาตามตำแหน่งของพวกเขาในชุดแถวเอาท์พุท
สำหรับการอ้างอิง
นี่คือโค้ด C # ที่ถูกลดขนาดบางส่วนที่แสดงให้เห็นถึงสิ่งที่เกิดขึ้นในแอปพลิเคชัน (สถานการณ์ที่ 1 ซึ่งเร็ว ๆ นี้จะถูกแปลงเป็นใช้SqlBulkCopy):
public IReadOnlyCollection<Target> InsertTargets(IEnumerable<Target> targets) {
   var targetList = targets.ToList();
   const string insertSql = @"
      INSERT dbo.Target (
         CoreItemId,
         TargetDateTimeUtc,
         TargetTypeId,
      )
      OUTPUT
         Inserted.TargetId
      SELECT
         input.CoreItemId,
         input.TargetDateTimeUtc,
         input.TargetTypeId,
      FROM
         (VALUES
            {0}
         ) input (
            CoreItemId,
            TargetDateTimeUtc,
            TargetTypeId
         );";
   var results = Connection.Query<DbTargetInsertResult>(
      string.Format(
         insertSql,
         string.Join(
            ", ",
            targetList
               .Select(target => $@"({target.CoreItemId
                  }, '{target.TargetDateTimeUtc:yyyy-MM-ddTHH:mm:ss.fff
                  }', {(byte) target.TargetType
                  })";
               )
         )
      )
      .ToList();
   return targetList
      .Zip( // The correlation that relies on the order of the two inputs being the same
         results,
         (inputTarget, insertResult) => new Target(
            insertResult.TargetId, // with the new TargetId to replace null.
            inputTarget.TargetDateTimeUtc,
            inputTarget.CoreItemId,
            inputTarget.TargetType
         )
      )
      .ToList()
      .AsReadOnly();
}
          

MERGEแต่ดูเหมือนว่าปลอดภัยและชัดเจนเพียงแค่ใช้