Collection Contents 上一页 下一页 PDF

ASA SQL 参考

SQL 语句

CREATE PROCEDURE 语句


说明 

此语句用于在数据库中创建过程。

语法 1 

CREATE PROCEDURE [ owner.]procedure-name ( [ parameter, ... ] )
{   [ RESULT ( result-column, ... ) | NO RESULT SET ]
    [ ON EXCEPTION RESUME ]
      compound-statement
   | AT location-string
   | EXTERNAL NAME library-call
   | [ DYNAMIC RESULT SETS integer-expression ]
     [ EXTERNAL NAME java-call LANGUAGE JAVA ]
    }

语法 2 

CREATE PROCEDURE [ owner.]procedure-name ( [ parameter, ... ] )
compound-statement

语法 3 

CREATE PROCEDURE [ owner.]procedure-name ( [ parameter, ... ] )
URL url-string
TYPE { 'HTTP[:{GET|POST}]' | 'SOAP[:{RPC|DOC}]' } ]
NAMESPACE namespace-string ]
CERTIFICATE certificate-string ]
CLIENTPORT clientport-string ]
PROXY proxy-string ]

url-string :
'{HTTP|HTTPS}://[user:password@]hostname[:port][/path]'

parameter :
  parameter_mode parameter-name data-type [ DEFAULT expression ]
SQLCODE
SQLSTATE

parameter_mode : IN | OUT | INOUT

result-column : column-name data-type

library-call :
'[operating-system:]function-name@library; ...'

operating-system :
Windows95 | WindowsNT | NetWare | UNIX

java-call :
'[package-name.]class-name.method-name method-signature'

method-signature :
([field-descriptor, ... ] ) return-descriptor

