2013-09-27 5 views
1

Я работаю над сценарием, который много раз требует нескольких соединений sql. Мне нужен параллелизм, чтобы ускорить все. Вот почему я хотел бы иметь фабрику SQL, которая возвращает мне дескриптор соединения. Но почему-то мой код не работает. Что я здесь делаю неправильно?PowerShell пытается закодировать фабрику SQL ...

$m = New-Module -Name sql_factory -AsCustomObject -ScriptBlock { 
    Function new_session { 
     $db_host = 'my.sqlhost.tld'; 
     $db_user = 'user'; 
     $db_pass = 'pass'; 
     $db_name = 'db'; 
     $table_name = $env:COMPUTERNAME; 

     $conn = New-Object system.data.sqlclient.sqlconnection; 
     $conn.ConnectionString = "Server=${db_host};Database=${db_name};User ID=${db_user};Password=${db_pass};"; 

     $cmd = New-Object System.Data.SqlClient.SqlCommand; 
     $cmd.connection = $conn; 

     return $cmd, $conn; 
    } 
} 

$test = { 
    $cmd, $conn = $m.new_session(); 

    $conn.Open(); 
    $cmd.CommandText = "INSERT INTO tableXXX (date, time, action, protocol, src_ip, dst_ip, src_port, dst_port, size, tcp_flags, tcpsyn, tcpack, tcpwin, icmptype, icmpcode, info, path) VALUES ('xxx','xxx','xxx','xxx','xxx','xxx','xxx','xxx','xxx','xxx','xxx','xxx','xxx','xxx','xxx','xxx','xxx')"; 
    $cmd.ExecuteNonQuery(); 
    $conn.Close();  
} 

start-job -ScriptBlock $test | Out-Null 
get-job | receive-job -AutoRemoveJob -Wait 

Это сообщение об ошибке я получаю ...

You cannot call a method on a null-valued expression. 
    + CategoryInfo   : InvalidOperation: (:) [], RuntimeException 
    + FullyQualifiedErrorId : InvokeMethodOnNull 
    + PSComputerName  : localhost 

You cannot call a method on a null-valued expression. 
    + CategoryInfo   : InvalidOperation: (:) [], RuntimeException 
    + FullyQualifiedErrorId : InvokeMethodOnNull 
    + PSComputerName  : localhost 

Property 'CommandText' cannot be found on this object; make sure it exists and is settable. 
    + CategoryInfo   : InvalidOperation: (:) [], RuntimeException 
    + FullyQualifiedErrorId : PropertyNotFound 
    + PSComputerName  : localhost 

You cannot call a method on a null-valued expression. 
    + CategoryInfo   : InvalidOperation: (:) [], RuntimeException 
    + FullyQualifiedErrorId : InvokeMethodOnNull 
    + PSComputerName  : localhost 

You cannot call a method on a null-valued expression. 
    + CategoryInfo   : InvalidOperation: (:) [], RuntimeException 
    + FullyQualifiedErrorId : InvokeMethodOnNull 
    + PSComputerName  : localhost 

ответ

1

Блок скрипта ничего не знаю о модуле вы создали не знает. Вы должны были бы передать его в качестве аргумента при запуске задания:

$test = { 
    param($db_factory) 

    $cmd, $conn = $db_factory.new_session() 

    ... 
} 

Start-Job -ScriptBlock $test -ArgumentList $m | Out-Null 
... 

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

$test = { 
    param($db_host, $db_user, $db_pass, $db_name) 

    $table_name = $env:COMPUTERNAME 
    $cs = "Server=$db_host;Database=$db_name;User ID=$db_user;Password=$db_pass;" 

    $conn = New-Object system.data.sqlclient.sqlconnection 
    $conn.ConnectionString = $cs 

    $cmd = New-Object System.Data.SqlClient.SqlCommand 
    $cmd.connection = $conn 

    $conn.Open() 
    ... 
} 

Start-Job -ScriptBlock $test -ArgumentList 'my.sqlhost.tld','user','pass','db' | 
    Out-Null 
... 
+0

Спасибо за ваш ответ. Я не хочу помещать код для установки в «Start-Job -ScriptBlock», потому что это будет очень повторительно. У меня есть несколько вставных элементов, которые запускаются параллельно с запуском-заданием, но у меня также есть несколько других соединений, которые настраивают свойства базы данных и таблицы ... – Matze

+0

Ваш код не менее повторяющийся. Это немного сложнее. –

1

Также вы можете использовать SQL Server Management Objects (SMO)

$m = { 
param($instanceName, $login, $pass, $dbName) 
#import SQL Server module 
Import-Module SQLPS -DisableNameChecking 

#Create server connection 
$srvConn = New-Object Microsoft.SqlServer.Management.Common.ServerConnection 
$srvConn.ServerInstance = $instanceName 
$srvConn.LoginSecure = $false 
$srvConn.Login = $login 
$srvConn.Password = $pass 

#Initiate the object and set the database 
$srv = New-Object Microsoft.SqlServer.Management.SMO.Server($srvConn) 
$db = $srv.Databases[$dbName] 
#Execute T-SQL 
$db.ExecuteNonQuery("INSERT INTO tableXXX (date, time, action, protocol, src_ip, dst_ip, src_port, dst_port, size, tcp_flags, tcpsyn, tcpack, tcpwin, icmptype, icmpcode, info, path) VALUES ('xxx','xxx','xxx','xxx','xxx','xxx','xxx','xxx','xxx','xxx','xxx','xxx','xxx','xxx','xxx','xxx','xxx')") 
} 

start-job -ScriptBlock $m -ArgumentList 'my.sqlhost.tld','user','pass','db' | Out-Null 
get-job | receive-job -AutoRemoveJob -Wait 
Смежные вопросы