SQL Anywhere JDBC 驱动程序支持两个异步回调,一个用来处理 SQL MESSAGE 语句,另外一个用于校验文件传输请求。这些类似于 SQL Anywhere ODBC 驱动程序支持的回调。
可使用 SQL MESSAGE 语句将消息从数据库服务器发送到客户端应用程序。长时间运行的数据库服务器语句也可以生成消息。
可创建消息处理程序例程来拦截这些消息。以下是一个消息处理程序回调例程的示例:
class T_message_handler implements sybase.jdbc4.sqlanywhere.ASAMessageHandler { private final int MSG_INFO = 0x80 | 0; private final int MSG_WARNING = 0x80 | 1; private final int MSG_ACTION = 0x80 | 2; private final int MSG_STATUS = 0x80 | 3; T_message_handler() { } public SQLException messageHandler(SQLException sqe) { String msg_type = "unknown"; switch( sqe.getErrorCode() ) { case MSG_INFO: msg_type = "INFO "; break; case MSG_WARNING: msg_type = "WARNING"; break; case MSG_ACTION: msg_type = "ACTION "; break; case MSG_STATUS: msg_type = "STATUS "; break; } System.out.println( msg_type + ": " + sqe.getMessage() ); return sqe; } } |
可以校验客户端文件传输请求。在允许进行任何传输前,JDBC 驱动程序会调用校验回调函数(如果存在)。如果在执行间接语句(从存储过程内部)期间,请求进行客户端数据传输,则除非客户端应用程序注册了校验回调函数,否则 JDBC 驱动程序将不允许进行传输。下面更详尽地介绍了进行校验调用的条件。下面是一个文件传输校验回调例程的示例。
class T_filetrans_callback implements sybase.jdbc4.sqlanywhere.SAValidateFileTransferCallback { T_filetrans_callback() { } public int callback(String filename, int is_write) { System.out.println( "File transfer granted for file " + filename + " with an is_write value of " + is_write ); return( 1 ); // 0 to disallow, non-zero to allow } } |
filename 参数是要读取或写入的文件的名称。如果请求读取(从客户端传输到服务器),则 is_write 参数为 0;如果请求写入,则该参数为非零值。如果不允许进行文件传输,则回调函数应返回 0,否则返回非零值。
为确保数据安全,服务器会跟踪请求文件传输的语句的源。服务器会确定语句是否是从客户端应用程序直接接收的。从客户端启动数据传输时,服务器会将语句源的相关信息发送到客户端软件。对于 JDBC 驱动程序而言,仅当是由于执行客户端应用程序直接发送的语句而请求数据传输时,它才会允许无条件传输数据。否则,应用程序必须注册上文所述的校验回调函数,如果未注册该函数,则传输会被拒绝,而且语句失败并出现一个错误。如果客户端语句调用的某个存储过程在数据库中已经存在,则对该存储过程本身的执行不被视为是客户端启动的语句所完成的。但是,如果客户端应用程序显式地创建一个临时存储过程,则服务器会将对该存储过程的执行视为是由客户端启动的。同样,如果客户端应用程序执行一个批处理语句,则该批处理语句的执行被视为是直接由客户端应用程序完成的。
下面的 Java 应用程序示例演示了如何使用 SQL Anywhere JDBC 4.0 驱动程序支持的回调。需要将 %SQLANY16%\java\sajdbc4.jar 文件放入类路径中。
import java.io.*; import java.sql.*; import java.util.*; public class callback { public static void main (String args[]) throws IOException { Connection con = null; Statement stmt; System.out.println ( "Starting... " ); con = connect(); if( con == null ) { return; // exception should already have been reported } System.out.println ( "Connected... " ); try { // create and register message handler callback T_message_handler message_worker = new T_message_handler(); ((sybase.jdbc4.sqlanywhere.IConnection)con).setASAMessageHandler( message_worker ); // create and register validate file transfer callback T_filetrans_callback filetran_worker = new T_filetrans_callback(); ((sybase.jdbc4.sqlanywhere.IConnection)con).setSAValidateFileTransferCallback( filetran_worker ); stmt = con.createStatement(); // execute message statements to force message handler to be called stmt.execute( "MESSAGE 'this is an info message' TYPE INFO TO CLIENT" ); stmt.execute( "MESSAGE 'this is an action message' TYPE ACTION TO CLIENT" ); stmt.execute( "MESSAGE 'this is a warning message' TYPE WARNING TO CLIENT" ); stmt.execute( "MESSAGE 'this is a status message' TYPE STATUS TO CLIENT" ); System.out.println( "\n==================\n" ); stmt.execute( "set temporary option allow_read_client_file='on'" ); try { stmt.execute( "drop procedure read_client_file_test" ); } catch( SQLException dummy ) { // ignore exception if procedure does not exist } // create procedure that will force file transfer callback to be called stmt.execute( "create procedure read_client_file_test()" + "begin" + " declare v long binary;" + " set v = read_client_file('sample.txt');" + "end" ); // call procedure to force validate file transfer callback to be called try { stmt.execute( "call read_client_file_test()" ); } catch( SQLException filetrans_exception ) { // Note: Since the file transfer callback returns 1, // do not expect a SQL exception to be thrown System.out.println( "SQLException: " + filetrans_exception.getMessage() ); } stmt.close(); con.close(); System.out.println( "Disconnected" ); } catch( SQLException sqe ) { printExceptions(sqe); } } private static Connection connect() { Connection connection; System.out.println( "Using jdbc4 driver" ); try { connection = DriverManager.getConnection( "jdbc:sqlanywhere:uid=DBA;pwd=sql" ); } catch( Exception e ) { System.err.println( "Error! Could not connect" ); System.err.println( e.getMessage() ); printExceptions( (SQLException)e ); connection = null; } return connection; } static private void printExceptions(SQLException sqe) { while (sqe != null) { System.out.println("Unexpected exception : " + "SqlState: " + sqe.getSQLState() + " " + sqe.toString() + ", ErrorCode: " + sqe.getErrorCode()); System.out.println( "==================\n" ); sqe = sqe.getNextException(); } } } |
![]() |
使用DocCommentXchange讨论此页。
|
版权 © 2013, SAP 股份公司或其关联公司. - SAP Sybase SQL Anywhere 16.0 |