SQLEXAMP.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:14k
源码类别:
Windows编程
开发平台:
Visual C++
- /* SQLEXAMP.C - Copyright (c) 1990 - 1995 by Craig Henry. This program may
- ** be freely distributed and copied, without charge. However, any attempt to
- ** charge for this program will be considered a copyright infringement and
- ** will be prosecuted to the fullest extent.
- **
- ** This program provides a simple example of logging onto a SQL Server,
- ** sending down commands, retrieving metadata, and result rows. Formatting
- ** and printing those results on the console.
- **
- */
- #if defined(DBNTWIN32)
- #include <windows.h>
- #endif
- #include "stdio.h" // include standard header
- #include "sqlfront.h" // include dblib macro/manifest defines
- #include "sqldb.h" // include dblib datatype, prottypes, etc
- #include "string.h" // include for string functions
- #include "malloc.h" // include for malloc and free
- // prototypes for internal functions
- extern int DetermineRowSize(DBPROCESS *,int);
- extern RETCODE PrintHeaders(DBPROCESS *);
- extern RETCODE PrintRow(DBPROCESS *);
- /*
- ** DetermineRowSize(DBPROCESS *,int)
- **
- ** This function returns either the size of all columns in the row, converted
- ** to character data (SQLCHAR) with one space between each column, or
- ** if col is non-zero, the length of the input column converted to string.
- ** It is used to build the header strings, and each row of data, and is
- ** called to allocate the memory needed for each row, and determine how
- ** much of that space is to be used for each column
- */
- int DetermineRowSize(dbproc,col)
- DBPROCESS *dbproc; // The SQL Server connection structure
- int col; // column size to get, 0 for all
- {
- int x,cols; // counters
- int length=0; // total length of column(row).
- int namelength; // length of name of column
- int prlength; // printable length
- char *name; // pointer to column name
- if(!col) // get number of columns
- cols = dbnumcols(dbproc);
- // count from 1 to numcols if col is 0, else x will = col only
- for(x=((col) ? col : 1);x<=((col) ? col : cols);x++)
- {
- switch(dbcoltype(dbproc,x)) // get column type, determine SQLCHAR
- { // converted length
- case SQLNUMERIC:
- case SQLDECIMAL:
- {
- DBCOL Col;
- dbcolinfo(dbproc,CI_REGULAR,x,0,&Col);
- prlength = Col.Precision + 2;
- }
- break;
- case SQLBIT: // The PR... values are found in the
- prlength = PRBIT; // SQLDB.H header file.
- break;
- case SQLINT1:
- prlength = PRINT1;
- break;
- case SQLINT2:
- prlength = PRINT2;
- break;
- case SQLINT4:
- prlength = PRINT4;
- break;
- case SQLFLT8:
- prlength = PRFLT8;
- break;
- case SQLDATETIME:
- prlength = PRDATETIME;
- break;
- case SQLMONEY:
- prlength = PRMONEY;
- break;
- case SQLVARBINARY : // VARBINARY IMAGE, and BINARY
- case SQLBINARY: // convert to 2 times length
- case SQLIMAGE:
- prlength = dbcollen(dbproc,x)*2;
- break;
- default :
- prlength = dbcollen(dbproc,x); // other types are maximum of
- break; // actual column length
- }
- name = (char *)dbcolname(dbproc,x); // names may be longer than
- namelength = (name) ? strlen(name) : 0; // column so use name len if
- if(prlength<namelength) // longer of two.
- length+=namelength+1; // add one for space between
- else // columns
- length+=prlength+1;
- }
- return length; // return the length of the
- // field
- }
- /*
- ** RETCODE PrintHeaders(DBPROCESS *)
- **
- ** This function builds the string that contains the names of each column,
- ** and a string containing '=' as a separator line. It does this by finding
- ** the print size of each column, allocating a buffer to hold all column names
- ** plus one space between each column name, then copying that name into the
- ** appropriate location into the buffer. Finally the two lines are
- ** printed.
- */
- RETCODE PrintHeaders(dbproc)
- DBPROCESS *dbproc; // The SQL Server connection structure pointer
- {
- int x,cols,size; // counters
- char *header; // pointer for separator buffer
- char *colnames; // pointer for column name buffer
- char *colname; // scratch pointers
- char *ptr,*hptr;
- size = DetermineRowSize(dbproc,0); // get size of buffers
- ptr = colnames = malloc(size+1); // get name buffer
- hptr = header = malloc(size+1); // get separator buf
- memset (header,' ',size); // set buffers to all spaces
- memset (colnames,' ',size);
- cols = dbnumcols(dbproc); // get number of columns
- for(x=1;x<=cols;x++) // loop on all columns
- {
- size = DetermineRowSize(dbproc,x); // get size of this column
- colname = (char *)dbcolname(dbproc,x); // get column name
- strncpy(ptr,colname,strlen(colname)); // copy name
- memset(hptr,'=',size-1); // set ='s in separator line
- hptr+=size; // move to next position
- ptr+=size; // move to next position
- }
- *ptr = ' '; // null term both strings
- *hptr = ' ';
- printf("%sn",colnames); // print both strings
- printf("%sn",header);
- free(colnames); // free both buffers
- free(header);
- return SUCCEED; // done
- }
- /*
- ** RETCODE PrintRow(DBPROCESS *)
- **
- ** This function prints out one row. dbnextrow() must be called to fetch the
- ** row to print. This routine could be used to print the current row as
- ** many times as wanted, as the current row data is always available until
- ** dbnextrow() is called to fetch the next row. This routine works like
- ** PrintHeaders above, but each column's data is obtained instead of a row
- ** name, and converted to a string. It is then set into the buffer.
- */
- RETCODE PrintRow(dbproc)
- DBPROCESS *dbproc; // SQL Server connection structure
- {
- int x,cols,size,datasize,colwidth,coltype; // counters
- char *datavals; // data buffer pointer
- char *data; // column data pointer
- char *ptr; // scratch pointer
- colwidth = DetermineRowSize(dbproc,0);
- ptr = datavals = malloc(colwidth+1); // get buffer
- cols = dbnumcols(dbproc); // get number of columns
- for(x=1;x<=cols;x++) // do all columns
- {
- coltype = dbcoltype(dbproc,x);
- size = DetermineRowSize(dbproc,x); // determine size of this column
- memset(ptr,' ',size); // set it to spaces
- data = (char *)dbdata(dbproc,x); // get pointer to column's data
- if(data == (BYTE *)NULL) // if NULL, use "NULL"
- {
- strncpy(ptr,"NULL",4); // set NULL into buffer
- ptr += size; // point past this column in output buf
- }
- else // else have data, so convert to char
- {
- datasize = dbconvert(dbproc,coltype,data,dbdatlen(dbproc,x),
- SQLCHAR,ptr,(DBINT)size-1);
- if (datasize < size && (coltype == SQLNUMERIC || coltype == SQLDECIMAL || coltype == SQLINT1 ||
- coltype == SQLINT2 || coltype == SQLINT4 || coltype == SQLFLT8 || coltype == SQLFLT4))
- {
- memmove(ptr+size-1-datasize,ptr,datasize);
- memset(ptr,' ',size-1-datasize);
- }
- ptr+=size;
- }
- }
- *ptr = ' '; // null term string
- printf("%sn",datavals); // print row
- free(datavals); // free buffer
- return SUCCEED; // done
- }
- /*
- **
- ** The below main is a mini isql interpreter and as such is only
- ** used for demonstration purposes. Command line args include the Server
- ** name as arg 1, User ID as arg 2, assumes the password is null.
- ** This routine requests opens the connection after obtaining the login record
- ** and filling it with the necessary info. Once the connection is established
- ** it accpets command input, set's it into the dbproc. On "go" it executes
- ** the command against the server, processes each results set and then returns
- ** to accepting command input. If "quit" or "exit" is input the program
- ** is terminated. This interpreter will not process COMPUTE statements,
- ** and will not work with commands that return text/image data.
- */
- int main(argc, argv)
- int argc;
- char *argv[];
- {
- LOGINREC *login; // login rec pointer
- DBPROCESS *dbproc; // SQL Server connection structure pointer
- char cmd[150]; // command buffer
- char server[30]; // server name buffer
- int x=1; // command line counter
- STATUS retc; // return code
- const char * sqlversion; // pointer for version string
- int err_handler(DBPROCESS*, int, int, int, char*, char*);
- int msg_handler(DBPROCESS*, DBINT, int, int, char*);
- *server = ' '; // null start these two buffers
- *cmd = ' ';
- if(argc == 1) // if no server name, request it
- {
- printf("Enter Server Name: ");
- gets(server);
- }
- else // else it was input as first arg
- strcpy(server,argv[1]);
- if(argc < 2) // if no login id, request it
- {
- printf("Enter User Name: ");
- gets(cmd);
- }
- else // otherwise it was input as second arg.
- strcpy(cmd,argv[2]);
- // check to see if communications layer was loaded (DOS ONLY)
- if((sqlversion = dbinit()) == (BYTE *)NULL)
- {
- // DOS TSR (DBNMPIPE.EXE) is not loaded, don't bother going any farther
- printf("Error in DB-Library initialization, exitingn");
- return 1;
- }
- else
- printf("DB-Library version: %sn",sqlversion); // print dblib version
- dbsettime(30); // set timeouts to 30 seconds
- // set error/msg handlers for this program
- dbmsghandle((DBMSGHANDLE_PROC)msg_handler);
- dberrhandle((DBERRHANDLE_PROC)err_handler);
- login = dblogin(); // get a login rec
- DBSETLUSER(login,cmd); // set login id
- DBSETLHOST(login,"SQL EXAMPLE"); // set host name for sp_who
- DBSETLVERSION(login, DBVER60);
- // open connection to requested server. Pass null server name for local
- // connection, if name not entered.
- if((dbproc = dbopen(login,(*server) ? server : (char *)NULL)) == (DBPROCESS *)NULL)
- {
- // no one answered, so couldn't connect or error occurred
- printf("Login failedn");
- return 1;
- }
- else
- {
- // loop on command input until quit or exit appears in first 4 bytes.
- while((strnicmp(cmd,"quit",4) != 0) && (strnicmp(cmd,"exit",4)!=0))
- {
- printf("%d> ",x++); // print command prompt
- gets(cmd); // get command
- if(strnicmp(cmd,"go",2) == 0) // is it go
- {
- if(dbsqlexec(dbproc) == FAIL) // execute command
- {
- // problem occurred, just try another command
- printf("Error in executing command batch!n");
- x = 1;
- continue;
- }
- // command executed correctly, get results information
- while((retc = dbresults(dbproc)) != NO_MORE_RESULTS)
- {
- if (retc == FAIL) // if error get out of loop
- break;
- // headers and data could be printed here with only two
- // function calls, dbprhead(dbproc), and dbprrow(dbproc),
- // which would output the headers, and all the data to
- // standard output. However, that isn't very informative
- // toward understanding how this data is obtained and
- // processed, so I do it the hard way, one column at a time.
- PrintHeaders(dbproc); // print header data
- // loop on each row, until all read
- while((retc= dbnextrow(dbproc))!=NO_MORE_ROWS)
- {
- if(retc == FAIL) // if fail, then clear
- { // connection completely, just
- dbcancel(dbproc); // in case.
- break;
- }
- else
- PrintRow(dbproc); // else print the current row
- }
- if(DBCOUNT(dbproc) == 1L) // print the row count
- printf("(1 row effected)n");
- else
- printf("(%ld rows effected)n",DBCOUNT(dbproc));
- } // end while(dbresults())
- x = 1; // reset command line counter
- }
- else
- {
- strcat(cmd," "); // go not detected, so put space
- dbcmd(dbproc,cmd); // between each command and set in
- } // dbproc.
- } // end while()
- dbclose(dbproc); // quit/exit input, close connection
- // print adios and exit.
- printf("SQL Server Connection to %s closed, bye bye.n",server);
- return 0;
- }
- }
- /*
- ** msg_handler(char *buffer, long len);
- **
- ** This routine is a local isql message handler call back function that
- ** is invoked whenever the SQL Server is sending a message back to
- ** the program.
- **
- */
- int msg_handler(dbproc, Msg, State, Severity, Message)
- DBPROCESS *dbproc; // SQL Server connection structure
- DBINT Msg; // SQL Server message number
- int State; // State of the message
- int Severity; // Severity of the message
- char *Message; // The message itself (read only)
- {
- printf("Message No.: %ld, Msg. State: %d, Msg. Severity: %dn",
- Msg,State,Severity);
- if(Message != NULL)
- printf("%sn",Message);
- return (0);
- }
- /*
- ** err_handler(char *buffer, long len);
- **
- ** This routine is a local error handler called by dblib if an internal
- ** error occurs, also to notify when a server message has been sent, which is
- ** obtained through the above message handler.
- **
- */
- int err_handler(dbproc, Severity,dberr, oserr, errstr, oserrstr)
- DBPROCESS *dbproc; // SQL Server connection structure
- int Severity; // Severity of Dblib error
- int dberr; // dblib error, all dblib errors start at 10000
- int oserr; // OS error from, C runtime
- char *errstr; // dblib error string
- char *oserrstr; // OS error string (if any)
- {
- printf("DB-LIBRARY Error - Severity: %d, Error No: %d, OS Error No: %dn",
- Severity, dberr, oserr);
- if(errstr != NULL)
- printf("%sn",errstr);
- if(oserrstr != NULL)
- printf("%sn",oserrstr);
- return INT_CANCEL;
- }
- /*****************************************************************************/
- /*======================== E N D - O F - F I L E ============================*/
- /*****************************************************************************/