• 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,可以编写出多么庞大的内部存储进程。




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

  • 相关阅读:
    P1031 均分纸牌
    P1130 红牌
    P1094 纪念品分组
    win32 公用对话框
    高性能完成端口socket服务(IOCP)
    一个简单的调试日志功能
    UI设计工具
    windows平台(不包括ARM的CE)通用的压缩和解压缩
    win api 实现 AES加密、解密,获取HASH
    win32sdk 编程整理的些资料
  • 原文地址:https://www.cnblogs.com/zgqjymx/p/1972811.html
Copyright © 2020-2023  润新知