作为标题,如何以并行方式执行存储过程?
更详细地说,我在Sql Server中创建了一个存储过程,调用Execute_Sql并将一个参数AreaID INT作为参数传递。
我通过一次传入一个ID并通过循环ID来获取New_ID,从.net C#成功调用并执行。
这是我的问题,我正在尝试执行存储的prod的并行方式。例如当我执行ID = 1时,同时我也同时执行了ID = 2.
在线程中出现了什么,创造了一种并行的处理方式。有没有办法在执行存储的prod时这样做?
答案 0 :(得分:0)
您可以调查sp_start_job
您无法将参数传递给作业,因此您需要通过其他方式获取参数。
您可以设置作业,以便从表中读取参数,并使用要运行sproc的值填充表,然后激活对作业的多个调用。
您可能希望您的作业通过更新行标记或行上的某些内容来标记它正在处理的行,以防止作业之间重复工作。
答案 1 :(得分:0)
首先,如果您发布了代码,将会很有帮助。通常可以修改SQL以“基于集合”的方式处理多个值。换句话说,如果要处理一组值,则可以同时处理它们。
有很多方法可以实现这一目标。您可以传入一个分隔的字符串,然后在您的proc中解析它。关于此here
的实施的许多想法您还可以使用APPLY
传入XML并“加入”流程中的XML。
在SQL 2008+中,您可以使用Table Valued Parameters
因为我不知道您对AreaID参数做了什么,我不知道我是否已回答您的问题,所以这里有更多信息。
如果要以异步方式运行存储过程,最好的选择是Service Broker,它允许您将参数放入队列中,并且单独的线程将处理队列。 SQL管理所有的排序,锁定,重试,产生/杀死线程等。这是一个非常强大的系统。
来自不同用户的问题有一个评论,他似乎与OP有关进度跟踪。这是一个想法:
您有一个“队列”表,其中包含batchid,areaID参数和状态标志。
CREATE TABLE asynchQueue
(
RecNo INT IDENTITY(1,1) PRIMARY KEY CLUSTERED,
BatchID INT,
AreaID INT,
Status TINYINT
)
您的C#应用已插入到队列表中,并为您的应用和呼叫添加了唯一的批次ID(将您的请求分组)
你有一个proc计划定期运行,如下所示:
CREATE PROC ProcessQueue
AS
BEGIN
SET XACT_ABORT ON
DECLARE @RecNo INT,
@AreaId INT
BEGIN TRAN
SELECT TOP 1 @RecNo = recNo,
@AreaID = areaId
FROM AsynchQueue WITH ROWLOCK, XLOCK
WHERE Status = 0
UPDATE AsynchQueue SET Status = 1 --Mark record as in progress
WHERE RecNo = @RecNo
COMMIT
EXEC YourProc @AreaId
UPDATE AsynchQueue SET Status = 2 -- Mark Record as complete
WHERE RecNo = @RecNo
END
或者proc可以包含一个循环来处理表中的所有记录。可以使用sp_start_job按需安排或调用proc,如John Weldon建议的那样。
然后您可以按如下方式查询状态:
SELECT COUNT(NULLIF(Status, 0))/COUNT(*) as PctComplete --in progress or complete div by total
FROM AsynchQueue WITH NOLOCK
WHERE BatchID = @yourBatchId
该查询将为您提供批次的完成百分比。