【问题标题】:Multiple inserts in a single stored procedure?单个存储过程中的多个插入?
【发布时间】:2014-05-28 18:39:30
【问题描述】:

表名:Information

将数据插入上表的存储过程。

CREATE PROCEDURE sp_insert_information
(
    @profileID as int,
    @profileName as varchar(8)
    @profileDescription as varchar(100)
)
AS
BEGIN
   INSERT INTO information(profileid, profilename, profiledescription)
   VALUES (@profileID, @profileName, @profileDescription);
END

我从.NET 调用此过程,如果我将profileID 作为逗号分隔的参数传递,有没有办法进行多次插入? (我可以使用拆分功能吗?)

我可以循环遍历profileID 并逐个发送给程序,但是我的数据将是相同的,除了不同的profileID

表格数据(3列):

1 profileUnavailable  User Error
2 profileUnavailable  User Error
3 profileUnavailable  User Error
4 profileUnavailable  User Error
5 profileUnavailable  User Error

我可以尝试一下其他任何方法吗?

【问题讨论】:

标签: c# sql .net sql-server stored-procedures


【解决方案1】:

不。该 sproc 一次插入一个,因为它是目前编写的。您必须单独调用它。

您也可以考虑将其包装到一个事务中,这样如果一个失败,它们都不会被提交。

【讨论】:

    【解决方案2】:

    你有几个选择:

    SqlBulkInsert - 您可以创建一个可以转储到表中的数据集。这对许多插入很有用。这将完全绕过该过程。

    Table Valued Parameters - 您可以使用表值参数作为存储过程的参数,再次使用数据集操作数据。

    带有字符串拆分的 CSV 参数是一个选项,但我会推荐以上之一。

    【讨论】:

    • 但是如果是通过 C# 代码(就像 OP 提到的那样),那么它只会逐行插入。
    • @Rahul 需要详细说明吗?我的解决方案都不是逐行的。
    【解决方案3】:

    几年前我最喜欢的技术是拥有一个拆分函数库,它可以将同质值的分隔列表(例如所有整数、所有布尔值、所有日期时间等)拆分为一个表变量。这是此类函数的示例。

    CREATE FUNCTION [dbo].[fn_SplitInt](@text varchar(8000), 
                                        @delimiter varchar(20) = '|')
    RETURNS @Values TABLE
    (    
      pos int IDENTITY PRIMARY KEY,
      val INT
    )
    
    AS
    BEGIN
    
      DECLARE @index int 
      SET @index = -1 
    
      -- while the list is not over...
      WHILE (LEN(@text) > 0) 
        BEGIN  
          -- search the next delimiter
          SET @index = CHARINDEX(@delimiter , @text)  
    
          IF (@index = 0) -- if no more delimiters (hence this field is the last one)
            BEGIN
              IF (LEN(@text) > 0) -- and if this last field is not empty
                INSERT INTO @Values VALUES (CAST (@text AS INT))  -- then insert it
              ELSE                -- otherwise, if this last field is empty
                INSERT INTO @Values VALUES (NULL)                 -- then insert NULL
              BREAK  -- in both cases exit, since it was the last field
            END  
          ELSE             -- otherwise, if there is another delimiter
            BEGIN   
              IF @index>1   -- and this field is not empty
                INSERT INTO @Values VALUES (CAST(LEFT(@text, @index - 1) AS INT)) -- then insert it
              ELSE          -- otherwise, if this last field is empty
                INSERT INTO @Values VALUES (NULL)                                 -- then insert NULL
              SET @text = RIGHT(@text, (LEN(@text) - @index))  -- in both cases move forward the read pointer,
                                                               -- since the list was not over
            END  
        END
      RETURN
    END
    

    当你有一组这样的函数时,你的问题就有一个像下面这样简单的解决方案:

    CREATE PROCEDURE sp_insert_information
    (
     @profileID as varchar(2000),
     @profileName as varchar(8)
     @profileDescription as varchar(100)
    )
    AS
    BEGIN
    
      DECLARE @T TABLE (Id int)
      INSERT INTO @T (Id) 
        SELECT val FROM dbo.fn_SplitInt(@profileID)
      INSERT INTO information(profileid, profilename,profiledescription)
        SELECT Id, @profileName, @profileDescription
          FROM @T
    
    END
    

    但是今天它可能会更快执行,甚至需要更少的编码,生成要插入的数据的 XML 表示,然后将 XML 传递给存储过程并让它 INSERT INTO table SELECT FROM xml,如果你知道的话我的意思。

    【讨论】:

      【解决方案4】:
         WHILE len(@ProfileId) > 0
          BEGIN
            DECLARE @comm int= charindex(',',@ProfileId)
      
            IF @comm = 0 set @comm = len(@ProfileId)+1
      
                DECLARE @Profile varchar(1000) = substring(@ProfileId, 1, @comm-1)
      
                INSERT INTO Information(ProfileId,ProfileName,ProfileDescription) 
                VALUES (@ProfileId,@ProfileName,@ProfileDescription)
      
           SET @ProfileId= substring(@ProfileId, @comm+1, len(@ProfileId)) 
      
          END
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-06
        • 1970-01-01
        相关资源
        最近更新 更多