2013-04-03 2 views
2

Как я могу запускать один и тот же хранимый procdure несколько раз с различным набором значений параметров и не ожидая завершения первого выполнения.Выполнение хранимой процедуры mutliple раз одновременно

Пример:

, если я получил прок sp_loaddatafrom @sourceId, @containerId

Execution - 1st: exec sp_loaddatafrom 100001, 36 
Execution - 2nd: exec sp_loaddatafrom 100008, 92 
Execution - 3rd: exec sp_loaddatafrom 100005, 112 

Я хочу, чтобы все работать одновременно.

Как это может быть достигнуто либо в T-SQL/SSIS/C#

+1

Если это вообще возможно, было бы лучше, чтобы изменить хранимую процедуру принять параметр [Table-value] (http://msdn.microsoft.com/en-gb/library/bb510489.aspx) - чтобы он мог запускать запрос на основе набора, который производит все результаты, - и SQL Server может соответствующим образом оптимизировать этот процесс. –

+1

Кроме того, вам следует избегать использования 'sp_' в качестве префикса для хранимых процедур. Он предназначен только для использования Microsoft и имеет специальное (иногда нежелательное) поведение (в частности, SQL Server всегда будет пытаться найти такие процедуры в 'master' перед поиском текущей базы данных, поэтому, если MS добавит новую, которая конфликты с выбранным вами именем, MS будет использоваться) –

+0

Кроме того, я лично использовал ORM, если в этом запросе не было побочных эффектов. – Aron

ответ

3

Если у вас есть доступ to .net 4.5 Я бы использовал следующий код.

var results = Task.WhenAll(
    Task.Run(() => RunStoredProc(1)), 
    Task.Run(() => RunStoredProc(2)), 
    Task.Run(() => RunStoredProc(3)) 
).Result; 

Если у меня только .net 4.0, я бы использовал TPL. Немного более громоздко, все же намного лучше, чем работник фона.

var arguments = new []{1,2,3}; 

var results = from x in arguments.AsParallel() 
       select RunStoredProc(x); 
1

Если вы будете использовать C#, вы можете использовать 3 BackgroundWorkers призывающих указанной хранимой процедуры на своем мероприятии Do_Work

+0

Я бы использовал только BackgroundWorkers IFF У меня только доступ к .net <= 3.5 – Aron

1

Это может быть сделано в SSIS с помощью 3 различных Execute SQL Task, которые не соединены друг с другом.

enter image description here

По умолчанию SSIS использует Serializable вариант для Isolation Level, которая блокирует все данные считываются и сохраняет блокировку до завершения транзакции. Поэтому для параллельного выполнения запросов вам необходимо изменить Isolation level на Snapshot, который в основном использует NOLOCK для данных при чтении.

Обновление: -

Поскольку число stored procedures выполняется это dynamically получается, то вам необходимо создать пакет programitically

public void CreatePackage() 
{ 
    Package package= new Package(); 
    ConnectionManager sqlConnection = GetSQLConnection(package, 
            "localhost", "Database Name"); 
    TaskHost taskHost=null; 
    for(int i=0;i<GetNoOfRowFromSQL();i++) 
    { 
     CreateDynamicTask(package); 
    } 
    package.Execute(); 
} 

public void CreateDynamicTask(package Package) 
{ 

     //Add the Execute SQL Task 
     package.Executables.Add("STOCK:SQLTask"); 
     taskHost = package.Executables[0] as TaskHost; 
     taskHost.Properties["SqlStatementSource"].SetValue(taskHost, 
              "EXECUTE Stored Proc); 
    //Setting the Isolation Level 
    taskHost.Properties["IsolationLevel"].SetValue(taskHost, 1048576); 
    //the number signify 1048576 =Serializable 
    } 
} 
+0

это всегда не просто три раза, чтобы вызвать процедуру; мои значения параметров поступают из таблицы и нет. хранимой процедуры времени, которая должна выполняться, зависит от количества строк из таблицы значений параметра. – Sreedhar

+0

Но вместо того, чтобы входить в создание пакета SSIS с использованием C#, я предпочитаю использовать TPL'System.Threading.Tasks.Parallel.Invoke (() => {CallSP1();},() => {CallSP12();} ,() => {CallSP3();}); ' – praveen

Смежные вопросы