Как я мог выполнить как запрос, так и оператор DML с тем же кодом в groovy?

Я автор SQL Fiddle. Это знание может помочь решить этот вопрос:

Я пытаюсь написать код Groovy, который будет выполнять любой произвольный код запроса /DML в моей базе данных. Основываясь на моем чтении Groovy Sql API, все эти функции ожидают чего-то особого. Например, "eachRow" ожидает возврата возвращаемого результата; если он не возвращен (например, в случае оператора UPDATE, например), то его использование вызовет ошибку. Я могу вызвать "выполнить" с любым типом оператора, однако я не могу вернуть набор результатов для своих операторов SELECT при использовании этого (что определенно является требованием).

В этот момент я думаю, что мне, возможно, придется отказаться от библиотеки Groovy Sql в пользу некоторой реализации JDBC более низкого уровня. По-моему, это было бы позором, но я готов пойти туда, если это необходимо. Я бы предпочел сохранить это как Groovy -esqe, насколько это возможно. Как я могу это сделать?

Ответ 1

Посмотрите на разновидности методов execute(), который возвращает boolean. Тип возврата в соответствии с документом:

true, если первым результатом является объект ResultSet; false, если это подсчет обновлений или результатов нет.

CREATE, DROP и INSERT были упомянуты в примере. Я надеюсь, что он будет работать так же, как и для UPDATE.

Для SELECT флаг должен быть проверен, если присутствует ResultSet. Если да, то второй запрос может быть запущен для получения строк. Например:

//If statement qualifies for select statements
//because .execute() will return true if there is a ResultSet
//present. It will be false for CREATE, UPDATE and DROP.
if( sql.execute("select name from Foo") ) {

    //Fire the second query to get the rows in case of SELECT query
    result = sql.rows "select name from Foo"
}

return result

UPDATE
Если есть проблема с выполнением запроса дважды по соображениям производительности, можно попробовать следующий подход:

def queryString = "update Foo set name = 'hello' where name = 'baz'"

try {
    sql.query queryString, { ResultSet rs ->
        //Result set returned for select query only
        //For all other cases exception is thrown
    }
} catch( java.sql.SQLException ) {
    //Throws exception for any other type of query
    //By now you should be smart enough exception is not 
    //thrown for any other cause.

    sql.execute queryString
}