私はもう一度あなたに助けを求めています。今回私は、私が関連付ける問題の大きな特殊性を考えれば、ほんのわずかしか反応しないと信じています。私は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
SQLエラーが発生した場合、通常はエラーメッセージを切り捨てるデータベースプロバイダであり、Delphiコードの範囲を超えています(つまり、Delphiやコードではなくデータベースプロバイダに問題があることを意味します)。 – LaKraven
@LaKraven - どういう意味ですか?完全なエラーメッセージを表示する方法はありませんか? –
このケースでは、データベースプロバイダがエラーメッセージを切り捨てている場合は、はい、完全なメッセージを取得する方法はありません(完全なメッセージを提供するようにプロバイダを再構成できない場合は除きます)。 – LaKraven