Abbrechen von Anweisungen¶
Es wird empfohlen, zum Abbrechen einer Anweisung die Schnittstelle der Anwendung zu verwenden, in der die Abfrage ausgeführt wird (z. B. das Arbeitsblatt der Snowflake-Weboberfläche), oder die vom Snowflake ODBC- oder JDBC-Treiber bereitgestellte Abbruch-API. In einigen Fällen ist es jedoch notwendig, eine Abfrage mit SQL abzubrechen.
Snowflake bietet die folgenden Funktionen, um die Verwendung von SQL zum Abbrechen von laufenden/aktiven Anweisungen zu unterstützen:
Beispiel¶
Im folgenden Java-Beispielcode werden SYSTEM$CANCEL_ALL_QUERIES und andere Snowflake-Funktionen verwendet, um eine in Ausführung befindliche Anweisung der aktuellen Sitzung nach 5 Sekunden abzubrechen:
Der Beispielcode führt zunächst einen SQL-Befehl für CURRENT_SESSION aus, um die Sitzungs-ID zu erhalten.
Dann wird eine Task erstellt, die 5 Sekunden später ausgeführt wird. Diese Task verwendet die Sitzungs-ID als Parameter für SYSTEM$CANCEL_ALL_QUERIES.
Dann wird eine Anweisung mit langer Ausführungszeit ausgeführt, bei der mit der Tabellenfunktion GENERATOR 120 Sekunden lang Zeilen generiert werden.
public void testCancelQuery() throws IOException, SQLException
{
Statement statement = null;
ResultSet resultSet = null;
ResultSetMetaData resultSetMetaData = null;
final Connection connection = getConnection(true);
try
{
// Get the current session identifier
Statement getSessionIdStmt = connection.createStatement();
resultSet = getSessionIdStmt.executeQuery("SELECT current_session()");
resultSetMetaData = resultSet.getMetaData();
assertTrue(resultSet.next());
final int sessionId = resultSet.getInt(1);
// Use Timer to cancel all queries of session in 5 seconds
Timer timer = new Timer();
timer.schedule( new TimerTask()
{
@Override
public void run()
{
try
{
// Cancel all queries on session
PreparedStatement cancelAll;
cancelAll = connection.prepareStatement(
"call system$cancel_all_queries(?)");
// bind the session identifier as first argument
cancelAll.setInt(1, sessionId);
cancelAll.executeQuery();
}
catch (SQLException ex)
{
logger.log(Level.SEVERE, "Cancel failed with exception {}", ex);
}
}
}, 5000);
// Use the internal row generator to execute a query for 120 seconds
statement = connection.createStatement();
resultSet = statement.executeQuery(
"SELECT count(*) FROM TABLE(generator(timeLimit => 120))");
resultSetMetaData = resultSet.getMetaData();
statement.close();
}
catch (SQLException ex)
{
// assert the sqlstate is what we expect (QUERY CANCELLED)
assertEquals("sqlstate mismatch",
SqlState.QUERY_CANCELED, ex.getSQLState());
}
catch (Throwable ex)
{
logger.log(Level.SEVERE, "Test failed with exception: ", ex);
}
finally
{
if (resultSet != null)
resultSet.close();
if (statement != null)
statement.close();
// close connection
if (connection != null)
connection.close();
}
}