使用此语句创建一个连接本地或外部函数的接口。要创建用户定义的 SQL 函数,请参见CREATE FUNCTION 语句。
CREATE [ OR REPLACE ] FUNCTION [ owner.]function-name ( [ parameter, ... ] ) RETURNS data-type [ SQL SECURITY { INVOKER | DEFINER } ] [ [ NOT ] DETERMINISTIC ] EXTERNAL NAME external-call [ LANGUAGE environment-name ]
parameter : [ IN ] parameter-name data-type [ DEFAULT expression ]
environment-name : C_ESQL32 | C_ESQL64 | C_ODBC32 | C_ODBC64 | CLR | JAVA | PERL | PHP
CREATE FUNCTION 您可以创建用于调用使用各种编程语言编写的外部或本地函数的永久存储函数。
参数名必须符合其它数据库标识符(如列名)的规则。它们必须是有效的 SQL 数据类型。有关有效数据类型的列表,请参见SQL 数据类型。
参数可以使用关键字 IN 作为前缀。但在缺省情况下,函数参数是 IN。
IN 此参数是一个为函数提供值的表达式。
执行函数时,不必指定所有参数。如果在 CREATE FUNCTION 语句中提供了缺省值,则会为缺少的参数指派缺省值。如果在执行函数时未提供参数也未设置缺省值,则会给出错误。
指定 OR REPLACE (CREATE OR REPLACE FUNCTION) 将创建一个新函数或替换同名的现有函数。此子句将更改函数的定义,但保留现有权限。TEMPORARY 函数不支持 EXTERNAL NAME 子句。
[ NOT ] DETERMINISTIC 子句 使用此子句指明函数是确定型函数还是非确定型函数。如果忽略此子句,便没有指定函数的确定型行为(缺省设置)。
如果将某个函数声明为 DETERMINISTIC,则在每次使用同一组参数调用该函数时,应返回同一个值。
如果将某个函数声明为 NOT DETERMINISTIC,则无法保证对于同一组参数会返回同一个值。声明为 NOT DETERMINISTIC 的函数每次在查询中调用时都将重新求值。如果已知给定一组参数的函数结果可以不同,则必须使用此子句。
另外,对于具有副作用(如修改基础数据)的函数,应将其声明为 NOT DETERMINISTIC。例如,一个生成主键值且用于 INSERT ... SELECT 语句的函数应声明为 NOT DETERMINISTIC:
CREATE FUNCTION keygen( increment INTEGER ) RETURNS INTEGER NOT DETERMINISTIC BEGIN DECLARE keyval INTEGER; UPDATE counter SET x = x + increment; SELECT counter.x INTO keyval FROM counter; RETURN keyval END INSERT INTO new_table SELECT keygen(1), ... FROM old_table; |
如果函数对给定输入参数总是返回相同的值,则该函数可以声明为 DETERMINISTIC。
SQL SECURITY 子句 SQL SECURITY 子句定义该函数是作为 INVOKER(调用该函数的用户)执行还是作为 DEFINER(拥有该函数的用户)执行。缺省值为 DEFINER。对于外部调用,此子句用于为外部环境中的非限定对象引用建立所有权上下文。
指定 SQL SECURITY INVOKER 后,必须对每个调用该函数的用户加以标注,因此会使用更多内存。另外,指定 SQL SECURITY INVOKER 后,也会作为调用者进行名称解析。因此,应注意用适合的所有者限定所有对象名称(表、过程等)。例如,假定 user1 创建了以下函数:
CREATE FUNCTION user1.myFunc() RETURNS INT SQL SECURITY INVOKER BEGIN DECLARE res INT; SELECT COUNT(*) INTO res FROM table1; RETURN res; END; |
如果 user2 试图运行此函数,而表 user2.table1 不 存在,则会产生表查寻错误。另外,如果 user2.table1 确实 存在,则使用该表而不使用预定的 user1.table1。为了防止出现这种情况,请在语句中限定表引用(user1.table1,而不只是 table1)。
native-call : [operating-system:]function-name@library; ...
operating-system : Unix
使用不带 LANGUAGE 属性的 EXTERNAL NAME 子句的函数用于定义一个连接本地函数(使用 C 语言等编程语言编写)的接口。该本地函数由数据库服务器装载到其地址空间中。
library 名可包含文件扩展名,通常在 Windows 中为 .dll,在 Unix 中为 .so。在没有扩展名的情况下,该软件附加平台特定的缺省库文件扩展名。以下为一个正式示例。
CREATE FUNCTION mystring( IN instr LONG VARCHAR ) RETURNS LONG VARCHAR EXTERNAL NAME 'mystring@mylib.dll;Unix:mystring@mylib.so'; |
下面是使用特定于平台的缺省值编写上述 EXTERNAL NAME 子句的更简单的方法:
CREATE FUNCTION mystring( IN instr LONG VARCHAR ) RETURNS LONG VARCHAR EXTERNAL NAME 'mystring@mylib'; |
如果调用,则包含此函数的库将被装载到数据库服务器的地址空间中。本地函数将作为服务器的一部分执行。在这种情况下,如果此函数导致故障,则会使数据库服务器终止。因此,建议在外部环境中装载和执行使用 LANGUAGE 属性的函数。如果函数在外部环境中导致故障,数据库服务器仍可继续运行。
有关本地库调用的信息,请参见从过程调用外部库。
EXTERNAL NAME c-call LANGUAGE {C_ESQL32 | C_ESQL64 | C_ODBC32 | C_ODBC64 } 子句 要在外部环境而非数据库服务器中调用编译后的本地 C 函数,存储过程或函数应使用后跟 LANGUAGE 属性的 EXTERNAL NAME 子句来定义,其中,LANGUAGE 属性指定 C_ESQL32、C_ESQL64、C_ODBC32 或 C_ODBC64。
指定 LANGUAGE 属性后,包含此函数的库将由外部进程装载,外部函数将在该外部进程中执行。在这种情况下,如果此函数导致故障,数据库服务器仍可继续运行。
以下是一个示例函数定义。
CREATE FUNCTION ODBCinsert( IN ProductName CHAR(30), IN ProductDescription CHAR(50) ) RETURNS INT EXTERNAL NAME 'ODBCexternalInsert@extodbc.dll' LANGUAGE C_ODBC32; |
有关详细信息,请参见ESQL 和 ODBC 外部环境。
EXTERNAL NAME clr-call LANGUAGE CLR 子句 要在外部环境中调用 .NET 函数,函数接口应使用后跟 LANGUAGE CLR 属性的 EXTERNAL NAME 子句来定义。
CLR 存储过程或函数的行为与 SQL 存储过程或函数的基本相同,只是过程或函数的代码以 C# 或 Visual Basic 等 .NET 语言编写并在数据库服务器外(即在单独的 .NET 可执行文件内)执行。
以下是一个示例函数定义。
CREATE FUNCTION clr_interface( IN p1 INT, IN p2 UNSIGNED SMALLINT, IN p3 LONG VARCHAR) RETURNS INT EXTERNAL NAME 'CLRlib.dll::CLRproc.Run( int, ushort, string )' LANGUAGE CLR; |
有关详细信息,请参见CLR 外部环境。
EXTERNAL NAME perl-call LANGUAGE PERL 子句 要在外部环境中调用 Perl 函数,函数接口应使用后跟 LANGUAGE PERL 属性的 EXTERNAL NAME 子句来定义。
Perl 存储过程或函数的行为与 SQL 存储过程或函数基本相同,只是过程或函数的代码以 Perl 编写并在数据库服务器外(即在 Perl 可执行实例内)执行。
以下是一个示例函数定义。
CREATE FUNCTION PerlWriteToConsole( IN str LONG VARCHAR) RETURNS INT EXTERNAL NAME '<file=PerlConsoleExample> WriteToServerConsole( $sa_perl_arg0 )' LANGUAGE PERL; |
有关详细信息,请参见PERL 外部环境。
EXTERNAL NAME php-call LANGUAGE PHP 子句 要在外部环境中调用 PHP 函数,函数接口应使用后跟 LANGUAGE PHP 属性的 EXTERNAL NAME 子句来定义。
PHP 存储过程或函数的行为与 SQL 存储过程或函数基本相同,只是过程或函数的代码以 PHP 编写并且在数据库服务器外(即在 PHP 可执行实例内)执行。
以下是一个示例函数定义。
CREATE FUNCTION PHPPopulateTable() RETURNS INT EXTERNAL NAME '<file=ServerSidePHPExample> ServerSidePHPSub()' LANGUAGE PHP; |
有关详细信息,请参见PHP 外部环境。
EXTERNAL NAME java-call LANGUAGE JAVA 子句 要在外部环境中调用 Java 方法,函数接口应使用后跟 LANGUAGE JAVA 属性的 EXTERNAL NAME 子句来定义。
采用 Java 接口技术的存储过程或函数的行为与 SQL 存储过程或函数的行为基本相同,只是过程或函数的代码以 Java 编写并且在数据库服务器外(即在 Java 虚拟机内)执行。
以下是一个示例函数定义。
CREATE FUNCTION HelloDemo( IN name LONG VARCHAR ) RETURNS INT EXTERNAL NAME 'Hello.main([Ljava/lang/String;)V' LANGUAGE JAVA; |
有关详细信息,请参见Java 外部环境。
CREATE FUNCTION 语句在数据库中创建函数。具有 DBA 权限的用户可以通过指定所有者为其他用户创建函数。函数以作为 SQL 表达式一部分的形式被调用。
从多个函数引用临时表时,如果该临时表定义不一致且高速缓存引用该表的语句,则会出现潜在问题。请参见在过程中引用临时表。
除非创建临时函数,否则必须具有 RESOURCE 权限。
引用外部函数或者为其他用户创建函数必须有 DBA 权限。
自动提交。
SQL/2003 持久存储模块特性。Java 结果集的语法扩展如可选的 J621 特性中所指定。
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |