Select(或拆分)来自 SQLCMD 输出的列
Select (or split) column from SQLCMD output
如何在 PowerShell v1 中 select 输出来自 SQLCMD
的列?我正在尝试在 PowerShell v1.
中使用 Write-Output
进行 JSON 输出
最后查询输出。
$_
returns 两列。如果我们可以使用 $_.name
和 $_.jobid
,但它们都是 returns 空行。解决此问题将是首选解决方案。
这是 PowerShell 命令:
Write-Output '{"data":[';
(SQLCMD -S 'x.x.x.x' -U 'user' -P 'passwors' -i "C:\query.sql" -W) | %{
try {
($coma + '{"{#JOBID}":"' + $_ + '",' + '"{#JOBNAME}":"' + $_ + '"}');
$coma=',';
} catch {}
};
Write-Output "]}"
它是什么returns:
{"data":[
,{"{#JOBID}":"12345-aaaa-1234-5678-000000000000000 Clear DB entries","{#JOBNAME}":"12345-aaaa-1234-5678-000000000000000 Clear DB entries"}
,{"{#JOBID}":"12345-bbbb-1234-5678-000000000000000 TempLog DB","{#JOBNAME}":"12345-bbbb-1234-5678-000000000000000 TempLog DB"}
]}
我的期望:
{"data":[
,{"{#JOBID}":"12345-aaaa-1234-5678-000000000000000","{#JOBNAME}":"Clear DB entries"}
,{"{#JOBID}":"12345-bbbb-1234-5678-000000000000000","{#JOBNAME}":"TempLog DB"}
]}
我不确定如何为 job_id
和 name
使用带制表符分隔符 ($_ -split "
t") 的拆分。我的尝试要么将两个列名作为一个返回,要么在某些情况下它返回空。
这是查询及其在命令行上的输出:
PS C:\> SQLCMD -S 'x.x.x.x' -U 'user' -P 'password' -i "C:\query.sql" -W
job_id name
12345-aaaa-1234-5678-000000000000000 Clear DB entries
12345-bbbb-1234-5678-000000000000000 TempLog DB
(2 rows affected)
我知道版本 3 上的 ConvertTo-Json
,但我想让它在 PowerShell v1 上运行,这样它对那些出于任何原因无法升级的人会有帮助。
我想出的解决方法是对第二列 #JOBNAME
使用 ($_ -split ' ')[1..100]
,对第一列 #JOBID
使用 ($_ -split ' ')[0]
。
注意:这只有效,因为 JOBID
列值被表述为一个单词。如果第一列的单词数是随机的,则它不适用于其他查询。
这是最终的命令和输出:
$coma=''; Write-Output '{"data":[';
(SQLCMD -S 'x.x.x.x' -U 'user' -P 'passwors' -i "C:\query.sql" -W) | %{
try {
($coma + '{"{#JOBID}":"' + ($_ -split ' ')[0] + '",' + '"{#JOBNAME}":"' + ($_ -split ' ')[1..100] + '"}');
$coma=',';
} catch {}
};
Write-Output "]}"
输出:
{"data":[
,{"{#JOBID}":"12345-aaaa-1234-5678-000000000000000","{#JOBNAME}":"Clear DB entries"}
,{"{#JOBID}":"12345-bbbb-1234-5678-000000000000000","{#JOBNAME}":"TempLog DB"}
]}
还有Invoke-SQLcmd方法,但是添加snap-in需要30秒,执行查询需要2秒。
Add-PSSnapin SqlServerCmdletSnapin100; $coma=''; Write-Output '{"data":[';
(Invoke-Sqlcmd -ServerInstance 'x.x.x.x' -username 'user' -password 'password' -inputfile "C:\query.sql") | %{
try {
($coma + '{"{#JOBID}":"' + $_.job_id + '",' + '"{#JOBNAME}":"' + $_.name + '"}');
$coma=',';
} catch {}
};
Write-Output "]}"
如果你有 Powershell v3
那么你可以使用 Sqlcmd... | ConvertTO-Json
另一种方法,看来靠谱。感谢 Bacon Bits 的回答。
$coma=''; Write-Output '{"data":[';
(SQLCMD -S 'x.x.x.x' -U 'user' -P 'password' -i "C:\query.sql" -W -m 1 -s `"`t`") | ConvertFrom-Csv -Delimiter "`t" | Select-Object -Skip 1 | %{
try {
($coma + '{"{#JOBID}":"' + $_.job_id + '",' + '"{#JOBNAME}":"' + $_.name + '"}');
$coma=',';
} catch {}
};
Write-Output "]}"
如果您的数据包含制表符,您将需要不同的分隔符。 Select-Object -Skip 1 是跳过 sqlcmd 总是在 header.
下面创建的下划线行
另请注意,您应该在 sqlcmd 上使用 -w 参数以防止任何不正确的换行。另请注意,空值始终作为文字字符串 NULL 输出。
再次推荐 Powershell v3
或 Invoke-SQLcmd
而不是此方法。
如何在 PowerShell v1 中 select 输出来自 SQLCMD
的列?我正在尝试在 PowerShell v1.
Write-Output
进行 JSON 输出
最后查询输出。
$_
returns 两列。如果我们可以使用 $_.name
和 $_.jobid
,但它们都是 returns 空行。解决此问题将是首选解决方案。
这是 PowerShell 命令:
Write-Output '{"data":[';
(SQLCMD -S 'x.x.x.x' -U 'user' -P 'passwors' -i "C:\query.sql" -W) | %{
try {
($coma + '{"{#JOBID}":"' + $_ + '",' + '"{#JOBNAME}":"' + $_ + '"}');
$coma=',';
} catch {}
};
Write-Output "]}"
它是什么returns:
{"data":[
,{"{#JOBID}":"12345-aaaa-1234-5678-000000000000000 Clear DB entries","{#JOBNAME}":"12345-aaaa-1234-5678-000000000000000 Clear DB entries"}
,{"{#JOBID}":"12345-bbbb-1234-5678-000000000000000 TempLog DB","{#JOBNAME}":"12345-bbbb-1234-5678-000000000000000 TempLog DB"}
]}
我的期望:
{"data":[
,{"{#JOBID}":"12345-aaaa-1234-5678-000000000000000","{#JOBNAME}":"Clear DB entries"}
,{"{#JOBID}":"12345-bbbb-1234-5678-000000000000000","{#JOBNAME}":"TempLog DB"}
]}
我不确定如何为 job_id
和 name
使用带制表符分隔符 ($_ -split "
t") 的拆分。我的尝试要么将两个列名作为一个返回,要么在某些情况下它返回空。
这是查询及其在命令行上的输出:
PS C:\> SQLCMD -S 'x.x.x.x' -U 'user' -P 'password' -i "C:\query.sql" -W job_id name 12345-aaaa-1234-5678-000000000000000 Clear DB entries 12345-bbbb-1234-5678-000000000000000 TempLog DB (2 rows affected)
我知道版本 3 上的 ConvertTo-Json
,但我想让它在 PowerShell v1 上运行,这样它对那些出于任何原因无法升级的人会有帮助。
我想出的解决方法是对第二列 #JOBNAME
使用 ($_ -split ' ')[1..100]
,对第一列 #JOBID
使用 ($_ -split ' ')[0]
。
注意:这只有效,因为 JOBID
列值被表述为一个单词。如果第一列的单词数是随机的,则它不适用于其他查询。
这是最终的命令和输出:
$coma=''; Write-Output '{"data":[';
(SQLCMD -S 'x.x.x.x' -U 'user' -P 'passwors' -i "C:\query.sql" -W) | %{
try {
($coma + '{"{#JOBID}":"' + ($_ -split ' ')[0] + '",' + '"{#JOBNAME}":"' + ($_ -split ' ')[1..100] + '"}');
$coma=',';
} catch {}
};
Write-Output "]}"
输出:
{"data":[
,{"{#JOBID}":"12345-aaaa-1234-5678-000000000000000","{#JOBNAME}":"Clear DB entries"}
,{"{#JOBID}":"12345-bbbb-1234-5678-000000000000000","{#JOBNAME}":"TempLog DB"}
]}
还有Invoke-SQLcmd方法,但是添加snap-in需要30秒,执行查询需要2秒。
Add-PSSnapin SqlServerCmdletSnapin100; $coma=''; Write-Output '{"data":[';
(Invoke-Sqlcmd -ServerInstance 'x.x.x.x' -username 'user' -password 'password' -inputfile "C:\query.sql") | %{
try {
($coma + '{"{#JOBID}":"' + $_.job_id + '",' + '"{#JOBNAME}":"' + $_.name + '"}');
$coma=',';
} catch {}
};
Write-Output "]}"
如果你有 Powershell v3
那么你可以使用 Sqlcmd... | ConvertTO-Json
另一种方法,看来靠谱。感谢 Bacon Bits 的回答。
$coma=''; Write-Output '{"data":[';
(SQLCMD -S 'x.x.x.x' -U 'user' -P 'password' -i "C:\query.sql" -W -m 1 -s `"`t`") | ConvertFrom-Csv -Delimiter "`t" | Select-Object -Skip 1 | %{
try {
($coma + '{"{#JOBID}":"' + $_.job_id + '",' + '"{#JOBNAME}":"' + $_.name + '"}');
$coma=',';
} catch {}
};
Write-Output "]}"
如果您的数据包含制表符,您将需要不同的分隔符。 Select-Object -Skip 1 是跳过 sqlcmd 总是在 header.
下面创建的下划线行另请注意,您应该在 sqlcmd 上使用 -w 参数以防止任何不正确的换行。另请注意,空值始终作为文字字符串 NULL 输出。
再次推荐 Powershell v3
或 Invoke-SQLcmd
而不是此方法。