2012-01-02 8 views
7

私はもう一度あなたに助けを求めています。今回私は、私が関連付ける問題の大きな特殊性を考えれば、ほんのわずかしか反応しないと信じています。私はDataSnapの世界で始まっていますが、私はこのエラーがどのように関連するか理解できません。Reconcile Error:切り詰められたエラーメッセージに問題があったのは誰ですか?

My DelphiはXE(バージョン1、アップデート1)です。私はポルトガル語(ブラジルポルトガル語)でエラーメッセージを生成するPostgresを使用しています。そのため、エラーメッセージにアクセントがあります。接続コンポーネントはZeosLibパッケージです。

私は、更新のアプリケーションから発生したエラーを表示し、テストするために、既に存在していたレコードを挿入しようとしているため、一意のキーに違反し、エラーダイアログを表示しました。

ダイアログのメモには、表示されるメッセージが切り捨てられています。つまり、切り詰められています。

ERRO: duplicar valor da chave viola a restrição de unicidade "uc_usu_va_login" 
DETAIL: Chave (va_login)=(admin) já existe. 
CONTEXT: comando SQL "INSERT INTO USUARIOS (VA_NOME 
          ,VA_LOGIN 
          ,CH 

をしかし、実際に何を返す必要があることはこれです:それをチェックアウト

ERRO: duplicar valor da chave viola a restrição de unicidade "uc_usu_va_login" 
DETAIL: Chave (va_login)=(admin) já existe. 
CONTEXT: comando SQL "INSERT INTO USUARIOS (VA_NOME 
           ,VA_LOGIN 
           ,CH_SENHA 
           ,VA_EMAIL) 
         VALUES (pVA_NOME 
           ,pVA_LOGIN 
           ,pCH_SENHA 
           ,pVA_EMAIL)" 
    PL/pgSQL function "idu_usuarios" line 7 at comando SQL 

私は問題がzeoslibのかどうかを確認するために、サーバー上でデバッグを行っているが、私は、エラーメッセージことがわかりましたZeosLibがメッセージを切り捨てないことを証明します。すべてがユニコードです。すべての文字列は、私のプログラムとZeosLibのWideString(デフォルト)です。

ご存じのように、サーバー上でスローされる例外は、DataSnapによってクライアントに転送され、クライアントでは、TClientDataSetのReconcileメソッドが問題があるかどうかを確認し、有名な例外をスローします。 EReconcileErrorはTClientDataSetのOnReconcileErrorイベントで処理できるため、メッセージがDataSnapによって切り捨てられていると思います。

クライアントでは、Reconcileメソッド(DBClient.pas)をデバッグし、例外がスローされる直前に、フローが、midas.dll、MidasLib.objというライブラリの一部であると思われるcppソースコード内の関数に入ります。私はこの戦略を使用しているので、私のアプリケーションでDLLを配布する必要はありません。

Check(FDSBase.Reconcile_MD(FReconcileDataSet.FDSBase, FDeltaPacket, VarToDataPacket(Results), Integer(Self), RCB)); 

この呼び出しは、Delphi XE Update1のDBClient.pasユニットの1952行目で行われます。 F7を押すと、デバッガはソースC++(cpp)に入り、midaslib.obj内にあると信じています。どのように私はC + +を理解していない、私は現在のメソッドを終了し、次の命令を返すためにShift-F8を押します、それは既にイベントの中にあるOnReconcileError !!したがって、truncationはmidaslib内のcppソース内で前述した関数内で行わなければなりません。

私の意図は、エラー、詳細、コンテキストの情報を別々に提供することで、最終的なユーザーだけでなく、個人をサポートするためのツールでもあります。これは多くの問題を発見するのに役立ちます。

問題は、メッセージを完全に表示することです。誰かがmidasによって切り詰められたメッセージに関してこの種の問題を抱えていましたか?それは例外に渡されるよう

また別のポイントDSClient.pas私は、エラーメッセージを抽出できます。

'Erro SQL: ERRO: duplicar valor da chave viola a restrição de unicidade "uc_usu_va_login"'#$A'DETAIL: Chave (va_login)=(admin) já existe.'#$A'CONTEXT: comando SQL "INSERT INTO USUARIOS (VA_NOME'#$A'       ,VA_LOGIN'#$A'       ,CH' 

