Powershell - SQL 查询结果到具有属性的变量
Powershell - SQL query result to variable with properties
为什么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 属性
PS C:> $var | select *
Length
------
11
53
显示 $var 类型
PS C:> $var.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
$var=(SQLCMD -S 'x.x.x.x' -U 'user' -P 'password' -i "C:\query.sql" -W -m 1)
您正在调用 sqlcmd.exe
,它不知道 .Net objects 是什么,更不用说如何将它们传递给 PowerShell。就 PowerShell 而言,该命令输出字符串。您需要自己将字符串转换为 objects。
如果你必须使用 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
总是在 header.
下面创建的下划线行
另请注意,您应该在 sqlcmd
上使用 -w
参数以防止任何不正确的换行。另请注意,空值始终输出为文字字符串 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()
}
}
为什么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 属性
PS C:> $var | select *
Length
------
11
53
显示 $var 类型
PS C:> $var.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
$var=(SQLCMD -S 'x.x.x.x' -U 'user' -P 'password' -i "C:\query.sql" -W -m 1)
您正在调用 sqlcmd.exe
,它不知道 .Net objects 是什么,更不用说如何将它们传递给 PowerShell。就 PowerShell 而言,该命令输出字符串。您需要自己将字符串转换为 objects。
如果你必须使用 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
总是在 header.
另请注意,您应该在 sqlcmd
上使用 -w
参数以防止任何不正确的换行。另请注意,空值始终输出为文字字符串 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()
}
}