tursodatabase/turso · error · SQLException

turso does not support stored procedures

Error message

turso does not support stored procedures

What it means

prepareCall (all overloads) throws because CallableStatement, the JDBC interface for stored procedures, is unsupported: a SQLite-compatible engine has no stored procedures to call. The exception is thrown for any SQL string passed, including plain SELECTs, since CallableStatement itself is not implemented by this driver.

Source

Thrown at bindings/java/src/main/java/tech/turso/jdbc4/JDBC4Connection.java:225

  public CallableStatement prepareCall(String sql) throws SQLException {
    return prepareCall(
        sql,
        ResultSet.TYPE_FORWARD_ONLY,
        ResultSet.CONCUR_READ_ONLY,
        ResultSet.CLOSE_CURSORS_AT_COMMIT);
  }

  @Override
  public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency)
      throws SQLException {
    return prepareCall(sql, resultSetType, resultSetConcurrency, ResultSet.CLOSE_CURSORS_AT_COMMIT);
  }

  @Override
  public CallableStatement prepareCall(
      String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
      throws SQLException {
    throw new SQLException("turso does not support stored procedures");
  }

  @Override
  public PreparedStatement prepareStatement(String sql) throws SQLException {
    return prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
  }

  @Override
  public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
      throws SQLException {
    return prepareStatement(
        sql, resultSetType, resultSetConcurrency, ResultSet.CLOSE_CURSORS_AT_COMMIT);
  }

  @Override
  public PreparedStatement prepareStatement(
      String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
      throws SQLException {

View on GitHub (pinned to bad083fafb)

Solutions

  1. Replace CallableStatement with PreparedStatement executing the equivalent inline SQL (SELECT for queries, INSERT/UPDATE/DELETE for mutations).
  2. Move stored-procedure logic into application code (a service method wrapping plain statements in one transaction).
  3. For small pieces of server-side logic, consider SQL triggers or views where they genuinely substitute.
  4. Remove @NamedStoredProcedureQuery / statementType="CALLABLE" mappings when migrating to Turso.

Example fix

// before
try (CallableStatement cs = conn.prepareCall("{call get_customer(?)}")) {
    cs.setLong(1, customerId);
    ResultSet rs = cs.executeQuery();
}

// after
try (PreparedStatement ps = conn.prepareStatement(
        "SELECT id, name FROM customers WHERE id = ?")) {
    ps.setLong(1, customerId);
    ResultSet rs = ps.executeQuery();
}
Defensive patterns

Strategy: validation

Validate before calling

private static boolean isStoredProcedureCall(String sql) {
    String s = sql.trim().toLowerCase(Locale.ROOT);
    return s.startsWith("{call") || s.startsWith("{") || s.contains("call ");
}
if (isStoredProcedureCall(sql)) {
    throw new UnsupportedOperationException(
        "stored procedures are not supported by Turso; inline the SQL instead");
}

Type guard

private static boolean requiresCallableStatement(String sql) {
    return isStoredProcedureCall(sql);
}

Try / catch

try {
    stmt = conn.prepareCall(sql);
} catch (SQLException e) {
    if (sql.trim().startsWith("{")) {
        throw new UnsupportedOperationException(
            "rewrite stored procedure call as inline SQL: " + sql, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: conn.prepareCall("{call some_proc(?)}"); JPA/Hibernate StoredProcedureQuery usage; MyBatis mappers with CallableStatement statementType; iBATIS/legacy DAO code; any {call ...} escape-syntax SQL.

Common situations: Porting an application from Oracle/SQL Server/PostgreSQL that uses stored procedures; JPA repositories declaring @NamedStoredProcedureQuery; reporting tools that fetch data via procedures; generated data-access code that defaults to prepareCall for all reads.

Related errors


AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16). Data as JSON: /api/errors/d62fe7b8ce4e058f. Report an issue: GitHub.