1

列を最大長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)

...私の悩みは私の解決策よりも速いペースで増加しています...はぁ...

4

2 に答える 2

1

うわー、これは厄介です。SQL SELECT ステートメントを変更して、オーバーフローの原因となっている可能性のあるテキスト フィールドごとに、フィールドの定義された長さSUBSTRING(1, n)を実行できますか? n各フィールドのすべてのデータを取得することはできませんが (これはそもそも不適切なデータです)、少なくとも例外は停止する可能性があります。

申し訳ありませんが、私は ProgressDB の専門家ではないので、T-SQL の観点からソリューションを組み立てています。

于 2012-04-17T21:00:08.687 に答える
0

進行中のテーブルの定義には width と呼ばれるフィールドがあり、ここで sql または odbc ソースの長さが定義されています。このフィールドは、すべてのデータを収めるのに十分な長さである必要があります。そうしないと、そのエラーが発生することになります。

于 2013-10-03T15:27:27.497 に答える