【问题标题】:Power SQL working with Data.tables使用 Data.tables 的 Power SQL
【发布时间】:2017-02-03 09:43:58
【问题描述】:

您好,我有以下代码

function Invoke-SQL {
    param(
        [string] $dataSource = ".\SKYPE",
        [string] $database = "LcsCDR",
        [string] $sqlCommand = "SELECT * From UsersView"
      )

    $connectionString = "Data Source=$dataSource; " +
            "Integrated Security=SSPI; " +
            "Initial Catalog=$database"

    $connection = new-object system.data.SqlClient.SQLConnection($connectionString)
    $command = new-object system.data.sqlclient.sqlcommand($sqlCommand,$connection)
    $connection.Open()

    $adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command
    $dataset = New-Object System.Data.DataSet
    $adapter.Fill($dataSet) | Out-Null

    $connection.Close()
    $dataSet.Tables

}

$results = Invoke-SQL 

Write-Host $results.Rows.Count

foreach ($row in $results.Rows)
{
Write-Host "value is : $($row[4])"

}

我所期望的就是拉回 UserView 表的内容并循环遍历它并将其显示在屏幕上。一切都直截了当。

但我在输出中使用列索引。我如何首先列出表格的列标题。然后能够通过使用标题而不是索引号进行循环。

所以我希望最后一行如下所示,其中“userid”是列标题。

Write-Host "value is : $($row["UserID"])"

这可能吗?

【问题讨论】:

    标签: sql powershell datatable datatables datasource


    【解决方案1】:

    你甚至不必循环!

    $results | Select-Object "UserID"
    

    替代方案:

    $results | Select-Object "UserID" | ForEach-Object {
        $_
    }
    
    $results | ForEach-Object {
        $_."UserID"
    }
    

    $_ 有点类似于 "this"

    【讨论】:

    • 干杯,遗憾的是,在编写脚本方面,我仍然非常业余。我将对这张表做的是基于两列匹配活动目录用户帐户,然后从其他列更新 AD 中的其他字段。就像你说的那样,我确信有更有效的方法可以做到这一点,for 和 if 循环我仍然对“真正的”scriper /程序感到惊讶。
    • @DevilWAH 添加了一些方法来循环到我的答案:-)
    【解决方案2】:

    我建议您使用我的通用Receive-SqlQuery 函数来关闭SqlConnectionSqlDataReader。您可以传入scriptblock 来处理读者。

    function Receive-SqlQuery
    {
        Param
        (
            [string]$ConnectionString,
            [string]$SqlQuery,
            [scriptblock]$ResultProcessor
        )
    
        try 
        {
            $sqlConnection = New-Object System.Data.SqlClient.SqlConnection $ConnectionString
            $sqlConnection.Open()
    
            try
            {
                $sqlCommand = New-Object System.Data.SqlClient.SqlCommand($SqlQuery, $sqlConnection)
                $reader = $sqlCommand.ExecuteReader()
                Invoke-Command $ResultProcessor -ArgumentList $reader
            }
            finally # cleanup reader
            {
                if ($reader)
                {
                    $reader.Close()
                }
            }
        }
        finally
        {
            $sqlConnection.Close();
        }
    }
    

    使用列名访问列的使用示例:

     $readerCallback = {
            Param($reader)
            while ($reader.Read()) {
                Write-Host $reader['UserID']
            }    
        }
    
    $retrieveUsers = 
    @'
    SELECT * From UsersView
    '@
    
    Receive-SqlQuery -ConnectionString "yourConnectionString" -SqlQuery $retrieveUsers -ResultProcessor $readerCallback
    

    【讨论】:

    • 为什么这种方式优先于我正在做的事情?拉回数据表有什么问题?老实说,我个人不知道这超出了我对 Powershell / SQL 知识的有限兴趣。
    • 你的解决方案没有问题,我只是担心关闭/处理对象,这就是为什么我更喜欢传递一个在两者之间运行的回调。
    • 再看一次,与我丑陋的黑客行为相比,“真正的”编码人员显示出整洁、结构良好的代码:)。谢谢你的cmets和洞察力。 :)
    【解决方案3】:

    哦,对不起,我知道我可以使用它们!我花了 20 分钟尝试它并盲目地尝试使用 {} 而不是 []。一个盲目的时刻。

    foreach ($row in $results.Rows)
    {
    Write-Host "calue is : $($row["UserID"])"
    
    }
    
    write-host $results.Columns
    

    是我所追求的命令。

    【讨论】:

      猜你喜欢
      • 2018-09-24
      • 2021-08-24
      • 1970-01-01
      • 1970-01-01
      • 2017-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-24
      相关资源
      最近更新 更多