Annulation d’instructions

La méthode recommandée pour annuler une instruction est d’utiliser l’interface de l’application dans laquelle la requête est exécutée (par exemple, la feuille de travail dans l’interface Web Snowflake) ou l’API d’annulation fournie par le pilote Snowflake ODBC ou JDBC. Cependant, dans certains cas, il est nécessaire d’annuler une requête en utilisant SQL.

Snowflake fournit les fonctions suivantes pour faciliter l’utilisation de SQL pour annuler les instructions en cours/actives :

Exemple

L’exemple de code Java suivant utilise SYSTEM$CANCEL_ALL_QUERIES et d’autres fonctions Snowflake pour annuler une instruction en cours dans la session en cours après 5 secondes :

  1. L’exemple de code émet d’abord une commande SQL pour CURRENT_SESSION afin obtenir l’identifiant de session.

  2. Il crée alors une tâche à exécuter 5 secondes plus tard. Cette tâche utilise l’identifiant de session comme paramètre pour SYSTEM$CANCEL_ALL_QUERIES.

  3. Ensuite, une longue instruction est exécutée en utilisant la fonction de table GENERATOR pour générer des lignes pendant 120 secondes.

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();
  }
}
Copy