DB2 9 独霸开辟(733 磨练)认证指南,第 9 部门: 用户定义的例程(6)

将定制的和庞大的营业逻辑集成到 SQL 语句中
developerWorks








内部存储进程

独霸内部存储进程

经由进程引用内部次序递次可以得到超出跨越 SQL PL 范围的茂盛遵守。经由进程独霸一个内部存储进程(即独霸 Java 措辞或 C# 等编程措辞编写的存储进程),可以处置惩罚内部数据源,也许实验数据库之外的内部法子。

与内部 UDF 近似,内部存储进程可以定义为以 NOT FENCEDFENCED 情势运转。异常,独霸 NOT FENCED 进程的长处是可以进步性能。然则,如果没有适外地编写这种进程,就会泛起内存裂痕,这种内存裂痕会掩饰覆盖与 DB2 引擎关系联的内存,因此会发作很是恶劣的影响。

确立内部存储进程

清单 25 显示了注册内部存储进程的简化语法图:

清单 25. 注册内部存储进程的简化语法图

                    
>>-CREATE PROCEDURE--procedure-name----------------------------->
>-- -------------------------------------------------------- --->
   '-(-- ---------------------------------------------- --)-'
        | .-,----------------------------------------. |
        | V .-IN----.                                | |
        '--- ------- -- ---------------- --data-type- -'
             -OUT---   '-parameter-name-'
            '-INOUT-'
>--*-- ------------------------- --*---------------------------->
      '-SPECIFIC--specific-name-'
   .-DYNAMIC RESULT SETS 0--------.     .-MODIFIES SQL DATA-.
>-- ------------------------------ --*-- ------------------- --->
   '-DYNAMIC RESULT SETS--integer-'      -NO SQL------------ 
                                         -CONTAINS SQL------ 
                                        '-READS SQL DATA----'
      .-NOT DETERMINISTIC-.     .-CALLED ON NULL INPUT-.
>--*-- ------------------- --*-- ---------------------- --*----->
      '-DETERMINISTIC-----'
   .-OLD SAVEPOINT LEVEL-.
>-- --------------------- --*--LANGUAGE-- -C----- --*----------->
   '-NEW SAVEPOINT LEVEL-'                -JAVA-- 
                                          -COBOL- 
                                          -CLR--- 
                                         '-OLE---'
>--EXTERNAL-- ---------------------- --*------------------------>
             '-NAME-- -'string'--- -'
                     '-identifier-'
   .-FENCED------------------------.
>-- ------------------------------- --*------------------------->
    -FENCED--*-- -THREADSAFE----- - 
   |            '-NOT THREADSAFE-' |
   |                .-THREADSAFE-. |
   '-NOT FENCED--*-- ------------ -'
   .-EXTERNAL ACTION----.  .-INHERIT SPECIAL REGISTERS-.
>-- -------------------- -- --------------------------- --*----->
   '-NO EXTERNAL ACTION-'
>--PARAMETER STYLE-- -DB2GENERAL--------- --*------------------->
                     -DB2SQL------------- 
                     -GENERAL------------ 
                     -GENERAL WITH NULLS- 
                     -JAVA--------------- 
                    '-SQL----------------'


这个语法图中的很多子句在之前的一些大节中曾经联络过。本节着重引见内部存储进程特有的一些主要部门。

  • LANGUAGE: 标明进程是用什么措辞编写的。可用于编写内部进程的措辞有 C、Java 措辞、COBOL、CLR 和 OLE。
  • EXTERNAL NAME: 指定用户编写的用来完成所定义进程的代码的称号。该字符串的花式取决于所指定的措辞。本教程简要地联络在独霸 C、Java 和 CLR 措辞时该字符串的花式。
  • EXTERNAL ACTION: 决定进程能否可以实验内部法子。
  • PARAMETER STYLE: 该子句用于指定进程通报参数和前去值的商定。可用的选项有:
    • DB2GENERAL: 独霸为 Java 方式定义的参数通报商定。只需在独霸 LANGUAGE JAVA 时,才气指定该选项。
    • DB2SQL: 当指定该选项时,可以将提供附加诊断信息的附加参数通报给进程。只需在指定 LANGUAGE CCOBOLCLROLE 时,才气指定该选项。
    • GENERAL: 招致进程接纳 CALL 语句中指定的参数,而不独霸 SQLDA 构造。只需在指定 LANGUAGE CCOBOLCLR 时,才气指定该选项。
    • GENERAL WITH NULLS: 近似于 GENERAL 选项,然则还将另一个参数通报给进程:该参数是由 null 指示符组成的一个向量,CALL 语句的每个参数对应一个 null 指示符。
    • JAVA: 招致进程独霸驯服 Java 措辞和 SQLJ 例程模范模范的参数通报商定。 以单条目数组的情势通报 IN/OUTOUT 参数,以便于前去值。只需当独霸 LANGUAGE JAVA 时,才气指定该选项。
    • SQL: 当指定该选项时,CALL 语句中包括提供附加诊断信息的附加参数。只需当独霸 LANGUAGE CCOBOLCLROLE 时,才气指定该选项。

方式会关于 CREATE PROCEDURE 语句中这些子句和其他子句的更多信息,请参阅 DB2 文档。





回页首



EXTERNAL NAME 子句选项

内部存储进程一个最紧张的强逼性质句就是 EXTERNAL NAME 子句。该子句控制 DB2 可以在那里探求编译后的进程代码。在本节中,您将认识在 C、Java 和 CLR 措辞中,该子句的字符串是若何任务的。

C 措辞

指定的字符串是库名和库中的进程,数据库打点器调用它来实验所确立的进程。在实验 CREATE PROCEDURE 语句时,这个库(以及库中的进程)不需求曾经存在。然则,当进程被调用时,这个库和库中的进程必须存在,并且可以也许从数据库效能器上会晤到。关于 C 措辞,指定的字符串花式如下:

>>-'-- -library_id------- -- ------------ --'------------------>|
      '-absolute_path_id-'  '-!--proc_id-'


下面别离刻画它的差别组成部门:

  • library_id: 包括该进程的库的称号。数据库打点器按如下方式探求库:
    • 在 UNIX 系统上,如果指定的 library_idmyfunc,数据库打点器在 /u/production 目录下运转,当指定 FENCED 时,数据库打点器在 /u/production/sqllib/function/myfunc 中探求进程库;当指定 NOT FENCED 时,数据库打点器在 /u/production/sqllib/function/unfenced/myproc 中探求进程库。
    • 在 Windows 操作系统上,数据库打点器在 LIBPATHPATH 情况变量指定的目录途径中探求进程库。
  • absolute_path_id: 标识包括该进程的文件的无缺途径名。
  • ! proc_id: 标识要调用的进程的入口称号。! 是库 ID 与进程 ID 之间的定界符。比喻,!proc8 将指示数据库打点器在 absolute_path_id 指定的职位探求库,并独霸那个库中的 proc8 入口。如果这个字符串的花式不对,就会前去错误。

Java 措辞

指定的字符串包括可选的 JAR 文件标识符、类标识符和方式标识符,数据库打点器调用它来实验所确立的进程。当实验 CREATE PROCEDURE 语句时,类标识符和方式标识符不需求曾经存在。如果指定了一个 jar_id,那么当实验 CREATE PROCEDURE 语句时,它必须曾经存在。异常的,当进程被调用时,类标识符和方式标识符必须曾经存在,并且可以从数据库效能器上会晤到。否则会前去错误。关于 Java 措辞,该字符串的花式为:

>>-'-- ---------- -->

下面别离刻画它的差别组成部门:

  • jar_id: JAR 聚集在被布置到数据库中时得到的 JAR 标识符。它可所以一个庞大的标识符,比喻 myJar,也可所以一个情势限定的标识符,比喻 mySchema.myJar
  • >: Java 对象的类标识符。如果这个类属于一个包,则类标识符部门还必须包括无缺的包前缀。比喻,如果独霸 myPacks.StoredProcs,则 Java 编造机将在 .../myPacks/StoredProcs/(关于 Windows,则为 ...\myPacks\StoredProcs\)目录中探求类。
  • method_id: 被调用的 Java 类中的方式的称号。

CLR

指定的字符串走漏表示 .NET 组合件(库或可实验文件)、组合件中的类以及类中的方式,数据库打点器将调用它来实验所确立的进程。当实验 CREATE PROCEDURE 语句时,模块、类和方式不需求曾经存在。然则,当进程被调用时,模块、类和方式必须存在,并且可以从数据库效能器上会晤到,否则会前去错误。关于 .NET 组合件(库或可实验文件),该字符串花式如下:

>>-'--assembly--:-->

下面别离刻画它的差别组成部门:

  • assembly: 类地址的 DLL 或其他文件的标识符。这里必须指定文件扩展名(比喻 .dll)。如果没有提供无缺的途径称号,那么该文件必须在 DB2 布置途径(比喻 C:\sqllib\function)的函数目录中。如果该文件在布置途径下的函数目录中的一个子目录中,那么可以在文件名之前提供这个子目录,而不用指定无缺的途径。比喻,如果布置目录为 C:\sqllib\function\myprocs\mydotnet.dll,那么只需为组合件指定 myprocs\mydotnet.dll。该参数的巨细写敏感性与文件系统相反。
  • >: 指定在给定的组合件中,要调用的方式地址的类的称号。如果这个类在一个称号空间中,那么除了类名之外,还需指定无缺的称号空间。比喻,如果类 Employee> 在称号空间 MyCompany.Procedure> 中,那么必须指定 MyCompany.Procedure>。该参数是巨细写敏感的。
  • method_id: 指定在给定类中要调用的方式。该参数是巨细写敏感的。

今朝,您曾经回首回头回忆了确立内部存储进程的语法,接上去可以看看确立 Java 存储进程的一个例子。





回页首



Java 存储进程例子

我们来看一个确立 Java 存储进程的例子。 清单 26 包括该进程的 Java 源代码:

清单 26. 一个庞大的 Java 存储进程的代码

                    
import java.sql.*;
public >

该进程的代码包括在一个名为 SimpleInsert() 的 Java 方式中,而这个 Java 方式又包括在一个名为 Simple 的 Java 类中。(因此寄存代码的文件名为 Simple.java)。清单 26 中的代码没有什么特别之处,它是规范的含有 JDBC 方式调用的 Java 代码。该进程有两个参数,都是字符串型的。第一个参数是输入参数,第二个参数是输入参数。仔细,输入参数被定义为一个 String 数组。该进程用于注册的 PARAMETER STYLE JAVA 属性要求 OUTINOUT 参数定义为数组。还需仔细的是该进程继承调用者到数据库的毗连的方式,它独霸的毗连字符串差别于规范的 JDBC 独霸次序递次。

经由进程独霸布置的系统上的也许 DB2 附带的 JDK,可以像下面这样编译该进程:

javac Simple.java


编译后会生成一个类文件。然后,可以将该文件转移到 sqllib/function 目录(DB2 探求存储进程可实验文件的默许职位),也许转移到您所选择的其他职位(只需在 CREATE PROCEDURE command 中独霸这个定制途径)。关于这个例子,独霸前一种目录,将类文件复制到 sqllib/function 目录中。

将类文件放在合适的职位后,便可以独霸 CREATE PROCEDURE 语句将该函数注册到 DB2 中,如 清单 27 所示:

清单 27. 注册 Java 存储进程

                    
CREATE PROCEDURE simple_insert (IN input CHAR(3), OUT outMsg VARCHAR(254))
SPECIFIC simple1
DYNAMIC RESULT SETS 0
DETERMINISTIC
LANGUAGE JAVA
PARAMETER STYLE JAVA
FENCED
THREADSAFE
MODIFIES SQL DATA
EXTERNAL NAME 'Simple!SimpleInsert'


注册函数之后,就可以调用该函数,如 清单 28 所示。仔细,问号(?)用于走漏表示输入参数。当从命令行调用存储进程时,都是用问号走漏表示输入参数。

清单 28. 调用 Java 存储进程

                    
CALL simple_insert('ABC', ?)
Value of output parameters
--------------------------
Parameter Name  : OUTMSG
Parameter Value : The update was successful.
 Return Status = 0
Result from DB2 sample database:
SELECT * FROM db2admin.mydata
COL1
----------------------------
ABC
  1 record(s) selected.


这个很是庞大的 Java 存储进程实践上也可以很苟且地编写成 SQL 存储进程。然则,看过这个例子之后,就应该了解,如果独霸主机编程措辞的悉数遵守和 API,可以编写出多么庞大的内部存储进程。




版权声明: 原创作品,许可转载,转载时请务必以超链接情势标明文章 原始情由 、作者信息和本声明。否则将清查执法责任。

原文地址:https://www.cnblogs.com/zgqjymx/p/1972811.html