Informix的时间序列批处理表

时间:2018-10-01 13:17:50

标签: java jdbc prepared-statement informix batch-insert

我正在尝试为Informix中的表进行批处理插入。 我尝试使用以下代码对普通表执行批处理插入。

PreparedStatement ps = conn.prepareStatement("insert into tableName (a,b,c,d) values(?,?,?,?)"); 
ps.addBatch();
int[] n =  ps.executeBatch();
System.out.println("Array size : " + n.length); // Output : Array size : 1

以上代码对于普通表成功运行。 但是,当我尝试在时间序列表上进行相同的批处理插入时,它不起作用,也没有捕获到任何异常,executeBatch()的返回类型int []也使我的计数为零。

int[] n = ps.executeBatch();
System.out.println("Array size : " + n.length); // Output : Array size : 0

任何想法我想念或做错了什么吗?

1 个答案:

答案 0 :(得分:3)

要记住的一件事是,对于Informix,时间序列看起来很像表中的表。因此,当您在基表中插入数据时,您会看到一列“时间序列”。然后,实际的时间序列数据将进入该列。由于您必须运行“ UPDATE”语句以“插入”时间序列数据,因此导致出现一些看起来很奇怪的SQL,因为我们基本上是在操纵基表的那一行中的那一列。

这是一个使用JDBC设置基本时间序列表并在时间序列列上进行批量插入的完整示例。此示例假定您每分钟输入一次时间序列数据并进行模拟。

try(Connection c = DriverManager.getConnection("jdbc:informix-sqli://HOST:PORT/DATABASENAME", "username", "password") {
        try(Statement s = c.createStatement()) {
            //Auto registers timeseries if it does not exist (12.10 or higher versions of the server I believe)
            s.execute("INSERT INTO CalendarPatterns VALUES ('patt_1min', '{1 on , 59 off}, second')");
            s.execute("INSERT INTO CalendarTable (c_name, c_calendar)" + 
                    "     VALUES ('cal_1min', 'startdate(2018-01-01 00:00:00), " + 
                    "     pattstart(2018-01-01 00:00:00), pattname(patt_1min)')");
            s.execute("CREATE ROW TYPE ts_basic_row(entry_time DATETIME YEAR TO FRACTION(5), value float NOT NULL)");
            s.execute("CREATE TABLE tstab1( id integer, sensor timeseries(ts_basic_row))");
            s.execute("EXECUTE PROCEDURE TSContainerCreate ('test_container', 'rootdbs','ts_basic_row', 0, 0)");
        }
        //Insert a row with a timeseries column
        //Note the origin date matches the calendar pattern and calendar from above (explaining those is another exercise)
        try(PreparedStatement p = c.prepareStatement("INSERT INTO tstab1 VALUES(?, ?)")) {
            p.setInt(1, 1);
            p.setString(2, "origin(2018-01-01 12:00:00.00000), calendar(cal_1min), container(test_container), threshold(0), irregular, []");
            p.execute();    
        }

        //Now we can bulk insert into our timeseries
        //There are other mechanisms (setting IFX_USEPUT, using a bulk loader, etc) which could be faster, but this is a good start
        Calendar cal = Calendar.getInstance();
        Random r = new Random();
        try(PreparedStatement p = c.prepareStatement("UPDATE tstab1 SET sensor = PutElem(sensor, ROW(?, ?)::ts_basic_row) WHERE id=?")) {
            for(int i = 0; i < 1000; i++) {
                p.setDate(1, new java.sql.Date(cal.getTimeInMillis()));
                //add a minute to the calendar
                cal.add(Calendar.MINUTE, 1);
                p.setDouble(2, r.nextDouble()); //your sensor/timeseries value
                p.setInt(3, 1);  //The row in your base table (matching the id column)
                p.addBatch();
            }
            int [] results = p.executeBatch();
            System.out.println(Arrays.toString(results)); // a bunch of '1' values as expected
        }
    }