コード例 #1
0
ファイル: ndbsql.cpp プロジェクト: SunguckLee/MariaDB
static int
do_stmt(Con& con, const char *sqlstr)
{
  SQLHSTMT hstmt;
  SQLCHAR errmsg[256];
  SQLCHAR colname[32];
  SQLSMALLINT coltype;
  SQLSMALLINT colnamelen;
  SQLSMALLINT nullable;
  SQLUINTEGER collen[MAXCOLS];
  SQLSMALLINT scale;
  SQLINTEGER outlen[MAXCOLS];
  SQLCHAR *data[MAXCOLS];
  SQLSMALLINT nresultcols = 0;
  SQLINTEGER rowcount;
  SQLINTEGER stmttype;
  SQLRETURN rc;

  /* allocate a statement handle */
  SQLAllocHandle(SQL_HANDLE_STMT, con.hdbc, &hstmt);

  /* execute the SQL statement */
  rc = SQLExecDirect(hstmt, (SQLCHAR*)sqlstr, SQL_NTS);
  if (rc == SQL_ERROR) {
    ndbout << "Operation failed" << endl;
    print_err(SQL_HANDLE_STMT, hstmt);
    return -1;
  }
  if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO && rc != SQL_NO_DATA_FOUND) {
    ndbout << "Operation returned unknown code " << rc << endl;
    return -1;
  }

  /* see what kind of statement it was */
  SQLGetDiagField(SQL_HANDLE_STMT, hstmt, 0,
		  SQL_DIAG_DYNAMIC_FUNCTION_CODE,
		  (SQLPOINTER)&stmttype, SQL_IS_INTEGER, (SQLSMALLINT *)NULL);

  switch (stmttype) {
    /* SELECT statement */
  case SQL_DIAG_SELECT_CURSOR:
    /* determine number of result columns */
    SQLNumResultCols(hstmt, &nresultcols);

    /***********************
     * Display column names 
     ***********************/
    /* Print vertical divider */
    printf("|");
    for (int i=0; i<nresultcols; i++) {
      SQLDescribeCol(hstmt, i+1, colname, sizeof(colname),
		     &colnamelen, &coltype, &collen[i], &scale, &nullable);
      collen[i] = display_length(coltype, collen[i], colname);
      for (SQLUINTEGER j=0; j<collen[i]; j++) printf("-");
      printf("--+");
    }
    printf("\n");

    printf("|");
    for (int i=0; i<nresultcols; i++) {
      SQLDescribeCol(hstmt, i+1, colname, sizeof(colname),
		     &colnamelen, &coltype, &collen[i], &scale, &nullable);
      
      /* assume there is a display_length function which
	 computes correct length given the data type */
      collen[i] = display_length(coltype, collen[i], colname);
      (void)printf(" %*.*s |", (int)collen[i], (int)collen[i], (char *)colname);
      
      /* allocate memory to bind column */
      data[i] = (SQLCHAR *) malloc(collen[i]);
      if (data[i] == NULL) {
	ndbout << "Failed to allocate malloc memory in NDB SQL program" 
	       << endl;
	exit(-1);
      }
      
      /* bind columns to program vars, converting all types to CHAR */
      SQLBindCol(hstmt, i+1, SQL_C_CHAR, data[i], collen[i], &outlen[i]);
    }
    printf("\n");

    /* Print vertical divider */
    printf("|");
    for (int i=0; i<nresultcols; i++) {
      SQLDescribeCol(hstmt, i+1, colname, sizeof(colname),
		     &colnamelen, &coltype, &collen[i], &scale, &nullable);
      collen[i] = display_length(coltype, collen[i], colname);
      for (SQLUINTEGER j=0; j<collen[i]; j++) printf("-");
      printf("--+");
    }
    printf("\n");

    /**********************
     * Display result rows 
     **********************/
    {
      int no_of_rows_fetched=0;
      while (1) {
	rc=SQLFetch(hstmt);
	errmsg[0] = '\0';
	if (rc == SQL_ERROR) {
	  print_err(SQL_HANDLE_STMT, hstmt);
	  break;
	}
	if (rc == SQL_NO_DATA) break;
	if (rc == SQL_SUCCESS) {
	  printf("|");
	  for (int i=0; i<nresultcols; i++) {
	    if (outlen[i] == SQL_NULL_DATA
		|| outlen[i] >= (SQLINTEGER) collen[i])
	      build_indicator_message(errmsg,
				      (SQLPOINTER *)data[i], collen[i],
				      &outlen[i], i);
	    (void)printf(" %*.*s |", (int)collen[i], (int)collen[i],
			 (char *)data[i]);
	  } 
	  /* print any truncation messages */
	  (void)printf("\n%s", (char *)errmsg);
	} else if (rc == SQL_SUCCESS_WITH_INFO) {
	  printf("|");
	  for (int i=0; i<nresultcols; i++) {
	    if (outlen[i] == SQL_NULL_DATA
		|| outlen[i] >= (SQLINTEGER) collen[i])
	      build_indicator_message(errmsg,
				      (SQLPOINTER *)data[i], collen[i],
				      &outlen[i], i);
	    (void)printf(" %*.*s |", (int)collen[i], (int)collen[i],
			 (char *)data[i]);
	  } /* for all columns in this row */
	  /* print any truncation messages */
	  (void)printf("\n%s", (char *)errmsg);
	}
	no_of_rows_fetched++;
      } /* while rows to fetch */
      /* Print vertical divider */
      printf("|");
      for (int i=0; i<nresultcols; i++) {
	SQLDescribeCol(hstmt, i+1, colname, sizeof(colname),
		       &colnamelen, &coltype, &collen[i], &scale, &nullable);
	collen[i] = display_length(coltype, collen[i], colname);
	for (SQLUINTEGER j=0; j<collen[i]; j++) printf("-");
	printf("--+");
      }
      printf("\n");
      ndbout << no_of_rows_fetched << " rows fetched" << endl;
    }
    SQLCloseCursor(hstmt);
    break;
    /* searched DELETE, INSERT or searched UPDATE statement */
  case SQL_DIAG_DELETE_WHERE:
  case SQL_DIAG_INSERT:
  case SQL_DIAG_UPDATE_WHERE:
    /* check rowcount */
    SQLRowCount(hstmt, (SQLINTEGER*)&rowcount);
    ndbout << (int)rowcount << " rows affected" << endl;
    break;
    /* other statements */
  case SQL_DIAG_ALTER_TABLE:
  case SQL_DIAG_CREATE_TABLE:
  case SQL_DIAG_CREATE_VIEW:
  case SQL_DIAG_DROP_TABLE:
  case SQL_DIAG_DROP_VIEW:
  case SQL_DIAG_CREATE_INDEX:
  case SQL_DIAG_DROP_INDEX:
  case SQL_DIAG_DYNAMIC_DELETE_CURSOR:
  case SQL_DIAG_DYNAMIC_UPDATE_CURSOR:
  case SQL_DIAG_GRANT:
  case SQL_DIAG_REVOKE:
    ndbout << "Operation successful" << endl;
    break;
    /* implementation-defined statement */
  default:
    (void)printf("Unknown Statement type=%ld\n", stmttype);
    break;
  }

  /* free data buffers */
  for (int i=0; i<nresultcols; i++) {
    (void)free(data[i]);
  }
  
  SQLFreeHandle(SQL_HANDLE_STMT, hstmt);  // free statement handle 
  return(0);
}
コード例 #2
0
ファイル: odbc_xsb.c プロジェクト: eden/navajoverb
/*-----------------------------------------------------------------------------*/
void ODBCDescribeSelect()
{
  int j;
  UCHAR colname[50];
  SWORD colnamelen;
  SWORD scale;
  SWORD nullable;
  UDWORD collen;
  struct Cursor *cur = (struct Cursor *)ptoc_int(2);

  cur->NumCols = 0;
  SQLNumResultCols(cur->hstmt, (SQLSMALLINT*)&(cur->NumCols));
  if (!(cur->NumCols)) {
    /* no columns are affected, set cursor status to unused */
    cur->Status = 1; 
    ctop_int(3,2);
    return;
  }
  /* if we aren't reusing a closed statement handle, we need to get*/
  /* resulting rowset info and allocate memory for it*/
  if (cur->Status != 2) {
    cur->ColTypes =
      (SWORD *)malloc(sizeof(SWORD) * cur->NumCols);
    if (!cur->ColTypes)
      xsb_exit("Not enough memory for ColTypes!");
    
    cur->Data =
      (UCHAR **)malloc(sizeof(char *) * cur->NumCols);
    if (!cur->Data)
      xsb_exit("Not enough memory for Data!");

    cur->OutLen =
      (UDWORD *)malloc(sizeof(UDWORD) * cur->NumCols);
    if (!cur->OutLen)
      xsb_exit("Not enough memory for OutLen!");

    cur->ColLen =
      (UDWORD *)malloc(sizeof(UDWORD) * cur->NumCols);
    if (!cur->ColLen)
      xsb_exit("Not enough memory for ColLen!");
    
    for (j = 0; j < cur->NumCols; j++) {
      SQLDescribeCol(cur->hstmt, (short)(j+1), (UCHAR FAR*)colname,
		     sizeof(colname), &colnamelen,
		     &(cur->ColTypes[j]),
		     &collen, &scale, &nullable);
      /* SQLServer returns this wierd type for a system table, treat it as varchar?*/
      if (cur->ColTypes[j] == -9) cur->ColTypes[j] = SQL_VARCHAR;
      colnamelen = (colnamelen > 49) ? 49 : colnamelen; 
      colname[colnamelen] = '\0';
      if (!(cur->ColLen[j] =
	    DisplayColSize(cur->ColTypes[j],collen,colname))) {
	/* let SetCursorClose function correctly free all the memory allocated*/
	/* for Data storage: cur->Data[j]'s*/
	cur->NumCols = j; /* set so close frees memory allocated thus far*/
	SetCursorClose(cur);
	/*	return(1);*/
	ctop_int(3,1);
	return;
      }
      cur->Data[j] =
	(UCHAR *) malloc(((unsigned) cur->ColLen[j]+1)*sizeof(UCHAR));
      if (!cur->Data[j])
	xsb_exit("Not enough memory for Data[j]!");
    }
  }
  /* bind them*/
  for (j = 0; j < cur->NumCols; j++) {
    SQLBindCol(cur->hstmt, (short)(j+1), 
	       ODBCToXSBType(cur->ColTypes[j]), cur->Data[j],
	       cur->ColLen[j], (SDWORD FAR *)(&(cur->OutLen[j])));
  }
  /*  return 0;*/
  ctop_int(3,0);
  return;
}