sql存储过程异常处理
A. pl/sql存储过程,函数,游标和触发器是什么异常处理什么意思
存储过程:存储过程是一组予编译的SQL语句
它的优点:1.允许模块化程序设计,就是说只需要创建一次过程,以后在程序中就可以调用该过程任意次。
2.允许更快执行,如果某操作需要执行大量SQL语句或重复执行,存储过程比SQL语句执行的要快。
3.减少网络流量,例如一个需要数百行的SQL代码的操作有一条执行语句完成,不需要在网络中发送数百行代码。
4.更好的安全机制,对于没有权限执行存储过程的用户,也可授权他们执行存储过程。
函数:函数是预先定义的功能块(由代码组成)。我们编写函数的目的通常是为了反复调用它(提高代码的复用性)。
游标:游标提供了一种对从表中检索出的数据进行操作的灵活手段,就本质而言,游标实际上是一种能从包括多条数据记录 的结果集中每次提取一条记录的机制。游标总是与一条T_SQL 选择语句相关联因为游标由结果集(可以是零条、一条或由相关的选择语句检索出的多条记录)和结果集中指向特定记录的游标位置组成。当决定对结果集进行处理时,必须声明一个指向该结果集的游标。如果曾经用 C 语言写过对文件进行处理的程序,那么游标就像您打开文件所得到的文件句柄一样,只要文件打开成功,该文件句柄就可代表该文件。对于游标而言,其道理是相同的。可见游标能够实现按与传统程序读取平面文件类似的方式处理来自基础表的结果集,从而把表中数据以平面文件的形式呈现给程序。
触发器:触发器是一种特殊的存储过程,它在试图更改触发器所保护的数据时自动执行。它被定义为在对表或视图发出 UPDATE、INSERT 或 DELETE 语句时自动执行,在有数据修改时自动强制执行其业务规则。触发器可以扩展 SQL Server 约束、默认值和规则的完整性检查逻辑,但只要约束和默认值提供了全部所需的功能,就应使用约束和默认值。
异常处理:异常处理功能提供了处理程序运行时出现的任何意外或异常情况的方法。异常处理使用 try、catch 和 finally 关键字来尝试可能未成功的操作,处理失败,以及在事后清理资源。
异常可以由公共语言运行库 (CLR)、第三方库或使用 throw 关键字的应用程序代码生成。
异常具有以下特点:
1.在应用程序遇到异常情况(如被零除情况或内存不足警告)时,就会产生异常。
2.发生异常时,控制流立即跳转到关联的异常处理程序(如果存在)。
3.如果给定异常没有异常处理程序,则程序将停止执行,并显示一条错误信息。
4.可能导致异常的操作通过 try 关键字来执行。
5.异常处理程序是在异常发生时执行的代码块。在 C# 中,catch 关键字用于定义异常处理程序。
6.程序可以使用 throw 关键字显式地引发异常。
7.异常对象包含有关错误的详细信息,其中包括调用堆栈的状态以及有关错误的文本说明。
8.即使引发了异常,finally 块中的代码也会执行,从而使程序可以释放资源。
异常处理理论上有两种基本模型.
一种称为"终止模型"(它是java与C++所支持的模型).在这种模型中,将假设错误非常关键,将以致于程序无法返回到异常发生的地方继续执行.一旦异常被抛出,就表明错误已无法挽回,也不能回来继续执行.
另一种称为"恢复模型".意思是异常处理程序的工作是修正错误,然后重新尝试调动出问题的方法,并认为的二次能成功.
对于恢复模型,通常希望异常被处理之后能继续执行程序.在这种情况下,抛出异常更像是对方法的调用--可以在Java里用这种方法进行配置,以得到类似恢复的行为.(也就是说,不是抛出异常,而是调用方法修正错误.)或者,把try块放在while循环里,这样就可以不断的进入try块,直到得到满意的结果.虽然恢复模型开始显得很吸引人,并且人们使用的操作系统也支持恢复模型的异常处理,但程序员们最终还是转向了使用类似"终止模型"的代码.因为:处理程序必须关注异常抛出的地点,这势必要包含依赖于抛出位置的非通用性代码.这增加了代码编写和维护的困难,对于异常可能会从许多地方抛出的大型程序来说,更是如此.
B. 存储过程出现 SQL statement ignored错误是什么问题
存储过程出现 SQL statement ignored错误是:存储过程语句错误,字段或变量名可能拼错,导致存储过程无法执行。
解决方法:仔细检查存储过程里的变量,字段,语句等是否正确。
(2)sql存储过程异常处理扩展阅读:
PL/SQL引擎的作用:
编写的SQL语句,通过网络、java程序或者客户端工具发送给关系型数据库管理系统,PL/SQL引擎负责拿到这个字符串(SQL语句就是一个字符串文本格式),对其SQL语句进行语法分析,判断该SQL语句否符合Oracle中的语法要求,若符合,则执行SQL语句。
PL/SQL程序块与SQL语言的功能:
SQL语句
通过多条SQL语句实现功能时,每条语句都需要在客户端和服务端传递,而且每条语句的执行结果也需要在网络中进行交互,占用了大量的网络带宽,消耗了大量网络传递的时间,而在网络中传输的那些结果,往往都是中间结果,而不是我们所关心的。
PL/SQL程序块
而使用PL/SQL程序是因为程序代码存储在数据库中,程序的分析和执行完全在数据库内部进行,用户所需要做的就是在客户端发出调用PL/SQL的执行命令,数据库接收到执行命令后,在数据库内部完成整个PL/SQL程序的执行,并将最终的执行结果反馈给用户。
在整个过程中网络里只传输了很少的数据,减少了网络传输占用的时间,所以整体程序的执行性能会有明显的提高。
参考资料来源:网络-SqlServer
C. sql存储过程中事务出现错误回滚,那么在回滚之后的语句会执行吗
会的。
一般回滚操作都是写在异常处理,或是sql的最后。如果你的sql中出现错误 ,代码会立即跳转到错误处理代码上执行,比如回滚,但紧接在错误行之后的代码不会执行的。
如
1.update .....;
2.select ......;
3.when Exception
....rollback;
4.insert into .....
以上伪代码,如果行1出错,行2将不会执行,直接跳转到行3,然后行4 也会执行。
D. db2的过程中怎样写异常处理
创建SQL存储过程(CREATEPROCEDURE(SQL)statement)
CREATEPROCEDUREprocere-name(IN|OUT|INOUTparameter-namedata-type,...))---存储过程可以设定输入参数和输出参数
LANGUAGESQL----DB2可以用多种语言编写存储过程,这里用的是纯SQL
BEGIN---开始
DECLAREvIDsmallint;---定义变量和Oracle一样DECLARE变量名变量的数据类型;
FORVASSELECTBRND_CDFROMTMP_BRND_CD---for循环tmp_brnd_cd预先创建好
DO---循环体开始
SETvID=BRND_CD;---对vID赋值,db2可以用set赋值,也可以用values赋值,这里可以写成values(BRND_CD)intovID
INSERTINTOWWM_FORINSERT_TESTVALUES(vID);---往wwm_forinsert_test插入数据
ENDFOR;-----循环体结束
END@-----存储过程结束
参数语法说明
1、procere-name:存储过程的名字,在同一个数据库的同一模式下,不能存在存储过程名相同参数数目相同的存储过程,即使参数的类型不同也不行。
2、(IN|OUT|INOUTparameter-namedata-type,...):传入参数IN:输入参数OUT:输出参数INOUT:作为输入输出参数parameter-name:参数名字,在此存储过程中唯一的标识符。data-type:参数类型,可以接收SQL类型和创建的表。不支持LONGVARCHAR,LONGVARGRAPHIC,DATALINK,REFERENCE和用户自定义类型。
3、SPECIFICspecific-name:唯一的特定名称(别名),可以用存储过程名代替,这个特定名称用于dorp存储过程,或者给存储过程添加注视用,但不能调用存储过程。如果不指定,则数据库会自动生成一个yymmddhhmmsshhn时间戳的名字。推荐给出别名。
4、DYNAMICRESULTSETSinteger:指定存储过程返回结果的最大数量。存储过程中虽然没有return语句,但是却能返回结果集。
5、CONTAINSSQL,READSSQLDATA,MODIFIESSQLDATA:指定存储过程中的SQL访问级别CONTAINSSQL:表示存储过程可以执行中,既不可读取SQL数据,也不可修改SQL数据。READSSQLDATA:表示存储过程可以执行中,可读取SQL,但不可修改SQL数据。MODIFIESSQLDATA:表示存储过程可以执行任何SQL语句。可以对数据库中的数据进行增加、删除和修改。
6、:表示存储过程是动态或者非动态的。动态的返回的值是不确定的。非动态的存储过程每次执行返回的值是相同的。
7、CALLEDONNULLINPUT:表示可以调用存储过程而不管任何的输入参数是否为NULL,并且,任何的OUT或者INOUT参数可以返回一个NULL或者非空值。检验参数是否为NULL是在过程中进行的。
8、INHERITSPECIALREGISTERS:表示继承专用寄存器。
9、:建立存储点。OLDSAVEPOINTLEVEL是默认的存储点。
10、LANGUAGESQL:指定程序的主体用的是SQL语言。
11、:表示存储过程是否执行一些改变理数据库状态的活动,而不通过数据库管理器管。默认是EXTERNALACTION。如果指定为NOEXTERNALACTION,则数据库会确定最最佳优化方案。
12、PARAMETERCCSID:指定所有输出字符串数据的编码,默认为UNICODE编码数据库为PARAMETERCCSIDUNICODE,其他的数据库默认为PARAMETERCCSID3ASCII。
13、SQL-procere-body:存储过程的主体
E. 如何在sqlserver 的函数或存储过程中抛出异常
其语法如下:
RAISERROR ( { msg_id | msg_str | @local_variable }
{ ,severity ,state }
[ ,argument [ ,...n ] ]
)
[ WITH option [ ,...n ] ]
简要说明一下:
第一个参数:{ msg_id | msg_str | @local_variable }
msg_id:表示可以是一个sys.messages表中定义的消息代号;
使用 sp_addmessage 存储在 sys.messages 目录视图中的用户定义错误消息号。
用户定义错误消息的错误号应当大于 50000。
msg_str:表示也可以是一个用户定义消息,该错误消息最长可以有 2047 个字符;
(如果是常量,请使用N'xxxx',因为是nvarchar的)
当指定 msg_str 时,RAISERROR 将引发一个错误号为 5000 的错误消息。
@local_variable:表示也可以是按照 msg_str 方式的格式化字符串变量。
第二个参数:severity
用户定义的与该消息关联的严重级别。(这个很重要)
任何用户都可以指定 0 到 18 之间的严重级别。
[0,10]的闭区间内,不会跳到catch;
如果是[11,19],则跳到catch;
如果[20,无穷),则直接终止数据库连接;
第三个参数:state
如果在多个位置引发相同的用户定义错误,
则针对每个位置使用唯一的状态号有助于找到引发错误的代码段。
介于 1 至 127 之间的任意整数。(state 默认值为1)
当state 值为 0 或大于 127 时会生成错误!
第四个参数:argument
用于代替 msg_str 或对应于 msg_id 的消息中的定义的变量的参数。
第五个参数:option
错误的自定义选项,可以是下表中的任一值:
LOG :在错误日志和应用程序日志中记录错误;
NOWAIT:将消息立即发送给客户端;
SETERROR:将 @@ERROR 值和 ERROR_NUMBER 值设置为 msg_id 或 50000;
[SQL]代码示例
--示例1DECLARE @raiseErrorCode nvarchar(50)
SET @raiseErrorCode = CONVERT(nvarchar(50), YOUR UNIQUEIDENTIFIER KEY)
RAISERROR('%s INVALID ID. There is no record in table',16,1, @raiseErrorCode)
--示例2RAISERROR (
N'This is message %s %d.', -- Message text,
10, -- Severity,
1, -- State,
N'number', -- First argument.
5 -- Second argument.
);
-- The message text returned is: This is message number 5.
GO
--示例3RAISERROR (N'<<%*.*s>>', -- Message text.
10, -- Severity,
1, -- State,
7, -- First argument used for width.
3, -- Second argument used for precision.
N'abcde'); -- Third argument supplies the string.
-- The message text returned is: << abc>>.
GO
--示例4RAISERROR (N'<<%7.3s>>', -- Message text.
10, -- Severity,
1, -- State,
N'abcde'); -- First argument supplies the string.
-- The message text returned is: << abc>>.
GO
--示例5
--A. 从 CATCH 块返回错误消息
以下代码示例显示如何在 TRY 块中使用 RAISERROR 使执行跳至关联的 CATCH 块中。
它还显示如何使用 RAISERROR 返回有关调用 CATCH 块的错误的信息。
BEGIN TRY
RAISERROR ('Error raised in TRY block.', -- Message text.
16, -- Severity.
1 -- State.
);
END TRY
BEGIN CATCH
DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;
SELECT
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
RAISERROR (@ErrorMessage, -- Message text.
@ErrorSeverity, -- Severity.
@ErrorState -- State.
);
END CATCH;
--示例6
--B. 在 sys.messages 中创建即席消息
以下示例显示如何引发 sys.messages 目录视图中存储的消息。
该消息通过 sp_addmessage 系统存储过程,以消息号50005添加到 sys.messages 目录视图中。
sp_addmessage @msgnum = 50005,
@severity = 10,
@msgtext = N'<<%7.3s>>';
GO
RAISERROR (50005, -- Message id.
10, -- Severity,
1, -- State,
N'abcde'); -- First argument supplies the string.
-- The message text returned is: << abc>>.
GO
sp_dropmessage @msgnum = 50005;
GO
--示例7
--C. 使用局部变量提供消息文本
以下代码示例显示如何使用局部变量为 RAISERROR 语句提供消息文本。sp_addmessage @msgnum = 50005,
@severity = 10,
@msgtext = N'<<%7.3s>>';
GO
RAISERROR (50005, -- Message id.
10, -- Severity,
1, -- State,
N'abcde'); -- First argument supplies the string.
-- The message text returned is: << abc>>.
GO
sp_dropmessage @msgnum = 50005;
GO
转自博客园: www.cnblogs.com/weixing/p/3930162.html
F. sql存储过程动态Insert参数异常
检查一下表 T_Score_1002的结构,很可能SubSemester列是varchar 类型的。必须保证触发器和存储过程中的@SubSemester变量的类型与表中SubSemester列的类型一致或者兼容。
G. 扫健康码SQL运行异常怎么办
解释如下。
在程序中,有时候完成一些Transact-SQL会出现错误、异常信息。如果我们想自己处理这些异常信息的话,需要手动捕捉这些信息。那么我们可以利用trycatch完成。
TRY?CATCH构造包括两部分:一个TRY块和一个CATCH块。如果在TRY块中所包含Transact-SQL语句中检测到错误条件,控制将被传递到CATCH块(可在此块中处理该错误)。
CATCH块处理该异常错误后,控制将被传递到ENDCATCH语句后面的第一个Transact-SQL语句。如果ENDCATCH语句是存储过程或触发器中的最后一条语句,控制将返回到调用该存储过程或触发器的代码。将不执行TRY块中生成错误的语句后面的Transact-SQL语句。
如果TRY块中没有错误,控制将传递到关联的ENDCATCH语句后紧跟的语句。如果ENDCATCH语句是存储过程或触发器中的最后一条语句,控制将传递到调用该存储过程或触发器的语句。
TRY块以BEGINTRY语句开头,以ENDTRY语句结尾。在BEGINTRY和ENDTRY语句之间可以指定一个或多个Transact-SQL语句。CATCH块必须紧跟TRY块。CATCH块以BEGINCATCH语句开头,以ENDCATCH语句结尾。在Transact-SQL中,每个TRY块仅与一个CATCH块相关联。
H. 如何在SQL存储过程中处理错误
1. 建立一个过程,第一个语句 DECLARE EXIT HANDLER是用来处理异常的,意思是如果错误 1216发生,这个程序将会在错误记录表中插入一行,
EXIT的意思是 当动作成功提交后推出这个复合语句。
create procere p22(parameter int)
begin
declare exit Handler for 1452
insert into error_log values(concat('Time: ',current_date,'.Foreign key reference failure for value=',parameter));
insert into t3 values(parameter);
end;//
2. 申明异常处理的语法 DECLARE HANDLER syntax:
DECLARE {EXIT|CONTINUE} HANDLER FOR {error_number|{SQLSTATE error-string}|condition} SQL Statement
上面就是错误处理的用法,也就是一段当程序出错后自动触发的代码,MYSQL允许两种处理器,一种是exit处理,另外一种是 continue处理,与exit
不同的是在于他执行后,原主程序仍然继续运行,那么该复合语句就没有出口了。
----continue处理的例子:
create table t4(s1 int primary key);//
create procere p23()
begin
declare continue handler for SQLSTATE '23000' set @x2=1;
set @x=1;
insert into t4 values (1);
set @x=2;
insert into t4 values(1);
set @x=3;
select @x, @x2;
end;//
call p23();//
---- rollback(回滚事务),定义自己的错误处理名字 declare '错误处理名' condition for SQLSTATE'23000';
create procere p24()
begin
declare ViolationSelf condition for SQLSTATE'23000';
DECLARE EXIT HANDLER for ViolationSelf rollback;
start transaction;
insert into t2 values(1);
insert into t2 values(1);
commit;
end;//
/******************************************** Cursor游标 **********************************************************/
游标实现功能的摘要: 声明游标, 打开游标,从游标里读取,关闭游标
DECLARE cursor-name CURSOR FOR SELECT ······
OPEN cursor-name;
FETCH cursor-name INTO variable;
CLOSE cursor-name;
1. create procere p25(out return_val int)
begin
DECLARE a,b,c int;
DECLARE cur_1 CURSOR for select s1 from t;
DECLARE continue handler for not found set b=1;
open cur_1;
set c=0;
repeat
fetch cur_1 into a;
until b=1
end repeat;
close cur_1;
set return_val=a;
end;//
2. create procere p25_1(out return_val int)
begin
DECLARE a,b,c int;
DECLARE cur_1 CURSOR for select s1 from t;
DECLARE continue handler for not found set b=1;
open cur_1;
set c=0;
lable_1:loop
fetch cur_1 into a;
if b=1 then
leave lable_1;
end if;
set c=c+1;
end loop;
close cur_1;
set return_val=c;
end;//
create procere p34(in va int)
begin
delete from t where s1=va;
end;//
I. mysql存储过程怎么获取异常信息
DECLARE handler_type HANDLER FOR condition_value[,...] sp_statement
其中,
handler_type的取值范围:CONTINUE | EXIT | UNDO
condition_value的取值范围:SQLSTATE [VALUE] sqlstate_value | condition_name | SQLWARNING | NOT FOUND | SQLEXCEPTION | mysql_error_code
这个语句指定每个可以处理一个或多个条件的处理程序。如果产生一个或多个条件,指定的语句被执行。 对一个CONTINUE处理程序,当前子程序的执行在执行处理程序语句之后继续。对于EXIT处理程序,当前BEGIN...END复合语句的执行被终止。UNDO 处理程序类型语句还不被支持。
· SQLWARNING是对所有以01开头的SQLSTATE代码的速记。
· NOT FOUND是对所有以02开头的SQLSTATE代码的速记。
· SQLEXCEPTION是对所有没有被SQLWARNING或NOT FOUND捕获的SQLSTATE代码的速记。
注:除了SQLSTATE值,MySQL错误代码也不被支持。
例:
delimiter $$
CREATE TABLE `_t1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`val1` varchar(20) DEFAULT NULL,
`val2` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=113 DEFAULT CHARSET=latin1$$
DELIMITER $$
CREATE DEFINER=`abandonship`@`%` PROCEDURE `P_TestException`()
BEGIN
declare _var,_err int default 0;
J. 如何在 SQL Server 的存储过程和函数里进行错误处理
在存储过程中使用事务时非常重要的,使用数据可以保持数据的关联完整性,在Sql server存储过程中使用事务也很简单,用一个例子来说明它的语法格式:
Create Procere MyProcere ( @Param1 nvarchar(10), @param2 nvarchar(10) ) AS BeginSet NOCOUNT ON; Set XACT_ABORT ON; Begin Tran Delete from table1 where name=’abc’; Insert into table2 values(value1,value2,value3); Commit Tran End