gpt4 book ai didi

sql-server - 在 Delphi 异常中获取 MS SQL Server 异常用户消息

转载 作者:行者123 更新时间:2023-12-03 19:25:05 27 4
gpt4 key购买 nike

我正在使用 Datasnap.DBClient 从我的 Delphi 应用程序访问 SQL Server 数据库。

我有一个记录器可以记录我的应用程序中的每个异常,但我发现 SQL 异常消息真的很不友好。

示例:当我在 Delphi 中捕获 SQL 异常时,我得到的消息是:

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



如果我在 SQL Profiler 中打开跟踪,我会收到两条消息:

第一个, 异常(exception) 与应用程序显示的消息相同:

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



第二个,是:

User Error Message: Invalid column name 'Column1'



有没有可能得到这个 用户错误消息 从我的 Delphi 应用程序中捕获的异常?

最佳答案

我不确定您使用的是 Ado 还是 DBExpress,但如果是 DBExpress,您可能不会问这个问题(请参阅下面的更新)。
TAdoConnection有一个 Errors对象(参见 AdoInt.Pas 中的定义)。到
调查一下,我在服务器上使用了一个存储过程,定义为

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

然后,在我的 Delphi 代码中,我有这样的东西:
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;

如果你试一试,你应该会发现 Errors 的内容收藏
是累积的,因此它应该捕获您之后的第二条消息。但是,当您说您正在使用“Datasnap dbclient”时,我并不完全确定您的意思:“DBClient”是声明 TClientDataSet 的单元,但您可能将它与 ADO 或 DBExpress 一起使用。我不确定 DBX Sql Server 驱动程序是否与您可以通过使用 DBX 组件获得的 AdoConnections Errors 集合对应。

更新 使用上面的代码,如果我执行一个 SELECT 故意引用一个不存在的列“aname”,我会在 Memo1 中得到这个:

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



,但它不会报告您得到的错误 207。

如果我在 DBX 项目中执行相同的 SELECT 并在打开连接到 SqlQuery 的 ClientDataSet 时捕获异常,如下所示:
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。

关于sql-server - 在 Delphi 异常中获取 MS SQL Server 异常用户消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42004554/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com