【问题标题】:Select (or split) column from SQLCMD output从 SQLCMD 输出中选择(或拆分)列
【发布时间】:2018-03-14 08:25:08
【问题描述】:

如何从 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"}
]}

我不确定如何对job_idname 使用带有制表符分隔符($_ -split "t") 的拆分。我的尝试要么将两个列名都返回为1,在某些情况下返回空。

这是查询及其在命令行上的输出:

PS C:\> SQLCMD -S 'x.x.x.x' -U '用户' -P '密码' -i "C:\query.sql" -W job_id 名称 12345-aaaa-1234-5678-000000000000000 清除数据库条目 12345-bbbb-1234-5678-000000000000000 TempLog DB (受影响的 2 行)

我知道 ConvertTo-Json 在第 3 版上,但我想让它在 PowerShell v1 上运行,以便对那些因任何原因无法升级的人有所帮助。

【问题讨论】:

  • 你试过$_.name而不是$_["name"]吗?
  • 也返回空
  • $_ | Get-Member 返回什么?
  • 如果我将 sqlcmd 输出分配给`$var1`,然后运行$var1 | select $_ | get-member,我会得到这个输出。 imgur.com/a/McJ1U 似乎整个 sqlcmd 输出都保存为基于文本的表,所以可能是它的属性?我不确定
  • 绝对没有使用 PowerShell v1 的正当理由。当前支持的所有 Windows 版本至少可以运行 PowerShell v3。甚至 Windows XP 和 Server 2003 至少也可以运行 PowerShell v2。立即升级。

标签: json powershell sqlcmd powershell-1.0


【解决方案1】:

我想出的解决方法是使用($_ -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

【讨论】:

    【解决方案2】:

    另一种方法,似乎可靠。感谢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 输出。

    再次推荐Powershell v3Invoke-SQLcmd,而不是这种方法。

    【讨论】:

      猜你喜欢
      • 2019-01-24
      • 1970-01-01
      • 1970-01-01
      • 2021-02-14
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      • 2017-08-05
      • 2017-04-18
      相关资源
      最近更新 更多