Пакетная вставка для таблицы временных рядов Informix - PullRequest
0 голосов
/ 01 октября 2018

Я пытаюсь сделать пакетную вставку для таблицы в 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

И приведенный выше код успешно работает для нормальной таблицы.Но когда я пытаюсь выполнить одну и ту же пакетную вставку в таблицу временных рядов, она не работает, и при этом не возникает никаких исключений, а также тип возвращаемого значения int [] executeBatch () дает мне отсчет как ноль.

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

Есть идеи, что я упускаю или делаю неправильно?

1 Ответ

0 голосов
/ 02 октября 2018

Следует помнить, что для Informix Timeseries очень похожа на таблицу внутри таблицы.Поэтому, когда вы вставляете в вашу базовую таблицу, у вас есть столбец типа «timeseries».Фактические данные временных рядов затем попадают в этот столбец.Это приводит к некоторому странно выглядящему SQL, так как вы должны запускать операторы «UPDATE» для «вставки» данных временных рядов, поскольку мы в основном манипулируем этим одним столбцом в одной строке в нашей базовой таблице.

Вот полный пример, который использует 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
        }
    }
...