dll调用sql server的存储过程的问题

时间:2021-11-10 04:25:12
下面是我dll调用存储过程的代码
SqlConnection myCn;
SqlCommand myCmd;

myCn = new SqlConnection(CDataAccess.strConn);
myCmd = new SqlCommand("autoCreatCode",myCn);
myCmd.CommandTimeout =30*60;
myCmd.CommandType = CommandType.StoredProcedure;

SqlParameter Outp = new SqlParameter("@strErr",SqlDbType.VarChar,4000);
Outp.Direction = ParameterDirection.Output;

myCmd.Parameters.Add(Outp);

try
{
myCn.Open();
myCmd.ExecuteNonQuery();
strErr =Convert.ToString(Outp.Value);
}
catch(System.Exception e)
{
strErr=strErr+e.Message.ToString();
}
finally
{
myCmd.Dispose();
myCn.Close();
}
问题是我的存储过程中定义了事务,对每一条新插入的纪录,如果成功则提交,失败回滚,错误信息放到输出参数里,现在是如果有四条记录成功了两条,失败两条,按道理是dll不应该报错,但是现在执行到myCmd.ExecuteNonQuery();这句就报错,其实已经成功插入两条记录到数据库,实际是应该接收返回值不应报错,不知为什么,那位高手帮帮忙!

7 个解决方案

#1


这里代码没有问题,你的存储过程代码贴出来。

另外你扑捉到的错误信息是啥??

#2


我的存储过程如下
CREATE  PROCEDURE [dbo].[autoCreatGoods]   @strErr nvarchar(4000) ='' output  AS
declare @strRecdNum  numeric
declare @strCustFSEQ numeric
declare @strCurNum  numeric
declare @strGdCode  nvarchar(16)
--declare @strGdCodeRec  nvarchar(16)
declare @strGdNameC nvarchar(40)
declare @strGdNameE  nvarchar(6)
declare @strGdNameA  nvarchar(8)
declare @strFUMM     nvarchar(14)
declare @strFUMS      nvarchar(14)

declare @ins_error int
set @strErr=''
set nocount on
 --更新客户代码
update wordig set fcompany=b.fcustcode   from wordig a left outer join wordim b on a.fseq=b.fseq where (a.fcompany='' or fcompany  is null)
--更新已有的货品的流水号
update wordig set fgdseq=b.fseq,fgdnamec=b.fnamec  from wordig a left outer join titemm b on a.fgdcode=b.fcode   left outer join tcorpm c on a.fcompany=c.fcode where  c.fseq=b.fcompany  and a.fgdcode=b.fcode
SET CURSOR_CLOSE_ON_COMMIT off
DECLARE Temp_Cust CURSOR static FOR

select b.fseq,a.fgdcode,a.fgdnamec,a.fgdnamee,a.fgdalias,a.fumm,a.fums
from wordig a left outer join tcorpm b on a.fcompany=b.fcode where a.fgdseq is null       and a. fgdnamec is not null  
     open Temp_Cust
set @strRecdNum=@@CURSOR_ROWS
--循环开始
while @strRecdNum>0
begin 

fetch next  from Temp_Cust into  @strCustFSEQ, @strGdCode,@strGdNameC,@strGdNameE,@strGdNameA,@strFUMM,@strFUMS
 
--select @strGdCodeRec=fcode from titemm where fcode=@strGdCode
  DECLARE Temp_Add  CURSOR static FOR
select fcode from titemm where fcode=@strGdCode
  open Temp_Add
--fetch next  from Temp_Add into @strGdCodeRec
set @strCurNum=@@CURSOR_ROWS
close Temp_Add
       DEALLOCATE Temp_Add
if (@strCurNum=0)
begin
BEGIN TRANSACTION 
 insert into titemm (FCOMPANY,FCODE,FNAMEC,FNAMEE,FALIAS,FUMM,FUMS,FFLAG,fst) 
values ( @strCustFSEQ, @strGdCode,@strGdNameC,@strGdNameE,@strGdNameA,@strFUMM,@strFUMS,'Y','U')
set @ins_error=@@ERROR
 if( @ins_error<>0)
