c# - MySql 使用.Net/Connector 批处理存储过程调用?

标签 c# .net mysql sql

有没有办法使用 .Net/Connector 在 MySql 中批量调用存储过程以提高性能?

场景如下...我正在使用接受一些参数作为输入的存储过程。此过程基本上检查是否应更新现有记录或插入新记录(我没有使用 INSERT INTO .. ON DUPLICATE KEY UPDATE 因为检查涉及日期范围,所以我不能真正制作主键的标准)。

我想多次调用此过程(比如说 1000 次左右)。我当然可以使用一个 MySqlConnection 和一个 MySqlCommand 实例并不断更改参数值,并调用 .ExecuteNonQuery()。

我想知道是否有更好的方法来批处理这些调用?

唯一想到的是手动构造一个字符串,如“call sp_myprocedure(@parama_1,@paramb_1);call sp_myprocedure(@parama_2,@paramb2);...”,然后创建所有适当的参数.我不相信这会比多次调用 .ExecuteNonQuery() 更好。

有什么建议吗?谢谢!

编辑:更多信息
我实际上是在尝试定期存储来自外部数据源的数据。基本上,我采用域拍卖的 rss 提要(来自各种来源,如 godaddy、pool 等),并使用此存储过程(我们称之为 sp_storeSale)更新包含拍卖信息的表。现在,在这个存储销售信息的表中,我想保留给定域的销售历史记录,所以我有一个表和一个销售表. sale 表与 domain 表具有多对一关系。

存储过程如下:

    -- --------------------------------------------------------------------------------
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$

CREATE PROCEDURE `DomainFace`.`sp_storeSale` 
(
    middle VARCHAR(63),
    extension VARCHAR(10),
    brokerId INT,
    endDate DATETIME,
    url VARCHAR(500),
    category INT,
    saleType INT,
    priceOrBid DECIMAL(10, 2),
    currency VARCHAR(3)    
)
BEGIN
    DECLARE existingId BIGINT DEFAULT NULL;
    DECLARE domainId BIGINT DEFAULT 0;

    SET @domainId = fn_getDomainId(@middle, @extensions);

    SET @existingId = (
        SELECT id FROM sale
        WHERE 
            domainId = @domainId
            AND brokerId = @brokerId
            AND UTC_TIMESTAMP() BETWEEN startDate AND endDate
    );

    IF @existingId IS NOT NULL THEN
        UPDATE sale SET
            endDate = @endDate,
            url = @url,
            category = @category,
            saleType = @saleType,
            priceOrBid = @priceOrBid,
            currency = @currency
        WHERE
            id = @existingId;
    ELSE
        INSERT INTO sale (domainId, brokerId, startDate, endDate, url,
                category, saleType, priceOrBid, currency)
            VALUES (@domainId, @brokerId, UTC_TIMESTAMP(), @endDate, @url,
                @category, @saleType, @priceOrBid, @currency);
    END IF;
END

如您所见,我基本上是在寻找未“过期”但具有相同域和经纪人的现有记录,在这种情况下我假设拍卖尚未结束,并且数据是更新现有拍卖。否则,我假设拍卖已经结束,这是一个历史记录,而我得到的数据是用于新拍卖的,所以我创建了一个新记录。

希望这能澄清我想要实现的目标:)

最佳答案

我不完全确定您要做什么,但这听起来有点像家务管理或维护相关,所以我不会因为发布以下建议而感到羞耻。

为什么不将所有逻辑都移到数据库中并在所有服务器端进行处理? 以下示例使用了游标(震惊/恐怖),但在这种情况下使用它们是完全可以接受的。

如果您完全可以避免使用游标 - 很好,但我建议的要点是将逻辑从您的应用程序层移回数据层以节省往返行程。您将调用以下存储过程一次,它将在一次调用中处理整个范围的数据。

call house_keeping(curdate() - interval 1 month, curdate());

此外,如果您可以提供更多有关您尝试执行的操作的信息,我们可能会建议其他方法。

示例存储过程

drop procedure if exists house_keeping;

delimiter #

create procedure house_keeping
(
in p_start_date date,
in p_end_date date
)
begin

declare v_done tinyint default 0;
declare v_id int unsigned;
declare v_expired_date date;

declare v_cur cursor for 
  select id, expired_date from foo where 
    expired_date between p_start_date and p_end_date;

declare continue handler for not found set v_done = 1;

open v_cur;

repeat
    fetch v_cur into v_id, v_expired_date;

    /*
    if <some condition> then
      insert ...
    else
      update ...
    end if;
    */

until v_done end repeat;
close v_cur;

end #

delimiter ; 

以防万一你认为我在建议游标时完全疯了你可能想阅读这篇文章 Optimal MySQL settings for queries that deliver large amounts of data?

希望这有帮助:)

关于c# - MySql 使用.Net/Connector 批处理存储过程调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4664553/

相关文章:

c# - 在 ASP.NET MVC 中修改样式表属性

c# - "If(..||..)"和 "If(...&&...)"结构内部发生了什么?

.net - 如何监听任何端口上的广播数据包?

c# - Microsoft Graph 仅返回前 100 个用户

c# - 将 PDF 中的外部链接转换为链接到 iTextSharp 中的嵌入式附件

c# - .NET 堆填满了字符串对象 -> OutOfMemoryException

c# - 如何编译使用不安全代码的解决方案?

python - 为什么同一对象在一个实例而不是其他实例中抛出 "NoneType"对象属性错误?

mysql - 如果查询包含 SET,Django 原始 sql 将不起作用

php - 如何从表 2 中选择数据与表 1 连接