1

我对 PowerShell 有点陌生,我有一个新的要求,就是将数据从 MySQL 数据库中取出并放入 Oracle 数据库中。我选择的策略是输出到 CSV,然后将 CSV 导入 Oracle。

我想获得一个从 MySQL 导出到 CSV 的进度条,所以我使用数据阅读器来实现这一点。它可以工作,并开始导出,但在导出过程中的某个地方(大约 450 万的记录 5,000 -不一致)它会抛出一个错误:

使用“0”参数调用“读取”的异常:“数据读取期间遇到致命错误。” 使用“0”参数调用“关闭”的异常:“IO 操作超时”方法调用失败,因为 [System.Management.Automation.PSObject] 不包含名为“op_Addition”的方法。使用“0”参数调用“ExecuteReader”的异常:“CommandText 属性尚未正确初始化。”

适用的代码块如下。我不确定我在这里做错了什么,如果有任何反馈,我将不胜感激。这几天我一直在拉头发。

注释: $tableObj是一个自定义对象,有几个字符串字段来保存表名和 SQL 值。此处未显示这些 SQL 查询,但它们有效。

Write-Host "[INFO]: Gathering data from MySQL select statement..."
$conn = New-Object MySql.Data.MySqlClient.MySqlConnection
$conn.ConnectionString = $MySQLConnectionString
$conn.Open()

#
# Get Count of records in table
#
$countCmd = New-Object MySql.Data.MySqlClient.MySqlCommand($tableObj.SqlCount, $conn)
$recordCount = 0
try{
  $recordCount = $countCmd.ExecuteScalar()
} Catch { 
  Write-Host "[ERROR]: (" $tableObj.Table ") Error getting Count."
  Write-Host "---" $_.Exception.Message
  Exit
} 
$recordCountString = $recordCount.ToString('N0')
Write-Host "[INFO]: Count for table '" $tableObj.Table "' is " $recordCountString

#
# Compose the command
#
$cmd = New-Object MySql.Data.MySqlClient.MySqlCommand($tableObj.SqlExportInit, $conn)

#
# Write to CSV using DataReader
#
Write-Host "[INFO]: Data gathered into memory. Writing data to CSV file '" $tableObj.OutFile "'"
$counter = 0 # Tracks items selected
$reader=$cmd.ExecuteReader()
$dataRows = @()
# Read all rows into a hash table
while ($reader.Read())
{
    $counter++
    $percent = ($counter/$recordCount)*100
    $percentString = [math]::Round($percent,3)
    $counterString = $counter.ToString('N0')
    Write-Progress -Activity '[INFO]: CSV Export In Progress' -Status "$percentString% Complete" -CurrentOperation "($($counterString) of $($recordCountString))" -PercentComplete $percent 
    $row = @{}
    for ($i = 0; $i -lt $reader.FieldCount; $i++)
    {
        $row[$reader.GetName($i)] = $reader.GetValue($i)
    }
    # Convert hashtable into an array of PSObjects
    $dataRows += New-Object psobject -Property $row            
}
$conn.Close()
$dataRows | Export-Csv $tableObj.OutFile -NoTypeInformation

编辑:没用,但我也在我的连接字符串中添加了这一行:defaultcommandtimeout=600;connectiontimeout=25per MySQL timeout in powershell

4

2 回答 2

0

使用@Carl Ardiente 的想法,查询超时,您必须将超时设置为疯狂的东西才能完全执行。在开始获取数据之前,您只需设置会话的超时值。

Write-Host "[INFO]: Gathering data from MySQL select statement..."
$conn = New-Object MySql.Data.MySqlClient.MySqlConnection
$conn.ConnectionString = $MySQLConnectionString
$conn.Open()

# Set timeout on MySql

$cmd = New-Object MySql.Data.MySqlClient.MySqlCommand("set net_write_timeout=99999; set net_read_timeout=99999", $conn) 
$cmd.ExecuteNonQuery()

#
# Get Count of records in table
#
...Etc....
于 2018-07-27T18:32:58.380 回答
0

并不是说我找到了解决方案,而是没有任何连接字符串更改起作用。手动设置超时似乎也没有帮助。这似乎是由于返回的行太多造成的,所以我将函数拆分为批量运行,并在运行时附加到 CSV。这消除了 IO / 超时错误。

于 2018-08-07T18:22:10.673 回答