code: public List<GroovyRowResult> executeInsert(String sql, List<Object> params, List<String> keyColumnNames) throws SQLException {
          Connection connection = createConnection();
          PreparedStatement statement = null;
          try {
              this.keyColumnNames = keyColumnNames;
              statement = getPreparedStatement(connection, sql, params, USE_COLUMN_NAMES);
              this.keyColumnNames = null;
              this.updateCount = statement.executeUpdate();
              ResultSet keys = statement.getGeneratedKeys();
              return asList(sql, keys);
          } catch (SQLException e) {
              LOG.warning("Failed to execute: " + sql + " because: " + e.getMessage());
              throw e;
          } finally {
              closeResources(connection, statement);
          }
      }
docs: Executes the given SQL statement (typically an INSERT statement).
  Use this variant when you want to receive the values of any auto-generated columns,
  such as an autoincrement ID field (or fields) and you know the column name(s) of the ID field(s).
  The query may contain placeholder question marks which match the given list of parameters.
  See {@link #executeInsert(GString)} for more details.
  <p>
  This method supports named and named ordinal parameters.
  See the class Javadoc for more details.
  <p>
  Resource handling is performed automatically where appropriate.
  
  @param sql            The SQL statement to execute
  @param params         The parameter values that will be substituted
  into the SQL statement's parameter slots
  @param keyColumnNames a list of column names indicating the columns that should be returned from the
  inserted row or rows (some drivers may be case sensitive, e.g. may require uppercase names)
  @return A list of the auto-generated row results for each inserted row (typically auto-generated keys)
  @throws SQLException if a database access error occurs
  @see Connection#prepareStatement(String, String[])
  @since 2.3.2