创建连接本地或外部函数的接口。
CREATE [ OR REPLACE ] FUNCTION [ owner.]function-name ( [ parameter, ... ] ) [ SQL SECURITY { INVOKER | DEFINER } ] RETURNS data-type [ [ NOT ] DETERMINISTIC ] { EXTERNAL NAME 'native-call' | EXTERNAL NAME 'c-call' LANGUAGE { C_ESQL32 | C_ESQL64 | C_ODBC32 | C_ODBC64 } | EXTERNAL NAME 'clr-call' LANGUAGE CLR | EXTERNAL NAME 'perl-call' LANGUAGE PERL | EXTERNAL NAME 'php-call' LANGUAGE PHP | EXTERNAL NAME 'java-call' LANGUAGE JAVA }
parameter : [ IN ] parameter-name data-type [ DEFAULT expression ]
native-call : [ operating-system:]function-name@library
result-column : column-name data-type
c-call : [ operating-system:]function-name@library; ...
clr-call : dll-name::function-name( param-type-1[, ... ] )
perl-call : <file=perl-file> $sa_perl_return = perl-subroutine( $sa_perl_arg0[, ... ] )
php-call : <file=php-file> print php-func( $argv[1][, ... ] )
java-call : [package-name.]class-name.method-name method-signature
operating-system :
Unix
method-signature : ( [ field-descriptor, ... ] ) return-descriptor
field-descriptor and return-descriptor : { Z | B | S | I | J | F | D | C | V | [descriptor | Lclass-name; }
参数名必须符合数据库标识符规则。它们必须是有效的 SQL 数据类型,且必须以关键字 IN 作为前缀,以表明参数是为函数提供值的表达式。但在缺省情况下,函数参数是 IN。
执行函数时,不必指定所有参数。如果在 CREATE FUNCTION 语句中提供 DEFAULT 值,则会为缺少的参数指派缺省值。如果调用程序既未提供参数又未设置缺省值,则会给出错误。
OR REPLACE 子句 指定 OR REPLACE 将创建一个新函数或替换同名的现有函数。此子句将更改函数的定义,但保留现有特权。不能将 OR REPLACE 子句与临时函数一起使用。
RETURNS 子句 使用 RETURNS 子句指定函数结果的数据类型。
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)。
[ 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。
native-call : [operating-system:]function-name@library; ...
operating-system : Unix
TEMPORARY 函数不支持 EXTERNAL NAME 子句。
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; |
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; |
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; |
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; |
EXTERNAL NAME java-call LANGUAGE JAVA 子句 要在外部环境中调用 Java 方法,函数接口应使用后跟 LANGUAGE JAVA 属性的 EXTERNAL NAME 子句来定义。
采用 Java 接口技术的存储过程或函数的行为与 SQL 存储过程或函数的行为基本相同,只是过程或函数的代码以 Java 编写,并且在数据库服务器外(即在 Java VM 内)执行过程或函数。
CREATE FUNCTION HelloDemo( IN name LONG VARCHAR ) RETURNS INT EXTERNAL NAME 'Hello.main([Ljava/lang/String;)V' LANGUAGE JAVA; |
参数的描述符以及 Java 方法的返回值具有以下含义:
字段类型 | Java 数据类型 |
---|---|
B | byte |
C | char |
D | double |
F | float |
I | int |
J | long |
L class-name; | 类 class-name 的实例。类名必须是完全限定的,而且名称中的任何点都必须替换为 /。例如,java/lang/String。 |
S | short |
V | void |
Z | Boolean |
[ | 数组的每个维度都使用一个。 |
CREATE FUNCTION 语句在数据库中创建函数。可通过指定所有者来为其他用户创建函数。函数以作为 SQL 表达式一部分的形式被调用。
从多个函数引用临时表时,如果该临时表定义不一致且高速缓存引用该表的语句,则会出现潜在问题。
要创建您自己拥有的外部函数,您必须具有 CREATE PROCEDURE 和 CREATE EXTERNAL REFERENCE 系统特权。
要创建由他人拥有的外部函数,您必须具有 CREATE ANY PROCEDURE 或 CREATE ANY OBJECT 系统特权,以及 CREATE EXTERNAL REFERENCE 系统特权。
创建临时函数不需要任何特权。
自动提交。
SQL/2008 外部语言环境的 CREATE FUNCTION 是 SQL/2008 标准的核心功能,尽管 SQL Anywhere 中支持的某些它的组件是可选 SQL/2008 语言功能。这些功能的子集包括:
SQL SECURITY 子句是可选语言功能 T324。
将 LONG VARCHAR、LONG NVARCHAR 或 LONG BINARY 值传递给 SQL 函数的能力是语言功能 T041。
对 LANGUAGE JAVA 的支持是可选 SQL/2008 语言功能 J621。
使用 CREATE TABLE 或 DROP TRIGGER 等语句在外部函数中创建或修改模式对象的能力是语言功能 T653。
在外部函数中使用动态 SQL 语句(包括 CONNECT、EXECUTE IMMEDIATE、PREPARE 和 DESCRIBE 等语句)的能力是语言功能 T654。
CREATE FUNCTION 语句的几个子句是服务商扩充。其中包括:
在 LANGUAGES 子句中支持 C_ESQL32、C_ESQL64、C_ODBC32、C_ODBC64、CLR、PERL 和 PHP 是服务商扩充。
external-call 的格式是由具体实现自行定义。
特定例程参数的可选 DEFAULT 子句是服务商扩充。
可选 OR REPLACE 子句是服务商扩充。
Transact-SQL Adaptive Server Enterprise 支持外部例程的 CREATE FUNCTION。Adaptive Server Enterprise 仅支持 LANGUAGE JAVA 作为外部函数的外部环境(SQL/2008 语言功能 J621)。
![]() |
使用DocCommentXchange讨论此页。
|
版权 © 2013, SAP 股份公司或其关联公司. - SAP Sybase SQL Anywhere 16.0 |