1、达梦数据库存储过程的特点doc达梦数据库存储过程的特点达梦数据库允许用户使用系统提供的DMPL/SQL语言创建过程或函数,这些过程或函数象普通的过程或函数一样,有输入、输出参数和返回值,它们与表和视图等数据库对象一样被存储在数据库中,供用户随时调用。存储过程和存储函数在功能上相当于客户端的一段SQL批处理程序,但是在许多方面有着后者无法比拟的优点,它为用户提供了一种高效率的编程手段,成为现代数据库系统的重要特征。25亿网站后台管理系统将存储过程和存储函数统称为存储模块。达梦数据库的存储模块机制是一种技术,而不是一种独立的工具,它是和服务器紧密结合在一起的。可以认为这种技术是执行DMPL/SQL
2、语言的一种机器,它可以接受任何有效的存储模块,按照语言本身所规定的语义执行,并将结果返回给客户。达梦数据库的存储模块机制具有如下优点:1. 提供更高的生产率(1) 在设计应用时,围绕存储过程/函数设计应用,可以避免重复编码,提高生产率;(2) 在自顶向下设计应用时,不必关心实现的细节;(3) 编程方便。2. 便于维护(1) 用户的存储模块在数据库集中存放;(2) 用户可以随时查询、删除它们,而应用程序可以不作任何修改,或只做少量调整。3. 提供更好的性能(1) 存储模块在创建时被编译成伪码序列,在运行时不需要重新进行编译和优化处理,它具有更快的执行速度,可以同时被多个用户调用,并能够减少操作错
3、误;如用sqlserver修改mssql2000的存储过程所有者为dbo,这些小地方还是有些麻烦的。(2) 存储模块在执行时数据对用户是不可见的,提高了数据库的安全性;(3) 存储模块具有更高的可靠性;(4) 存储模块是一种高效访问数据库的机制,网站后台管理模板使用存储模块可减少应用对DM的调用,降低了系统资源浪费,显著提高性能,尤其是在网络上与DM通讯的应用更显著。2.1.4.3 DM与Oracle存储过程对比表操作OracleDM差异基本语法存储过程:CREATE OR REPLACE PROCEDURE procedure_name ( argumentIN | OUT | IN OUT
4、 type,.argumentIN | OUT | IN OUT type) IS | ASprocedure_body其中procedure_name是要创建的过程名,argument是过程的参数名,type是关联参数的类型,procedure_body是构成该过程代码的PL/SQL块。IN,OUT,和IN OUT是参数的模式,如果没有为参数指定模式,则参数缺省的模式是IN。存储函数:CREATE OR REPLACE FUNCTION function_name( argumentIN | OUT | IN OUT type,.argumentIN | OUT | IN OUT type)
5、RETURN return_typeIS | ASfunction_body其中function_name是函数的名称,参数argument和type的含义与过程相同, return_type是函数返回值的类型,function_body是包括函数体的P L / S Q L块。IN , OUT,和IN OUT是参数的模式。如果没有为参数指定模式,则参数缺省的模式是IN。存储过程:CREATE OR REPLACE PROCEDURE ( , )AS | ISEND;存储函数:CREATE OR REPLACE FUNCTION ( , )RETURN AS | ISEND;在存储函数中必须使用
6、RETURN语句向函数的调用环境返回一个值。存储函数不能用CALL语句调用,它只能出现在表达式中。存储函数和存储过程很相似,它们的区别在于:1.存储过程没有返回值,而存储函数有;2.存储过程中可以没有返回语句,而存储函数必须通过返回语句结束;3.存储过程的返回语句中不能带表达式,而存储函数必须带表达式;4.存储过程不能出现在一个表达式中,而存储函数只能出现在表达式中。无创建存储过程CREATE OR REPLACE PROCEDURE ( , ) WITH ENCRYPTION AS | IS BEGIN END; CREATE OR REPLACE PROCEDURE ( , ) WITH
7、ENCRYPTION AS | IS BEGIN END;无撤销存储过程DROP PROCEDURE ;DROP PROCEDURE ;无调用存储过程CALL (,);1. CALL (,);2. EXEC (,);3. (,);DM支持多种调用方式创建存储函数CREATE OR REPLACE FUNCTION ( , ) RETURN WITH ENCRYPTION AS | IS BEGIN END;CREATE OR REPLACE FUNCTION ( , ) RETURN WITH ENCRYPTION AS | IS BEGIN END;无撤销存储函数DROP FUNCTION
8、;DROP FUNCTION ;无调用存储函数SELECT (,);SELECT (,);无PLSQL支持的结构1. 顺序结构;2. 分支结构,包括条件、循环结构等;3. 迭代结构,包括子过程、子函数的调用。1. 顺序结构;2. 分支结构,包括条件、循环结构等;3. 迭代结构,包括子过程、子函数的调用。无语句块结构DECLARE.BEGIN.EXCEPTION.END;语法格式:DECLARE ; BEGINENDDMPL/SQL基本的程序单元;一个语句可以当作一个整体SQL语句对待,允许嵌套,可出现在SQL语句能出现的任何地方。无赋值语句variable := expression;给对象赋
9、值;语法格式:1. :=2. SET =需要注意的是,使用第2种形式时,不需要冒号“:”。DM支持多种赋值方式变量定义variable data_type:=|DEFAULT default_value;1. 在语句块的说明部分可以定义变量、游标、异常变量、子过程或子函数;2. 需要强调的一点是,一个语句块意味着一个作用域范围,也就是说,在一个语句块的说明部分定义的任何对象,其作用域就是该语句块;3. 暂不支持缺省值的定义。ORACLE支持缺省值;DM不支持缺省值;返回语句RETURN;RETURN ;RETURN;RETURN ;1. 结束存储模块的运行,将控制返回给调用者;2. 如果从函数
10、返回,同时返回函数的结果。无退出循环EXIT WHEN condition;EXIT WHEN condition;1. EXIT与循环语句一起使用,用于终止循环语句的执行,将控制转移到循环语句的下一个语句;2. 可以无条件终止循环语句;3. 可以带条件终止循环语句,当检测条件满足时才执行EXIT语句。无IF语句IF THENELSIF ELSIF ELSEEND IF;根据布尔表达式的值,进行程序的分支控制;语法格式:IF THEN;ELSEIF|ELSIF THEN;ELSE ;END IF;注意:ELSEIF与ELSIF两种写法。DM支持两种语法标记循环语句1. WHILEWHILE L
11、OOP;.END LOOP;2. LOOP LOOPstatementsEND LOOP label ;2FORFOR 循环计数器 IN REVERSE 下限 . 上限 LOOP要执行的语句;END LOOP;5. FOR_QUERYFOR loop_name IN LOOP;END LOOP;1. LOOP:循环执行,直至EXIT语句终止;CREATE OR REPLACE PROCUDURE P2AS A INT;BEGIN A := 0; LOOP IF A10 THEN EXIT; ELSE A := A+1; END IF; END LOOP;END;2. WHILE:循环检测执行条
12、件,为TRUE时执行,否则退出;CREATE OR REPLACE PROCEDURE P3ASDECLARE A INT;BEGIN A := 10; WHILE A0 LOOP A := A-1; END LOOP;END;3. FOR:执行指定次数;CREATE OR REPLACE PROCEDURE P4ASDECLARE A INT;BEGIN FOR A IN 1 . 10 LOOP PRINT A; END LOOP;END;4. REPEAT:重复执行,直至达到条件要求。CREATE OR REPLACE PROCEDURE P5ASDECLARE A INT;BEGIN A
13、 := 0; REPEAT A := A+1; UNTIL A10;END;无NULL语句NULL;NULL;1. 不执行任何操作;2. 只用于增强程序的可读性。无打印语句dbms_output.put_line(v_out.xx);PRINT ;打印调试信息,用于调试存储模块。打印语句不同,但不影响整理逻辑性动态语句执行EXECUTE IMMEDIATE commandstringINTO USING IN OUT ;EXECUTE IMMEDIATE commandstringINTO USING IN OUT ;如下例所示:CREATE OR REPLACE PROCEDURE P8AS
14、 V_SQL VARCHAR(2000); V_A INT; V_B INT;BEGIN V_SQL := INSERT INTO T1(A,B) VALUES(?,?); V_A := 10; V_B := 10; EXECUTE IMMEDIATE V_SQL USING V_A,V_B; END;无游标的使用1. 定义游标CURSOR cursor_name(parameter, parameter) IS select_statement;2. 打开游标OPEN cursor_name(parameter = value, parameter= value);OPEN curso_na
15、me FOR query_string USING IN OUTINOUT ;3. 使用游标获取数据FETCH cursor_name INTO variable_list |record_variable ;4. 关闭游标CLOSE cursor_name;5. 游标的属性(1) %FOUND 布尔型属性,当最近一次读记录时成功返回,则值为TRUE;(2) %NOTFOUND 布尔型属性,与%FOUND相反;(3) %ISOPEN 布尔型属性,当游标已打开时返回 TRUE;(4) %ROWCOUNT 数字型属性,返回已从游标中读取的记录数。1. 游标不能作为参数传递,也不能被赋值;2. 游标
16、的四个属性:(1) FOUND:拨动游标,取到数据为真,否则为假;(2) NOTFOUND:拨动游标,取到数据为假,否则为真;(3) ISOPEN:游标打开为真,否则为假;(4) ROWCOUNT:第一次拨动之前为0,否则为拨动游标后已经取得的数据数。3. 游标变量与普通游标不同,游标变量可以指向不同的游标工作区,它为用户提供了更灵活的数据操作方法。定义和打开游标变量的语法与普通游标不同。定义游标变量: CURSOR 打开游标变量: OPEN FOR 或 OPEN FOR USING , 其它的游标操作与普通游标相同。例子如下: CREATE OR REPLACE PROCEDURE curv
17、ar ASc1 CURSOR;vename CHAR(10);vempno NUMERIC(4);vsal NUMERIC(7,2);BEGIN vsal:=2000;OPEN c1 FOR SELECT ENAME, EMPNO FROM OTHER.EMPSALARY where SAL ? USING vsal; LOOPFETCH c1 INTO vename, vempno; EXIT WHEN c1%NOTFOUND;PRINT NAME = | vename | NO = |vempno;END LOOP;CLOSE c1;END;本例中的OPEN语句也可写成如下等价的形式:OP
18、EN c1 FOR SELECT ENAME, EMPNO FROM EMP where SAL vsal;无动态语句游标定义TYPE name_type IS REF CURSOR;name name_type;暂不提供动态游标的支持。此功能非常用功能CASE语句CASE expression1WHEN expression2 THEN;.WHEN expression3 THEN;.ELSE;.END CASE;暂不提供CASE语句的支持。可以使用if语句代替。CASE表达式CASE WHEN condition THENresultWHEN .ELSE resultEND暂不提供CASE
19、表达式的支持。可以使用if语句代替。异常的处理1. 自定义异常声明EXCEPTION;2. 抛出自定义异常RAISE ;1. 异常的处理(1) 在模块正常执行的过程中,可能会出现未预料的事件,称之为异常;(2) 异常会导致执行不正确的结束,因此需要进行异常处理;(3) DM提供了一些预定义的异常,与常见的DM错误相对应;(4) OTHERS:特殊的异常名,用于处理没有明确列出的异常。2. 异常变量的定义(1) 用户可以自定义异常变量; EXCEPTION FOR ;(2) 其中,FOR子句用来为异常变量绑定错误号(SQLCODE值);(3) 异常变量类似于一般的变量,必须在块的说明部分说明,有
20、同样的生存期和作用域;(4) 但是异常变量不能作参数传递,也不能被赋值;(5) 需要注意的是,为异常变量绑定的错误号不一定是DM返回的系统错误,但是该错误号必须是一个负整数。3. 抛出异常(1) 当异常发生时,系统会自动抛出异常;(2) 用户也可以主动抛出异常:RAISE ;(3) 一旦异常抛出,执行将转到相应的异常处理部分。4. 异常处理器(1) 语法格式: := EXCEPTION ; :=WHEN THEN ; (2) OTHERS必须在最后。5. 异常处理的实例CREATE OR REPLACE PROCEDURE P6AS A INT; E1 EXCEPTION;BEGIN A :=
21、 A/0; RAISE E1;EXCEPTION WHEN ZERO_DIVIDE THEN PRINT DIVIDED BY ZERO; WHEN E1 THEN PRINT E1; WHEN OTHERS THEN PRINT ERROR;END;无SELECT INTO赋值SELECT select_expressions INTO targetFROM .;EXECUTE IMMEDIATE commandstringINTO USING IN OUTSELECT select_expressions INTO targetFROM .;EXECUTE IMMEDIATE comman
22、dstringINTO USING IN OUT无GOTO语句goto label_name;只能由内部的语句块跳往外部块 设置标签可以为循环设置标签declareid number:=1;beginloop dbms_output.put_line(循环次数-|id);id :=id+1;if id=10 then goto a;end if;end loop;dbms_output.put_line(跳出循环);end;1. GOTO语句无条件地跳转到一个标号所在的位置。2. 标号的定义在一个语句块中必须是唯一的。其语法如下:GOTO GOTO语句将控制权交给带有标号的语句或语句块。3.
23、为了保证GOTO语句的使用不会引起程序的混乱,达梦数据库对GOTO语句的使用有下列限制:(1) GOTO语句不能跳入一个IF语句、循环语句或下层语句块中; (2) GOTO语句不能从一个异常处理器跳回当前块,但是可以跳转到包含当前块的上层语句块。无返回查询结果集CREATE OR REPLACE PROCEDURE p_sel_result(UserTag byte) AS BEGINIF (UserTag = 1) THENSELECT * FROM SYSTABLES WHERE ID 1000; ELSESELECT * FROM SYSTABLES WHERE ID 1000; ELS
24、ESELECT * FROM SYSTABLES WHERE ID 1000;END IF;END;无数据类型引用%TYPE和%ROWTYPE扩展了存储过程类型,方便用户使用。1. %TYPE在许多情况下,存储过程变量可以被用来处理存储在数据库表中的数据。在这种情况下,变量应该拥有与表列相同的类型。2. %ROWTYPE在存储过程中将一个记录声明为具有相同类型的数据库行的作法也很常见。下例子中使用的表T的结果如下: CREATE TABLE T(ID INT, NAME VARCHAR(10); INSERT INTO T VALUES(1, 达梦数据库); COMMIT;1. %TYPE例如表T中有个字段NAME类型为VARCHAR(20)。对应的在存储过程中,可以声明一个变量: DELCARE V_NAME VARCHAR(20); 但是如果T中的NAME字段定义发生了变化,比如变为VARCHAR(100)。那么存储过程中的变量V_NAME也要做相应修改为DELCAR
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1