Powershell - результат запроса SQL к переменной со свойствами

Почему сохраненный вывод SQLCMD имеет только Length собственность вместо column names?. Разве нельзя хранить sqlcmd вывод со своими свойствами?

Invoke-sqlcmd хранит это правильно, но Invoke-SQLcmd процесс занимает немного больше времени, поэтому я пытаюсь заставить его работать с SQLcmd, так как этот метод будет частью различных сценариев, запуск которых запланирован каждую минуту, раз в час и т. д.,

Любая идея, если это возможно, или в чем проблема?

Сохранение вывода и echo $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

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

Показать тип $var

     PS C:> $var.GetType()

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

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

Я использую вкладку в качестве разделителя полей. Если ваши данные содержат вкладки, вам понадобится другой разделитель. Вы также можете столкнуться с проблемами, если ваши данные содержат двойные кавычки. Select-Object -Skip 1 это пропустить подчеркивание строки, которая sqlcmd всегда создает ниже заголовка.

Также помните, что вы должны использовать -w параметр на sqlcmd чтобы предотвратить любую неправильную упаковку. Также помните, что нулевые значения всегда выводятся в виде литеральной строки NULL,

Тем не менее, я все равно, вероятно, придерживаться Invoke-Sqlcmd, Это намного менее подвержено ошибкам и гораздо более предсказуемо. Если бы я действительно нуждался в производительности, я бы, вероятно, использовал прямые методы.Net или SSIS.

Я написал для этой цели функцию... не до конца понятную... надеюсь, это поможет

    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()
      }
    }
Другие вопросы по тегам