华为云用户手册

  • SQLExecute 功能描述 如果语句中存在参数标记的话,SQLExecute函数使用参数标记参数的当前值,执行一条准备好的SQL语句。 原型 1 SQLRETURN SQLExecute(SQLHSTMT StatementHandle); 参数 表8 SQLExecute参数 关键字 参数说明 StatementHandle 要执行语句的语句句柄。 返回值 SQL_SUC CES S:表示调用正确。 SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。 SQL_NEED_DATA:表示在执行SQL语句前没有提供足够的参数。 SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 SQL_NO_DATA:表示SQL语句不返回结果集。 SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。 SQL_STILL_EXECUTING:表示语句正在执行。 注意事项 当SQLExecute函数返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,可通过调用SQLGetDiagRec函数,并将HandleType和Handle参数设置为SQL_HANDLE_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 示例 参见:示例
  • SQLGetData 功能描述 SQLGetData返回结果集中某一列的数据。可以多次调用它来部分地检索不定长度的数据。 原型 1 2 3 4 5 6 SQLRETURN SQLGetData(SQLHSTMT StatementHandle, SQLUSMALLINT Col_or_Param_Num, SQLSMALLINT TargetType, SQLPOINTER TargetValuePtr, SQLLEN BufferLength, SQLLEN *StrLen_or_IndPtr); 参数 表12 SQLGetData参数 关键字 参数说明 StatementHandle 语句句柄,通过SQLAllocHandle获得。 Col_or_Param_Num 要返回数据的列号。结果集的列按增序从1开始编号。书签列的列号为0。 TargetType TargetValuePtr缓冲中的C数据类型的类型标识符。若TargetType为SQL_ARD_TYPE,驱动使用ARD中SQL_DESC_CONCISE_TYPE字段的类型标识符。若为SQL_C_DEFAULT,驱动根据源的SQL数据类型选择缺省的数据类型。 TargetValuePtr 输出参数:指向返回数据所在缓冲区的指针。 BufferLength TargetValuePtr所指向缓冲区的长度。 StrLen_or_IndPtr 输出参数:指向缓冲区的指针,在此缓冲区中返回长度或标识符的值。 SQL_SUCCESS:表示调用正确。 SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。 SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 SQL_NO_DATA:表示SQL语句不返回结果集。 SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。 SQL_STILL_EXECUTING:表示语句正在执行。 注意事项 当调用SQLFetch函数返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,通过调用SQLGetDiagRec函数,并将HandleType和Handle参数分别设置为SQL_HANDLE_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 示例 参见:示例
  • SQLGetDiagRec 功能描述 返回诊断记录的多个字段的当前值,其中诊断记录包含错误、警告及状态信息。 原型 1 2 3 4 5 6 7 8 SQLRETURN SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecNumber, SQLCHAR *SQLState, SQLINTEGER *NativeErrorPtr, SQLCHAR *MessageText, SQLSMALLINT BufferLength, SQLSMALLINT *TextLengthPtr); 参数 表13 SQLGetDiagRec参数 关键字 参数说明 HandleType 句柄类型标识符,它说明诊断所要求的句柄类型。必须为下列值之一: SQL_HANDLE_ENV SQL_HANDLE_DBC SQL_HANDLE_STMT SQL_HANDLE_DESC Handle 诊断数据结构的句柄,其类型由HandleType来指出。如果HandleType是SQL_HANDLE_ENV,Handle可以是共享的或非共享的环境句柄。 RecNumber 指出应用从查找信息的状态记录。状态记录从1开始编号。 SQLState 输出参数:指向缓冲区的指针,该缓冲区存储着有关RecNumber的五字符的SQLSTATE码。 NativeErrorPtr 输出参数:指向缓冲区的指针,该缓冲区存储着本地的错误码。 MessageText 指向缓冲区的指针,该缓冲区存储着诊断信息文本串。 BufferLength MessageText的长度。 TextLengthPtr 输出参数:指向缓冲区的指针,返回MessageText中的字节总数。如果返回字节数大于BufferLength,则MessageText中的诊断信息文本被截断成BufferLength减去NULL结尾字符的长度。 返回值 SQL_SUCCESS:表示调用正确。 SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。 SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。 注意事项 SQLGetDiagRec不发布自己的诊断记录。它用下列返回值来报告它自己的执行结果: SQL_SUCCESS:函数成功返回诊断信息。 SQL_SUCCESS_WITH_INFO:*MessageText太小以致不能容纳所请求的诊断信息。没有诊断记录生成。 SQL_INVALID_HANDLE:由HandType和Handle所指出的句柄是不合法句柄。 SQL_ERROR:RecNumber小于等于0或BufferLength小于0。 如果调用ODBC函数返回SQL_ERROR或SQL_SUCCESS_WITH_INFO,可调用SQLGetDiagRec返回诊断信息值SQLSTATE,SQLSTATE值的如下表。 表14 SQLSTATE值 SQLSATATE 错误 描述 HY000 一般错误 未定义特定的SQLSTATE所产生的一个错误。 HY001 内存分配错误 驱动程序不能分配所需要的内存来支持函数的执行或完成。 HY008 取消操作 调用SQLCancel取消执行语句后,依然在StatementHandle上调用函数。 HY010 函数系列错误 在为执行中的所有数据参数或列发送数据前就调用了执行函数。 HY013 内存管理错误 不能处理函数调用,可能由当前内存条件差引起。 HYT01 连接超时 数据源响应请求之前,连接超时。 IM001 驱动程序不支持此函数 调用了StatementHandle相关的驱动程序不支持的函数 示例 参见:示例
  • SQLExecDirect 功能描述 使用参数的当前值,执行一条准备好的语句。对于一次只执行一条SQL语句,SQLExecDirect是最快的执行方式。 原型 1 2 3 SQLRETURN SQLExecDirect(SQLHSTMT StatementHandle, SQLCHAR *StatementText, SQLINTEGER TextLength); 参数 表7 SQLExecDirect参数 关键字 参数说明 StatementHandle 语句句柄,通过SQLAllocHandle获得。 StatementText 要执行的SQL语句。不支持一次执行多条语句。 TextLength StatementText的长度。 返回值 SQL_SUCCESS:表示调用正确。 SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。 SQL_NEED_DATA:在执行SQL语句前没有提供足够的参数。 SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。 SQL_STILL_EXECUTING:表示语句正在执行。 SQL_NO_DATA:表示SQL语句不返回结果集。 注意事项 当调用SQLExecDirect函数返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,通过调用SQLGetDiagRec函数,并将HandleType和Handle参数设置为SQL_HANDLE_STMT和StatementHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 示例 参见:示例
  • SQLDisconnect 功能描述 关闭一个与特定连接句柄相关的连接。 原型 1 SQLRETURN SQLDisconnect(SQLHDBC ConnectionHandle); 参数 表6 SQLDisconnect参数 关键字 参数说明 ConnectionHandle 连接句柄,通过SQLAllocHandle获得。 返回值 SQL_SUCCESS:表示调用正确。 SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。 SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。 注意事项 当调用SQLDisconnect函数返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,通过调用SQLGetDiagRec函数,并将HandleType和Handle参数设置为SQL_HANDLE_DBC和ConnectionHandle,可得到一个相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 示例 参见:示例
  • SQLAllocHandle 功能描述 分配环境、连接、语句或描述符的句柄,它替代了ODBC 2.x函数SQLAllocEnv、SQLAllocConnect及SQLAllocStmt。 原型 1 2 3 SQLRETURN SQLAllocHandle(SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE *OutputHandlePtr); 参数 表1 SQLAllocHandle参数 关键字 参数说明 HandleType 由SQLAllocHandle分配的句柄类型。必须为下列值之一: SQL_HANDLE_ENV(环境句柄) SQL_HANDLE_DBC(连接句柄) SQL_HANDLE_STMT(语句句柄) SQL_HANDLE_DESC(描述句柄) 申请句柄顺序为,先申请环境句柄,再申请连接句柄,最后申请语句句柄,后申请的句柄都要依赖它前面申请的句柄。 InputHandle 将要分配的新句柄的类型。 如果HandleType为SQL_HANDLE_ENV,则这个值为SQL_NULL_HANDLE。 如果HandleType为SQL_HANDLE_DBC,则这一定是一个环境句柄。 如果HandleType为SQL_HANDLE_STMT或SQL_HANDLE_DESC,则它一定是一个连接句柄。 OutputHandlePtr 输出参数:一个缓冲区的指针,此缓冲区以新分配的数据结构存放返回的句柄。 返回值 SQL_SUCCESS:表示调用正确。 SQL_SUCCESS_WITH_INFO:表示会有一些警告信息。 SQL_ERROR:表示比较严重的错误,如:内存分配失败、建立连接失败等。 SQL_INVALID_HANDLE:表示调用无效句柄。其他API的返回值同理。 注意事项 当分配的句柄并非环境句柄时,如果SQLAllocHandle返回的值为SQL_ERROR,则它会将OutputHandlePtr的值设置为SQL_NULL_HDBC、SQL_NULL_HSTMT或SQL_NULL_HDESC。之后,通过调用带有适当参数的SQLGetDiagRec,其中HandleType和Handle被设置为IntputHandle的值,可得到相关的SQLSTATE值,通过SQLSTATE值可以查出调用此函数的具体信息。 示例 参见:示例
  • 常见问题处理 Server common name "xxxx" does not match host name "xxxxx" 此问题的原因是使用了SSL加密的“verify-full”选项,这时驱动程序会验证证书中的主机名与实际部署数据库的主机名是否一致。碰到此问题可以使用“verify-ca”选项,不再校验主机名;或者重新生成一套与数据库所在主机名相同的CA证书。 connect to server failed: no such file or directory 此问题可能的原因: 配置了错误的/不可达的数据库地址,或者端口 请检查数据源配置中的Servername及Port配置项。 服务器监听不正确 如果确认Servername及Port配置正确,请根据“操作步骤”中数据库服务器的相关配置,确保数据库监听了合适的网卡及端口。 防火墙及网闸设备 请确认防火墙设置,将数据库的通信端口添加到可信端口中。 如果有网闸设备,请确认相关的设置。 在指定的DSN中,驱动程序和应用程序之间的体系结构不匹配 此问题可能的原因:在64位程序中使用了32位驱动,或者相反。 C:\Windows\SysWOW64\odbcad32.exe:这是32位ODBC驱动管理器。 C:\Windows\System32\odbcad32.exe:这是64位ODBC驱动管理器。 The password-stored method is not supported. 此问题可能原因: 数据源中未配置sslmode配置项,请调整此项至allow或以上级别,允许SSL连接,此选项的更多说明,请见表1。 authentication method 10 not supported. 使用开源客户端碰到此问题,可能原因: 数据库中存储的口令校验只存储了SHA256格式哈希,而开源客户端只识别MD5校验,双方校验方法不匹配报错。 数据库并不存储用户口令,只存储用户口令的哈希码。 早期版本(V100R002C80SPC300之前的版本)的数据库只存储了SHA256格式的哈希,并未存储MD5的哈希,所以无法使用MD5做用户口令校验。 新版本(V100R002C80SPC300及之后版本)的数据库当用户更新用户口令或者新建用户时,会同时存储两种格式的哈希码,这时将兼容开源的认证协议。 但是当老版本升级到新版本时,由于哈希的不可逆性,所以数据库无法还原用户口令,进而生成新格式的哈希,所以仍然只保留了SHA256格式的哈希,导致仍然无法使用MD5做口令认证。 要解决该问题,参见以下操作: 新建一个数据库用户用于连接,或者重置准备使用的数据库用户的密码。 如果您使用的是管理员账号,参见重置密码。 如果是普通用户,可以先通过其他客户端工具(例如Data Studio)连接数据库后,使用ALTER USER语句来修改密码。 再尝试连接数据库。 unsupported frontend protocol 3.51: server supports 1.0 to 3.0 目标数据库版本过低,或者目标数据库为开源数据库。请使用对应版本的数据库驱动连接目标数据库。 FATAL: GSS authentication method is not allowed because XXXX user password is not disabled. 或:GSSAPI authentication not supported. 目标CN的pg_hba.conf里配置了当前客户端IP使用“gss”方式来做认证,该认证算法不支持用作客户端的身份认证,请修改到“sha256”后再试。 同时请注意,数据库当前不支持在集群内跨节点连接数据库,如果是在集群内跨节点连接CN出现此问题,请将业务程序调整到集群外后重试。
  • 常见问题处理 [UnixODBC][Driver Manager]Can't open lib 'xxx/xxx/psqlodbcw.so' : file not found. 此问题的可能原因: odbcinst.ini文件中配置的路径不正确 确认的方法:执行ls 报错信息中的路径,确保该psqlodbcw.so文件存在,同时具有执行权限。 psqlodbcw.so的依赖库不存在,或者不在系统环境变量中 确认的办法:执行ldd 报错信息中的路径,如果是缺少libodbc.so.1等UnixODBC的库,那么按照“操作步骤”中的方法重新配置UnixODBC,并确保它的安装路径下的lib目录添加到了LD_LIBRARY_PATH中;如果是缺少其他库,请将ODBC驱动包中的lib目录添加到LD_LIBRARY_PATH中。 [UnixODBC]connect to server failed: no such file or directory 此问题可能的原因: 配置了错误的/不可达的数据库地址,或者端口 请检查数据源配置中的Servername及Port配置项。 服务器监听不正确 如果确认Servername及Port配置正确,请根据“操作步骤”中数据库服务器的相关配置,确保数据库监听了合适的网卡及端口。 防火墙及网闸设备 请确认防火墙设置,将数据库的通信端口添加到可信端口中。 如果有网闸设备,请确认相关的设置。 [unixODBC]The password-stored method is not supported. 此问题可能原因: 数据源中未配置sslmode配置项。 解决办法: 请配置该选项至allow或以上选项。此配置的更多信息,见表3。 Server common name "xxxx" does not match host name "xxxxx" 此问题的原因: 使用了SSL加密的“verify-full”选项,驱动程序会验证证书中的主机名与实际部署数据库的主机名是否一致。 解决办法: 碰到此问题可以使用“verify-ca”选项,不再校验主机名;或者重新生成一套与数据库所在主机名相同的CA证书。 Driver's SQLAllocHandle on SQL_HANDLE_DBC failed 此问题的可能原因: 可执行文件(比如UnixODBC的isql,以下都以isql为例)与数据库驱动(psqlodbcw.so)依赖于不同的odbc的库版本:libodbc.so.1或者libodbc.so.2。此问题可以通过如下方式确认: ldd `which isql` | grep odbc ldd psqlodbcw.so | grep odbc 这时,如果输出的libodbc.so最后的后缀数字不同或者指向不同的磁盘物理文件,那么基本就可以断定是此问题。isql与psqlodbcw.so都会要求加载libodbc.so,这时如果它们加载的是不同的物理文件,便会导致两套完全同名的函数列表,同时出现在同一个可见域里(UnixODBC的libodbc.so.*的函数导出列表完全一致),产生冲突,无法加载数据库驱动。 解决办法: 确定一个要使用的UnixODBC,然后卸载另外一个(比如卸载库版本号为.so.2的UnixODBC),然后将剩下的.so.1的库,新建一个同名但是后缀为.so.2的软链接,便可解决此问题。 FATAL: Forbid remote connection with trust method! 由于安全原因,数据库CN禁止集群内部其他节点无认证接入。 如果要在集群内部访问CN,请将ODBC程序部署在CN所在机器,服务器地址使用"127.0.0.1"。建议业务系统单独部署在集群外部,否则可能会影响数据库运行性能。 [unixODBC][Driver Manager]Invalid attribute value 在使用SQL on other GaussDB 功能时碰到此问题,有可能是unixODBC的版本并非推荐版本,建议通过“odbcinst --version”命令排查环境中的unixODBC版本。 authentication method 10 not supported. 使用开源客户端碰到此问题,可能原因: 数据库中存储的口令校验只存储了SHA256格式哈希,而开源客户端只识别MD5校验,双方校验方法不匹配报错。 数据库并不存储用户口令,只存储用户口令的哈希码。 早期版本(V100R002C80SPC300之前的版本)的数据库只存储了SHA256格式的哈希,并未存储MD5的哈希,所以无法使用MD5做用户口令校验。 新版本(V100R002C80SPC300及之后版本)的数据库当用户更新用户口令或者新建用户时,会同时存储两种格式的哈希码,这时将兼容开源的认证协议。 但是当老版本升级到新版本时,由于哈希的不可逆性,所以数据库无法还原用户口令,进而生成新格式的哈希,所以仍然只保留了SHA256格式的哈希,导致仍然无法使用MD5做口令认证。 要解决该问题,可以更新用户口令;或者新建一个用户,赋予同等权限,使用新用户连接数据库。 unsupported frontend protocol 3.51: server supports 1.0 to 3.0 目标数据库版本过低,或者目标数据库为开源数据库。请使用对应版本的数据库驱动连接目标数据库。
  • javax.sql.ConnectionPoolDataSource javax.sql.ConnectionPoolDataSource是数据源连接池接口。 表9 对javax.sql.ConnectionPoolDataSource的支持情况 方法名 返回值类型 支持JDBC 4 getLoginTimeout() int Yes getLogWriter() PrintWriter Yes getPooledConnection() PooledConnection Yes getPooledConnection(String user,String password) PooledConnection Yes setLoginTimeout(int seconds) void Yes setLogWriter(PrintWriter out) void Yes
  • CopyManager CopyManager是GaussDB(DWS) JDBC驱动中提供的一个API接口类,用于批量向GaussDB(DWS)集群中导入数据。 CopyManager的继承关系 CopyManager类位于org.postgresql.copy Package中,继承自java.lang.Object类,该类的声明如下: public class CopyManager extends Object 构造方法 public CopyManager(BaseConnection connection) throws SQLException 常用方法 表14 CopyManager常用方法 返回值 方法 描述 throws CopyIn copyIn(String sql) - SQLException long copyIn(String sql, InputStream from) 使用COPY FROM STDIN从InputStream中快速向数据库中的表加载数据。 SQLException,IOException long copyIn(String sql, InputStream from, int bufferSize) 使用COPY FROM STDIN从InputStream中快速向数据库中的表加载数据。 SQLException,IOException long copyIn(String sql, Reader from) 使用COPY FROM STDIN从Reader中快速向数据库中的表加载数据。 SQLException,IOException long copyIn(String sql, Reader from, int bufferSize) 使用COPY FROM STDIN从Reader中快速向数据库中的表加载数据。 SQLException,IOException CopyOut copyOut(String sql) - SQLException long copyOut(String sql, OutputStream to) 将一个COPY TO STDOUT的结果集从数据库发送到OutputStream类中。 SQLException,IOException long copyOut(String sql, Writer to) 将一个COPY TO STDOUT的结果集从数据库发送到Writer类中。 SQLException,IOException
  • javax.sql.DataSource javax.sql.DataSource是数据源接口。 表10 对javax.sql.DataSource接口的支持情况 方法名 返回值类型 支持JDBC 4 getConnection() Connection Yes getConnection(String username,String password) Connection Yes getLoginTimeout() int Yes getLogWriter() PrintWriter Yes setLoginTimeout(int seconds) void Yes setLogWriter(PrintWriter out) void Yes
  • javax.sql.PooledConnection javax.sql.PooledConnection是由连接池创建的连接接口。 表11 对javax.sql.PooledConnection的支持情况 方法名 返回值类型 支持JDBC 4 addConnectionEventListener (ConnectionEventListener listener) void Yes close() void Yes getConnection() Connection Yes removeConnectionEventListener (ConnectionEventListener listener) void Yes addStatementEventListener (StatementEventListener listener) void Yes removeStatementEventListener (StatementEventListener listener) void Yes
  • javax.naming.Context javax.naming.Context是连接配置的上下文接口。 表12 对javax.naming.Context的支持情况 方法名 返回值类型 支持JDBC 4 bind(Name name, Object obj) void Yes bind(String name, Object obj) void Yes lookup(Name name) Object Yes lookup(String name) Object Yes rebind(Name name, Object obj) void Yes rebind(String name, Object obj) void Yes rename(Name oldName, Name newName) void Yes rename(String oldName, String newName) void Yes unbind(Name name) void Yes unbind(String name) void Yes
  • java.sql.ResultSet java.sql.ResultSet是执行结果集接口。 表6 对java.sql.ResultSet的支持情况 方法名 返回值类型 支持JDBC 4 findColumn(String columnLabel) int Yes getBigDecimal(int columnIndex) BigDecimal Yes getBigDecimal(String columnLabel) BigDecimal Yes getBoolean(int columnIndex) boolean Yes getBoolean(String columnLabel) boolean Yes getByte(int columnIndex) byte Yes getBytes(int columnIndex) byte[] Yes getByte(String columnLabel) byte Yes getBytes(String columnLabel) byte[] Yes getDate(int columnIndex) Date Yes getDate(String columnLabel) Date Yes getDouble(int columnIndex) double Yes getDouble(String columnLabel) double Yes getFloat(int columnIndex) float Yes getFloat(String columnLabel) float Yes getInt(int columnIndex) int Yes getInt(String columnLabel) int Yes getLong(int columnIndex) long Yes getLong(String columnLabel) long Yes getShort(int columnIndex) short Yes getShort(String columnLabel) short Yes getString(int columnIndex) String Yes getString(String columnLabel) String Yes getTime(int columnIndex) Time Yes getTime(String columnLabel) Time Yes getTimestamp(int columnIndex) Timestamp Yes getTimestamp(String columnLabel) Timestamp Yes isAfterLast() boolean Yes isBeforeFirst() boolean Yes isFirst() boolean Yes next() boolean Yes 一个Statement不能有多个处于“open”状态的ResultSet。 用于遍历结果集(ResultSet)的游标(Cursor)在被提交后不能保持“open”的状态。
  • java.sql.Statement java.sql.Statement是SQL语句接口。 表8 对java.sql.Statement的支持情况 方法名 返回值类型 支持JDBC 4 close() void Yes execute(String sql) boolean Yes executeQuery(String sql) ResultSet Yes executeUpdate(String sql) int Yes getConnection() Connection Yes getResultSet() ResultSet Yes getQueryTimeout() int Yes getUpdateCount() int Yes isClosed() boolean Yes setQueryTimeout(int seconds) void Yes setFetchSize(int rows) void Yes cancel() void Yes 通过setFetchSize可以减少结果集在客户端的内存占用情况。它的原理是通过将结果集打包成游标,然后分段处理,所以会加大数据库与客户端的通信量,会有性能损耗。 由于数据库游标是事务内有效,所以,在设置setFetchSize的同时,需要将连接设置为非自动提交模式,setAutoCommit(false)。同时在业务数据需要持久化到数据库中时,在连接上执行提交操作。
  • java.sql.ResultSetMetaData java.sql.ResultSetMetaData是对ResultSet对象相关信息的具体描述。 表7 对java.sql.ResultSetMetaData的支持情况 方法名 返回值类型 支持JDBC 4 getColumnCount() int Yes getColumnName(int column) String Yes getColumnType(int column) int Yes getColumnTypeName(int column) String Yes
  • java.sql.Driver java.sql.Driver是数据库驱动接口。 表4 对java.sql.Driver的支持情况 方法名 返回值类型 支持JDBC 4 acceptsURL(String url) boolean Yes connect(String url, Properties info) Connection Yes jdbcCompliant() boolean Yes getMajorVersion() int Yes getMinorVersion() int Yes
  • java.sql.PreparedStatement java.sql.PreparedStatement是预处理语句接口。 表5 对java.sql.PreparedStatement的支持情况 方法名 返回值类型 支持JDBC 4 clearParameters() void Yes execute() boolean Yes executeQuery() ResultSet Yes executeUpdate() int Yes getMetaData() ResultSetMetaData Yes setBoolean(int parameterIndex, boolean x) void Yes setBigDecimal(int parameterIndex, BigDecimal x) void Yes setByte(int parameterIndex, byte x) void Yes setBytes(int parameterIndex, byte[] x) void Yes setDate(int parameterIndex, Date x) void Yes setDouble(int parameterIndex, double x) void Yes setFloat(int parameterIndex, float x) void Yes setInt(int parameterIndex, int x) void Yes setLong(int parameterIndex, long x) void Yes setNString(int parameterIndex, String value) void Yes setShort(int parameterIndex, short x) void Yes setString(int parameterIndex, String x) void Yes addBatch() void Yes executeBatch() int[] Yes clearBatch() void Yes addBatch()、execute()必须在clearBatch()之后才能执行。 调用executeBatch()方法并不会清除batch。用户必须显式使用clearBatch()清除 。 在添加了一个batch的绑定变量后,用户若想重用这些值(再次添加一个batch),无需再次使用set*()方法 。 以下方法是从java.sql.Statement继承而来:close,execute,executeQuery,executeUpdate,getConnection,getResultSet,getUpdateCount,isClosed,setMaxRows, setFetchSize。
  • java.sql.DatabaseMetaData java.sql.DatabaseMetaData是数据库对象定义接口。 表3 对java.sql.DatabaseMetaData的支持情况 方法名 返回值类型 支持JDBC 4 getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) ResultSet Yes getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) ResultSet Yes getTableTypes() ResultSet Yes getUserName() String Yes isReadOnly() boolean Yes nullsAreSortedHigh() boolean Yes nullsAreSortedLow() boolean Yes nullsAreSortedAtStart() boolean Yes nullsAreSortedAtEnd() boolean Yes getDatabaseProductName() String Yes getDatabaseProductVersion() String Yes getDriverName() String Yes getDriverVersion() String Yes getDriverMajorVersion() int Yes getDriverMinorVersion() int Yes usesLocalFiles() boolean Yes usesLocalFilePerTable() boolean Yes supportsMixedCaseIdentifiers() boolean Yes storesUpperCaseIdentifiers() boolean Yes storesLowerCaseIdentifiers() boolean Yes supportsMixedCaseQuotedIdentifiers() boolean Yes storesUpperCaseQuotedIdentifiers() boolean Yes storesLowerCaseQuotedIdentifiers() boolean Yes storesMixedCaseQuotedIdentifiers() boolean Yes supportsAlterTableWithAddColumn() boolean Yes supportsAlterTableWithDropColumn() boolean Yes supportsColumnAliasing() boolean Yes nullPlusNonNullIsNull() boolean Yes supportsConvert() boolean Yes supportsConvert(int fromType, int toType) boolean Yes supportsTableCorrelationNames() boolean Yes supportsDifferentTableCorrelationNames() boolean Yes supportsExpressionsInOrderBy() boolean Yes supportsOrderByUnrelated() boolean Yes supportsGroupBy() boolean Yes supportsGroupByUnrelated() boolean Yes supportsGroupByBeyondSelect() boolean Yes supportsLikeEscapeClause() boolean Yes supportsMultipleResultSets() boolean Yes supportsMultipleTransactions() boolean Yes supportsNonNullableColumns() boolean Yes supportsMinimumSQLGrammar() boolean Yes supportsCoreSQLGrammar() boolean Yes supportsExtendedSQLGrammar() boolean Yes supportsANSI92EntryLevelSQL() boolean Yes supportsANSI92IntermediateSQL() boolean Yes supportsANSI92FullSQL() boolean Yes supportsIntegrityEnhancementFacility() boolean Yes supportsOuterJoins() boolean Yes supportsFullOuterJoins() boolean Yes supportsLimitedOuterJoins() boolean Yes isCatalogAtStart() boolean Yes supportsSchemasInDataManipulation() boolean Yes supportsSavepoints() boolean Yes supportsResultSetHoldability(int holdability) boolean Yes getResultSetHoldability() int Yes getDatabaseMajorVersion() int Yes getDatabaseMinorVersion() int Yes getJDBCMajorVersion() int Yes getJDBCMinorVersion() int Yes
  • java.sql.CallableStatement java.sql.CallableStatement是存储过程执行接口。 表2 对java.sql.CallableStatement的支持情况 方法名 返回值类型 支持JDBC 4 registerOutParameter(int parameterIndex, int type) void Yes wasNull() boolean Yes getString(int parameterIndex) String Yes getBoolean(int parameterIndex) boolean Yes getByte(int parameterIndex) byte Yes getShort(int parameterIndex) short Yes getInt(int parameterIndex) int Yes getLong(int parameterIndex) long Yes getFloat(int parameterIndex) float Yes getDouble(int parameterIndex) double Yes getBigDecimal(int parameterIndex) BigDecimal Yes getBytes(int parameterIndex) byte[] Yes getDate(int parameterIndex) Date Yes getTime(int parameterIndex) Time Yes getTimestamp(int parameterIndex) Timestamp Yes getObject(int parameterIndex) Object Yes 不允许含有OUT参数的语句执行批量操作。 以下方法是从java.sql.Statement继承而来:close,execute,executeQuery,executeUpdate,getConnection,getResultSet,getUpdateCount,isClosed,setMaxRows , setFetchSize。 以下方法是从java.sql.PreparedStatement继承而来:addBatch,clearParameters,execute,executeQuery,executeUpdate,getMetaData,setBigDecimal,setBoolean,setByte,setBytes,setDate,setDouble,setFloat,setInt,setLong,setNull,setObject,setString,setTime,setTimestamp 。
  • java.sql.Connection java.sql.Connection是数据库连接接口。 表1 对java.sql.Connection接口的支持情况 方法名 返回值类型 支持JDBC 4 close() void Yes commit() void Yes createStatement() Statement Yes getAutoCommit() boolean Yes getClientInfo() Properties Yes getClientInfo(String name) String Yes getTransactionIsolation() int Yes isClosed() boolean Yes isReadOnly() boolean Yes prepareStatement(String sql) PreparedStatement Yes rollback() void Yes setAutoCommit(boolean autoCommit) void Yes setClientInfo(Properties properties) void Yes setClientInfo(String name,String value) void Yes 接口内部默认使用自动提交模式,若通过setAutoCommit(false)关闭自动提交,将会导致后面执行的语句都受到显式事务包裹,数据库中不支持事务中执行的语句不能在此模式下执行。
  • 从MySQL向GaussDB(DWS)进行数据迁移 下面示例演示如何通过CopyManager从mysql向GaussDB(DWS)进行数据迁移的过程。 以下用例以gsjdbc4.jar为例,如果要使用gsjdbc200.jar,请替换驱动类名(将代码中的“org.postgresql”替换成“com.huawei.gauss200.jdbc”)与连接URL串前缀(将“jdbc:postgresql”替换为“jdbc:gaussdb”)。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 import java.io.StringReader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import org.postgresql.copy.CopyManager; import org.postgresql.core.BaseConnection; public class Migration{ public static void main(String[] args) { String url = new String("jdbc:postgresql://10.180.155.74:8000/gaussdb"); //数据库URL String user = new String("jack"); //DWS用户名 String pass = new String("********"); //DWS密码 String tablename = new String("migration_table"); //定义表信息 String delimiter = new String("|"); //定义分隔符 String encoding = new String("UTF8"); //定义字符集 String driver = "org.postgresql.Driver"; StringBuffer buffer = new StringBuffer(); //定义存放格式 化数据的缓存 try { //获取源数据库查询结果集 ResultSet rs = getDataSet(); //遍历结果集,逐行获取记录 //将每条记录中各字段值,按指定分隔符分割,由换行符结束,拼成一个字符串 //把拼成的字符串,添加到缓存buffer while (rs.next()) { buffer.append(rs.getString(1) + delimiter + rs.getString(2) + delimiter + rs.getString(3) + delimiter + rs.getString(4) + "\n"); } rs.close(); try { //建立目标数据库连接 Class.forName(driver); Connection conn = DriverManager.getConnection(url, user, pass); BaseConnection baseConn = (BaseConnection) conn; baseConn.setAutoCommit(false); //初始化表信息 String sql = "Copy " + tablename + " from STDIN DELIMITER " + "'" + delimiter + "'" + " ENCODING " + "'" + encoding + "'"; //提交缓存buffer中的数据 CopyManager cp = new CopyManager(baseConn); StringReader reader = new StringReader(buffer.toString()); cp.copyIn(sql, reader); baseConn.commit(); reader.close(); baseConn.close(); } catch (ClassNotFoundException e) { e.printStackTrace(System.out); } catch (SQLException e) { e.printStackTrace(System.out); } } catch (Exception e) { e.printStackTrace(); } } 从源数据库返回查询结果集: private static ResultSet getDataSet() { ResultSet rs = null; try { Class.forName("com.mysql.jdbc.Driver").newInstance(); Connection conn = DriverManager.getConnection("jdbc:mysql://10.119.179.227:3306/jack?useSSL=false&allowPublicKeyRetrieval=true", "jack", "********"); Statement stmt = conn.createStatement(); rs = stmt.executeQuery("select * from migration_table"); } catch (SQLException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return rs; } }
  • 通过本地文件导入导出数据 在使用JAVA语言基于GaussDB(DWS)进行二次开发时,可以使用CopyManager接口,通过流方式,将数据库中的数据导出到本地文件或者将本地文件导入数据库中,文件格式支持 CS V、TEXT等格式。 样例程序如下,执行时需要加载GaussDB(DWS) jdbc驱动。 以下用例以gsjdbc4.jar为例,如果要使用gsjdbc200.jar,请替换驱动类名(将代码中的“org.postgresql”替换成“com.huawei.gauss200.jdbc”)与连接URL串前缀(将“jdbc:postgresql”替换为“jdbc:gaussdb”)。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 import java.sql.Connection; import java.sql.DriverManager; import java.io.IOException; import java.io.FileInputStream; import java.io.FileOutputStream; import java.sql.SQLException; import org.postgresql.copy.CopyManager; import org.postgresql.core.BaseConnection; public class Copy{ public static void main(String[] args) { String urls = new String("jdbc:postgresql://10.180.155.74:8000/gaussdb"); //数据库URL String username = new String("jack"); //用户名 String password = new String("********"); //密码 String tablename = new String("migration_table"); //定义表信息 String tablename1 = new String("migration_table_1"); //定义表信息 String driver = "org.postgresql.Driver"; Connection conn = null; try { Class.forName(driver); conn = DriverManager.getConnection(urls, username, password); } catch (ClassNotFoundException e) { e.printStackTrace(System.out); } catch (SQLException e) { e.printStackTrace(System.out); } 执行数据导入导出: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 // 将migration_table查询结果导出到本地文件d:/data.txt try { copyToFile(conn, "d:/data.txt", "(SELECT * FROM migration_table)"); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } //将d:/data.txt中的数据导入到migration_table_1中。 try { copyFromFile(conn, "d:/data.txt", migration_table_1); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 将migration_table_1中的数据导出到本地文件d:/data1.txt try { copyToFile(conn, "d:/data1.txt", migration_table_1); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void copyFromFile(Connection connection, String filePath, String tableName) throws SQLException, IOException { FileInputStream fileInputStream = null; try { CopyManager copyManager = new CopyManager((BaseConnection)connection); fileInputStream = new FileInputStream(filePath); copyManager.copyIn("COPY " + tableName + " FROM STDIN", fileInputStream); } finally { if (fileInputStream != null) { try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } public static void copyToFile(Connection connection, String filePath, String tableOrQuery) throws SQLException, IOException { FileOutputStream fileOutputStream = null; try { CopyManager copyManager = new CopyManager((BaseConnection)connection); fileOutputStream = new FileOutputStream(filePath); copyManager.copyOut("COPY " + tableOrQuery + " TO STDOUT", fileOutputStream); } finally { if (fileOutputStream != null) { try { fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
  • 示例2 客户端内存占用过多解决 此示例主要使用setFetchSize来调整客户端内存使用,它的原理是通过数据库游标来分批获取服务器端数据,但它会加大网络交互,可能会损失部分性能。 由于游标事务内有效,故需要先关闭自动提交。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 // 关闭掉自动提交 conn.setAutoCommit(false); Statement st = conn.createStatement(); // 打开游标,每次获取50行数据 st.setFetchSize(50); ResultSet rs = st.executeQuery("SELECT * FROM mytable"); while (rs.next()){ System.out.print("a row was returned."); } rs.close(); // 关闭服务器游标。 st.setFetchSize(0); rs = st.executeQuery("SELECT * FROM mytable"); while (rs.next()){ System.out.print("many rows were returned."); } rs.close(); // Close the statement. st.close();
  • 获取结果集中的数据 ResultSet对象提供了丰富的方法,以获取结果集中的数据。获取数据常用的方法如表4所示,其他方法请参考JDK官方文档。 表4 ResultSet对象的常用方法 方法 描述 int getInt(int columnIndex) 按列标获取int型数据。 int getInt(String columnLabel) 按列名获取int型数据。 String getString(int columnIndex) 按列标获取String型数据。 String getString(String columnLabel) 按列名获取String型数据。 Date getDate(int columnIndex) 按列标获取Date型数据 Date getDate(String columnLabel) 按列名获取Date型数据。
  • 设置结果集类型 不同类型的结果集有各自的应用场景,应用程序需要根据实际情况选择相应的结果集类型。在执行SQL语句过程中,都需要先创建相应的语句对象,而部分创建语句对象的方法提供了设置结果集类型的功能。具体的参数设置如表1所示。涉及的Connection的方法如下: 1 2 3 4 5 6 7 8 //创建一个Statement对象,该对象将生成具有给定类型和并发性的ResultSet对象。 createStatement(int resultSetType, int resultSetConcurrency); //创建一个PreparedStatement对象,该对象将生成具有给定类型和并发性的ResultSet对象。 prepareStatement(String sql, int resultSetType, int resultSetConcurrency); //创建一个CallableStatement对象,该对象将生成具有给定类型和并发性的ResultSet对象。 prepareCall(String sql, int resultSetType, int resultSetConcurrency); 表1 结果集类型 参数 描述 resultSetType 表示结果集的类型,具体有三种类型: ResultSet.TYPE_FORWARD_ONLY:ResultSet只能向前移动。是缺省值。 ResultSet.TYPE_SCROLL_SENSITIVE:在修改后重新滚动到修改所在行,可以看到修改后的结果。 ResultSet.TYPE_SCROLL_INSENSITIVE:对可修改例程所做的编辑不进行显示。 说明: 结果集从数据库中读取了数据之后,即使类型是ResultSet.TYPE_SCROLL_SENSITIVE,也不会看到由其他事务在这之后引起的改变。调用ResultSet的refreshRow()方法,可进入数据库并从其中取得当前游标所指记录的最新数据。 resultSetConcurrency 表示结果集的并发,具体有两种类型: ResultSet.CONCUR_READ_ONLY:如果不从结果集中的数据建立一个新的更新语句,不能对结果集中的数据进行更新。 ResultSet.CONCUR_UPDATEABLE:可改变的结果集。对于可滚动的结果集,可对结果集进行适当的改变。
  • 获取结果集中光标的位置 对于可滚动的结果集,可能会调用定位方法来改变光标的位置。JDBC驱动程序提供了获取结果集中光标所处位置的方法。获取光标位置的方法如表3所示。 表3 获取结果集光标的位置 方法 描述 isFirst() 是否在一行。 isLast() 是否在最后一行。 isBeforeFirst() 是否在第一行之前。 isAfterLast() 是否在最后一行之后。 getRow() 获取当前在第几行。
  • 在结果集中定位 ResultSet对象具有指向其当前数据行的光标。最初,光标被置于第一行之前。next方法将光标移动到下一行;因为该方法在ResultSet对象没有下一行时返回false,所以可以在while循环中使用它来迭代结果集。但对于可滚动的结果集,JDBC驱动程序提供更多的定位方法,使ResultSet指向特定的行。定位方法如表2所示。 表2 在结果集中定位的方法 方法 描述 next() 把ResultSet向下移动一行。 previous() 把ResultSet向上移动一行。 beforeFirst() 把ResultSet定位到第一行之前。 afterLast() 把ResultSet定位到最后一行之后。 first() 把ResultSet定位到第一行。 last() 把ResultSet定位到最后一行。 absolute(int) 把ResultSet移动到参数指定的行数。 relative(int) 向前或者向后移动参数指定的行。
  • 执行预编译SQL语句 预编译语句是只编译和优化一次,然后可以通过设置不同的参数值多次使用。由于已经预先编译好,后续使用会减少执行时间。因此,如果多次执行一条语句,请选择使用预编译语句。可以按以下步骤执行: 调用Connection的prepareStatement方法创建预编译语句对象。 1 PreparedStatement pstmt = con.prepareStatement("UPDATE customer_t1 SET c_customer_name = ? WHERE c_customer_sk = 1"); 调用PreparedStatement的setShort设置参数。 1 pstmt.setShort(1, (short)2); 调用PreparedStatement的executeUpdate方法执行预编译SQL语句。 1 int rowcount = pstmt.executeUpdate(); 调用PreparedStatement的close方法关闭预编译语句对象。 1 pstmt.close();
  • 调用存储过程 GaussDB(DWS)支持通过JDBC直接调用事先创建的存储过程,步骤如下: 调用Connection的prepareCall方法创建调用语句对象。 1 CallableStatement cstmt = myConn.prepareCall("{? = CALL TESTPROC(?,?,?)}"); 调用CallableStatement的setInt方法设置参数。 1 2 3 cstmt.setInt(2, 50); cstmt.setInt(1, 20); cstmt.setInt(3, 90); 调用CallableStatement的registerOutParameter方法注册输出参数。 1 cstmt.registerOutParameter(4, Types.INTEGER); //注册out类型的参数,类型为整型。 调用CallableStatement的execute执行方法调用。 1 cstmt.execute(); 调用CallableStatement的getInt方法获取输出参数。 1 int out = cstmt.getInt(4); //获取out参数 示例: 1 2 3 4 5 6 7 8 9 10 11 12 //在数据库中已创建了如下存储过程,它带有out参数。 create or replace procedure testproc ( psv_in1 in integer, psv_in2 in integer, psv_inout in out integer ) as begin psv_inout := psv_in1 + psv_in2 + psv_inout; end; / 调用CallableStatement的close方法关闭调用语句。 1 cstmt.close(); 很多的数据库例如Connection、Statement和ResultSet都有close()方法,在使用完对象后应把它们关闭。要注意的是,Connection的关闭将间接关闭所有与它关联的Statement,Statement的关闭间接关闭了ResultSet。 一些JDBC驱动程序还提供命名参数的方法来设置参数。命名参数的方法允许根据名称而不是顺序来设置参数,若参数有默认值,则可以不用指定参数值就可以使用此参数的默认值。即使存储过程中参数的顺序发生了变更,也不必修改应用程序。目前GaussDB(DWS)数据库的JDBC驱动程序不支持此方法。 GaussDB(DWS)数据库不支持带有输出参数的函数,也不支持存储过程和函数参数默认值。 当游标作为存储过程的返回值时,如果使用JDBC调用该存储过程,返回的游标将不可用。 存储过程不能和普通SQL在同一条语句中执行。
共100000条