private void runPatchStatement(DatabaseConnection pDatabaseConnection, PatchRunController pPatchRunController, PatchScript pPatchScript, ScriptExecutable pScriptExecutable, int pSequence) 
  throws ExPromote {
        
    //Check the execution is allowed and log the start
    boolean lRunStatement = pPatchRunController.validateAndStartScriptExecutable(pScriptExecutable, pSequence);    
    
    if(lRunStatement) {
      boolean lSuccess = true;
      try {
        long lStart = System.currentTimeMillis();
        Logger.logInfo(pPatchScript.getDisplayName() +  " - Execute (" + pDatabaseConnection.currentUserName() +"):\n" + pScriptExecutable.getDisplayString() + "\n/");
        
        //Run the statement
        pScriptExecutable.execute(pDatabaseConnection);
        long lTimeMS = System.currentTimeMillis() - lStart;
        Logger.logInfo("OK (took " + lTimeMS + " ms)\n");
      }
      catch(Throwable th){
        lSuccess = false;
        Logger.logInfo("SERIOUS ERROR! HALTING PATCH EXECUTION");
        ExPromote lError = new ExPromote("Error executing patch " + pPatchScript.getDisplayName() + ": " + th.getMessage(), th);
        Logger.logError(lError);
        throw lError;
      }
      finally {
        try {
          pPatchRunController.endPatchRunStatement(pScriptExecutable, lSuccess);
        }
        catch (Throwable th){
          if(lSuccess) {
            //Only rethrow if there was not already an error
            throw new ExFatalError("Error logging patch statement result", th);
          }
          else {
            Logger.logInfo("Failed to log patch statement failure: " + th.getMessage());
          }
        }
      }
    }
    else {
      Logger.logInfo("Skipping " + (pPatchRunController.isNoExecController() ? "(-noexec)" : "(already run)") + ":\n" + pScriptExecutable.getDisplayString()  + "\n/\n");
    } 
    
  }