あなたは(空白での#$ A(1文字)を引用符を取り外して交換した場合1つの文字)、文字列が正確に255文字を持っていることがわかります!!

また、dspickle.cppの "GetErrorString"は、bdetypes.hで127(半分255)として定義されている定数DBIMAXMSGLENを使用することも発見しました。 Unicodeの世界では、文字あたり2バイトを持つためにこの値を255に増やすことは問題ではありません。これは単なる推測です...

私はC++を理解するための知識が不足しているため、質問を残しています:)誰が助けることができるのですか.Dspickle.cppの関数実装 "GetErrorString"を見てください。これがあります:

LoadString((HINSTANCE)hDll, iErrCode, pString, DBIMAXMSGLEN) 

pStringは、私はさらに微調整することを決定し、最終的には「和解するの文字数を増やす方法を考え出し他人の意見に矛盾したエラーメッセージとDBIMAXMSGLEN = 127

+0

SQLエラーが発生した場合、通常はエラーメッセージを切り捨てるデータベースプロバイダであり、Delphiコードの範囲を超えています(つまり、Delphiやコードではなくデータベースプロバイダに問題があることを意味します)。 – LaKraven

+0

@LaKraven - どういう意味ですか?完全なエラーメッセージを表示する方法はありませんか? –

+0

このケースでは、データベースプロバイダがエラーメッセージを切り捨てている場合は、はい、完全なメッセージを取得する方法はありません(完全なメッセージを提供するようにプロバイダを再構成できない場合は除きます)。 – LaKraven

答えて

6

です" エラーメッセージ。私は問題がmidas.dllにあると思った、またはより具体的にはmidas.dllを構成するソース。同じソースセットでmidaslibを作成することができます。これはmidas.dllを必要としません。解決するには、私はmidasをコンパイルするためにDelphi C++パーソナリティをインストールしなければなりませんでした。

エラーの行を見つけた後、私は、Embarcaderoのスタッフによって無視されたように見えるQC(http://qc.embarcadero.com/wc/qcmain.aspx?d=84960)の修理の依頼さえあることを発見しました。次のリリースに延期されていますが、リクエストは2010年のものです。私はデルファイXEを使用していますが、私の意見では解決策が必要ですが、ここで私は自分で修正しています)

問題は内部です2133行目のソース "ds.cpp"内の "DSBASE"クラスの "Clone"(Delphi XE、Update1)。以下はコードブロックです。赤線は問題のある線です。

// Set the third field for the error string. 
LdStrCpy((pCHAR)pFldDes->szName, szdsERRMESSAGE); 
pFldDes->iFldType = fldZSTRING; 
pFldDes->iUnits1 = 255; // Increased on request.. DBIMAXMSGLEN; 
pFldDes++; 

問題行は非常に興味深いことに注意してください。それはエラーメッセージのサイズを制限する255の一定値を持ち、コメントは "要求時に増加"します。また、コメントの隣には定数DBIMAXMSGLENがありますが、これはすでに問題の原因となっていると思われますが、使用されていないのでDBIMAXMSGLENの値を変更しましたが、エラーメッセージは常に変更なしで表示されます。 (;)それは、セミコロンがあることを言及する価値があるDBIMAXMSGLEN後にする前に、この行はちょうど私の修正した後だったものだった(とき私は知らない)ことを考えるように私をリード:

​​

それは誰かのようです意図的にフィールドの値を255に設定していました。以前の実装は実際にはダイナミックで一見正しいものが削除されていました。行の置換を実行した後、DBIMAXMSGLENの値を1024に増やしました。DBIMAXMSGLENは定義として "bdetypes.h"と宣言されています。 「ds.cpp」と「bdetypes.h」でこれら二つの変更は、私は、テストを構築し、予想通りの結果だった後

#define DBIMAXMSGLEN   1024   // Max message len 

:エラーメッセージがいっぱいに提示された行を修正した後、次のように行ってきました[Reconcile]ダイアログに表示されます。

この問題を抱えている人は、MIDASのソースが必要です。私が正しく覚えていれば、2010年からDelphiが付属しています。皆さんお元気で。

+1

誰かが:) –

+0

@SertacAkyuz - 正確に;) –

+0

私はさらに進んで、midas(ハイパーベースに基づく)の独自の実装では、keepの問題を解決することに決め、基になるフィールドのタイプを文字列からメモに変更しました – vavan