begin      
set @strErr=@strErr+'    货品代码:'+@strGdCode+' 生成临时货品出错, 错误代码:'+Cast(@ins_error as nvarchar(10)) +';'
     ROLLBACK TRANSACTION
             end
else  
  begin
 COMMIT  TRANSACTION
end
end
set @strRecdNum=@strRecdNum-1
end
   close Temp_Cust
DEALLOCATE Temp_Cust

--更新已有的货品的流水号
update wordig set fgdseq=b.fseq,fgdnamec=b.fnamec  from wordig a left outer join titemm b on a.fgdcode=b.fcode   left outer join tcorpm c on a.fcompany=c.fcode where  c.fseq=b.fcompany  and a.fgdcode=b.fcode
 set @ins_error=@@ERROR
 if( @ins_error<>0)
  begin
set @strErr=@strErr+'    更新货品代码出错, 错误代码:'+Cast(@ins_error as nvarchar(10)) +';'
end
select  @strErr
return
GO

#3


sql server 中, @@ERROR 返回的是最后一次错误信息。

比如以下代码:

insert ....

update ...
set @ins_error=@@ERROR
if( @ins_error<>0)
begin
set @strErr=@strErr+'    更新货品代码出错, 错误代码:'+Cast(@ins_error as nvarchar(10)) +';'
end

如果 insert 出现错误(等级比较高,不是可以继续下去的错误),或者产生异常, 是不会执行到 set @ins_error=@@ERROR 这一步的。

所以你的错误在存储过程中扑捉不到。

#4


使用 @@ERROR
如果最后的 Transact-SQL 语句执行成功,则 @@ERROR 系统函数返回 0;如果此语句产生错误,则 @@ERROR 返回错误号。每一个 Transact-SQL 语句完成时,@@ERROR 的值都会改变。

因为每个 Transact-SQL 语句执行完毕时,@@ERROR 都会得到一个新的值,@@ERROR 可用以下两种方法处理: 

在 Transact-SQL 语句后,马上检测或使用 @@ERROR。


在 Transact-SQL 语句完成后,马上把 @@ERROR 存储到一个整型变量中。此变量的值可供以后使用。

#5


上上一个说错了,看我上一个的说明。那个是正确的

#6


我是这么做的呀

#7


至少:
update wordig set fcompany=b.fcustcode   from wordig a left outer join wordim b on a.fseq=b.fseq where (a.fcompany='' or fcompany  is null)
--更新已有的货品的流水号
update wordig set fgdseq=b.fseq,fgdnamec=b.fnamec  from wordig a left outer join titemm b on a.fgdcode=b.fcode   left outer join tcorpm c on a.fcompany=c.fcode where  c.fseq=b.fcompany  and a.fgdcode=b.fcode

这两句sql以后 你没有记录 @@Error

#1


这里代码没有问题,你的存储过程代码贴出来。

另外你扑捉到的错误信息是啥??

#2


我的存储过程如下
CREATE  PROCEDURE [dbo].[autoCreatGoods]   @strErr nvarchar(4000) ='' output  AS
declare @strRecdNum  numeric
declare @strCustFSEQ numeric
declare @strCurNum  numeric
declare @strGdCode  nvarchar(16)
--declare @strGdCodeRec  nvarchar(16)
declare @strGdNameC nvarchar(40)
declare @strGdNameE  nvarchar(6)
declare @strGdNameA  nvarchar(8)
declare @strFUMM     nvarchar(14)
declare @strFUMS      nvarchar(14)

declare @ins_error int
set @strErr=''
set nocount on
 --更新客户代码
update wordig set fcompany=b.fcustcode   from wordig a left outer join wordim b on a.fseq=b.fseq where (a.fcompany='' or fcompany  is null)
--更新已有的货品的流水号
update wordig set fgdseq=b.fseq,fgdnamec=b.fnamec  from wordig a left outer join titemm b on a.fgdcode=b.fcode   left outer join tcorpm c on a.fcompany=c.fcode where  c.fseq=b.fcompany  and a.fgdcode=b.fcode
SET CURSOR_CLOSE_ON_COMMIT off
DECLARE Temp_Cust CURSOR static FOR

