【问题标题】:sql server :Insert Multiple records in two tables in the same momentsql server : 同时在两张表中插入多条记录
【发布时间】:2014-01-29 08:41:07
【问题描述】:

我有两个表employee和employeeDetails,两个表之间的关系是一对一的,我想在employee表上插入所有记录后获取所有Id并将其插入employeeDetails表中。

我从 xml 查询选择并插入到表员工中

my query:
INSERT INTO employee
SELECT ID,Name, Salary
FROM OPENXML(@hDoc, 'employees/employee') // file contains 50000 record
WITH 
(
ID int 'ID',
Name [varchar](50) 'Name',
Salary money 'Salary',  
)

但我不想使用触发器

【问题讨论】:

  • 如果第二个表只是从第一个表复制数据,为什么会有两个表?这种设计背后的动机是什么?
  • @Damien_The_Unbeliever 有关 emloyee1 员工的更多详细信息
  • 如果其中一个表是另一个表的扩展,则使用外键。不要重复数据。
  • @DotNetDeveloper 是的,我想做这个解决方案

标签: sql-server database sql-server-2005


【解决方案1】:

在事务中使用任何类型的 TEMP 表,下面我在 SQL Server 中使用 TABLE VARIABLE,但您也可以简单地创建一个#TEMP 表。将 50000 多行放入 @TEMP_EMPLOYEE 表中,以免它们与现有数据混合,然后只需将 @TEMP_EMPLOYEE 表中的行插入 EMPLOYEE 和 EMPLOYEE1 表中。

此答案针对您的原始问题,未提及 IDENTITY 列或外键。

BEGIN TRANSACTION
   DECLARE @TEMP_EMPLOYEE TABLE
   (
     Id INT, 
     Name VARCHAR(50),
     Salary MONEY
   )

   INSERT INTO @TEMP_EMPLOYEE
   SELECT ID,Name, Salary
      FROM OPENXML(@hDoc, 'employees/employee') -- file contains 50000 record
   WITH 
   (
      Id INT 'ID',
      Name [varchar](50) 'Name',
      Salary money 'Salary'
   )

   INSERT INTO employee  SELECT Id, Name, Salary FROM @TEMP_EMPLOYEE
   INSERT INTO employee1 SELECT Id, Name, Salary FROM @TEMP_EMPLOYEE

COMMIT TRANSACTION

但是,如果我正确理解您的 cmets,如果 EMPLOYEE 表具有 IDENTITY 列 ID,并且 EMPLOYEE1 表在第一个 EMPLOYEE 表的 ID 列上具有 FOREIGN KEY CONSTRAINST,那么您可以使用 CURSOR 和SCOPE_IDENTITY。

BEGIN TRANSACTION
   DECLARE @TEMP_EMPLOYEE TABLE
   (
     Id INT, 
     Name VARCHAR(50),
     Salary MONEY
   )

   INSERT INTO @TEMP_EMPLOYEE
   SELECT ID,Name, Salary
      FROM OPENXML(@hDoc, 'employees/employee') -- file contains 50000 record
   WITH 
   (
      Id INT 'ID',
      Name [varchar](50) 'Name',
      Salary money 'Salary'
   )

   DECLARE @CURSOR_ID INT
   DECLARE @CURSOR_NAME VARCHAR(50)
   DECLARE @CURSOR_SALARY MONEY
   DECLARE @IDENT_ID INT

   DECLARE EmployeeCursor CURSOR FOR SELECT [Id], [Name], [Salary] FROM @TEMP_EMPLOYEE
   OPEN EmployeeCursor
   FETCH NEXT FROM EmployeeCursor INTO @CURSOR_ID,@CURSOR_NAME, @CURSOR_SALARY
   WHILE @@FETCH_STATUS = 0
   BEGIN
      -- Table with the Identity Column
      INSERT INTO Employee(Name, Salary) VALUES(@CURSOR_NAME, @CURSOR_SALARY)
      SELECT @IDENT_ID = SCOPE_IDENTITY()
      --Table with the Foreign Key Column
      INSERT INTO Employee1(Id, Name, Salary) VALUES(@IDENT_ID, @CURSOR_NAME,     @CURSOR_SALARY)
      FETCH NEXT FROM EmployeeCursor INTO @CURSOR_ID,@CURSOR_NAME, @CURSOR_SALARY
   END
   CLOSE EmployeeCursor
   DEALLOCATE EmployeeCursor

COMMIT TRANSACTION

【讨论】:

  • 但员工 id 是 IDENTITY 和 Relation 一对一
  • 请解释为什么您认为应该更改答案并让发布它的人更新它(除非是小修改)。
  • 因为员工的 id 是 IDENTITY,我不能在 temp_employee 表中插入它,我想在员工中插入记录并获取插入的 id
  • @user3152935 请将表格定义添加到您的问题中。如果具有列 ID 的员工表是 IDENTITY,那么在您的问题中,您将插入该列 ID,这是不正确且具有误导性的。您的问题 IDENTITY 列中也没有任何内容。
  • 我的回答仅适用于您的原始问题,没有提及 IDENTITY 或 FOREIGN KEYS。因此,请提及一个表是否具有另一个表的外键,以及哪些表或两者都具有 IDENTITY,您在问题中没有提及,这些都是非常关键的信息。那我就可以回答了。
【解决方案2】:

【讨论】:

  • 这是 5000 条记录的批量插入,我无法使用 SCOPE_IDENTITY()
【解决方案3】:
declare @Temp table(
   id int
   )

INSERT INTO employee OUTPUT INSERTED.id INTO @Temp
SELECT ID,Name, Salary
FROM OPENXML(@hDoc, 'employees/employee') // file contains 50000 record
WITH 
(
ID int 'ID',
Name [varchar](50) 'Name',
Salary money 'Salary',  
)

insert into employeeDetails
   select * from @Temp

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-09
    • 1970-01-01
    • 1970-01-01
    • 2011-10-26
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多