How I stopped manually rebuilding Java PreparedStatement SQL
If you work with Java/JDBC long enough, you eventually run into this situation: You have code like this: String sql = "SELECT * FROM users WHERE id = ? AND status = ?" ; PreparedStatement pst = con . prepareStatement ( sql ); pst . setLong ( 1 , userId ); pst . setString ( 2 , status ); And then, from a log or debugger, you know something like: userId = 42 status = ACTIVE But what you actually need is the SQL you can paste into your database client: SELECT * FROM users WHERE id = 42 AND status = 'ACTIVE' ; Doing this once is trivial. Doing it repeatedly while debugging production issues is annoying. It gets worse when: the SQL is split across several Java strings; values come from map.get("KEY"); there are dates or timestamps; strings contain apostrophes; some parameters are unresolved; the method contains several PreparedStatements. I kept doing this manually, so I built a small tool called Bind2SQL. What it does Bind2SQL takes Java/JDBC code and reconstructs the executable SQL. For example: String sql = "SELECT * FROM person " + "WHERE person_id = ? " + "AND type_id = ? " + "AND created_at >= ?" ; PreparedStatement pst = con . prepareStatement ( sql ); pst . setLong ( 1 , values . get ( "PERSON_ID" )); pst . setInt ( 2 , values . get ( "TYPE_ID" )); pst . setDate ( 3 , Date . valueOf ( "2026-09-02" )); With runtime values: {PERSON_ID=12648350, TYPE_ID=29} It produces something like: SELECT * FROM person WHERE person_id = 12648350 AND type_id = 29 AND created_at >= DATE '2026-09-02' ; The important part is that unresolved parameters are not silently guessed. If Bind2SQL cannot resolve something, it leaves it clearly marked so you can review it manually. Why I made it browser-only I often use this kind of tool with real application code and runtime values. That may include: internal SQL; identifiers; production log values; table names; application-specific data. So I didn't want a server in the middle. Bind2SQL runs entirely in the browser. There is: no backend; no