Invoke-SqlCmd输出DataTables后修改数据再回写SQL数据库的实现咨询
正确实现方案
你之前的写法不生效,核心原因是Invoke-SqlCmd指定-OutputAs DataTables参数后,管道输出的是完整的DataTable对象,而非逐行输出DataRow,直接修改$_.CaptureDate是给DataTable对象新增了一个无关属性,根本没有修改到表内的行数据。
正确的修改逻辑是拿到DataTable对象后,遍历所有行修改指定列的值,再把修改后的整个DataTable传给Write-SqlTableData即可,示例代码如下:
# 提前定义CaptureDate的值,注意直接用DateTime类型,不要加引号包裹 $capturedate = Get-Date # 也可以指定固定日期:Get-Date "2024-05-20 12:00:00" Invoke-Sqlcmd -ServerInstance $instance -Database master -InputFile (Join-Path $scriptPath $script) -OutputAs DataTables | ForEach-Object { # 可选:如果原查询结果没有CaptureDate列,先新增列,已有该列可以注释掉下面3行 $newCol = New-Object System.Data.DataColumn("CaptureDate", [DateTime]) $newCol.AllowDBNull = $false $_.Columns.Add($newCol) # 遍历表内所有行,修改CaptureDate列的值 foreach ($row in $_.Rows) { $row.CaptureDate = $capturedate } # 将修改完成的DataTable继续向下传递给写入命令 $_ } | Write-SqlTableData -ServerInstance $collectionInstance -DatabaseName $collectionDatabase -SchemaName "dbo" -TableName $script.Replace(".sql","") -Force
注意事项
- 不要给
$capturedate加单引号或者双引号包裹,操作DataRow时直接赋值对应类型的值即可,包裹引号会变成字符串类型,和日期列的类型不匹配会触发写入报错。 - 如果需要兼容CaptureDate为空的场景,可以把
$newCol.AllowDBNull设为$true,赋值为空时用$row.CaptureDate = [DBNull]::Value即可。
内容的提问来源于stack exchange,提问作者Bukester
相关产品推荐
相关产品推荐

