2017-02-02 23 views
0

- 私でMS SQL Serverの例外ユーザー・メッセージを取得します。は私のDelphiアプリケーションからSQL ServerデータベースにアクセスするためにDatasnap.DBClientを使用してDelphiの例外

私は私のアプリですべての例外をログに記録するロガーを持っていますが、 - 私は、SQLの例外メッセージは本当にunfriendliesを見つけます。

例:私はDelphiでSQL例外をキャッチすると、私が得るメッセージは次のとおりです。

最初の1、例外:

EOleException: SQL State: 42S22, SQL Error Code: 207

私はSQLプロファイラでトレースを開くと、私は2つのメッセージを取得します、

Exception: Error: 207, Severity: 16, State: 1

第二の一つである:はアプリが示す同じメッセージである

User Error Message: Invalid column name 'Column1'

UserErrorMessage私のDelphiアプリケーションでは、キャッチされた例外からですか?

答えて

3

AdoまたはDBExpressを使用しているかどうかはわかりませんが、DBExpressの場合は、おそらく質問はしません(下記の更新を参照)。

TAdoConnectionにはErrorsオブジェクトがあります(AdoInt.Pasの定義を参照)。

uses [...] AdoInt, AdoDB, [...] 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    S : String; 
    IErrors : Errors; 
    IError : Error; 
    ErrorCount : Integer; 
    i : Integer; 
begin 
    S := 'exec spRaiseError ' + Edit1.Text; 
    AdoQuery1.SQL.Text := S; 
    try 
    AdoQuery1.Open; 
    except 
    IErrors := AdoConnection1.Errors; 
    ErrorCount := IErrors.Count; 
    for i := 0 to ErrorCount - 1 do begin 
     IError := IErrors.Item[i]; 
     S := Format('error: %d, source: %s description: %s', [i, IError.Source, IError.Description]); 
     Memo1.Lines.Add(S); 
    end; 
    Caption := IntToStr(ErrorCount); 
    end; 
end; 

あなたはそれを試してみる場合は、あなたが見つける必要があります。 にそれを調査し、私は私のDelphiのコードで、私はこのような何かを持っている、そして、

create PROCEDURE [dbo].[spRaiseError](@AnError int) 
AS 
BEGIN 
    declare @Msg Char(20) 
    if @AnError > 0 
    begin 
     Select @Msg = 'MyError ' + convert(Char(8), @AnError) 
     RaisError(@Msg, 16, -1) 
    end 
    else 
    select 1 
END 

として定義されているサーバー上のストアドプロシージャを使用しましたそれは第2のメッセージをキャプチャする必要がありますErrorsコレクション の内容は累積的であることを、あなたは後にしています。しかし、「Datasnap dbclient」を使用しているとはどういう意味ですか?「DBClient」はTClientDataSetを宣言するユニットですが、ADOまたはDBExpressで使用している可能性があります。私はDBX SQL Serverのドライバを使用すると、DBXコンポーネントを使用してで取得することができAdoConnectionsエラーコレクションへの対応を持っていることはよく分かりません。

error: 0, source: Microsoft OLE DB Provider for SQL Server description: Invalid column name 'aname'.

が、それは報告しません:私は意図的に「ANAME」、存在しない列を参照するSELECTを行う場合は、上記のコードを使用して

更新は、私がMEMO1でこれを取得しますエラー207が表示されます。

私は、次のように、のSQLQueryに接続ClientDataSetのを開くと、私はDBXプロジェクトやトラップに例外を同じSELECTない場合:

procedure TForm1.Button1Click(Sender: TObject); 
var 
    S : String; 
begin 
    S := 'select id, aname from atable'; 
    ClientDataSet1.CommandText := S; 
    try 
    ClientDataSet1.Open; 
    except 
    Memo1.Lines.Add(Exception(ExceptObject).Message); 
    end; 
end; 

私はこの

