列を最大長xの文字列として定義する ProgressDB テーブルを使用していますが、形状やフォームが実際にこの制限を強制することは決してありません。定義された列の長さよりも列のデータが大幅に大きいケースをいくつか発見しました。(それが可能でさえあることを発見するのは不快なショックでした)。データベース側でこれらの制約を強制する方法があると考えられますが、現時点では多くの理由から実用的ではありません。
私のアプリケーションは、そのような不正なデータを含む行に遭遇すると、かなり壮観な方法で爆発します。行読み取りレベルで例外をキャッチできますが、文字列データを操作していて長さはまったく気にしないので、行を読み取って例外を無視したいのです。
IDataReader
インターフェイスを使用してこれを行う方法はありますか? これらは大規模なデータセットであり、それを操作することはDataTable
現実的な解決策ではありません。
更新これは興味深い(イライラする)ことです:私は次のIDataReader.Read()
ように悪いことをキャプチャしようとしました:
var reading = true;
do
{
try
{
reading = r.Read();
if (reading)
{
var columns = new string[columnCount - 1];
try
{
for (int i = 0; i < (columnCount - 1); i++)
{
columns[i] = Convert.ToString(r.GetValue(i));
}
writer.Write(string.Join(this.ColumnDelimiter, columns) + this.RowDelimiter);
}
catch (Exception ex)
{
Log.Error(string.Format("Exception dumping table {0}. At the point of the error, the columns resembled:\r\n{1}\r\n\r\nThe exception was: {2}",
this.TableName, string.Join(this.ColumnDelimiter, columns.Select(c => c ?? string.Empty).ToArray()), ex.ToString()), ex);
}
}
}
catch(Exception ex)
{
Log.Error("Error reading row.", ex);
}
} while (reading);
...しかし、これを実行すると、アプリケーションはキャッチされない例外を吐き出しました:
2012-04-17 16:14:22,863 [1] ERROR GHM.ODBCSqlDump.Parser [(null)] - Error reading row.
System.Data.Odbc.OdbcException (0x80131937): ERROR [HY000] [DataDirect][ODBC Progress OpenEdge Wire Protocol driver][OPENEDGE]Column [ColumnName] in table [TableName] has value exceeding its max length or precision.
at System.Data.Odbc.OdbcConnection.HandleError(OdbcHandle hrHandle, RetCode retcode)
at System.Data.Odbc.OdbcDataReader.Read()
at GHM.ODBCSqlDump.Parser.Execute(Stream streamOut)
Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at System.Data.Common.UnsafeNativeMethods.SQLFetch(OdbcStatementHandle StatementHandle)
at System.Data.Odbc.OdbcStatementHandle.Fetch()
at System.Data.Odbc.OdbcDataReader.Read()
at GHM.ODBCSqlDump.Parser.Execute(Stream streamOut)
at GHM.DatabaseDump.Executor.ExecuteGroup(TransferGroup group)
at GHM.DatabaseDump.Executor.Execute()
at GHM.DatabaseDump.Program.Main(String[] args)
...私の悩みは私の解決策よりも速いペースで増加しています...はぁ...