Powershell - 如何仅将 foreach 应用于从 T-SQL 查询返回的不同值

问题描述

我对 powershell 非常陌生 - 目前使用它从我们在 sql 服务器数据库上运行的 EHR 输出 PDF 文件

在我的 powershell 函数中,我有一个 tsql 查询,它为同一事件返回多行。一个事件可能包含多个问题,每个问题可以有多个答案 - 因此在 t-sql 查询结果中为每个事件创建多行。
我将在底部发布我的 pshell 函数代码(减去实际的 t-sql 查询) 我的 tsql 测试查询返回这些结果: t-sql query results for test event

在 PDF 输出中,我希望输出如下所示:
事件:面对面 - FPS 测试
日期:3/2/2021
答案:
信仰支持
禁毒协会(NA)
测试
答案:
Note_text:
测试

事件:电话(其他)
日期:2021/3/3
Note_text:
测试第二个事件

通过将 t-sql 查询分成不同的查询,我可以很好地将问题输出为多个答案,并且我也可以获得要输出的事件列表,但是当我尝试将两者结合时它会中断.我最终得到了这样的结果:

current results

它会为“社区联系”问题的每个答案拆分一个新条目,而不是创建一个列表。

有没有办法在 powershell 中使用 foreach 来查看从 t-sql 查询返回的不同 event_log_ids 而不是使用 foreach($row in $table.rows)?在单个事件有多行的情况下,与同一事件相关的每一行都将具有相同的 event_log_id。

pshell 函数代码:`function Get-MonthlyReport-ServiceNotes-FPS([string]$templatePath,[string]$pplid,[string]$programenrollmentid,[string]$fdom,[string]$ldom){ $dbconn = ($ConfigFile.Settings.DBCONN_EVOLV);

    # html template
    $templateFilename = "$($templatePath)\mr_segment_servicenotes - FPS.html";
    $htmltemplate = Get-HTMLTemplate -htmlfilename $templateFilename;
    $htmlbody = '';

    # sql query - returns columns actual_date,event_name,note_text,answer,and event_log_id
    
    
    Try
    {
        $connection = new-object system.data.sqlClient.sqlConnection($dbconn);
        $command = new-object system.data.sqlclient.sqlcommand($sqlquery,$connection);
        $command.CommandTimeout=0;
        $connection.open();
        $adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command;
        $dataset = New-Object System.Data.DataSet;
        $adapter.Fill($dataSet) | Out-Null;
        $connection.Close();
        $table = $dataset.Tables[0]
        $eventLogList = @($dataset.Tables[0] | select-object -Property event_log_ids | sort-object | Get-unique)
        

        # default content
        $htmlcontent = $htmltemplate;

        if($dataset.Tables[0].Rows.count -gt 0){         

            # add content
            foreach($row in $table.rows) {    
        
                
                # remove HTML tags and formatting from note_text
                if (-not ("$($row.note_text)" -eq $null)) {
                    $ntxt = Remove-HTMLTags -html "$($row.note_text)";
                    $htmlbody += "<tr>";
                    $htmlbody += "<td style=`"font-size: 9pt; font-weight: bold;`">Service:<br>$($row.event_name)</td>";
                    $htmlbody += "</tr>"; 
                    $htmlbody += "<tr>";
                    $htmlbody += "<td style=`"font-size: 9pt; font-weight: bold;`">event_log_id:<br>$($row.event_log_ids)</td>";
                    $htmlbody += "</tr>";
                    $htmlbody += "<tr>";
                    $htmlbody += "<td style=`"font-size: 9pt; font-weight: bold;`">Date:<br>$($row.actual_date)</td>";
                    $htmlbody += "</tr>";
                    $htmlbody += "<tr>";
                    $htmlbody += "<td style=`"font-size: 9pt; font-weight: bold;`">Community Connection:<br>$($row.answer)</td>";
                    $htmlbody += "</tr>";
                    $htmlbody += "<tr>";
                    $htmlbody += "<td style=`"font-size: 9pt;`">$($ntxt)<br>"
                    $htmlbody += "<hr style=`"border-top: dotted 1px;`" /></td>";
                    $htmlbody += "</tr>";
                    
            
                    
                 
                }
            }

            # assemble html
            if (-not ([string]::IsNullOrEmpty($htmlbody))) { 
                 $htmlcontent = $htmlcontent.Replace("{{table-set}}",$($htmlbody));
            } else {
                $nodata = "<tr><td style=`"font-size: 9pt;`" colspan=`"3`">No service notes were provided during this period.</td><tr>";
                $htmlcontent = $htmlcontent.Replace("{{table-set}}",$($nodata));
            } 

        } else {

             #if no data is returned
            $nodata = "<tr><td style=`"font-size: 9pt;`" colspan=`"3`">No service notes were provided during this period.</td><tr>";
            $htmlcontent = $htmlcontent.Replace("{{table-set}}",$($nodata));
        }

        # return string
        return $htmlcontent; 
    }
    Catch
    {
        $me = "Get-MonthlyReport-ServiceNotes-FPS";
        $msg = $_.Exception.Message;
        Put-EventLog -key "ERROR" -eventtype "PROCESS" -eventsource $me -description $msg;
        throw $_.Exception; 
    } 
}`

解决方法

如果您只想要 ID,那么在 SQL 中使用 DISTINCT 就很简单了。

在 Powershell 中,您可以执行类似操作来获取列表。

$SqlResults | Select-Object -Property event_log_ids | Sort-Object -Unique

编辑:如果您使用的是 SQL Server 2016+,则可以使用 STRING_AGG 函数将答案合并到上游列表中。

select actual_date
--other fields,string_agg(Answer,',') as AnswerCommaSeparated,char(13)+char(10)) as AnswerNewLineSeparated
from SomeTable
group by actual_date