{"id":228,"date":"2017-10-25T17:57:25","date_gmt":"2017-10-25T17:57:25","guid":{"rendered":"https:\/\/www.morsello.com\/?p=228"},"modified":"2017-10-25T17:57:25","modified_gmt":"2017-10-25T17:57:25","slug":"i-dont-ever-want-to-write-sql-again","status":"publish","type":"post","link":"https:\/\/www.morsello.com\/index.php\/2017\/10\/25\/i-dont-ever-want-to-write-sql-again\/","title":{"rendered":"I Don\u2019t Ever Want to Write SQL Again"},"content":{"rendered":"<p>Actually, I think SQL is great.\u00a0 It\u2019s one of the earliest declarative languages, handing the work of figuring out how best to get the desired result to where it should be\u2014 the computer.\u00a0 It\u2019s also so well designed that it\u2019s still in widespread use today in relationship databases, with little complaint.<\/p>\n<p>No, my problem is that almost all of the SQL that I\u2019m called upon to write has to live within another programming language, like Java or Python.\u00a0 Most language environments support connection to a SQL data source in some form or another.\u00a0 This generally means writing additional wrapper code, but still placing SQL in local strings.<\/p>\n<p>The consequence of this lack of support is that<\/p>\n<ul>\n<li>developer tools that can help me assure that my types and logic are correct don\u2019t help me<\/li>\n<li>I can\u2019t directly execute the SQL code, because it\u2019s formatted in my source language, wrapped in quotes, and formatted incorrectly.<\/li>\n<li>I can\u2019t easily refactor my SQL.<\/li>\n<\/ul>\n<p>A typical query might look like this:<\/p>\n<pre>String query = \"SELECT firstName, lastName, id FROM my_table WHERE state = ? AND category = ?\";\r\n\r\ntry {\r\n    PreparedStatement stmt = connection.prepareStatement(query);\r\n    stmt.setString(1, state);\r\n    stmt.setInt(2, category);\r\n    ResultSet rs = stmt.executeQuery();\r\n    List&lt;Record&gt; records = new ArrayList&lt;&gt;();\r\n\r\n    while (rs.next()) {\r\n        records.append(new Record(rs.getString(1), rs.getString(2));\r\n    }\r\n\r\n    return records;\r\n} catch (SQLException e) {\r\n    throw new RuntimeException(e);\r\n}<\/pre>\n<p>This is dumb.\u00a0 Dumb like burning fossil fuels to power passenger vehicles.\u00a0 Expedient once, perhaps, but on the wrong side of history.<\/p>\n<p>The code <i>could<\/i> look like this:<\/p>\n<pre>return l.stream().filter(b-&gt; b.hasState(state)).filter(b -&gt; b.inCategory(category).collect(Collectors.toList());<\/pre>\n<p>How about that?\u00a0 If SQL queries were built into Java 8 streams, the actual SQL could be generated on the fly within the streams mechanism, allowing optimization of the number of items queried on the client side.\u00a0 The set of items being queried could then be incorporated into Java refactoring.<\/p>\n<p>Why stop there?\u00a0 In debugging at least, SQL errors could be handled much more intelligently.\u00a0 Actually query the schema of the database and propose solutions!\u00a0 Check that the model in use at the client is the model actually in use at the database server.<\/p>\n<p>jOOQ is the closest tool to actually self-writing SQL I know of.\u00a0 Still looking for other solutions.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Actually, I think SQL is great.\u00a0 It\u2019s one of the earliest declarative languages, handing the work of figuring out how best to get the desired result to where it should be\u2014 the computer.\u00a0 It\u2019s also so well designed that it\u2019s still in widespread use today in relationship databases, with little complaint. No, my problem is&hellip;<\/p>\n<p><a class=\"more-link\" href=\"https:\/\/www.morsello.com\/index.php\/2017\/10\/25\/i-dont-ever-want-to-write-sql-again\/\" title=\"Continue reading &lsquo;I Don\u2019t Ever Want to Write SQL Again&rsquo;\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/www.morsello.com\/index.php\/wp-json\/wp\/v2\/posts\/228"}],"collection":[{"href":"https:\/\/www.morsello.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.morsello.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.morsello.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.morsello.com\/index.php\/wp-json\/wp\/v2\/comments?post=228"}],"version-history":[{"count":1,"href":"https:\/\/www.morsello.com\/index.php\/wp-json\/wp\/v2\/posts\/228\/revisions"}],"predecessor-version":[{"id":229,"href":"https:\/\/www.morsello.com\/index.php\/wp-json\/wp\/v2\/posts\/228\/revisions\/229"}],"wp:attachment":[{"href":"https:\/\/www.morsello.com\/index.php\/wp-json\/wp\/v2\/media?parent=228"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.morsello.com\/index.php\/wp-json\/wp\/v2\/categories?post=228"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.morsello.com\/index.php\/wp-json\/wp\/v2\/tags?post=228"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}