导出SQL数据到CSV时PartNo格式异常如何解决?
问题描述
- 需求:用PowerShell脚本从SQL Server提取数据并保存为CSV,要求数据与SQL表完全一致
- 异常现象:PartNo列中格式为
xxxx-x-x的值导出CSV后变为x\x\xxxx,终端输出该字段正常,Excel格式化无法修复(导出后数据已异常) - 环境:Windows 10 22h2、MS SQL Server 2005、PowerShell 7.2.11、Excel 365(Version 2310 Build 16.0.16924.20054)
- 现有代码:
Import-Module ImportExcel $dataFile = Import-Excel -Path "C:\Desktop\Scripts\Aras\Copy of Part RN Sample Export - 11-11-23.xlsx" $server = "ServerName" $database = "DatabaseName" $csvFilePath="C:\Desktop\Scripts\Aras\CSVOutput\Output_EngParts.csv" #Write-Host $dataFile.PartRn ForEach ($partRnItem in $dataFile){ Write-host $partRnItem.PartRN $partRn = $partRnItem.PartRN $queryEngParts = "SELECT [PartRn], [PartNo], [Title], [CompanyId] FROM [NIMS_Eng].[dbo].[EngParts] WHERE PartRn = $partRn" $invokeSql = Invoke-Sqlcmd -ServerInstance $server -Database $database -Query $queryEngParts $invokeSql | Export-Csv -Path $csvFilePath -Append -NoTypeInformation }
问题原因
Invoke-Sqlcmd将PartNo列中类似xxxx-x-x的值误识别为DateTime类型,终端输出时PowerShell会自动转为字符串显示(保持原格式),但Export-Csv导出时会按照系统默认日期格式(斜杠分隔)输出,导致格式异常。
解决方案
方法一:SQL查询中强制转换字段类型
修改SELECT语句,将PartNo转为字符串类型,从源头避免类型识别错误:
# 修正后的查询语句 $queryEngParts = "SELECT [PartRn], CAST([PartNo] AS VARCHAR(255)) AS [PartNo], [Title], [CompanyId] FROM [NIMS_Eng].[dbo].[EngParts] WHERE PartRn = $partRn"
方法二:PowerShell中强制转换字段类型
如果无法修改SQL查询,可在导出前将PartNo字段强制转为字符串:
# 替换原导出代码 $invokeSql | ForEach-Object { # 强制将PartNo转为字符串,覆盖原有类型 $_ | Add-Member -MemberType NoteProperty -Name 'PartNo' -Value ([string]$_.PartNo) -Force return $_ } | Export-Csv -Path $csvFilePath -Append -NoTypeInformation
优化建议:批量导出提升效率
原循环中每次Append导出CSV效率较低,建议先收集所有数据再一次性导出:
Import-Module ImportExcel $dataFile = Import-Excel -Path "C:\Desktop\Scripts\Aras\Copy of Part RN Sample Export - 11-11-23.xlsx" $server = "ServerName" $database = "DatabaseName" $csvFilePath="C:\Desktop\Scripts\Aras\CSVOutput\Output_EngParts.csv" $allResults = @() ForEach ($partRnItem in $dataFile){ Write-host $partRnItem.PartRN $partRn = $partRnItem.PartRN $queryEngParts = "SELECT [PartRn], CAST([PartNo] AS VARCHAR(255)) AS [PartNo], [Title], [CompanyId] FROM [NIMS_Eng].[dbo].[EngParts] WHERE PartRn = $partRn" $invokeSql = Invoke-Sqlcmd -ServerInstance $server -Database $database -Query $queryEngParts $allResults += $invokeSql } # 一次性导出所有数据 $allResults | Export-Csv -Path $csvFilePath -NoTypeInformation
内容的提问来源于stack exchange,提问作者Brute
相关产品推荐
相关产品推荐

