1

我正在编写一个一遍又一遍地需要多个 sql 连接的脚本。我需要并行性来加快速度。这就是为什么我想要一种返回连接句柄的 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
4

2 回答 2

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
...
于 2013-09-27T09:23:48.483 回答
1

您还可以使用 SQL Server 管理对象 (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
于 2013-09-28T08:43:21.223 回答