Vertica6.1.x对超长字符串的处理
来源:互联网 发布:sas软件使用 编辑:程序博客网 时间:2024/06/04 20:03
在Vertica5中,对于超长的字符串类型的列在插入/更新的时候会自动将字符串的值揭短成数据库中定义长度,然后将截短后的字符串写入数据库,但是在升级了Vertica和Vertica JDBC驱动到6以后,再执行同样的操作,就会出异常,看下面代码
这里创建了一个表,其中字符串列的长度为32字节
CREATE TABLE t1 (id Integer NOT NULL,col1 Varchar(32),col2 Varchar(32),col3 Varchar(32),CONSTRAINT C_PRIMARY PRIMARY KEY (id));
然后看Java代码,这里使用的是Batch模式插入,使用Batch模式主要是为了有更好的写入性能
package com.googlecode.garbagecan.dbtest.vertica;import java.sql.BatchUpdateException;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ParameterMetaData;import java.sql.PreparedStatement;import java.sql.SQLException;import java.util.Arrays;public class VerticaTest {// vertica5 driver// private static final String driver = "com.vertica.Driver";// vertica6 driverprivate static final String driver = "com.vertica.jdbc.Driver";private static final String url = "jdbc:vertica://padev3:5433/padb";private static final String username = "pauser";private static final String password = "papassword";public static void main(String[] args) throws Exception {test();}private static void test() throws Exception {Connection conn = getConnection();PreparedStatement ps = null;try {ps = conn.prepareStatement("insert into t1(id, col1, col2, col3)values(?,?,?,?)");ps.setInt(1, 1);ps.setObject(2, "value1");ps.setObject(3, "value2");ps.setObject(4, "value3");ps.addBatch();ps.setInt(1, 2);ps.setObject(2, "value1");ps.setObject(3, "value2");ps.setObject(4, "=========================================================");ps.addBatch();int[] results = ps.executeBatch();System.out.println("No exception and results: " + Arrays.toString(results));conn.commit();} catch(SQLException ex) {if (ex instanceof BatchUpdateException) {System.out.println("SQLException and results: " + Arrays.toString(((BatchUpdateException) ex).getUpdateCounts()));}conn.rollback();throw ex;} finally {conn.close();}}private static Connection getConnection() throws Exception {Class.forName(driver);Connection conn = DriverManager.getConnection(url, username, password);conn.setAutoCommit(false);return conn;}}
这里向数据库表中用Batch模式插入了两条记录,其中第一条记录的col3的值是小于schema中定义的长度的,而第二条记录的col3的值大于schema。
首先在Vertica5上用Vertica5的JDBC驱动测试,得出如下结果:
No exception and results: [1, 1]返回结果是[1, 1]说明两条记录都写入成功,查看数据库,第二条记录的col3列的值被截断了。
然后我们在Vertica6上用Vertica6的JDBC驱动再测试一下,得出结果如下:
SQLException and results: [1, -3]Exception in thread "main" java.sql.BatchUpdateException: [Vertica][VJDBC](100172) One or more rows were rejected by the server.at com.vertica.jdbc.SStatement.processBatchResults(Unknown Source)at com.vertica.jdbc.SPreparedStatement.executeBatch(Unknown Source)at com.googlecode.garbagecan.dbtest.vertica.VerticaTest.test(VerticaTest.java:45)at com.googlecode.garbagecan.dbtest.vertica.VerticaTest.main(VerticaTest.java:22)
代码执行的时候出了异常,然后我们在捕获的异常代码块中用下面的代码来获取执行的结果
if (ex instanceof BatchUpdateException) {System.out.println("SQLException and results: " + Arrays.toString(((BatchUpdateException) ex).getUpdateCounts()));}结果是[1, -3],说明第一条记录执行成功,第二条执行失败。这里由于在出异常的时候执行了rollback操作,所以数据库里应该没有值。
查看Vertica6.1.x的文档https://my.vertica.com/docs/6.1.x/HTML/index.htm#16701.htm,在新版本中只能自己来trancate超过数据库定义的字符串,所以没办法只能自己干了。下面是更新后的代码:
package com.googlecode.garbagecan.dbtest.vertica;import java.sql.BatchUpdateException;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ParameterMetaData;import java.sql.PreparedStatement;import java.sql.SQLException;import java.util.Arrays;public class VerticaTest {private static final String driver = "com.vertica.jdbc.Driver";private static final String url = "jdbc:vertica://padev3:5433/padb";private static final String username = "pauser";private static final String password = "papassword";public static void main(String[] args) throws Exception {test();}private static void test() throws Exception {Connection conn = getConnection();PreparedStatement ps = null;try {ps = conn.prepareStatement("insert into t1(id, col1, col2, col3)values(?,?,?,?)");ps.setInt(1, 1);ps.setObject(2, "value1");ps.setObject(3, "value2");ps.setObject(4, "value3");ps.addBatch();ps.setInt(1, 2);ps.setObject(2, "value1");ps.setObject(3, "value2");ParameterMetaData pmd = ps.getParameterMetaData();String col3 = "=========================================================";if (pmd.getParameterTypeName(4).equalsIgnoreCase("VARCHAR")) {int maxLength = pmd.getPrecision(4);if (col3.toString().length() > maxLength) {col3 = col3.substring(0, maxLength);}}ps.setObject(4, col3);ps.addBatch();int[] results = ps.executeBatch();System.out.println("No exception and results: " + Arrays.toString(results));conn.commit();} catch(SQLException ex) {if (ex instanceof BatchUpdateException) {System.out.println("SQLException and results: " + Arrays.toString(((BatchUpdateException) ex).getUpdateCounts()));}conn.rollback();throw ex;} finally {conn.close();}}private static Connection getConnection() throws Exception {Class.forName(driver);Connection conn = DriverManager.getConnection(url, username, password);conn.setAutoCommit(false);return conn;}}
其中的使用了ParameterMetaData类来获取数据库中定义的列的长度,然后根据定义的长度来truncate数据长度,然后再加入到Batch里执行。下面是修改后代码执行的结果:
No exception and results: [1, 1]
返回结果是[1, 1]说明两条记录都写入成功,查看数据库,第二条记录的col3列的值被截断了。
所以,Vertica的6.1.x的版本和之前版本还是有很多行为不一致的问题,这次在升级的过程中还发现了很多,下次有机会再整理一下。
0 0
- Vertica6.1.x对超长字符串的处理
- 说说Vertica5和Vertica6.1.x对写入错误和异常的处理
- 超长字符串换行处理
- 对超长的文字换行处理:程序和CSS样式
- SQLServer 存储过程处理超长字符串问题
- 超长短信的处理办法
- 超长短信的处理办法
- 超长短信的处理办法
- 处理超长位数的数
- 超长字符串
- 超长字符串
- Javascript对字符串的处理
- js对字符串的处理
- C++对字符串的处理
- PHP对字符串的处理
- dos 对字符串的处理
- python对字符串的处理
- Matlab 对字符串的处理
- JAVA中的Calendar
- 织梦自定义模型采集
- javascript深入理解js闭包
- 20131212孤独者之旅08
- SQL触发器使用样例
- Vertica6.1.x对超长字符串的处理
- POJ 2718 Smallest Difference (dfs)
- leetcode Trapping Rain Water
- 线程-保护块示例程序
- java删除文件时总是返回false,删不掉
- hibernate annotation 之 主键生成策略
- 增量聚集
- Python模块 - __init__.py
- Linux 下怎么用命令修改分辨率