You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell脚本插入XML数据到SQL报错:字符串转uniqueidentifier失败

Fixing "WriteToServer" Error When Converting XML String to SQL uniqueidentifier in PowerShell

我来帮你搞定这个头疼的问题——你遇到的WriteToServer报错,核心原因是XML里的字符串没有被正确转换成SQL能识别的uniqueidentifier类型,单纯改Columns.Add()的类型声明根本不够,因为PowerShell和ADO.NET需要明确的类型转换逻辑才行。

下面是一步步的解决方案,亲测有效:

1. 先确认XML里的GUID格式是否合规

首先得确保XML中的ScheduleId和AccountingPeriodCase_PK_ID是标准的GUID格式(比如123e4567-e89b-12d3-a456-426614174000)。如果是不带连字符的短格式(比如123e4567e89b12d3a456426614174000),先在脚本里转成标准格式:

$rawGuid = $xmlNode.ScheduleId
$formattedGuid = [Guid]::ParseExact($rawGuid, "N").ToString() # 把无连字符的GUID转成带连字符的标准格式

2. 构建DataTable时,强制把值转成Guid对象

当你创建DataTable的时候,不仅要把列类型设为UniqueIdentifier,更重要的是每一行的对应值必须是实际的Guid对象,而不是字符串。这里给你一段示例代码:

# 初始化DataTable并定义列
$dt = New-Object System.Data.DataTable
# 明确指定列的SQL数据类型
$dt.Columns.Add("ScheduleId", [System.Data.SqlDbType]::UniqueIdentifier) | Out-Null
$dt.Columns.Add("AccountingPeriodCase_PK_ID", [System.Data.SqlDbType]::UniqueIdentifier) | Out-Null
# 其他列按需添加...

# 遍历XML节点,插入数据行
foreach ($node in $xml.DocumentElement.SelectNodes("//YourTargetNode")) {
    $row = $dt.NewRow()
    # 关键:把XML里的字符串强制转换成Guid对象
    $row["ScheduleId"] = [Guid]$node.ScheduleId
    $row["AccountingPeriodCase_PK_ID"] = [Guid]$node.AccountingPeriodCase_PK_ID
    # 其他列赋值...
    $dt.Rows.Add($row)
}

# 执行批量插入
$bulkCopy = New-Object System.Data.SqlClient.SqlBulkCopy($yourConnectionString)
$bulkCopy.DestinationTableName = "YourSQLTableName"
$bulkCopy.WriteToServer($dt)

3. 处理空值或无效GUID的情况

如果XML里存在空值或者格式错误的GUID,直接转换会炸,所以最好加个安全转换的小函数:

function Convert-ToSafeGuid($inputString) {
    if ([string]::IsNullOrWhiteSpace($inputString)) {
        return [DBNull]::Value # 对应SQL里的NULL值
    }
    try {
        return [Guid]$inputString
    }
    catch {
        Write-Warning "发现无效GUID格式: $inputString,将用NULL代替"
        return [DBNull]::Value
    }
}

# 使用这个函数赋值就安全多了
$row["ScheduleId"] = Convert-ToSafeGuid $node.ScheduleId

4. 检查列映射(如果DataTable和SQL表列名不匹配)

如果你的DataTable列名和SQL目标表的列名不完全一致,记得手动添加列映射,确保类型对应上:

$bulkCopy.ColumnMappings.Add("DataTable里的列名", "SQL表的列名") | Out-Null
# 比如:
$bulkCopy.ColumnMappings.Add("ScheduleId", "ScheduleId") | Out-Null
$bulkCopy.ColumnMappings.Add("AccountingPeriodCase_PK_ID", "AccountingPeriodCase_PK_ID") | Out-Null

总的来说,核心就是让DataTable里的对应列值是Guid对象而不是字符串,同时确保XML里的GUID格式正确,这样SqlBulkCopy就能顺利把数据转换成SQL的uniqueidentifier类型了。

内容的提问来源于stack exchange,提问作者B21

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:15:19