docs: public int executeUpdate(String strSQL, int iType)
          throws DBException
      {
          int iRowsUpdated = 0;
          try
          {
              Utility.getLogger().info(strSQL);
              if (SQLParams.USE_INSERT_UPDATE_LITERALS)
              {   // Convert all field values to literals
                  if (this.getStatement(iType) == null)
                      this.setStatement(((JdbcDatabase)this.getDatabase()).getJDBCConnection().createStatement(), iType);
                  iRowsUpdated = this.getStatement(iType).executeUpdate(strSQL);
              }
              else
              {   // Set the field values in the prepared statement, then execute it!
                  if (this.getStatement(iType) != null)
                  {
                      if (!strSQL.equals(this.getLastSQLStatement(iType)))
                          this.setStatement(null, iType);   // Not the same as last time.
                  }
                  if (this.getStatement(iType) == null)
                      this.setStatement(((JdbcDatabase)this.getDatabase()).getJDBCConnection().prepareStatement(strSQL), iType);
                  this.setLastSQLStatement(strSQL, iType);
                  m_iNextParam = 1;           // First param row
                  if ((iType == DBConstants.SQL_UPDATE_TYPE) || (iType == DBConstants.SQL_INSERT_TABLE_TYPE))   // Have WHERE X=?
                  {
                      Record record = this.getRecord();
                      for (int iFieldSeq = DBConstants.MAIN_FIELD; iFieldSeq <= record.getFieldCount() + DBConstants.MAIN_FIELD - 1; iFieldSeq++)
                      {
                          BaseField field = record.getField(iFieldSeq);
                          if (field.getSkipSQLParam(iType))
                              continue; // Skip this param
                          field.getSQLFromField((PreparedStatement)this.getStatement(iType), iType, m_iNextParam++);
                      }
                  }
                  if (m_iNextParam == 1)
                      iRowsUpdated = 1; // No data = no need to update
                  KeyArea keyArea = this.getRecord().getKeyArea(0); // Primary index
                  boolean bIncludeTempFields = (iType == DBConstants.SQL_UPDATE_TYPE);
                  if (!keyArea.isNull(DBConstants.TEMP_KEY_AREA, bIncludeTempFields))
                      if ((iType == DBConstants.SQL_UPDATE_TYPE) || (iType == DBConstants.SQL_DELETE_TYPE)) // Have WHERE X=?
                          m_iNextParam = keyArea.getSQLFromField((PreparedStatement)this.getStatement(iType), iType, m_iNextParam, DBConstants.TEMP_KEY_AREA, false, bIncludeTempFields);    // Always add!?   
                  iRowsUpdated = ((PreparedStatement)this.getStatement(iType)).executeUpdate();
              }
          } catch (SQLException e)    {
              DBException ex = this.getDatabase().convertError(e);
              if (this.createIfNotFoundError(ex))
              { // Table not found, create it.
                  this.getRecord().setOpenMode((this.getRecord().getOpenMode() | DBConstants.OPEN_DONT_CREATE));   // Only try to create once.
                  return this.executeUpdate(strSQL, iType);
              }
              else if (ex.getErrorCode() == DBConstants.BROKEN_PIPE)
              { // If there is a pipe timeout or a broken pipe, try to re-establish the connection and try again
                  if (!m_bInRecursiveCall)
                  {
                      m_bInRecursiveCall = true;  // Only try once
  
                      this.close();
                      this.getDatabase().close();     // Next access will force an open.
                      int iResult = this.executeUpdate(strSQL, iType);
  
                      m_bInRecursiveCall = false;
                      return iResult;
                  }
              }
              String strError = "SQL Excep: " + e.getMessage() + " -> DB Ex: " + ex.getMessage() + " on " + strSQL;
              if ((ex.getErrorCode() == DBConstants.DUPLICATE_COUNTER) || (ex.getErrorCode() == DBConstants.DUPLICATE_KEY))
              	Utility.getLogger().info(strError);
              else
              	Utility.getLogger().warning(strError);
              throw ex;
          } finally {
              m_iNextParam = -1;  // This way dataToFields is not confused.
              if (CLEANUP_STATEMENTS)
                  this.setStatement(null, iType);
          }
          Utility.getLogger().info("Rows updated: " + iRowsUpdated);
          if (iRowsUpdated == 0)
              throw new DBException(DBConstants.INVALID_RECORD);
          return iRowsUpdated;
      }