sql

All things SQL and JDBC...
dangercoder 2020-07-02T04:56:33.090800Z

Thanks David, I read through the docs yesterday and found a lot of places that has to be correctly configured 🙂

2020-07-02T06:30:21.091400Z

Did you manage to make it work?

dangercoder 2020-07-02T17:34:46.095600Z

I tried the :multi-rs option today on a sql server stored procedure and it worked perfectly (18 results). Thanks a lot for all the effort @seancorfield

1
seancorfield 2020-07-02T17:46:42.096800Z

I have been meaning to add support for that since the "early days" of maintaining clojure.java.jdbc (even tho' I don't use stored procs ever and I don't use SQL Server).

seancorfield 2020-07-02T17:48:00.097900Z

@jarvinenemil I gather you got Windows auth working? Would you like to create an issue on next.jdbc documenting how? Or even a PR for the Tips & Tricks > MS SQL Server section?

dangercoder 2020-07-02T18:06:51.104600Z

Windows Auth - not yet, I did a workaround (username + password) just so I could evaluate next.jdbc and SQL Server SPs on my local instance. I'll give it another try tomorrow at work if I get the time. I'm pretty sure it's the auth-dll missing. If I get it working I'll make a PR for the MS SQL Server section ✌️.

1
kwrooijen 2020-07-02T22:09:24.110100Z

Hi, using next-jdbc, I'm using jdbc/execute-one! . If I get a duplicate key error, I'd like to handle that in my application. I can't find an option to return a map with info instead of an exception. If I catch the exception, then the only option I have is to parse a string (as far as I can see). That doesn't sound very reliable. Any advice on how I should tackle this problem? example of desired result:

(jdbc/execute-one! db query) ;; PSQLException, duplicate key
; => {:error :duplicate-key, :column :email}

emccue 2020-07-05T01:35:08.125700Z

As someone who just learned about the ON CONFLICT clause in postgres - maybe that would solve your issue without going back to the application

kwrooijen 2020-07-05T16:04:47.125900Z

Thanks, but sadly that doesn't solve my issue. I actually want to go back to the application

2020-07-02T22:11:21.110200Z

I'm no expert, but my first hunch is that what you want is easy to do with some databases, harder with others (requiring parsing) and impossible to do with one universal mechanism

2020-07-02T22:15:53.110400Z

@kevin.van.rooijen this might help with processing the exception object https://docs.oracle.com/javase/tutorial/jdbc/basics/sqlexception.html

2020-07-02T22:18:08.110700Z

these are the valid values for sqlstate https://docs.oracle.com/cd/A87860_01/doc/appdev.817/a58231/appd.htm

kwrooijen 2020-07-02T22:23:14.110900Z

I see, sounds like if next-jdbc isn't handling this, I'd have to parse it myself after all

kwrooijen 2020-07-02T22:24:32.111100Z

Those links are helpful, thanks. I'll take another look at this tomorrow

2020-07-02T22:24:34.111300Z

don't take my word for it though - the dev does check this channel - I was surprised to see there is programmatic access without parsing (though I just found the docs, haven't used it in anger)

2020-07-02T22:24:45.111500Z

but regardless, that method and those codes should work

2020-07-02T22:26:32.111700Z

I find no match for the getSqlState method in the next.jdbc repo, might make for a nice PR...

seancorfield 2020-07-02T22:29:51.112700Z

@kevin.van.rooijen Interesting idea. clojure.java.jdbc and next.jdbc have always just relied on the JDBC driver throwing an exception and leaving it at that.

kwrooijen 2020-07-03T07:26:12.122700Z

Didn't expect my question to spark such an in depth conversation haha. (I just woke up). Thanks a lot for the info! It does sound like I have to manage this for my specific vendor, which is fine. I at least have a good understanding about how I could tackle this issue

seancorfield 2020-07-02T22:31:01.113200Z

As @noisesmith says, handling that level of detail in any universal mechanism is likely impossible.

2020-07-02T22:32:12.113600Z

mentioned in the thread above, I found an method that gives a supposedly portable error code, a hash map from code to human readable keyword and a hash-map from code to printable message might be nice

seancorfield 2020-07-02T22:32:15.113800Z

This is what I have to work with from a "standard" JDBC point of view https://docs.oracle.com/en/java/javase/11/docs/api/java.sql/java/sql/SQLException.html

seancorfield 2020-07-02T22:34:34.114200Z

Yeah, the common subset may be portable, but you can already catch-by-type for a number of them. The duplicate key error should be (a subtype of) https://docs.oracle.com/en/java/javase/11/docs/api/java.sql/java/sql/SQLIntegrityConstraintViolationException.html

2020-07-02T22:35:13.114400Z

ahh

seancorfield 2020-07-02T22:36:05.114600Z

getSQLState() returns a String. getErrorCode() returns an int -- and it is vendor-specific.

seancorfield 2020-07-02T22:37:07.114800Z

The Oracle docs link you provided isn't about portable values as far as I can see?

seancorfield 2020-07-02T22:38:33.115Z

Turning an exception into a bean is trivial and would at least make it more Clojure-y. It still wouldn't solve @kevin.van.rooijen’s problem in any generic way.

seancorfield 2020-07-02T22:40:11.115500Z

I don't see anything more useful in PostgreSQL's exception type either https://jdbc.postgresql.org/development/privateapi/org/postgresql/util/PSQLException.html

seancorfield 2020-07-02T22:41:40.115800Z

And there's nothing about duplicate key / constraint violation here https://jdbc.postgresql.org/development/privateapi/org/postgresql/util/PSQLState.html

seancorfield 2020-07-02T22:42:58.116500Z

So I think the bottom line is that JDBC simply doesn't provide that information (i.e., which constraint failed).

seancorfield 2020-07-02T22:44:06.117500Z

(it's a shame because it is a pain to have to parse a string, although you can at least narrow down the exception type use try / catch / catch with some subtypes in there)

2020-07-02T22:46:22.117600Z

getSQLState returns a code, those codes are standardized by xopen https://docs.oracle.com/cd/A87860_01/doc/appdev.817/a58231/appd.htm

2020-07-02T22:46:44.117800Z

what I don't know is how good the individual sqls are at implementing those codes

seancorfield 2020-07-02T22:57:20.118Z

"integrity constraint violation" is both 23000 and 40002 (and there's nothing in any of this that provides information about which constraint was violated) so I'm not sure how that's useful -- given that you can catch java.sql.SQLIntegrityConstraintViolationException for that

2020-07-02T22:58:04.118200Z

yeah, that makes sense

seancorfield 2020-07-02T23:02:46.118400Z

This shows all the portable exceptions that can be caught https://docs.oracle.com/en/java/javase/11/docs/api/java.sql/java/sql/package-tree.html

2020-07-02T23:06:17.118600Z

I found a better SQLState reference, but that still proves nothing about the quality of various db's implementation of the standard (and the standard itself is something expensive...) https://www.ibm.com/support/knowledgecenter/en/SS6NHC/com.ibm.swg.im.dashdb.messages.doc/doc/rdb2stt.html

2020-07-02T23:14:01.118800Z

the ibm doc says that 40xxx is transaction rollback, and 23xxx is constraight violation, and the two codes you mentioned aren't documented specifically at all

seancorfield 2020-07-02T23:43:08.119Z

Figures. I think the best you can do in any vaguely portable way is to catch by the various standard JDBC exception types (and then parse the vendor-specific message you get from that exception).