MySQL数据库读取器的Powershell Export-CSV在中间导出失败

时间:2018-07-27 17:10:24

标签: mysql powershell csv mysqldatareader

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

我想获得一个从MySQL导出到CSV的进度条,因此我使用了数据读取器来实现这一点。它可以正常工作,然后开始导出,但是在导出过程中的某个位置(大约450万的记录5,000中-不一致)会抛出错误:

  

使用“ 0”参数调用“ Read”的异常:“在读取数据时遇到致命错误。”异常调用参数“ 0”的“ Close”:“ 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

编辑:无效,但我还将此行添加到了我的连接字符串中:MySQL timeout in powershell中的defaultcommandtimeout=600;connectiontimeout=25

2 个答案:

答案 0 :(得分: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....

答案 1 :(得分:0)

不是我找到了解决方案,但是没有任何更改连接字符串的方法。手动设置超时似乎也无济于事。它似乎是由于返回的行过多而导致的,因此我分拆了要分批运行的函数,并随即追加到CSV文件中。这消除了IO /超时错误。