SQL State: 42000, SQL Error Code: 8180 Statement(s) could not be prepared. SQL State: 42S22, SQL Error Code: 207 Invalid column name 'aname'.

を取得いくつかの点ではもう少し有益です。同時に、あなたのロギング機能は、これを記録します

Fecha: 2017-02-03 18:44:02 
Sesion: {2E7176CB-56FD-41C4-BE67-7B9E1D3486B4} 
Proyecto: dbxerrors.exe 
Aplicación:  
Ruta: D:\aaad7\Ado\ 
Usuario: ??? 
Error: SQL State: 42000, SQL Error Code: 8180 
Statement(s) could not be prepared. 
SQL State: 42S22, SQL Error Code: 207 
Invalid column name 'aname'. 

Exception EDatabaseError: SQL State: 42000, SQL Error Code: 8180 
Statement(s) could not be prepared. 
SQL State: 42S22, SQL Error Code: 207 
Invalid column name 'aname'. 

    Exception 
    UnitName : 
    Procedure : 
    Line : 0 
    BinaryFileName : 


Fecha: 2017-02-03 18:44:02 
Sesion: {2E7176CB-56FD-41C4-BE67-7B9E1D3486B4} 
Proyecto: dbxerrors.exe 
Aplicación:  
Ruta: D:\aaad7\Ado\ 
Usuario: ??? 
Error: SQL State: 42000, SQL Error Code: 8180 
Statement(s) could not be prepared. 
SQL State: 42S22, SQL Error Code: 207 
Invalid column name 'aname' 
Exception EOleException: SQL State: 42000, SQL Error Code: 8180 
Statement(s) could not be prepared. 
SQL State: 42S22, SQL Error Code: 207 
Invalid column name 'aname' 
    Exception 
    UnitName : 
    Procedure : 
    Line : 0 
    BinaryFileName : 

ことができます場合は、あなたが見ることができるように、これは私のテストプロジェクトのDFM

object SQLConnection1: TSQLConnection 
    ConnectionName = 'MSSQLConnection' 
    DriverName = 'MSSQL' 
    GetDriverFunc = 'getSQLDriverMSSQL' 
    LibraryName = 'dbexpmss.dll' 
    LoginPrompt = False 
    Params.Strings = (
     'DriverName=MSSQL' 
     'HostName=MAT410\ss2014' 
     'DataBase=MATest' 
     'User_Name=sa' 
     'Password=sa' 
     'BlobSize=-1' 
     'ErrorResourceFile=' 
     'LocaleCode=0000' 
     'MSSQL TransIsolation=ReadCommited' 
     'OS Authentication=False') 
    VendorLib = 'oledb' 
    Left = 40 
    Top = 32 
    end 
    object SQLQuery1: TSQLQuery 
    MaxBlobSize = -1 
    Params = <> 
    SQLConnection = SQLConnection1 
    Left = 88 
    Top = 32 
    end 
    object DataSetProvider1: TDataSetProvider 
    DataSet = SQLQuery1 
    Options = [poAllowCommandText] 
    Left = 136 
    Top = 32 
    end 
    object ClientDataSet1: TClientDataSet 
    Aggregates = <> 
    Params = <> 
    ProviderName = 'DataSetProvider1' 
    Left = 184 
    Top = 32 
    end 

の部分的な抽出物である、それはかなりミニマルです。 DelphiのバージョンはWin10 64ビットのD7で、サーバーはSQL Server 2014です。

+0

ありがとう@MartynA。私はDBExpressを使用しています。答えの終わりに、その説明をどうやって得ましたか? – Andres

+0

私は実際にJCLDebuggerで例外を取得していますが、私はそれをキャッチする以外は試していません。アイデアは、すべてのSQLエラーをテキストファイルに記録することです。 – Andres

+1

@Andres: "あなたは答えの最後にその説明をどうやって得ましたか"私の答えに追加したコードを見てください。 – MartynA

関連する問題