11

私は次のPS機能を持っています:

function GetBuildData {
    [System.Data.SqlClient.SqlConnection] $conn = New-Object System.Data.SqlClient.SqlConnection
    [System.Data.SqlClient.SqlCommand] $cmd = New-Object System.Data.SqlClient.SqlCommand
    [System.Data.SqlClient.SqlDataAdapter] $adapter = New-Object System.Data.SqlClient.SqlDataAdapter
    [System.Data.DataTable] $dt = New-Object System.Data.DataTable

    try {
        [string] $connStr = "myConnectionString"

        $conn.ConnectionString = $connStr
        $cmd.Connection = $conn
        $cmd.CommandText = "SELECT * FROM TestTable"

        $conn.Open

        $adapter.SelectCommand = $cmd

        $adapter.Fill($dt)

        $conn.Close
    }
    catch [system.exception]
    {
        Write-Host $_
    }
    finally {
        $adapter.Dispose
        $cmd.Dispose
        $conn.Dispose
    }

    return $dt
}

簡潔にするために、ほとんどの関数は削除されています。私が抱えている問題は、次のように関数を呼び出すときです。

[System.Data.DataTable] $buildData = GetBuildData

次のエラーが発生します。

タイプ「System.Object[]」の「System.Object[]」値をタイプ「System.Data.DataTable」に変換できません。

$ dt変数がDataTableであることが明らかなのに、Powershellがobject []配列を返したいと考えるのはなぜですか?

編集:

私は再確認しました$dtが、データが含まれています。たとえば、Rows.Countの数は1であると予想されます。

4

4 に答える 4

20

人々が提起している他の問題については知りませんが、Object[].

  1. 関数内の別の場所でキャプチャされていない出力がある可能性があります。あなたの場合、 をFill返しますint。これを関数呼び出しの最後に追加してみてください:

    | Out-Null
    

    例えば、

    $adapter.Fill($dt) | Out-Null
    

    いずれかのステートメントが値を返し、それをキャプチャしていない場合、出力は戻り値に含まれます。その時点で複数の戻り値があるため、PowerShell はそれらすべてを配列に詰め込みます。

  2. もう 1 つの可能性は、PowerShell が返されたあらゆる種類のコレクションを に変換することObject[]です。演算子を使用して,、マングルされていない値を返します。

    return , $dt
    

    ,、後続の値のみを含む配列を作成します。私が推測できる限りでは、実際の戻り値は 1 つの値のみを含む配列であるため、PowerShell は自動的に最も外側の配列をアンロールし、値をそのままにします。

    returnキャプチャされていない値が戻り値に含まれるため、これは実際にはオプションです。

    昨日、自分でこれに出くわしました。私は一生、黙って変換することObject[]が役立つと誰かが考える理由を理解できません。

于 2012-12-22T00:19:23.790 に答える
0

要因は、実際にはopenメソッドとcloseメソッドを呼び出しているのではなく、代わりにそれらを参照していることです。PowerShellは、これらのメソッドへの参照とデータテーブルを出力しています(接続が開いていないため、実際にはデータが入力されていないと思います)。

次のように、open/closeメソッドに括弧を含める必要があります。

$conn.Open()
...
$conn.Close()

また、変数に割り当てるか、out-nullにパイプすることによって、消費していない値を返すメソッド(.Add()メソッドはこれで有名です)にも注意する必要があります。

于 2012-12-20T20:27:51.780 に答える
0

変数に割り当てられていないすべてのドットコマンドを無効にするだけです

function GetBuildData {
    [System.Data.SqlClient.SqlConnection] $conn = New-Object   System.Data.SqlClient.SqlConnection
    [System.Data.SqlClient.SqlCommand] $cmd = New-Object System.Data.SqlClient.SqlCommand
    [System.Data.SqlClient.SqlDataAdapter] $adapter = New-Object System.Data.SqlClient.SqlDataAdapter
    [System.Data.DataTable] $dt = New-Object System.Data.DataTable

    try {
        [string] $connStr = "myConnectionString"

        $conn.ConnectionString = $connStr
        $cmd.Connection = $conn
        $cmd.CommandText = "SELECT * FROM TestTable"

        [void]$conn.Open

        $adapter.SelectCommand = $cmd

        $adapter.Fill($dt)

        [void]$conn.Close
    }
    catch [system.exception]
    {
        Write-Host $_
    }
    finally {
         [void]$adapter.Dispose
         [void]$cmd.Dispose
         [void]$conn.Dispose
    }

    $dt
}

あなたの質問はなぜですか?... Keith Hill のブログを読む: powershell 関数を返す方法

于 2014-02-19T04:46:14.160 に答える
0

あなたが投稿したものにはいくつかの問題があります。で明示的に DataTable オブジェクトを作成するNew-Object System.Data.DataTableため、 で DataTable 型に強制する理由もありません[System.Data.DataTable]。関数を呼び出す場合も同様です。DataTable オブジェクトを返しているので、それが返されます。また、変数の型を指定する場合は、型識別子と変数名の間にスペースを入れないでください。いずれにせよ、これらの問題によって、表示されている動作が発生することはありません。私はこのコードを実行しました:

function GetBuildData {
    $dt = New-Object System.Data.DataTable
    $column1 = New-Object system.Data.DataColumn 'Col1'
    $column2 = New-Object system.Data.DataColumn 'Col2'
    $dt.columns.add($column1)
    $dt.columns.add($column2)
    $row = $dt.NewRow()
    $row.col1 = '1'
    $row.col2 = '2'
    $dt.rows.add($row)

    return $dt
}

$buildData = GetBuildData
$buildData
Col1                                                                     Col2
----                                                                     ----
1                                                                        2

そして、それはうまくいきました。問題の原因となっているビットは、おそらく簡潔にするために除外したビットにあると思われます。近道はめったになく、部分的なデータから正確な答えを得ることはめったにありません。

于 2012-12-20T15:10:18.110 に答える