MS Access 使用 Powershell 脚本插入 UTF-8
Posted
技术标签:
【中文标题】MS Access 使用 Powershell 脚本插入 UTF-8【英文标题】:MS Access insert UTF-8 with Powershell script 【发布时间】:2020-03-20 11:38:33 【问题描述】:我有一个带有西班牙变音符号的 CSV 文件 UTF-8 格式,如果我从 Access 加载它并选择 UTF-8 一切都很好。我想自动化我的工作,所以我制作了一个 Powershell 脚本。因为表已经创建,所以我无法使用SELECT *
但INSERT INTO
加载数据。使用SELECT *
,我可以指定UTF-8 字符集,如[text;HDR=Yes;CharacterSet=65001;]
。如何使用“INSERT INTO”做到这一点?
到目前为止我的代码(工作但 utf-8 字符乱码):
$PSDefaultParameterValues['*:Encoding'] = 'utf8'
$connectstring = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=C:\Users\Nobody\Desktop\Mexico-test.accdb"
$conn = New-Object System.Data.OleDb.OleDbConnection($connectstring)
$conn.Open()
$Voters = Import-Csv -Delimiter "," -Path "C:\Users\Nobody\Desktop\mexico.csv"
foreach ($Voter in $Voters)
$curp = $Voter.curp
$age = $Voter.age
$forename = $Voter.forename
$middlename = $Voter.middlename
$surname = $Voter.surname
$fatherSurname = $Voter.fatherSurname
$motherSurname = $Voter.motherSurname
$cmd = $conn.CreateCommand()
$cmd.CommandText="INSERT INTO voters(curp,age,forename,middlename,surname,fatherSurname,motherSurname) VALUES('$curp','$age','$forename','$middlename','$surname','$fatherSurname','$motherSurname')"
$cmd.ExecuteNonQuery()
$conn.Close()
【问题讨论】:
对***.com/a/40098904/229367的任何建议有帮助吗? 我认为与 Powershell 无关。 您是否尝试将从文件中读取的值打印到控制台?它们显示正确吗? 似乎无法向控制台显示:Campo L�pez
应该是 Campo López
这意味着 C:\Users\Derecha\Desktop\table.csv
实际上不是 UTF-8 - 您需要确定实际编码并将其与 -Encoding
匹配;例如,在 Windows PowerShell 中尝试 -Encoding Default
。
【参考方案1】:
您的代码通过以下语句正确请求会话范围使用 UTF-8 编码:
$PSDefaultParameterValues['*:Encoding'] = 'utf8'
查看通过首选项变量$PSDefaultParameterValues
实现的参数预设字典的文档。
因此,在您的情况下,-Encoding UTF8
在调用任何具有-Encoding
参数(例如Import-Csv
)的 cmdlet 时隐式生效。
因此:
您的Import-Csv
调用确实将您的 CSV 文件读取为 UTF-8。
但是,您的症状(控制台中的值未正确打印)表明您的 CSV 输入文件实际上不是 UTF-8 编码的。
因此,解决方案是确定 CSV 文件的实际编码[1] 并将其名称传递给-Encoding
参数强>:
鉴于您已经确认,您的文件的实际编码是 ANSI(由系统的活动旧代码页确定的固定单字节编码),请使用 @987654335 Windows PowerShell 中的@编码名称:
$voters = Import-Csv -Encoding Default -Delimiter ',' -Path C:\Users\Nobody\Desktop\mexico.csv
在 PowerShell [Core] 6+ 中,您实际上需要传递使用的特定 ANSI 代码页e,这在美国英语例如,systems 是Windows-1252
(有关支持的代码页列表,请参阅the docs;使用“.NET 名称”列中的值或“标识符”列中的数字,但没有前导0
)。
# Use the Windows-1252 ANSI encoding.
$voters = Import-Csv -Encoding 1252 -Delimiter ',' -Path C:\Users\Nobody\Desktop\mexico.csv
注意:从 v7.0 开始,对 Default
编码名称引用活动 ANSI 代码页的支持莫名其妙地没有实现 - 请参阅 this GitHub issue;如果您希望看到这种变化,请在那里听到您的声音。
有关 PowerShell 中编码行为的全面概述 以及它在 Windows PowerShell(最高 v5.1 的版本)和 PowerShell [Core](从 v6 开始的版本)之间的变化,请参阅 @987654324 @。
[1] 确定文本文件的编码:
注意:在 PowerShell [Core] 6+ 中,Get-Content
将文件的文本正确打印到屏幕 意味着 所有 cmdlet 将正确解释它;可悲的是,由于 Windows PowerShell(最高 v5.1 的版本)中 cmdlet 的行为非常不一致,这不一定是正确的; Import-Csv
是一个很好的例子,因为它默认为 ASCII(!) 编码 - 有关背景信息,请参阅 this answer。
平台特定选项:
Windows:
将文件加载到 记事本,在没有 Unicode BOM(签名)的情况下尝试自动检测编码,然后通常可以区分 UTF-8 和 ANSI:查看文本是否正确显示,然后在右下角(状态栏)查看正在显示的编码名称,例如“ANSI”;但是请注意,它无法告诉您可能使用了哪些特定的 ANSI 代码页(如果文件来自不同的文化),因为这通常无法推断。类 Unix 平台(macOS、Linux,包括 WSL):
使用file
实用程序(例如,file mexico.csv
)尝试自动检测编码。
警告:file
错误地将 Windows-1252 识别为 ISO-8859,这并不完全正确 - 它们在很大程度上重叠,但并不完全相同:请参阅 the docs。
跨平台选项:
将您的文件传递给Format-Hex
(例如Format-Hex mexico.csv
)以检查字节值;注意:务必将文件作为参数传递给(隐含的)-Path
参数,而不是通过Get-Content
将其内容传递给Format-Hex
,因为在后一种情况Get-Content
可能已经曲解了文件。
使用 Visual Studio Code:虽然它不会尝试自动检测编码,但它提供了一种方便的方法来重新读取具有不同编码的文件 strong>:点击右下角附近的编码名称(状态栏;例如“UTF-8”)并选择Reopen with Encoding
,然后选择感兴趣的编码;冲洗并重复,直到文本正确显示。
【讨论】:
【参考方案2】:我实现了一个没有数据库连接的最小示例,因为我没有 MS Access。能不能在你的电脑上把-Encoding
参数指定为Import-Csv
看看能不能用?
省略此参数会在我的屏幕上呈现乱码。
C??mo est??s
将其显式指定为 UTF8 会呈现此内容。
Cómo estás
$lines = Import-Csv -Delimiter "," -Path "words.csv" -Encoding utf8
foreach ($line in $lines)
$word = $line
$query = "INSERT INTO voters(word) VALUES('$line')"
Write-Host $query
words.csv
Cómo estás
Dónde estás
quién eres tú
cuando estás llegando
【讨论】:
检查 .csv 本身。在 Sublime Text 等兼容 UTF-8 的文本编辑器中打开它。该文件也必须编码为 UTF-8 格式。 问题,我认为是文件,是 ANSI,UTF-8 显示正常:Cómo estás
请注意@bsteo 的Import-Csv
在问题中的调用隐式 使用-Encoding Utf8
,感谢$PSDefaultParameterValues['*:Encoding'] = 'utf8'
,所以这不是解决方案,而且确实不是't,正如 bsteo 已经证实的那样。由于问题中的代码与您的代码在功能上没有区别,因此这个答案会让未来的读者感到困惑。以上是关于MS Access 使用 Powershell 脚本插入 UTF-8的主要内容,如果未能解决你的问题,请参考以下文章
使用 VBA 或 PowerShell 将所有 MS Access SQL 查询导出到文本文件