PowerShell中如何验证下一行FirstOnlyDesignNumber等于上一行NextDesignNumber
问题描述
我有如下PowerShell代码:
try { #Connect to the SQL server and retrieves the data $query = 'Query.sql' $SQLConnection = Invoke-Sqlcmd2 -ServerInstance "$Instance" -Database $DB -InputFile $query -Credential (Get-Credential) -As DataSet } catch { Write-Error $_.Exception.Message } #Output the retrieved data $table = $SQLConnection.Tables[0] $count = $table.Rows.Count $NextDesignNumber = "" if (-not $count -eq 0) { foreach ($row in $table.Rows){ $Obj = [PSCustomObject] @{ FirstOnlyDesignNumber = $row.'First/Only Design Number' ApplicationCount = $row.'Application Count' NextDesignNumber = [int]$row.'First/Only Design Number' + [int]$row.'Application Count' } } }
该代码执行后输出:
FirstOnlyDesignNumber ApplicationCount NextDesignNumber --------------------- ---------------- ---------------- 1231231 1 1231232
我需要验证下一行的FirstOnlyDesignNumber是否等于上一行的NextDesignNumber,示例如下:
FirstOnlyDesignNumber ApplicationCount NextDesignNumber --------------------- ---------------- ---------------- 1231231 1 1231232 1231232 4 1231236
若符合规则则不执行操作,不符合则执行特定操作。我曾尝试以下代码但未得到预期结果:
Compare-Object $Obj.FirstOnlyDesignNumber $Obj.NextDesignNumber
以及:
If($Obj.FirstOnlyDesignNumber -notmatch $Obj.NextDesignNumber){ //do something }else{ //do nothing }
请问该如何实现此需求?
解决方案
你的核心问题是当前代码里的$Obj每次循环都会被覆盖,最后只保留最后一行的数据,没法对比前后行。需要先把所有行的处理结果存储到一个集合里,再遍历这个集合做前后行的校验。
步骤1:收集所有处理后的对象
修改原代码的循环部分,把每个$Obj添加到数组里:
try { #Connect to the SQL server and retrieves the data $query = 'Query.sql' $SQLConnection = Invoke-Sqlcmd2 -ServerInstance "$Instance" -Database $DB -InputFile $query -Credential (Get-Credential) -As DataSet } catch { Write-Error $_.Exception.Message } #Output the retrieved data $table = $SQLConnection.Tables[0] $count = $table.Rows.Count # 定义一个数组存储所有处理后的对象 $processedObjects = @() if (-not $count -eq 0) { foreach ($row in $table.Rows){ $Obj = [PSCustomObject] @{ FirstOnlyDesignNumber = $row.'First/Only Design Number' ApplicationCount = $row.'Application Count' NextDesignNumber = [int]$row.'First/Only Design Number' + [int]$row.'Application Count' } # 将当前对象添加到数组 $processedObjects += $Obj } }
步骤2:遍历数组校验前后行
现在可以遍历$processedObjects,从第2个元素开始,和前一个元素对比:
# 从索引1开始(跳过第一个元素,对比第2个和第1个) for ($i = 1; $i -lt $processedObjects.Count; $i++) { $prevObj = $processedObjects[$i-1] $currObj = $processedObjects[$i] # 注意要转成int类型后再对比,避免字符串匹配的问题 if ([int]$currObj.FirstOnlyDesignNumber -ne [int]$prevObj.NextDesignNumber) { # 不符合规则,执行你的特定操作 Write-Warning "行$i不符合规则:当前FirstOnlyDesignNumber是$($currObj.FirstOnlyDesignNumber),上一行NextDesignNumber是$($prevObj.NextDesignNumber)" # 这里替换成你的具体操作,比如: # Invoke-YourSpecificAction -Data $currObj } # 符合规则则不做操作 }
关键注意点
- 必须先收集所有行的处理结果,不能每次循环覆盖
$Obj,否则无法保留前一行的数据。 - 对比时要转成
int类型,避免因为字符串格式问题导致对比错误(比如数字前面有空格的情况)。 - 循环从索引1开始,确保每次对比的是当前行和上一行。
内容的提问来源于stack exchange,提问作者Robert Gething
相关产品推荐
相关产品推荐

