Powershell - 带有属性的SQL查询结果变量

时间:2018-03-14 18:01:11

标签: powershell sqlcmd invoke-sqlcmd

为什么SQLCMD的存储输出只有Length属性而不是column names?是否无法存储sqlcmd输出及其属性?

Invoke-sqlcmd正确存储它,但Invoke-SQLcmd需要花费更长的时间才能处理,因此我尝试使其与SQLcmd一起使用,因为此方法将成为计划每分钟运行的不同脚本的一部分,曾经一个小时等,

是否有可能或问题是什么?

存储输出并回显$ var:

     PS C:> $var=(SQLCMD -S 'x.x.x.x' -U 'user' -P 'password' -i "C:\query.sql" -W -m 1) 

     PS C:> $var
     job_id name
     ------ ----
     12345-aaaa-1234-5678-000000000000000 Clear DB entries
     12345-bbbb-1234-5678-000000000000000 TempLog DB

Echo $ var [0,1,2],它不显示属性名称。

     PS C:> $var[0]
     job_id name
     PS C:> $var[1]
     ------ ----
     PS C:> $var[2]
     12345-aaaa-1234-5678-000000000000000 Clear DB entries

显示$ var properties

     PS C:> $var | select *
     Length
     ------
     11
     53

显示$ var type

     PS C:> $var.GetType()

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

2 个答案:

答案 0 :(得分:2)

$var=(SQLCMD -S 'x.x.x.x' -U 'user' -P 'password' -i "C:\query.sql" -W -m 1) 

你正在调用sqlcmd.exe,它没有关于.Net对象如何将它们传递给PowerShell的概念。就PowerShell而言,该命令输出字符串。您需要自己将字符串转换为对象。

如果你必须使用sqlcmd.exe,我会建议这样的事情:

$Delimiter = "`t"
$var = SQLCMD -S 'x.x.x.x' -U 'user' -P 'password' -i "C:\query.sql" -W -m 1 -s $Delimiter |
    ConvertFrom-Csv -Delimiter $Delimiter |
    Select-Object -Skip 1

我正在使用tab作为字段分隔符。如果您的数据包含标签,则需要使用其他分隔符。如果您的数据包含双引号,也可能会遇到问题。 Select-Object -Skip 1将跳过sqlcmd始终在标题下创建的下划线。

另请注意,您应使用-w上的sqlcmd参数来防止任何错误的换行。另请注意,空值始终作为文字字符串NULL输出。

那就是说,我仍然可能坚持Invoke-Sqlcmd。它更不容易出错,而且更容易预测。如果我真的需要性能,我可能会使用直接.Net方法或SSIS。

答案 1 :(得分:0)

我为此目的编写了一个函数......并没有完全充实...希望它有所帮助

    function Invoke-MSSqlCommand
    {
      [CmdletBinding()]
      param
      (
        [Parameter(Position=0, Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $Query,

        [Parameter(Position=1, Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $ConnectionString,

        [Switch]
        $NoOutput
      )
      try {
        $connection = New-Object -TypeName System.Data.SqlClient.SqlConnection
        $connection.ConnectionString = $ConnectionString
        $null = $connection.Open()
      }
      catch {
        Throw "$connectionstring could not be contacted"
      }
      $command = New-Object -TypeName System.Data.SqlClient.SqlCommand
      $command.CommandText = $query
      $command.Connection = $connection


      if ($NoOutput) {
        $null = $command.ExecuteNonQuery()
      }
      else {

        if ($dataset.Tables[0].Rows[0] -eq $null) {
          write-verbose -Message 'no record'
          $connection.Close()
          return $null
        }

        $dataset.Tables[0].Rows
        $connection.close()
      }
    }