CLOB in – CLOB out -> Grails + SQL

Zdarza mi się w pracy pisać troszkę więcej niż tylko CRUDy.  Pewnego dnia wynikła potrzeba przekazania CLOBa do procedury w SQLu i odebranie kolejnego CLOBa z wyjścia procedury. W Grailsach? Nic prostszego.

Pierwszy problem – stworzenie CLOBa w grailsach. Okazało się, że nie mogę go stworzyć za pomocą new CLOB(). To by było za proste. Do stworzenia CLOBa potrzebuję połączenia z bazą danych (wstrzyknięte – magia), a potem ustawiam mu wartość na pożądanej pozycji (najlepiej na początku). Trzeba wiedzieć, że pozycje w CLOBie numeruje się od 1…

Clob jsonInput = dataSource.getConnection().createClob()
clob.setString(1, jsonInput)
clob in

Wywołanie procedury SQLowej jest dość standardowe:

new Sql(dataSource).call("{? = call pkg.fancy_procedure_input_output_clob(in_json => ?)}",
[Sql.CLOB,
clob])

Pod kolejne ’?’ będą podstawiane pod kolejne argumenty z tablicy przekazanej jako drugi parametr w wywołaniu funkcji call.

Jako, że na wyjściu procedury też jest CLOB, trzeba jeszcze dorzucić jeden parametr do wywołania funkcji call. To groovy, więc jeśli ostatni parametr jest typu closure to można go wynieść poza nawias:

{ jsonOutput -> result = jsonOutput?.characterStream?.text }
view raw closure.groovy hosted with ❤ by GitHub
closure

Podłączam się pod strumień i pobieram text. Korzystam z characterStream żeby nie zgubić unicode’ów. Do tego zabezpieczam się przed nullami, bo bazie nigdy nie można ufać 😉 

Na koniec można zebrać wszystko w jedno, zadeklarować odpowiednie zmienne i otoczyć na wszelki wypadek try/catchem:

def dataSource
String fancyFunction(String jsonInput) {
String result = ''
Clob jsonInput = dataSource.getConnection().createClob()
clob.setString(1, jsonInput)
try {
new Sql(dataSource).call("{? = call pkg.fancy_procedure_input_output_clob(in_json => ?)}",
[Sql.CLOB,
clob])
{ jsonOutput -> result = jsonOutput?.characterStream?.text }
} catch (SQLException ex) {
log.error('Error during executing fancy procedure: ', ex)
}
return result
}
clob in – clob out

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

This site uses Akismet to reduce spam. Learn how your comment data is processed.