2014-03-02 78 views
3

背景信息Powershell Receive-Job是否可以返回DataSet?

我有一个应用程序,使得对目前需要一个非常非常长的时间来执行多个数据库的多个SQL连接。

Powershell(.NET)将等待每个过程“SQL-GET”函数完成,然后才能触发下一个。我觉得我可以通过在自己的后台作业中同时触发每个“SQL-GET”函数来显着加快这个应用程序的速度!我将在每个作业完成时检索数据。理想的是作为DataSet系统对象。

的问题

检索从后台作业的数据时,我只能设法得到一个的System.Array对象返回。我后面实际上是一个System.DataSet对象。这是必要的,因为应用程序内的所有逻辑都依赖于DataSet对象。

守则

这里的代码,将创建一个SQL连接,并填写与结果的新创建的DataSet对象返回v.simple片。作品一种享受。 $ results是一个DataSet对象,我可以很好地操作它。

$query = "SELECT * FROM [database]..[table] WHERE column = '123456'" 

$Connection = New-Object System.Data.SqlClient.SQLConnection  
$ConnectionString = "Server='SERVER';Database='DATABASE';User ID='SQL_USER';Password='SQL_PASSWORD'" 
$Connection.ConnectionString = $ConnectionString  
$Connection.Open() 
$Command = New-Object system.Data.SqlClient.SqlCommand($Query,$Connection) 
$Adapter = New-Object system.Data.SqlClient.SqlDataAdapter 
$Adapter.SelectCommand = $Command 
$Connection.Close() 
[System.Data.SqlClient.SqlConnection]::ClearAllPools() 

$results = New-Object system.Data.DataSet 

[void]$Adapter.fill($results) 

$results.Tables[0] 

这里是非常相同的代码封装到一个新的后台作业的脚本块参数。只有在调用Receive-Job后,我才得到一个数组,而不是数据集。

 $test_job = Start-Job -ScriptBlock { 

$query = "SELECT * FROM [database]..[table] WHERE column = '123456'" 

$Connection = New-Object System.Data.SqlClient.SQLConnection  
$ConnectionString = "Server='SERVER';Database='DATABASE';User ID='SQL_USER';Password='SQL_PASSWORD'" 
$Connection.ConnectionString = $ConnectionString  
$Connection.Open() 
$Command = New-Object system.Data.SqlClient.SqlCommand($Query,$Connection) 
$Adapter = New-Object system.Data.SqlClient.SqlDataAdapter 
$Adapter.SelectCommand = $Command 
$Connection.Close() 
[System.Data.SqlClient.SqlConnection]::ClearAllPools() 

$results = New-Object system.Data.DataSet 

[void]$Adapter.fill($results) 
return $results.Tables[0] 

} 

Wait-Job $test_job 
$ret_results = Receive-Job $test_job 

任何帮助将不胜感激!

研究迄今

我已经做旧的谷歌,但所有的帖子,博客和文章中,我偶然发现似乎进入EXTREME深度有关解决此管理作业和所有的花里胡哨。是否只有通过receive-job cmdlet返回数组才是powershell的基本属性?

我已阅读关于返回表达式的stack post。我以为我在谈论某件事情。尝试:

  • return $results.Tables[0]
  • return ,$results.Tables[0]
  • return ,$results

所有仍返回数组。

我已经看到人们很麻烦地手动将数组转换回数据集对象 - 虽然这看起来很“脏” - 我很迂腐,希望活着,希望这个神奇的数据集对象能够遍历后台工作和我当前的会话!:)

重申

基本上,我想是有$ ret_results对象来自接收工作cmdlet的检索是一个DataSet ...甚至一个DataTable。我会采取......不是一个阵列:)

回答

2

在PowerShell中,一个任意类型的多个对象的集合返回集合中是很常见的。考虑这个改变的例子,我建立了自己的表格:

PS C:\> $job = Start-Job -ScriptBlock { 
>> 
>> $table = New-Object system.Data.DataTable “MyTable” 
>> 
>> $col1 = New-Object system.Data.DataColumn MyFirstCol,([string]) 
>> $col2 = New-Object system.Data.DataColumn MyIntCol,([int]) 
>> 
>> $table.columns.add($col1) 
>> $table.columns.add($col2) 
>> 
>> $row1 = $table.NewRow() 
>> $row1.MyFirstCol = "FirstRow" 
>> $row1.MyIntCol = 1 
>> $row2 = $table.NewRow() 
>> $row2.MyFirstCol = "SecondRow" 
>> $row2.MyIntCol = 2 
>> 
>> $table.Rows.Add($row1) 
>> $table.Rows.Add($row2) 
>> 
>> $dataSet = New-Object system.Data.DataSet 
>> $dataSet.Tables.Add($table) 
>> 
>> $dataSet.Tables[0] 
>> 
>> } 
>> 
PS C:\> $output = Receive-Job -Job $job 

收到的输出。那么我们得到了什么?

PS C:\> $output.GetType() 

IsPublic IsSerial Name          BaseType 
-------- -------- ----          -------- 
True  True  Object[]         System.Array 

一个数组,如你所描述的。但这是整个对象。如果我们分别对其成员进行分析,请将它们分配到Get-Member

PS C:\> $output | gm 

    TypeName: Deserialized.System.Data.DataRow 

Name    MemberType Definition 
----    ---------- ---------- 
ToString   Method  string ToString(), string ToString(string format, System.IFormatProvider formatProvi... 
PSComputerName  NoteProperty System.String PSComputerName=localhost 
PSShowComputerName NoteProperty System.Boolean PSShowComputerName=False 
RunspaceId   NoteProperty System.Guid RunspaceId=186c51c3-d3a5-404c-9a4a-8ff3d3a7f024 
MyFirstCol   Property  System.String {get;set;} 
MyIntCol   Property  System.Int32 {get;set;} 

PS C:\> $output 


RunspaceId : 186c51c3-d3a5-404c-9a4a-8ff3d3a7f024 
MyFirstCol : FirstRow 
MyIntCol : 1 

RunspaceId : 186c51c3-d3a5-404c-9a4a-8ff3d3a7f024 
MyFirstCol : SecondRow 
MyIntCol : 2 

考虑以下几点:

  • 在你的工作,你已指定$results.Tables[0]应返回。通过指定特定的Tables迭代,您将返回描述该表的对象......也许是一个DataTable,或者在这种情况下DataRows ...而不是像您似乎期望的DataSet?

  • DataTables有行。如果DataTable具有多行,PowerShell会将其返回到DataRows集合中,如上所示。您可能会惊讶地发现,单行返回并不是这种情况 - 它只会返回单个DataRow对象,而不是DataRow对象的集合。

  • 如果这确实是您期望的输出,您可能需要强制它始终返回一个集合,方法是将输出指定为@($results.Tables[0])。这样,你总是知道期望一个集合,并且可以适当地处理结果内容(通过迭代集合来管理单个对象)。

+1

@ Hhyper-anthony,感谢您的迅速回复!首先,我刚刚意识到DataSet对象用于存储DataTable对象的集合,因此我可以在上面的代码示例中安全地将DataTable替换为DataSet。 经过进一步检查,您绝对正确,因为返回的数据实际上是一个System.Data.DataRow对象的数组。这可以很容易地完整地构建回DataTable。 – Mitch

相关问题