docs: def callproc(self, procname, parameters=(), quiet=False, expect_return_value=False):
          """Calls a MySQL stored procedure procname and returns the return values. This uses DictCursor.
              To get return values back out of a stored procedure, prefix the parameter with a @ character.
          """
          self.procedures_run += 1
          i = 0
          errcode = 0
          caughte = None
  
          out_param_indices = []
          for j in range(len(parameters)):
              p = parameters[j]
              if type(p) == type('') and p[0] == '@':
                  assert(p.find(' ') == -1)
                  out_param_indices.append(j)
  
          if procname not in self.list_stored_procedures():
              raise Exception("The stored procedure '%s' does not exist." % procname)
          if not re.match("^\s*\w+\s*$", procname):
              raise Exception("Expected a stored procedure name in callproc but received '%s'." % procname)
          while i < self.numTries:
              i += 1
              try:
                  self._get_connection()
                  cursor = self.connection.cursor()
                  if type(parameters) != type(()):
                      parameters = (parameters,)
                  errcode = cursor.callproc(procname, parameters)
                  self.lastrowid = int(cursor.lastrowid)
                  cursor.close()
  
                  # Get the out parameters
                  out_param_results = []
                  if out_param_indices:
                      out_param_results = self.execute('SELECT %s' % ", ".join(['@_%s_%d AS %s' % (procname, pindex, parameters[pindex][1:]) for pindex in out_param_indices]))
  
                  return out_param_results
              except MySQLdb.OperationalError, e:
                  self._close_connection()
                  errcode = e[0]
                  caughte = e
                  continue
              except:
                  self._close_connection()
                  traceback.print_exc()
                  break
  
          if not quiet:
              sys.stderr.write("\nSQL execution error call stored procedure %s at %s:" % (
              procname, datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
              sys.stderr.write("\nErrorcode/Error: %d - '%s'.\n" % (errcode, str(caughte)))
              sys.stderr.flush()
          raise MySQLdb.OperationalError(caughte)