taosdata/TDengine

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

Open

#24,513 opened on Jan 18, 2024

View on GitHub
 (0 comments) (0 reactions) (0 assignees)C (5,002 forks)batch import
help wantedquestion

Repository metrics

Stars
 (24,849 stars)
PR merge metrics
 (Avg merge 1d 1h) (4 merged PRs in 30d)

Description

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";
}

}`

Contributor guide