再问关于SQL中的错误处理的问题(300分)

  • 主题发起人 萧月禾
  • 开始时间

萧月禾

Unregistered / Unconfirmed
GUEST, unregistred user!
在SQL中有一存储过程,内容为:
if exists(select * from t_table_name)
raiserror('TEST!',16,1)

在Delphi中,执行
try
ADOCommand1.Execute;
except
on E: Exception do
showmessage(e.Message);
end;

发生异常,返回提升:“TEST!”(该表有记录)

但如果在该存储过程中,先执行一SQL语句,再执行上面的语句,如:
Update ...
Set ...

if exists(select * from t_table_name)
raiserror('TEST!',16,1)

在Delphi执行该存储过程,则该异常不返回,怪之
究竟这raiserror是怎么用的?
 
存储过程没问题的。能够返回异常提示。
只要表中没数据肯定会返回你所说的异常。
 
在存储过程中定义一个参数Result,作为返回值,
在Delphi中直接读取该返回值就可以
 
我的目的是为了的得到raiserror()的返回信息呀
 
都有错误返回啊,代码:
delphi:
with dm do
begin
adoquery1.Close ;
adoquery1.SQL.Clear ;
adoquery1.SQL.Add('aaa');
try
adoquery1.ExecSQL ;
except
on e:exception do
ShowMessage(e.Message );
end;
end;

存储过程:
Alter Procedure aaa
/*
(
@parameter1 datatype = default value,
@parameter2 datatype OUTPUT
)
*/
As
update a1 set a='123'
if exists(select * from a1)
raiserror('TEST!',16,1)
return

Alter Procedure aaa
/*
(
@parameter1 datatype = default value,
@parameter2 datatype OUTPUT
)
*/
As
--update a1 set a='123'
if exists(select * from a1)
raiserror('TEST!',16,1)
return

不知是否你说的情况?
 
还有:
with dm do
begin
adoquery1.Close ;
adoquery1.SQL.Clear ;
adoquery1.SQL.Add('update a1 set a=''123''');
adoquery1.SQL.Add('if exists(select * from a1)');
adoquery1.SQL.Add('raiserror(''TEST!'',16,1)');
try
adoquery1.ExecSQL ;
except
on e:exception do
ShowMessage(e.Message );
end;
end;

with dm do
begin
ADOStoredProc1.Close ;
ADOStoredProc1.ProcedureName:='aaa';
ADOStoredProc1.Prepared :=true;
try
ADOStoredProc1.ExecProc ;
except
on e:exception do
ShowMessage(e.Message );
end;
end;
还有
with dm do
begin
ADOCommand1.CommandText :='aaa' ;
ADOCommand1.Prepared :=true;
try
ADOCommand1.Execute ;
except
on e:exception do
ShowMessage(e.Message );
end;
end;

都很好的返回了错误:test!
 
1、去掉“if exists(select * from a1)”是否还能返回raiserror的内容
2、如果“update a1 set a='123'”出错,是否还能继续执行“if exists(select * from a1)”
 
惊闻萧大侠散分,老兄我。。。顶!!!
 
谁说我散分??
我是真心诚意问问题的[:(]
 
62. Delphi中获得BDE、ADO的错误号
Delphi的数据库对象,如Ttable和TadoTable有以下一些Error事件:OnDeleteError、OnDeleteErro、OnPostError。这些事件的定义如下,都是数据集错误:
type TDataSetErrorEvent = procedure(DataSet: TDataSet; E: EDatabaseError; var Action: TDataAction) of object;
property OnPostError: TDataSetErrorEvent;

在这些事件在EdatabaseError中是无法得到错误号的,其中只有Message属性。在发生BDE错误时可如下得到错误号:
if E is EDBEngineError then
showmessage(inttostr(EDBEngineError(E).Errors[0].ErrorCode));
也可以这么写:
if E is EDBEngineError then
showmessage(inttostr((E As EDBEngineError).Errors[0].ErrorCode));
但在发生ADO错误时不能这样: E is EadoError。
其实Ado错误在数据集相应的数据库连接中都有:TadoConnection.Errors。
procedure TForm1.Table1PostError(DataSet: TDataSet; E: EDatabaseError;
var Action: TDataAction);
var
i:integer;
begin
memo1.Lines.Add(inttostr(table1.Connection.errors.count ));
for i:=0 to AdoConnection1.errors.count-1 do
begin
memo1.Lines.Add('number:'+inttohex(AdoConnection1.errors.Number,8 ));
memo1.Lines.Add('NativeCode:'+inttostr(AdoConnection1.errors.NativeError ));
memo1.Lines.Add(inttostr(AdoConnection1.errors.HelpContext ));
memo1.Lines.Add(AdoConnection1.errors.Source );
memo1.Lines.Add(AdoConnection1.errors.SQLState );
memo1.Lines.Add('Description:'+AdoConnection1.errors.Description );
end;
memo1.Lines.Add('error Msg :'+e.message);
end;
NativeError是Foxpro的原生错误号,非常详细,一般用这个来判断发生的错误。Number是Sql错误号,是大的分类,一般一个Number和多个NativeError对应。
这些错误码的信息在文档Drvvfp.hlp中都有。

 
需要在存储过程中定义一个参数,返回值Result,
再在Delphi中读取返回值
试试
 
只要在 raiserror 函数之前有操作了数据集(在ISQL中运行的时候有 n Rows), Delphi中就不能捕获到失败消息
 
存储过程最前面加上
set nocount on就行了,一直这样用,效率也能增加。
 
今天又学到一招,
 
USE pubs

-- 创建表
IF EXISTS (SELECT name FROM sysobjects
WHERE name = ''ConfinedTable'' AND type = ''U'')
DROP TABLE confinedtable
GO
CREATE TABLE confinedtable ( name char(10), id int, note varchar(255) )

-- 创建触发器
IF EXISTS (SELECT name FROM sysobjects
WHERE name = ''trConfinedTable'' AND type = ''TR'')
DROP TRIGGER trConfinedTable
GO
CREATE TRIGGER trConfinedTable
ON ConfinedTable
FOR INSERT
AS
/* Get the range of level for this job type from the jobs table. */
DECLARE @record_count int
SELECT @record_count = count(1)
FROM ConfinedTable
IF ( @record_count > 3 ) -- 最大记录数为3
BEGIN
RAISERROR (''这张表只能保存3条记录.'',16,1)
ROLLBACK TRANSACTION

END
GO
 
这个问题,我也正在研究,不知道是怎么回事
哪个大侠给系统讲一下,sqlserver的错误处理的机制就好了

 
我这里怎么是这样,自动作为系统提示显示出来,不用再抓异常了
sqlserver2000
 
顶部