如何使用 PowerShell 将 csv 文件与 sql 数据库进行比较

How to compare csv file with sql database using PowerShell

我的 CSV 文件中有最新数据,我正在尝试与包含使用 EmpId 和名称列的旧数据的 SQL 服务器数据库示例 1 table 进行比较。如果 csv 文件中有新数据,则更新 Example1 table 并仅将新数据插入 Example2 table.

我是初学者,我被逻辑部分困住了,所以如果我能得到任何帮助或建议,我将不胜感激。任何指导将不胜感激。

我的 CSV 文件,Example1 和 Example2 数据库 table 看起来像这样

EmpId    Name           Hold
324   John Smith     Yes
432   Tim Cook       Yes
        $csv_file = "C:\scripts\user-info.csv"
        
        $csvImport = import-csv $csv_file

        foreach ($i in $csvImport){
              $EmpId = $i.EmpId
              $Name = $i.Name
              $Hold = $i.Hold

        }


        $Server = 'Server'
        $query = "SELECT EmpId,Name FROM Example1"
        $Database = 'DatabaseName'
        $result = Invoke-Sqlcmd -Query $query -ServerInstance $Server -Database $Database  | Select-Object * -ExcludeProperty ItemArray, Table, RowError, RowState, HasErrors

由于我一直在与 Compare-Object cmdlet 作斗争,这里有一个选项可以 'manually' 比较差异

假设 EmpId 字段是唯一的:

$Server   = 'Server'
$query    = "SELECT EmpId,Name FROM Example1"
$Database = 'DatabaseName'
$dbData   = Invoke-Sqlcmd -Query $query -ServerInstance $Server -Database $Database | 
            Select-Object * -ExcludeProperty ItemArray, Table, RowError, RowState, HasErrors
$csvData  = Import-Csv -Path 'C:\scripts\user-info.csv'

# iterate over the data rows in the CSV file
$result = foreach ($item in $csvData) {
    $dbRecord = @($dbData | Where-Object { $_.EmpId -eq $item.EmpId })
    if ($dbRecord.Count -eq 0) {
        # this is a new user to be added in the database

        # you can perform the INSERT statement right here or do that
        # afterwards by iterating the $result array and checking for items
        # where the Status field is 'New'.
        # for the latter, output an object:
        $item | Select-Object *, @{Name = 'Status'; Expression = {'New'}}
    }
    else {
        $dbRecord | ForEach-Object {
            if ($_.Name -ne $item.Name -or $_.Hold -ne $item.Hold) {
                # this is an existing record that needs updating. output what is in the CSV

                # you can perform the UPDATE statement right here or do that
                # afterwards by iterating the $result array and checking for items
                # where the Status field is 'Update'.
                # for the latter, output an object:
                $item | Select-Object *, @{Name = 'Status'; Expression = {'Update'}}
            }
        }
    }
}

现在在变量 $result 中,您应该有一个包含所有差异的数组,包括一个状态 属性,您可以从中知道是插入新记录还是更新现有记录。

最好按照 Teja Goud Kandula 提到的操作...将完整的 csv 加载到阶段 table,然后使用 SQL 命令快速插入新记录或更新现有记录(又名 UPSERT) .这是一个极其常见的场景。步骤是:

  1. 截断阶段table
  2. 运行 用于将 csv 加载到舞台的 Powershell 脚本 table
  3. 运行 SQL 从阶段到生产的插入或更新脚本 table

最后,如果您有 SQL 服务器,那么您可能有 SSIS,它就是用来执行这些类型的步骤的……不需要 Powershell。