为什么我的SQL通过Start-Job执行而不是返回我期望的答案?

时间:2015-07-27 15:00:36

标签: sql sql-server-2008 powershell jobs powershell-v4.0

我有一个托管在SQL Server 2008上的数据库,我的普通用户帐户无法访问该数据库。为了查询它,我需要使用我的特殊" admin"帐户(只是另一个AD帐户,但与我的常规用户帐户不同)。

我想出了一个想法,通过Start-Job在Powershell中使用后台作业来对这个数据库运行查询,因为你可以使用登录用户的不同凭据启动作业,从而使数据库上的集成安全性正常工作。自从我的问题以来,我今天下午搜索了很多,看到有些人出于同样的原因采用了这种方法,但他们的结果似乎确实有效 - 而我的出于某种原因并不是。

我有以下的powershell代码:

[scriptblock]$sql_block = {
    $Query = "select * from some_table"
    $CW_DBConnection = New-Object Data.SqlClient.SQLConnection
    $CW_DBConnection.ConnectionString = "Data Source=someserver;Initial Catalog=some_database;Integrated Security=SSPI;"
    $CW_DBConnection.Open()

    $Command = New-Object Data.SqlClient.SqlCommand($Query,$CW_DBConnection)
    $Adapter = New-Object Data.SqlClient.SqlDataAdapter
    $DataSet = New-Object Data.DataSet

    $Adapter.SelectCommand = $Command
    [void]$Adapter.Fill($DataSet)

    $CW_DBConnection.Close()

    return $DataSet
}

我通过以下方式执行:

$mySQLJob = Start-Job -ScriptBlock $sql_block -Credential $(Get-Credential -UserName AD\MyAdminAccount -Message "Enter Admin Password")
Wait-Job $mySQLJob
$results = Receive-Job $mySQLJob

这一切都在游泳。但是,当我来询问结果对象时,我看到了这一点:

$results
RunspaceId              : 975030ec-d336-4583-9260-48439bb34292
RemotingFormat          : Xml
SchemaSerializationMode : IncludeSchema
CaseSensitive           : False
DefaultViewManager      : {System.Data.DataViewManagerListItemTypeDescriptor}
EnforceConstraints      : True
DataSetName             : NewDataSet
Namespace               :
Prefix                  :
ExtendedProperties      : {}
HasErrors               : False
IsInitialized           : True
Locale                  : en-GB
Site                    :
Relations               : {}
Tables                  : {System.Data.DataRow}
Container               :
DesignMode              : False
ContainsListCollection  : True

当我试图找到表位时:

$results.Tables[0]
System.Data.DataRow

$results.Tables[0].GetType()
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     ArrayList                                System.Object

$results.Tables[0][0]
System.Data.DataRow

$results.Tables[0][0].GetType()
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

从字面上看,结果只是字符串" System.Data.DataRow"。

我在哪里竖起来?

注意 - 从一个实际作为我的Admin ID执行的powershell会话运行,而不是通过Start-Job执行它(即只执行内联的SQL位)按预期工作,我从数据库中获取实际数据。

1 个答案:

答案 0 :(得分:0)

当我发布这个问题时,我已经在Can Powershell Receive-Job return a DataSet?阅读了这个问题 - 但显然我没有仔细阅读它 - 因为工作答案不是返回顶级DataSet对象,而是表格[0]属性就可以了。

我今天早上改变了我的脚本块以返回它,而且,我现在得到了实际的SQL数据。

所以似乎Receive-Job没有将它返回的对象序列化到足够的深度,你可以返回任意的(尽管我猜你可以尝试自己序列化它们 - 我还没有尝试过。更新:见下文)。

所以,总结一下

的一行变化
@app.route("/news/<date:selected_date>", methods=['GET', 'POST'])

return $DataSet

诀窍。

更新:我现在已经尝试过自行序列化&#39;方法,这似乎工作正常。因此,首先更新脚本块以在最后执行此操作:

return $DataSet.Tables[0]

然后当你想要结果时:

$Serialized_DataSet = [System.Management.Automation.PSSerializer]::Serialize($DataSet,2)
return $Serialized_DataSet

然后您可以看到$ deserialized_results.Tables [0]实际上包含您可以使用的结果。