【问题标题】:Join SQL query Results and Get-ChildItem Results加入 SQL 查询结果和 Get-ChildItem 结果
【发布时间】:2015-09-08 00:07:54
【问题描述】:

背景:我有一个目录,其中包含许多导入到 SQL 服务器的文件。

任务:创建一个 PowerShell 脚本,该脚本将在该目录中提取文件并使用 SQL 查询中的文件名。

最终目标:要显示除了文件名之外的 SQL 结果,但所显示的结果集还应该显示在 SQL Server 中没有条目的文件。 SQL 服务器查询中的 RIGHT JOIN 之类的东西。

Powershell 代码

$files = Get-ChildItem -Recurse -Force $filePath -ErrorAction SilentlyContinue | Where-Object { ($_.PSIsContainer -eq $false) } | Select-Object Name
$Server = "Loadv1"
$DB = "LoadDB"
$dbResults = @()

ForEach ($file in $files)
{
    $fileName = $file.name
    write-host $fileName

    if($fileName.Length -gt 1)
    {
        $Query = "
            SELECT FileName,CurrentStatus 
            FROM LogStatus
            WHERE FileName LIKE '$fileName%'
        "
#       Write-host $Query
    }

    $dbResults += Invoke-Sqlcmd -ServerInstance $Server -Database $DB -Query $Query
}
$dispResults = $dbResults,$file
$dispResults | Format-Table -autosize

到目前为止所做的工作:我已经能够使用 Get-ChildItem 获取文件名并循环它们以获取查询结果。但是,我目前得到的结果没有显示在 SQL Server 表中没有相应条目的文件

当前结果

OperationalLanding20150622061502.dat
OperationalLandingAudit20150622061502.dat
OperativeThird_Party_System20150616090701.dat


FileName                                       CurrentStatus
OperationalLandingAudit20150622061502.dat      SSIS Package Complete
OperativeThird_Party_System20150616090701.dat  SSIS Package Complete

预期结果

OperationalLanding20150622061502.dat
OperationalLandingAudit20150622061502.dat
OperativeThird_Party_System20150616090701.dat


FileName                                       CurrentStatus
OperationalLanding20150622061502.dat           NULL
OperationalLandingAudit20150622061502.dat      SSIS Package Complete
OperativeThird_Party_System20150616090701.dat  SSIS Package Complete

希望我能在上面解释我的要求。

【问题讨论】:

    标签: sql-server sql-server-2008 powershell


    【解决方案1】:

    好的,如果 SQL 查询没有结果,则返回 NULL,本质上,不会将任何内容添加到 $dbResults 数组中。相反,让我们将结果附加到自定义对象。我不知道你有什么 PowerShell 版本,所以我需要做一些我知道应该工作的事情。我也很少使用 SQL cmdlet,所以我不得不猜测其中的一些。

    $files = Get-ChildItem -Recurse -Force $filePath -ErrorAction SilentlyContinue | 
        Where-Object {$_.PSIsContainer -eq $false -and $_.Length -gt 1} | 
        Select-Object -ExpandProperty Name
    $Server = "Loadv1"
    $DB = "LoadDB"
    
    $files | ForEach-Object{
        write-host $_
    
        $Query = "
            SELECT FileName,CurrentStatus 
            FROM LogStatus
            WHERE FileName LIKE '$_%'
        "
        $Results = Invoke-Sqlcmd -ServerInstance $Server -Database $DB -Query $Query
    
        $props = @{Name = $_}
    
        If($Results){
            $props.CurrentStatus = $Results.CurrentStatus
        } Else {
            $props.CurrentStatus = "Null"
        }
    
        New-Object -TypeName PSCustomObject -Property $props
    
    } | Format-Table -autosize
    

    这样做是创建一个包含 sql 查询结果的自定义对象(由于上述原因我没有更改)。如果没有返回结果,我们使用字符串“null”作为填充符。

    我清理了您如何生成$files 变量,方法是使用-Expand 制作一个简单的字符串数组,并将长度条件也移到那里。

    应该现在拥有所有预期的结果。我说应该,因为我假设返回对象的样子。

    【讨论】:

    • 不错的 powershell 脚本,显然我更喜欢 sql 人,甚至选择不碰 powershell :) 非常好的解决方案
    • @PhilipDevine 同样适用于您评论中的技术:)
    • 谢谢马特!这就像魅力一样。由于我正在尝试通过更多选项实现更多功能,因此我可能会使用您的解决方案并对其进行开发。
    【解决方案2】:
    $Query = "
                SELECT isNull(A.FileName, b.FileName) FileName,ISNULL(A.CurrentStatus,B.CurrentStatus) CurrentStatus 
            FROM LogStatus A
            Right JOIN (SELECT '$filename' FileName,NULL CurrentStatus) B 
            ON a.Filename like '$filename%'
    
            "
    

    这应该为您填充文件名。由于它在 powershell 中,因此制作原型有点困难,但我可能会想出一个 sql fiddle 来证明它。

    编辑

    答案已编辑,带有 sql fiddle: http://sqlfiddle.com/#!3/12b43/9

    显然,由于您在游标中,我们一次只能证明一个查询。

    【讨论】:

    • 谢谢菲利普!我得说你的 SQL 解决方案非常适合我的代码。除了查询之外,我不需要更改任何其他内容,但我仍然选择了马特的解决方案,因为我可能会更多地探索他创建的自定义对象并在其上进行开发。再次感谢..这仍然是一个很大的帮助:)
    • 该死,很高兴我能帮上忙,这绝对是一个有趣的问题 :)
    猜你喜欢
    • 2021-08-05
    • 2012-12-30
    • 2018-11-22
    • 1970-01-01
    • 2017-05-13
    • 2023-03-10
    • 2013-12-14
    • 1970-01-01
    • 2014-11-08
    相关资源
    最近更新 更多