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
Правильный и безопасный метод для закрытия ресурсов, связанных с 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();
}
Теперь я использую Oracle с Java. Здесь моя точка зрения:
Вы должны явно закрыть ResultSet
и Statement
, потому что раньше у Oracle были проблемы с тем, чтобы курсоры открывались даже после закрытия соединения. Если вы не закроете ResultSet
(курсор), это вызовет ошибку, как превышены максимальные открытые курсоры.
Я думаю, что вы можете столкнуться с той же проблемой с другими используемыми вами базами данных.
Вот учебник Закрыть ResultSet по окончании :
Закрыть ResultSet при завершении
Закрыть объект
ResultSet
, как только вы закончите работу с объектомResultSet
, хотя объектStatement
неявно закрывает объектResultSet
, когда он закрывается, закрываяResultSet
явно дает возможность сборщику мусора запомнить память как можно раньше, потому что объектResultSet
может занимать много памяти в зависимости от запроса.blockquote>
ResultSet.close();
Если вам нужен более компактный код, я предлагаю использовать 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);
}
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
.
С формой 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 одновременных пользователей), и у нас не было проблем с ним, поэтому никогда не см. Это предупреждение.
Из javadocs :
Когда объект
blockquote>Statement
закрыт, его текущийResultSet
объект, если он существует, также закрыт.Однако javadocs не очень понятны, закрыты ли
Statement
иResultSet
, когда вы закрываете базовыйConnection
. Они просто утверждают, что закрытие Connection:Немедленно освобождает эту базу данных объекта
blockquote>Connection
и ресурсы JDBC вместо того, чтобы ждать их автоматического выхода.По-моему, всегда явно закрывайте
ResultSets
,Statements
иConnections
, когда вы закончите с ними, поскольку реализацияclose
может различаться между драйверами баз данных.Вы можете сэкономить много кода котельной пластины с использованием таких методов, как
closeQuietly
в DBUtils из Apache.
Нет, вам не нужно закрывать что-либо, НО соединение. В спецификациях JDBC, закрывающих любой более высокий объект, автоматически закрываются нижние объекты. Закрытие Connection
закроет любое Statement
s, созданное соединением. Закрытие любого Statement
закроет все ResultSet
s, созданные этим Statement
. Не имеет значения, является ли Connection
объединенным или нет. Даже общее соединение должно очищаться, прежде чем возвращаться в бассейн.
Конечно, у вас могут быть длинные вложенные циклы на Connection
, создающие множество утверждений, а затем их закрыть. Я почти никогда не закрываю ResultSet
, хотя, кажется чрезмерным при закрытии Statement
или Connection
ЗАКРЫВАЕТ их.