Should you make multiple insert calls or pass XML?

前端 未结 4 458
一整个雨季
一整个雨季 2020-12-04 02:24

I have an account creation process and basically when the user signs up, I have to make entries in mutliple tables namely User, Profile, Addresses. There will be 1 entry in

相关标签:
4条回答
  • 2020-12-04 02:51

    Have you noticed any performance problems, what you are trying to do is very straight forward and many applications do this day in day out. Be careful not to be drawn into any premature optimization.

    Database inserts should be very cheep, as you have suggested create a new transaction scope, open you connection, run your inserts, commit the transaction and finally dispose everything.

    using (var tran = new TransactionScope())
    using (var conn = new SqlConnection(YourConnectionString))
    using (var insetCommand1 = conn.CreateCommand())
    using (var insetCommand2 = conn.CreateCommand())
    {
        insetCommand1.CommandText = \\SQL to insert
    
        insetCommand2.CommandText = \\SQL to insert
    
        insetCommand1.ExecuteNonQuery();
    
        insetCommand2.ExecuteNonQuery();
    
        tran.Complete();
    }
    

    Bundling all your logic into a stored procedure and using XML gives you added complications, you will need to have additional logic in your database, you now have to transform your entities into an XML blob and you code has become harder to unit test.

    There are a number of things you can do to make the code easier to use. The first step would be to push your database logic into a reusable database layer and use the concept of a repository to read and write your objects from the database.

    You could of course make your life a lot easier and have a look at any of the ORM (Object-relational mapping) libraries that are available. They take away the pain of talking to the database and handle that for you.

    0 讨论(0)
  • 2020-12-04 03:01

    For example assuming your xml as below

    <StoredProcedure>
    <User>
     <UserName></UserName>
    </User>
    <Profile>
     <FirstName></FirstName>
    </Profile>
    <Address>
     <Data></Data>
     <Data></Data>
     <Data></Data>
    </Address>
    </StoredProcedure>
     
    

    this would be your stored procedure

    INSERT INTO Users (UserName) SELECT(UserName) FROM OPENXML(@idoc,'StoredProcedure/User',2)
    WITH ( UserName NVARCHAR(256))
    

    where this would provide idoc variable value and @doc is the input to the stored procedure

    DECLARE @idoc INT
    
    --Create an internal representation of the XML document.        
    EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
    

    using similar technique you would run 3 inserts in single stored procedure. Note that it is single call to database and multiple address elements will be inserted in single call to this stored procedure.

    Update

    just not to mislead you here is a complete stored procedure for you do understand what you are going to do

    USE [DBNAME]
    GO
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER OFF
    GO  
    CREATE PROCEDURE [dbo].[procedure_name]
        @doc [ntext]
    WITH EXECUTE AS CALLER
    AS
    DECLARE @idoc INT  
    DECLARE @RowCount INT
    SET @ErrorProfile = 0
    
    --Create an internal representation of the XML document.
    EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
    
    BEGIN TRANSACTION
    
    INSERT INTO Users (UserName)
    SELECT UserName FROM OPENXML(@idoc,'StoredProcedure/User',2)
    WITH ( UserName NVARCHAR(256) )
    
    -- Insert Address
    
    -- Insert Profile
    
    
    SELECT @ErrorProfile = @@Error                              
    
    IF @ErrorProfile = 0
        BEGIN
                COMMIT TRAN
        END
    ELSE
        BEGIN
                ROLLBACK TRAN
        END
    
    EXEC sp_xml_removedocument @idoc   
    
    0 讨论(0)
  • 2020-12-04 03:11

    If you want to insert records in multiple table then using XML parameter is a complex method. Creating Xml in .net and extracting records from xml for three diffrent tables is complex in sql server.

    Executing queries within a transaction is easy approach but some performance will degrade there to switch between .net code and sql server.

    Best approach is to use table parameter in storedprocedure. Create three data table in .net code and pass them in stored procedure.

    --Create Type TargetUDT1,TargetUDT2 and TargetUDT3 for each type of table with all fields which needs to insert

    CREATE TYPE [TargetUDT1] AS TABLE
                 (
                 [FirstName] [varchar](100)NOT NULL,
                 [LastName] [varchar](100)NOT NULL,
                 [Email] [varchar](200) NOT NULL
                 )
    

    --Now write down the sp in following manner.

     CREATE PROCEDURE AddToTarget(
         @TargetUDT1 TargetUDT1 READONLY,
         @TargetUDT2 TargetUDT2 READONLY,
         @TargetUDT3 TargetUDT3 READONLY)
         AS
     BEGIN
           INSERT INTO [Target1]
           SELECT * FROM @TargetUDT1
    
           INSERT INTO [Target2]
           SELECT * FROM @TargetUDT2
    
           INSERT INTO [Target3]
           SELECT * FROM @TargetUDT3
     END
    

    In .Net, Create three data table and fill the value, and call the sp normally.

    0 讨论(0)
  • 2020-12-04 03:14

    No offence, but you're over thinking this.

    Gather your information, when you have it all together, create a transaction and insert the new rows one at a time. There's no performance hit here, as the transaction will be short lived.

    A problem would be if you create the transaction on the connection, insert the user row, then wait for the user to enter more profile information, insert that, then wait for them to add address information, then insert that, DO NOT DO THIS, this is a needlessly long running transaction, and will create problems.

    However, your scenario (where you have all the data) is a correct use of a transaction, it ensures your data integrity and will not put any strain on your database, and will not - on it's own - create deadlocks.

    Hope this helps.

    P.S. The drawbacks with the Xml approach is the added complexity, your code needs to know the schema of the xml, your stored procedure needs to know the Xml schema too. The stored procedure has the added complexity of parsing the xml, then inserting the rows. I really don't see the advantage of the extra complexity for what is a simple short running transaction.

    0 讨论(0)
提交回复
热议问题