从SQLCMD输出中选择(或拆分)列

时间:2018-03-14 08:25:09

标签: json powershell sqlcmd powershell-v1.0

如何从PowerShell v1中的SQLCMD输出中选择列?我试图在PowerShell v1中使用Write-Output进行JSON输出。

最后查询输出。

$_返回两列。如果我们只能使用$_.name$_.jobid,但它们都返回空行。解决这个问题将是首选解决方案。

这是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 "]}"

它返回的内容:

{"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"}
]}

我不确定如何对($_ -split "job_id的制表符分隔符name 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上工作,这样对那些无论出于何种原因无法升级的人都有帮助。

2 个答案:

答案 0 :(得分:0)

我提出的解决方法是将($_ -split ' ')[1..100]用于第二列#JOBNAME,将($_ -split ' ')[0]用于第一列#JOBID

注意:这仅适用,因为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 方法,但添加管理单元需要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

答案 1 :(得分:0)

另一种方法,似乎可靠。感谢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始终在标题下创建的下划线。

另请注意,您应该在sqlcmd上使用-w参数以防止任何错误的换行。还要注意,null值总是以文字字符串NULL形式输出。

建议再次Powershell v3Invoke-SQLcmd使用此方法。