field-descriptor | return-descriptor :
Z | B | S | I | J | F | D | C | V | [descriptor | Lclass-name;

参数 

CREATE PROCEDURE 子句    参数名必须符合其它数据库标识符(如列名)的规则。它们必须是有效的 SQL 数据类型(请参见 SQL 数据类型)。参数可以使用的前缀有:IN、OUT 或 INOUT。如果未指定上述任何前缀,缺省使用 INOUT 参数。这些关键字具有以下含义:

使用 CALL 语句执行过程时,不需要指定所有的参数。如果在 CREATE PROCEDURE 语句中提供了缺省值,缺少的参数会被分配缺省值。如果 CALL 语句中没有提供参数并且没有设置缺省值,则发生错误。

SQLSTATE 和 SQLCODE 是特殊参数,它们在过程结束时输出 SQLSTATE 或 SQLCODE 值(它们是 OUT 参数)。无论是否指定 SQLSTATE 和 SQLCODE 参数,总是可以在过程调用后立即检查 SQLSTATE 和 SQLCODE 特殊值以测试过程的返回状态。

SQLSTATE 和 SQLCODE 特殊值在执行下一个 SQL 语句时被修改。将 SQLSTATE 或 SQLCODE 作为过程参数提供可允许返回代码存储在变量中。

RESULT 子句    RESULT 子句声明结果集中列的数量和类型。RESULT 关键字后面括在括号内的列表定义结果的列名和类型。描述 CALL 语句时,嵌入式 SQL DESCRIBE 或 ODBC SQLDescribeCol 返回此信息。SQL 数据类型中列出了允许使用的数据类型。

有关从过程返回的结果集的详细信息,请参见从过程返回结果

因执行的方式不同,有些过程可产生多个结果集,并且列数也不同。例如,下面的过程在有些情况下返回两列,在有些情况下返回一列。

CREATE PROCEDURE names( IN formal char(1))
BEGIN
   IF formal = 'n' THEN
      SELECT emp_fname
      FROM employee
   ELSE
      SELECT emp_lname,emp_fname
      FROM employee
   END IF
END

包含可变结果集的过程必须不带 RESULT 子句写出,或者用 Transact-SQL 写出。它们的使用受以下限制:

如果过程仅返回一个结果集,则应使用 RESULT 子句。该子句可防止 ODBC 和 Open Client 应用程序在游标打开后重新描述结果集。

为处理多个结果集,ODBC 必须描述当前正在执行的游标,而不是过程的已定义结果集。因此,ODBC 不会始终按过程定义的 RESULT 子句中的定义来描述列名。为避免这种问题,请在生成结果集的 SELECT 语句中使用列的别名。

NO RESULT SET 子句    声明此过程不返回结果集。当外部环境需要知道某个过程不返回结果集时,这是非常有用的。

ON EXCEPTION RESUME 子句    该子句使类似 Transact-SQL 的错误处理能够在 Watcom-SQL 语法过程中使用。

如果使用 ON EXCEPTION RESUME,则过程会根据 ON_TSQL_ERROR 选项的设置采取不同的操作。如果 ON_TSQL_ERROR 设置为 CONDITIONAL(缺省设置),则当下一条语句能处理错误时,将继续执行下面的语句;否则将退出。

错误处理语句包括以下这些:

在 ON EXCEPTION RESUME 子句中不要使用显式错误处理代码。

有关详细信息,请参见 ON_TSQL_ERROR 选项 [compatibility]

EXTERNAL NAME 子句    使用 EXTERNAL NAME 子句的过程是包含外部库调用的包装。使用 EXTERNAL NAME 的存储过程在参数列表后可以不使用其它子句。library 名可包含文件扩展名,在 Windows 中通常为 .dll、在 UNIX 中通常为 .so、在 NetWare 中通常为 .nlm。在没有扩展名的情况下,该软件附加平台特定的缺省库文件扩展名。在 NetWare 上,如果未指定 NLM 名称,则在调用函数时,必须已加载包含该符号的 NLM。

有关外部库调用的信息,请参见从过程调用外部库

AT location-string 子句    在当前数据库中为 location-string 指定的远程过程创建代理存储过程。AT 子句支持分号 (;) 作为 location-string 中的字段分隔符。如果没有分号,则使用句号作为字段分隔符。这允许在数据库和所有者字段中使用文件名和扩展名。

例如,下面的语句创建一个代理过程 (remotewho),此过程调用位于 bostonase 服务器的 master 数据库中的 dbo.sp_who 过程:

CREATE PROCEDURE remotewho ()
AT 'bostonase.master.dbo.sp_who

远程过程在输出变量中最多只能返回 254 个字符。

有关远程服务器的信息,请参见 CREATE SERVER 语句。有关使用远程过程的信息,请参见使用远程过程调用 (RPC)

DYNAMIC RESULT SETS 子句    该子句与属于 Java 方法包装的过程一起使用。如果不提供 DYNAMIC RESULT SETS 子句,则假定此方法不返回结果集。

URL 子句    仅用于定义 HTTP 或 SOAP Web 服务客户端函数。指定 Web 服务的 URI。

TYPE 子句    用于指定创建 Web 服务请求时使用的格式。如果指定 SOAP 或未包括类型子句,则使用缺省类型 SOAP:RPC。HTTP 隐含 HTTP:POST。由于 SOAP 请求总是作为 XML 文档发送,因此总是使用 HTTP:POST 发送 SOAP 请求。

NAMESPACE 子句    仅适用于 SOAP 客户端过程。此子句标识 SOAP:RPC 和 SOAP:DOC 请求通常都需要的方法命名空间。处理请求的 SOAP 服务器使用此命名空间来解释 SOAP 请求消息主体中的实体的名称。可以从 Web 服务服务器中可用的 SOAP 服务的 WSDL 说明中获取命名空间。缺省值是过程的 URL,但是不包括可选的路径组件。

CERTIFICATE 子句    为了创建安全 (HTTPS) 请求,客户端必须能够访问 HTTPS 服务器所用的证书。必要的信息在一个用分号分隔的键/值对字符串中指定。可以将证书放置在一个文件中并使用 file 项提供的文件名,或是将整个证书放置在一个字符串中,但是两种方法不可同时使用。可以使用以下项:

EXTERNAL NAME LANGUAGE JAVA 子句    使用带 LANGUAGE JAVA 子句的 EXTERNAL NAME 的过程是包含 Java 方法的包装。

如果参数数目比方法签名中指出的数目少,则差值必须等于 DYNAMIC RESULT SETS 中指定的数目,并且方法签名中超出过程参数列表中的参数的每个参数必须具有方法签名 [Ljava/SQL/ResultSet;

Java 方法签名是参数类型和返回值类型的压缩字符表示形式。在签名前放置空格被视为错误。

field-descriptorreturn-descriptor 有以下含义:

字段类型 Java 数据类型
B byte
C char
D double
F float
I int
J long
Lclass-name; class-name 的实例。类名必须是完全限定的,而且名称中的任何点都必须由 / 代替。例如,java/lang/String
S short
V void
Z Boolean
[ 数组的每个维度都使用一个

例如,

double some_method(
  boolean a,
  int b,
  java.math.BigDecimal c,
  byte [][] d,
  java.SQL.ResultSet[] rs ) {
}

有如下签名:

'(ZILjava/math/BigDecimal;[[B[Ljava/SQL/ResultSet;)D'

有关详细信息,请参见从 Java 方法返回结果集

用法 

CREATE PROCEDURE 语句在数据库中创建过程。具有 DBA 权限的用户可以通过指定 owner 为其他用户创建过程。过程由 CALL 语句激活。

如果存储过程返回一个结果集,则它不能同时设置输出参数或返回一个返回值。

参数值作为请求的一部分进行传递。使用的语法取决于请求的类型。对于 HTTP:GET,参数作为 URL 的一部分传递;对于 HTTP:POST 请求,则将值放在请求主体中。SOAP 请求的参数总是捆绑在请求主体中。

返回到 SOAP 和 HTTP 过程的值和标头 [ UNDER CONSTRUCTION ]

权限 

必须有 RESOURCE 权限。

引用外部过程或者为其他用户创建过程必须有 DBA 权限。

副作用 

自动提交。

另请参见 
标准和兼容性 
示例 

下面的过程使用 case 语句对查询结果归类。

CREATE PROCEDURE ProductType (IN product_id INT, OUT type CHAR(10))
BEGIN
   DECLARE prod_name CHAR(20);
   SELECT name INTO prod_name FROM "DBA"."product"
   WHERE id = product_id;
   CASE prod_name
   WHEN 'Tee Shirt' THEN
      SET type = 'Shirt'
   WHEN 'Sweatshirt' THEN
      SET type = 'Shirt'
   WHEN 'Baseball Cap' THEN
      SET type = 'Hat'
   WHEN 'Visor' THEN
      SET type = 'Hat'
   WHEN 'Shorts' THEN
      SET type = 'Shorts'
   ELSE
      SET type = 'UNKNOWN'
   END CASE;
END

下面的过程使用游标并循环通过游标的行以返回单值。

CREATE PROCEDURE TopCustomer (OUT TopCompany CHAR(35), OUT TopValue INT)
BEGIN
   DECLARE err_notfound EXCEPTION
   FOR SQLSTATE '02000';
   DECLARE curThisCust CURSOR FOR
      SELECT company_name,
          CAST(sum(sales_order_items.quantity *
          product.unit_price) AS INTEGER) VALUE
      FROM customer
      LEFT OUTER JOIN sales_order
      LEFT OUTER JOIN sales_order_items
      LEFT OUTER JOIN product
      GROUP BY company_name;
   DECLARE ThisValue INT;
   DECLARE ThisCompany CHAR(35);
   SET TopValue = 0;
   OPEN curThisCust;
   CustomerLoop:
   LOOP
      FETCH NEXT curThisCust
      INTO ThisCompany, ThisValue;
      IF SQLSTATE = err_notfound THEN
         LEAVE CustomerLoop;
      END IF;
      IF ThisValue > TopValue THEN
         SET TopValue = ThisValue;
         SET TopCompany = ThisCompany;
         END IF;
   END LOOP CustomerLoop;
   CLOSE curThisCust;
END

Collection Contents 上一页 下一页 PDF