C# 在SQL Server 2008中的多个表中插入数据

C# 在SQL Server 2008中的多个表中插入数据,c#,asp.net,sql,sql-server,C#,Asp.net,Sql,Sql Server,我的数据库中有3个不同的表,如下所示 Table 1: ResourceID | ResourceTitle| ResourceCategory Table 2: DocumentID| DocName | DocSize Table 3: ResourceID | DocumentID 现在我想分别向上面的表中添加一些值(使用C#.ASP.NET) 我的第一个表有一行要添加到资源中 表(表1) 第二个表我有多行要添加到 文件表(表2) 第三个表需要将前两个表中的所有ID作

我的数据库中有3个不同的表,如下所示

Table 1:
ResourceID |  ResourceTitle|  ResourceCategory

Table 2:
DocumentID|  DocName  |  DocSize

Table 3:
ResourceID  |  DocumentID
现在我想分别向上面的表中添加一些值(使用C#.ASP.NET)

  • 我的第一个表有一行要添加到资源中 表(表1)
  • 第二个表我有多行要添加到 文件表(表2)
  • 第三个表需要将前两个表中的所有ID作为ResourceDocument表(表3)中的外键保留
所有进程都需要在一个事务中完成,因此在我的asp.net c#类中,第二个表数据将有一个循环

我遇到的问题是找到正确的方法来处理事务以完成这项工作,我还需要确保在这些进程运行时,不会让其他用户修改这些数据


非常感谢您的帮助。

您可以使用事务范围,因为您可以看到此链接


您可以使用事务范围,因为您可以看到此链接

试试这个

DECLARE @ResourceID int
 DECLARE @DocumentID int
 Insert into Table 1(ResourceTitle,  ResourceCategory)value("values","values")          

 SELECT @ResourceID=SCOPE_IDENTITY()
 Insert into Table 2( DocName , DocSize) value("values","values")
 SELECT @DocumentID =SCOPE_IDENTITY()
 Insert into Table 3( ResourceID  ,  DocumentID) values(@ResourceID ,@DocumentID)
试试这个

DECLARE @ResourceID int
 DECLARE @DocumentID int
 Insert into Table 1(ResourceTitle,  ResourceCategory)value("values","values")          

 SELECT @ResourceID=SCOPE_IDENTITY()
 Insert into Table 2( DocName , DocSize) value("values","values")
 SELECT @DocumentID =SCOPE_IDENTITY()
 Insert into Table 3( ResourceID  ,  DocumentID) values(@ResourceID ,@DocumentID)

可以在存储过程中使用表值参数

这是一个在存储过程中创建和使用TVP的好方法

然后您需要通过页面/表单中的TVP

你可以看一看,得到一个想法

创建表类型的示例:

CREATE TYPE yourDocumentTableType AS TABLE 
(
    docID INT NOT NULL IDENTITY(1, 1),
    docName VARCHAR(50),
    docSize INT 
)
GO
您的存储过程应该是这样的

CREATE PROCEDURE yourInsertOperation 
    -- Add the parameters for the stored procedure here
    @Param1 INT, 
    @Param2 VARCHAR(20),
    --......your parameter list goes here
    -- here you would pass the records for your document table
    @YourTableValuedParam dbo.yourDocumentTableType READONLY 
AS
    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;

        -- declare temp table type & assign the TVP to it
        DECLARE @TempDocuments dbo.yourDocumentTableType

        INSERT INTO @TempDocuments (docName, docSize)
        SELECT docName, docSize FROM @YourTableValuedParam

        DECLARE @ResourceID BIGINT            

        --Marking the start of a transaction
        BEGIN TRANSACTION

        --Inserting records into resource table
        INSERT INTO resourceTable(column1, column2) VALUES (@param1, @param2)

        --selecting resourceID to be inserted into document table & resource-document table
        SELECT @ResourceID = SCOPE_IDENTITY()

        WHILE EXISTS(SELECT * FROM @TempDocuments)
            BEGIN                        
                DECLARE @DocumentID BIGINT

                --Inserting records into document table from the table valued parameter
                INSERT INTO documentTable(docName, docSize, resourceID)
                SELECT TOP 1 docName, docSize, @ResourceID FROM @TempDocuments

                SELECT @DocumentID = SCOPE_IDENTITY()
                INSERT INTO resouceDocumentTable(resourceID, docID) VALUES (@ResourceID, @DocumentID)

                DELETE TOP (1) FROM @TempDocuments
            END

    --Checking for any error in the whole transaction (all 3 table insert operation)
    IF @@ERROR > 0
        --rollback if there was any error
        ROLLBACK TRANSACTION
    ELSE
        --commit whole transaction (all 3 table insert operation)
        COMMIT TRANSACTION

END
GO

可以在存储过程中使用表值参数

这是一个在存储过程中创建和使用TVP的好方法

然后您需要通过页面/表单中的TVP

你可以看一看,得到一个想法

创建表类型的示例:

CREATE TYPE yourDocumentTableType AS TABLE 
(
    docID INT NOT NULL IDENTITY(1, 1),
    docName VARCHAR(50),
    docSize INT 
)
GO
您的存储过程应该是这样的

CREATE PROCEDURE yourInsertOperation 
    -- Add the parameters for the stored procedure here
    @Param1 INT, 
    @Param2 VARCHAR(20),
    --......your parameter list goes here
    -- here you would pass the records for your document table
    @YourTableValuedParam dbo.yourDocumentTableType READONLY 
AS
    BEGIN
        -- SET NOCOUNT ON added to prevent extra result sets from
        -- interfering with SELECT statements.
        SET NOCOUNT ON;

        -- declare temp table type & assign the TVP to it
        DECLARE @TempDocuments dbo.yourDocumentTableType

        INSERT INTO @TempDocuments (docName, docSize)
        SELECT docName, docSize FROM @YourTableValuedParam

        DECLARE @ResourceID BIGINT            

        --Marking the start of a transaction
        BEGIN TRANSACTION

        --Inserting records into resource table
        INSERT INTO resourceTable(column1, column2) VALUES (@param1, @param2)

        --selecting resourceID to be inserted into document table & resource-document table
        SELECT @ResourceID = SCOPE_IDENTITY()

        WHILE EXISTS(SELECT * FROM @TempDocuments)
            BEGIN                        
                DECLARE @DocumentID BIGINT

                --Inserting records into document table from the table valued parameter
                INSERT INTO documentTable(docName, docSize, resourceID)
                SELECT TOP 1 docName, docSize, @ResourceID FROM @TempDocuments

                SELECT @DocumentID = SCOPE_IDENTITY()
                INSERT INTO resouceDocumentTable(resourceID, docID) VALUES (@ResourceID, @DocumentID)

                DELETE TOP (1) FROM @TempDocuments
            END

    --Checking for any error in the whole transaction (all 3 table insert operation)
    IF @@ERROR > 0
        --rollback if there was any error
        ROLLBACK TRANSACTION
    ELSE
        --commit whole transaction (all 3 table insert operation)
        COMMIT TRANSACTION

END
GO

正确处理交易的方法到底有什么问题?如果您使用的是某种ORM,它很可能使用工作单元模式,并且您的所有数据库操作都将在提交时包装到事务中,如果不是,您可以使用
TransactionScope
手动处理事务范围。如果您使用Linq,您可以执行所有更改,并在循环结束时强制转换SubmitChanges()方法。我不确定问题出在哪里?正确处理交易的方法到底有什么问题?如果您使用的是某种ORM,它很可能使用工作单元模式,并且您的所有数据库操作都将在提交时包装到事务中,如果不是,您可以使用
TransactionScope
手动处理事务范围。如果您使用Linq,您可以执行所有更改,并在循环结束时强制转换SubmitChanges()方法。我不确定问题出在哪里?感谢您的回答,我编写了相同的查询,但正如我所说,我需要在第二个表中同时添加多行,因此当用户单击按钮时,包含多个文档的资源将同时保存在数据库中。您编写此查询的方式仅适用于一个资源和一个文档。感谢您的回答,我编写了相同的查询,但正如我所说,我需要在第二个表中同时添加多行,因此当用户单击按钮时,包含多个文档的资源将同时保存在数据库中。您编写此文件的方式仅适用于一个资源和一个文档。上述策略很好,但代码工作不正常,以下行有错误(必须声明标量变量)“SET-TempDocuments=YourTableValuedParam”@AliShahrokhi,请检查代码是否正常工作。它需要使用insert语句而不是SET语句,因为变量的类型是table。我已经测试过了&它正在工作。抱歉,响应延迟。上述策略很好,但代码工作不正常,以下行有错误(必须声明标量变量)“SET-TempDocuments=YourTableValuedParam”@AliShahrokhi,请检查代码是否正常工作。它需要使用insert语句而不是SET语句,因为变量的类型是table。我已经测试过了&它正在工作。很抱歉延迟回复。