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()
}
}