MS Access 使用 Powershell 脚本插入 UTF-8
MS Access insert UTF-8 with Powershell script
我有一个带有西班牙变音符号的 UTF-8 格式的 CSV 文件,如果我从 Access 加载它并且 select UTF-8 一切都很好。我想自动化我的工作,所以我制作了一个 Powershell 脚本。因为 table 已经创建,所以我无法使用 SELECT *
但 INSERT INTO
加载数据。使用 SELECT *
我可以像 [text;HDR=Yes;CharacterSet=65001;]
一样指定 UTF-8 字符集。我怎样才能用 "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()
我实现了一个没有数据库连接的最低限度示例,因为我没有 MS Access。能不能在电脑上给Import-Csv
指定-Encoding
参数,看看能不能用?
省略此参数会在我的屏幕上呈现乱码。
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
您的代码正确请求 会话范围 使用 UTF-8 编码 并声明:
$PSDefaultParameterValues['*:Encoding'] = 'utf8'
请参阅通过首选项变量 $PSDefaultParameterValues
实现的 参数预设 字典的文档。
因此,在您的情况下,-Encoding UTF8
是 隐含地 在调用具有 -Encoding
参数的任何 cmdlet 时有效,例如 Import-Csv
.
因此:
您的 Import-Csv
调用 确实 将您的 CSV 文件读取为 UTF-8。
但是,您的症状(值未在控制台中正确打印)表明您的 CSV 输入文件实际上不是 UTF-8 编码的。
因此,解决方案是确定CSV文件的实际编码[1]并将其名称传递给
-Encoding
参数:
鉴于您已经确认,您的文件的实际编码是 ANSI(由系统的活动遗留代码页确定的固定单字节编码),在Windows PowerShell:
中使用Default
编码名称
$voters = Import-Csv -Encoding Default -Delimiter ',' -Path C:\Users\Nobody\Desktop\mexico.csv
在PowerShell [Core] 6+中,你实际上需要传递特定的 ANSI代码页e 使用,例如在美式英语系统上是 Windows-1252
(有关支持的代码页列表,请参阅 the docs;使用“.NET 名称”列中的值或来自 "Identifier" 列的数字,但没有前导 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 开头的版本),请参阅 .
[1] 确定文本文件的编码:
注意:在 PowerShell [Core] 6+ 中,Get-Content
正确打印文件的文本 到屏幕 意味着 all cmdlet 将正确解释它;遗憾的是,由于 Windows PowerShell(最高 v5.1 的版本)中的 cmdlet 行为极其不一致,这不一定是正确的; Import-Csv
是一个很好的例子,因为它默认为 ASCII(!) 编码 - 请参阅 了解背景信息。
平台特定 选项:
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:虽然它不会尝试自动检测编码,但它提供了一种方便的方法重新读取不同编码的文件:单击右下角附近的编码名称(状态栏;例如,"UTF-8")和select Reopen with Encoding
,然后选择一个感兴趣的编码;冲洗并重复,直到文本显示正确。
我有一个带有西班牙变音符号的 UTF-8 格式的 CSV 文件,如果我从 Access 加载它并且 select UTF-8 一切都很好。我想自动化我的工作,所以我制作了一个 Powershell 脚本。因为 table 已经创建,所以我无法使用 SELECT *
但 INSERT INTO
加载数据。使用 SELECT *
我可以像 [text;HDR=Yes;CharacterSet=65001;]
一样指定 UTF-8 字符集。我怎样才能用 "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()
我实现了一个没有数据库连接的最低限度示例,因为我没有 MS Access。能不能在电脑上给Import-Csv
指定-Encoding
参数,看看能不能用?
省略此参数会在我的屏幕上呈现乱码。
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
您的代码正确请求 会话范围 使用 UTF-8 编码 并声明:
$PSDefaultParameterValues['*:Encoding'] = 'utf8'
请参阅通过首选项变量 $PSDefaultParameterValues
实现的 参数预设 字典的文档。
因此,在您的情况下,-Encoding UTF8
是 隐含地 在调用具有 -Encoding
参数的任何 cmdlet 时有效,例如 Import-Csv
.
因此:
您的
Import-Csv
调用 确实 将您的 CSV 文件读取为 UTF-8。但是,您的症状(值未在控制台中正确打印)表明您的 CSV 输入文件实际上不是 UTF-8 编码的。
因此,解决方案是确定CSV文件的实际编码[1]并将其名称传递给
-Encoding
参数:
鉴于您已经确认,您的文件的实际编码是 ANSI(由系统的活动遗留代码页确定的固定单字节编码),在Windows PowerShell:
中使用Default
编码名称
$voters = Import-Csv -Encoding Default -Delimiter ',' -Path C:\Users\Nobody\Desktop\mexico.csv
在PowerShell [Core] 6+中,你实际上需要传递特定的 ANSI代码页e 使用,例如在美式英语系统上是 Windows-1252
(有关支持的代码页列表,请参阅 the docs;使用“.NET 名称”列中的值或来自 "Identifier" 列的数字,但没有前导 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 开头的版本),请参阅
[1] 确定文本文件的编码:
注意:在 PowerShell [Core] 6+ 中,Get-Content
正确打印文件的文本 到屏幕 意味着 all cmdlet 将正确解释它;遗憾的是,由于 Windows PowerShell(最高 v5.1 的版本)中的 cmdlet 行为极其不一致,这不一定是正确的; Import-Csv
是一个很好的例子,因为它默认为 ASCII(!) 编码 - 请参阅
平台特定 选项:
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:虽然它不会尝试自动检测编码,但它提供了一种方便的方法重新读取不同编码的文件:单击右下角附近的编码名称(状态栏;例如,"UTF-8")和select
Reopen with Encoding
,然后选择一个感兴趣的编码;冲洗并重复,直到文本显示正确。