Java / SQL - Вызов .execute () для объекта Statement vs. createStatement.execute () [duplicate]

DECLARE @id_list VARCHAR(MAX) = '1234,23,56,576,1231,567,122,87876,57553,1216'
DECLARE @table TABLE ( id VARCHAR(50) )
DECLARE @x INT = 0
DECLARE @firstcomma INT = 0
DECLARE @nextcomma INT = 0

SET @x = LEN(@id_list) - LEN(REPLACE(@id_list, ',', '')) + 1 -- number of ids in id_list

WHILE @x > 0
    BEGIN
        SET @nextcomma = CASE WHEN CHARINDEX(',', @id_list, @firstcomma + 1) = 0
                              THEN LEN(@id_list) + 1
                              ELSE CHARINDEX(',', @id_list, @firstcomma + 1)
                         END
        INSERT  INTO @table
        VALUES  ( SUBSTRING(@id_list, @firstcomma + 1, (@nextcomma - @firstcomma) - 1) )
        SET @firstcomma = CHARINDEX(',', @id_list, @firstcomma + 1)
        SET @x = @x - 1
    END

SELECT  *
FROM    @table
206
задан Zeemee 5 June 2015 в 11:12
поделиться

7 ответов

Правильный и безопасный метод для закрытия ресурсов, связанных с JDBC, это (взято из Как правильно закрыть ресурсы JDBC - Every Time ):

Connection connection = dataSource.getConnection();
try {
    Statement statement = connection.createStatement();

    try {
        ResultSet resultSet = statement.executeQuery("some query");

        try {
            // Do stuff with the result set.
        } finally {
            resultSet.close();
        }
    } finally {
        statement.close();
    }
} finally {
    connection.close();
}
163
ответ дан bluish 23 August 2018 в 15:53
поделиться

Теперь я использую Oracle с Java. Здесь моя точка зрения:

Вы должны явно закрыть ResultSet и Statement, потому что раньше у Oracle были проблемы с тем, чтобы курсоры открывались даже после закрытия соединения. Если вы не закроете ResultSet (курсор), это вызовет ошибку, как превышены максимальные открытые курсоры.

Я думаю, что вы можете столкнуться с той же проблемой с другими используемыми вами базами данных.

Вот учебник Закрыть ResultSet по окончании :

Закрыть ResultSet при завершении

Закрыть объект ResultSet, как только вы закончите работу с объектом ResultSet, хотя объект Statement неявно закрывает объект ResultSet, когда он закрывается, закрывая ResultSet явно дает возможность сборщику мусора запомнить память как можно раньше, потому что объект ResultSet может занимать много памяти в зависимости от запроса.

ResultSet.close();

163
ответ дан bluish 23 August 2018 в 15:53
поделиться

Если вам нужен более компактный код, я предлагаю использовать Apache Commons DbUtils . В этом случае:

Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
    conn = // Retrieve connection
    stmt = conn.prepareStatement(// Some SQL);
    rs = stmt.executeQuery();
} catch(Exception e) {
    // Error Handling
} finally {
    DbUtils.closeQuietly(rs);
    DbUtils.closeQuietly(stmt);
    DbUtils.closeQuietly(conn);
}
5
ответ дан baron5 23 August 2018 в 15:53
поделиться

Java 1.7 значительно облегчает нашу жизнь благодаря запросу try-with-resources .

try (Connection connection = dataSource.getConnection();
    Statement statement = connection.createStatement()) {
    try (ResultSet resultSet = statement.executeQuery("some query")) {
        // Do stuff with the result set.
    }
    try (ResultSet resultSet = statement.executeQuery("some query")) {
        // Do more stuff with the second result set.
    }
}

Этот синтаксис довольно короткий и изящный. И connection действительно будет закрыт, даже когда невозможно создать statement.

94
ответ дан Christian Hujer 23 August 2018 в 15:53
поделиться

С формой Java 6, я думаю, лучше проверить, что она закрыта или нет до закрытия (например, если какой-либо пул соединений выдает соединение в другом потоке) - например, какая-то сетевая проблема - состояние оператора и результатов может быть закрыто , (это не часто бывает, но у меня была эта проблема с Oracle и DBCP). Моим шаблоном для этого (в старшем синтаксисе Java) является:

    try {
        ...   
        return resp;
    } finally {
        if (rs != null && !rs.isClosed()) {
            try {
                rs.close();
            } catch (Exception e2) { 
                log.warn("Cannot close resultset: " + e2.getMessage());
           }
        }
        if (stmt != null && !stmt.isClosed()) {
            try {
               stmt.close();
            } catch (Exception e2) {
                log.warn("Cannot close statement " + e2.getMessage()); 
            }
        }
        if (con != null && !conn.isClosed()) {
            try {
                con.close();
            } catch (Exception e2) {
                log.warn("Cannot close connection: " + e2.getMessage());
            }
    }

Теоретически это не на 100% идеально, потому что между проверкой состояния закрытия и самого закрытия есть небольшая комната для изменение для состояния. В худшем случае вы получите предупреждение долго. - но это меньше, чем возможность изменения состояния в долгосрочных запросах. Мы используем этот шаблон в производстве с «avarage» load (150 одновременных пользователей), и у нас не было проблем с ним, поэтому никогда не см. Это предупреждение.

-1
ответ дан Csákány Róbert 23 August 2018 в 15:53
поделиться

Из javadocs :

Когда объект Statement закрыт, его текущий ResultSet объект, если он существует, также закрыт.

Однако javadocs не очень понятны, закрыты ли Statement и ResultSet, когда вы закрываете базовый Connection. Они просто утверждают, что закрытие Connection:

Немедленно освобождает эту базу данных объекта Connection и ресурсы JDBC вместо того, чтобы ждать их автоматического выхода.

По-моему, всегда явно закрывайте ResultSets, Statements и Connections, когда вы закончите с ними, поскольку реализация close может различаться между драйверами баз данных.

Вы можете сэкономить много кода котельной пластины с использованием таких методов, как closeQuietly в DBUtils из Apache.

56
ответ дан dogbane 23 August 2018 в 15:53
поделиться

Нет, вам не нужно закрывать что-либо, НО соединение. В спецификациях JDBC, закрывающих любой более высокий объект, автоматически закрываются нижние объекты. Закрытие Connection закроет любое Statement s, созданное соединением. Закрытие любого Statement закроет все ResultSet s, созданные этим Statement. Не имеет значения, является ли Connection объединенным или нет. Даже общее соединение должно очищаться, прежде чем возвращаться в бассейн.

Конечно, у вас могут быть длинные вложенные циклы на Connection, создающие множество утверждений, а затем их закрыть. Я почти никогда не закрываю ResultSet, хотя, кажется чрезмерным при закрытии Statement или Connection ЗАКРЫВАЕТ их.

-2
ответ дан user207421 23 August 2018 в 15:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: