TDengine icon indicating copy to clipboard operation
TDengine copied to clipboard

TSWSPreparedStatement.executeUpdate throws (0x22a):Stmt API usage error

Open mjmiki opened this issue 1 year ago • 0 comments

General Questions Description

使用WebSocket连接的方式通过参数绑定写入20万的数据(单条插入),调用executeUpdate()方法报错(0x22a):Stmt API usage error,但是第一条数据可以成功插入,第二条数据开始就报错API用法错误。taosAdapter中记录了第一条的执行日志也报错,日志如下 image 图1 但是同样的代码把executeUpdate()替换成execute()方法就能成功运行,程序和taosAdapter都不会报错。

然后尝试改进代码,每次循环都创建一个TSWSPreparedStatement,executeUpdate方法可以成功运行,程序也不会中断报错,数据也可以成功插入,但是taosAdapter中都是图1中的那种日志。

Environment

  • macOS系统(系统版本:13.3.1 (22E261) 处理器:3.6 GHz 四核Intel Core i3 内存:16G 磁盘空间:121G)
  • TDengine 客户端版本 3.2.2.0 服务端版本 3.2.2.0(客户端与服务端都在同一机器上)
  • taos-jdbcdriver 版本 3.2.4
  • JDK版本 jdk1.8

To Reproduce

重现代码如下 `import com.taosdata.jdbc.ws.TSWSPreparedStatement;

import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; import java.sql.Timestamp;

public class TestWSParamExecuteUpdate { private static final int RECORDS_PER_TABLE = 200000;

public static void main(String[] args) throws SQLException {
    System.load("/usr/local/lib/libtaos.dylib");
    insertData();
}

private static void insertData() throws SQLException {
    long start = System.currentTimeMillis();
    try (final Connection conn = getConnection()) {
        createTable(conn);

        final String psql = "INSERT INTO power.d0 USING power.meters TAGS('California.SanFrancisco', 2) VALUES(?, ?, ?, ?)";

        try (final TSWSPreparedStatement pst = (TSWSPreparedStatement) conn.prepareStatement(psql)) {
            System.out.println("-> 开始插入数据 <-");

            for (int i = 1; i <= RECORDS_PER_TABLE; i++) {
                String[] parts = getRowData(i).split(",");

                // 绑定数据列
                pst.setTimestamp(1, new Timestamp(Long.parseLong(parts[1]))); // ts
                pst.setFloat(2, Float.parseFloat(parts[2])); // current
                pst.setInt(3, Integer.parseInt(parts[3])); // voltage
                pst.setFloat(4, Float.parseFloat(parts[4])); // phase

                pst.executeUpdate();
                //pst.execute();

                if (i % 5000 == 0) {
                    System.out.println("------------已插入数据 " + i);
                }
            }
            System.out.println("执行完毕");
        } catch (SQLException e) {
            System.out.println("ERROR Message: " + e.getMessage());
            System.out.println("ERROR Code: " + e.getErrorCode());
            e.printStackTrace();
        }
    }  catch (SQLException e) {
        System.out.println("ERROR Message: " + e.getMessage());
        System.out.println("ERROR Code: " + e.getErrorCode());
        e.printStackTrace();
    } finally {
        System.out.println("-> 数据插入耗时 " + (System.currentTimeMillis() - start) + "ms <-");
    }
}

private static Connection getConnection() throws SQLException {
    System.out.println("-> 建立连接 <-");
    String jdbcUrl = "jdbc:TAOS-RS://localhost:6041/?batchfetch=true";
    return DriverManager.getConnection(jdbcUrl, "root", "taosdata");
}

private static void createTable(Connection conn) throws SQLException {
    System.out.println("-> 创建数据库和超级表 <-");
    try (Statement stmt = conn.createStatement()) {
        stmt.execute("DROP DATABASE IF EXISTS power");
        stmt.execute("CREATE DATABASE IF NOT EXISTS power KEEP 3650");
        stmt.executeUpdate("USE power");
        stmt.execute("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT)" +
                "TAGS (location BINARY(64), groupId INT)");
    }
}

private static String getRowData(int i) {
    final long time = 1691478964333L + i;
    return "d0," + time + ",10.30000,219,0.31000,California.SanFrancisco,2";
}

}`

mjmiki avatar Jan 18 '24 02:01 mjmiki