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_idname 使用带制表符分隔符 ($_ -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 v3Invoke-SQLcmd 而不是此方法。