select b.fseq,a.fgdcode,a.fgdnamec,a.fgdnamee,a.fgdalias,a.fumm,a.fums
from wordig a left outer join tcorpm b on a.fcompany=b.fcode where a.fgdseq is null       and a. fgdnamec is not null  
     open Temp_Cust
set @strRecdNum=@@CURSOR_ROWS
--循环开始
while @strRecdNum>0
begin 

fetch next  from Temp_Cust into  @strCustFSEQ, @strGdCode,@strGdNameC,@strGdNameE,@strGdNameA,@strFUMM,@strFUMS
 
--select @strGdCodeRec=fcode from titemm where fcode=@strGdCode
  DECLARE Temp_Add  CURSOR static FOR
select fcode from titemm where fcode=@strGdCode
  open Temp_Add
--fetch next  from Temp_Add into @strGdCodeRec
set @strCurNum=@@CURSOR_ROWS
close Temp_Add
       DEALLOCATE Temp_Add
if (@strCurNum=0)
begin
BEGIN TRANSACTION 
 insert into titemm (FCOMPANY,FCODE,FNAMEC,FNAMEE,FALIAS,FUMM,FUMS,FFLAG,fst) 
values ( @strCustFSEQ, @strGdCode,@strGdNameC,@strGdNameE,@strGdNameA,@strFUMM,@strFUMS,'Y','U')
set @ins_error=@@ERROR
 if( @ins_error<>0)
begin      
set @strErr=@strErr+'    货品代码:'+@strGdCode+' 生成临时货品出错, 错误代码:'+Cast(@ins_error as nvarchar(10)) +';'
     ROLLBACK TRANSACTION
             end
else  
  begin
 COMMIT  TRANSACTION
end
end
set @strRecdNum=@strRecdNum-1
end
   close Temp_Cust
DEALLOCATE Temp_Cust

--更新已有的货品的流水号
update wordig set fgdseq=b.fseq,fgdnamec=b.fnamec  from wordig a left outer join titemm b on a.fgdcode=b.fcode   left outer join tcorpm c on a.fcompany=c.fcode where  c.fseq=b.fcompany  and a.fgdcode=b.fcode
 set @ins_error=@@ERROR
 if( @ins_error<>0)
  begin
set @strErr=@strErr+'    更新货品代码出错, 错误代码:'+Cast(@ins_error as nvarchar(10)) +';'
end
select  @strErr
return
GO

#3


sql server 中, @@ERROR 返回的是最后一次错误信息。

比如以下代码:

insert ....

update ...
set @ins_error=@@ERROR
if( @ins_error<>0)
begin
set @strErr=@strErr+'    更新货品代码出错, 错误代码:'+Cast(@ins_error as nvarchar(10)) +';'
end

如果 insert 出现错误(等级比较高,不是可以继续下去的错误),或者产生异常, 是不会执行到 set @ins_error=@@ERROR 这一步的。

所以你的错误在存储过程中扑捉不到。

#4


使用 @@ERROR
如果最后的 Transact-SQL 语句执行成功,则 @@ERROR 系统函数返回 0;如果此语句产生错误,则 @@ERROR 返回错误号。每一个 Transact-SQL 语句完成时,@@ERROR 的值都会改变。

因为每个 Transact-SQL 语句执行完毕时,@@ERROR 都会得到一个新的值,@@ERROR 可用以下两种方法处理: 

在 Transact-SQL 语句后,马上检测或使用 @@ERROR。


在 Transact-SQL 语句完成后,马上把 @@ERROR 存储到一个整型变量中。此变量的值可供以后使用。

#5


上上一个说错了,看我上一个的说明。那个是正确的

#6


我是这么做的呀

#7


至少:
update wordig set fcompany=b.fcustcode   from wordig a left outer join wordim b on a.fseq=b.fseq where (a.fcompany='' or fcompany  is null)
--更新已有的货品的流水号
update wordig set fgdseq=b.fseq,fgdnamec=b.fnamec  from wordig a left outer join titemm b on a.fgdcode=b.fcode   left outer join tcorpm c on a.fcompany=c.fcode where  c.fseq=b.fcompany  and a.fgdcode=b.fcode

这两句sql以后 你没有记录 @@Error