home *** CD-ROM | disk | FTP | other *** search
- ///////////////////////////////////////////////////////////////////////////////
- //
- // FILE: example5.sqc
- //
- // Sample Embedded SQL for C application
- //
- // FUNCTIONS:
- //
- // main() - Main program
- // ErrorHandler - Embedded SQL for C error handler
- //
- // COMMENTS:
- //
- // Copyright (C) 1992 - 1994 Microsoft Corporation
- //
- ///////////////////////////////////////////////////////////////////////////////
-
- #include <stddef.h> // standard C run-time header
- #include <stdio.h> // standard C run-time header
- #include "gcutil.h" // utility header
-
- // GLOBAL VARIABLES
-
- #define STRUCTURE // See comments in the singleton_select procedure.
- #define DEF_PUBNAME 'Yoyodyne Publishing'
- #define DATELEN 26
-
- EXEC SQL BEGIN DECLARE SECTION;
- char title_id[99];
-
- struct
- {
- char len;
- char data[23];
- } myvarchar;
-
- struct tr
- {
- char title_id[7];
- char title[81];
- double price;
- long royalty;
- char pubdate[27];
- };
-
- struct
- {
- short title_id_ind;
- short title_ind;
- short pricenul;
- short royaltynul;
- short pubdate_ind;
- } tr_ind;
-
- EXEC SQL END DECLARE SECTION;
-
- /* These lines show that the pre-compiler can deal with typedef'd data. */
-
- typedef double BUCKS;
- typedef char BYTE;
- typedef BYTE YAHOO;
- typedef YAHOO CHRSTR;
- typedef CHRSTR STRING;
- typedef BUCKS DOLLARINOS;
-
- typedef struct tr T_RECORD;
-
- EXEC SQL BEGIN DECLARE SECTION;
-
- YAHOO title[81]; // Resolves to a character array.
- BUCKS price = 2.99; // Resolves to double.
- DOLLARINOS *pprice = &price; // Resolves also to double.
- long royalty;
- char pubdate[DATELEN + 1];
-
- int yy(double *);
- int ss(BUCKS *);
-
- int pricenul;
- int royaltynul;
- int loginame;
-
- char pubname[4 * 10 + 1];
- char pubname2[] = "Shaw Enterprises";
- char city[21] = "Pardess Hanna";
- char state[3] = "WA";
-
- typedef T_RECORD T_REC_ORD;
-
- char cmdbuf[81];
-
- T_RECORD t_rec;
-
- EXEC SQL END DECLARE SECTION;
-
- // function prototypes (instead of header file)
- void ErrorHandler (void);
- void singleton_select(T_REC_ORD *pt_rec_param);
- void cursor_select();
- void cursor_exec();
- void static_insert(char *p_pubname2);
- void dynamic_insert();
- void date_formats();
- void printline();
- void date_formats();
- void print_t_rec();
- unsigned validId(char *pubid);
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // FUNCTION: main()
- //
- // Main application
- //
- // PARAMETERS:
- //
- // argc - count of command line args
- // argv - array of command line argument strings
- // envp - array of environment strings
- //
- // RETURNS: 0 if successful, 1 if error
- //
- // COMMENTS:
- //
- ///////////////////////////////////////////////////////////////////////////////
-
- int main (
- int argc,
- char** argv,
- char** envp)
- {
- int nRet; // for return values
-
- EXEC SQL BEGIN DECLARE SECTION;
- // for CONNECT TO
- char szServerDatabase[(SQLID_MAX * 2)+2] = "";
- char szLoginPassword[(SQLID_MAX * 2)+2] = "";
-
- T_REC_ORD *pt_rec = &t_rec;
- EXEC SQL END DECLARE SECTION;
-
- // install Embedded SQL for C error handler
- EXEC SQL WHENEVER SQLERROR CALL ErrorHandler();
- // set Embedded SQL for C options
- EXEC SQL SET OPTION LOGINTIME 10;
- EXEC SQL SET OPTION QUERYTIME 100;
-
- // display logo
- printf("Sample Embedded SQL for C application\n");
-
- // get info for CONNECT TO statement
- nRet = GetConnectToInfo(argc, argv,
- szServerDatabase,
- szLoginPassword);
- if (!nRet)
- {
- return (1);
- }
-
- // attempt connection to SQL Server
- EXEC SQL CONNECT TO :szServerDatabase
- USER :szLoginPassword;
- if (SQLCODE == 0)
- {
- printf("Connection to SQL Server established\n");
- }
- else
- {
- // problem connecting to SQL Server
- printf("ERROR: Connection to SQL Server failed\n");
- return (1);
- }
-
- EXEC SQL SET CURSORTYPE CUR_BROWSE;
-
- exec sql select max(name) into :myvarchar from sysobjects;
-
- printf("%.*s\n", myvarchar.len, myvarchar.data);
-
- singleton_select(pt_rec);
- cursor_exec();
- cursor_select();
- static_insert("Morris, Marshall, Faulkner & Co, Publishers");
- dynamic_insert();
- date_formats();
-
- printf("\n===================== THE END ======================\n");
-
- // disconnect from SQL Server
- EXEC SQL DISCONNECT ALL;
-
- return (0);
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- //
- // FUNCTION: ErrorHandler()
- //
- // Called on Embedded SQL for C error, displays fields from SQLCA
- //
- // PARAMETERS: none
- //
- // RETURNS: none
- //
- // COMMENTS:
- //
- ///////////////////////////////////////////////////////////////////////////////
-
- void ErrorHandler (void)
- {
- // display error information from SQLCA
- printf("Error Handler called:\n");
- printf(" SQL Code = %li\n", SQLCODE);
- printf(" SQL Server Message %li: '%Fs'\n", SQLERRD1, SQLERRMC);
- }
-
- #ifdef STRUCTURE
- /* Test of singleton select, selecting into a structure. */
- void singleton_select(T_REC_ORD *pt_rec_param)
- {
-
- printf("\n============= TEST OF SINGLETON-SELECT =============\n");
- /* Just do this once - loop to make sure they enter something */
- do {
- printf("Enter TitleId (such as BU1032 or PC9999): ");
- gets(title_id);
- } while (strlen(title_id) == 0);
-
-
- EXEC SQL
- SELECT title_id, title, price, royalty, pubdate
- INTO :pt_rec_param:tr_ind
- FROM titles
- WHERE title_id = :title_id;
-
-
- if (SQLCODE == 0 || SQLCODE == 1 ) {
- print_t_rec();
- printf("%s\n\n", pt_rec_param->title);
- } else if (SQLCODE == 100 && title_id[0] > ' ') {
- printf("No row with that ID\n");
- }
-
- }
-
- #else
- /* This is effectively the same as the above procedure, but selects
- * into individual fields of the structure.
- * Remove the #ifdef if you wish to replace the structure form.
- */
-
- void singleton_select(T_REC_ORD *pt_rec_param)
- {
-
- printf("\n============= TEST OF SINGLETON-SELECT =============\n");
- /* Just do this once - loop to make sure they enter something */
- do {
- printf("Enter TitleId (such as BU1032 or PC9999): ");
- gets(title_id);
- } while (strlen(title_id) == 0);
-
- EXEC SQL
- SELECT title_id, title, price, royalty, pubdate
- INTO :pt_rec_param->title_id, :pt_rec_param->title,
- :pt_rec_param->price:pricenul, :pt_rec_param->royalty
- :royaltynul,
- :pt_rec_param->pubdate
- FROM titles
- WHERE title_id = :title_id;
-
-
- if (SQLCODE == 0 || SQLCODE == 1 ) {
- print_t_rec();
- printf("%s\n\n", pt_rec_param->title);
- } else if (SQLCODE == 100 && title_id[0] > ' ') {
- printf("No row with that ID\n");
- }
-
- }
- #endif // STRUCTURE
-
-
- /* Note that whitespace is ignored. */
- EXEC SQL DECLARE C1 CURSOR FOR
- SELECT title_id, title, price, royalty, pubdate
- FROM titles
- WHERE price <= :*pprice + 2;
-
-
- void cursor_select()
- {
- unsigned short book_ct = 0;
- char buff[80];
- EXEC SQL WHENEVER NOT FOUND GOTO DONE;
- price = 0.00; // initialize it
-
- printf("\n=============== TEST OF CURSOR SELECT ==============\n");
-
- /* loop to make sure user enters something */
- do {
- printf("Enter max price [1.50 - 22.95] (I will add 2 to it): ");
- gets(buff);
- sscanf(buff, "%lf", &price);
- } while (price == 0.00);
-
- printf("Listing publications whose price is <= %f\n", price+2);
- EXEC SQL OPEN C1;
- if (SQLCODE) {
- ErrorHandler();
- }
-
- /* Loop terminated via the 'WHENEVER NOT FOUND GOTO DONE' condition. */
- for (;;) {
- EXEC SQL FETCH C1
- INTO :title_id, :title, :price:pricenul,
- :royalty:royaltynul, :pubdate;
-
- printline();
- printf("%s\n\n", title);
- book_ct++; // Keep count of publications selected
- }
-
- DONE:
- printf("\nTotal of %d publications\n\n", book_ct);
- EXEC SQL CLOSE C1;
-
- EXEC SQL WHENEVER NOT FOUND CONTINUE;
- }
-
- void cursor_exec()
- {
- EXEC SQL BEGIN DECLARE SECTION;
- /* The following data items are used in the ESQL statement(s). */
- int spid;
- char status[11];
- char loginame[13];
- char host_name[11];
- char blk[7];
- char dbname[11];
- char cmd[17];
- EXEC SQL END DECLARE SECTION;
-
- printf("\n=============== TEST OF STATIC CURSOR ==============\n");
-
- EXEC SQL DECLARE C_2 CURSOR FOR STMT1;
- strcpy(cmdbuf, "sp_who");
- EXEC SQL PREPARE STMT1 FROM :cmdbuf;
- EXEC SQL OPEN C_2;
-
- EXEC SQL WHENEVER NOT FOUND GOTO DONE;
-
- printf(" SPID\tLOGINAME\tHOSTNAME\tDBNAME\t\tCMD\n");
- while (SQLCODE == 0) {
- EXEC SQL FETCH C_2 INTO
- :spid, :status, :loginame, :host_name, :blk, :dbname, :cmd;
-
- printf("%4d\t%-12s\t%-10s\t%-10s\t%-18s\n",
- spid, loginame, host_name, dbname, cmd);
-
- }
-
- DONE:
-
- EXEC SQL CLOSE C_2;
-
- printf("\n");
-
- EXEC SQL WHENEVER NOT FOUND CONTINUE;
-
- }
-
-
- /* Note the placing of the Begin declare section. The function parameter
- ** itself is a host variable.
- */
-
- EXEC SQL BEGIN DECLARE SECTION;
- void static_insert(char *p_pubname2)
- {
-
- printf("\n=============== TEST OF STATIC INSERT ==============\n");
-
- do {
- printf("Enter new publisher name: ");
- gets(pubname);
- } while (strlen(pubname) == 0);
-
- EXEC SQL BEGIN TRAN
- INSERT INTO publishers (pub_id, pub_name, city, state)
- VALUES ("9989", :pubname, :city, :state)
- INSERT INTO publishers (pub_id, pub_name, city, state)
- VALUES ("9987", DEF_PUBNAME, :city, :state)
- INSERT INTO publishers (pub_id, pub_name, city, state)
- VALUES ("9988", :p_pubname2, :city, :state)
- COMMIT TRAN
- ;
-
- if (SQLCODE == 0) {
- printf("Select pub_id between '9980' and '9989' with ISQL; ");
- printf("press Enter when done: ");
- gets(pubname);
- } else {
- ErrorHandler();
- }
-
- strcpy(cmdbuf, "delete publishers where pub_id between '9980' and '9989'");
- EXEC SQL EXECUTE IMMEDIATE :cmdbuf;
- }
- EXEC SQL END DECLARE SECTION;
-
-
- void dynamic_insert()
- {
- EXEC SQL BEGIN DECLARE SECTION;
- char pubid[5];
- int statenul = -1;
- EXEC SQL END DECLARE SECTION;
-
- printf("\n=============== TEST OF DYNAMIC INSERT =============\n");
-
- strcpy(cmdbuf, "insert publishers (pub_id, pub_name, city, state) values(?,?,?,?)");
- EXEC SQL PREPARE STMT1 FROM :cmdbuf;
-
- if (SQLCODE != 0)
- ErrorHandler();
- else {
- strcpy(pubname, "Dynamic Publisher");
- do {
- printf("Enter new publisher id (998\?): ");
- gets(pubid);
- } while (!validId(pubid));
-
- EXEC SQL EXECUTE STMT1 USING
- :pubid, :pubname, :city, :state:statenul;
-
-
- if (SQLCODE == 0) {
- printf("Select pub_id = <your pub_id> with ISQL; ");
- printf("press Enter when done: ");
- gets(pubname);
- } else
- ErrorHandler();
- }
-
- strcpy(cmdbuf, "delete publishers where pub_id between '9980' and '9989'");
- EXEC SQL EXECUTE IMMEDIATE :cmdbuf;
-
- }
-
-
- void date_formats()
- {
- EXEC SQL BEGIN DECLARE SECTION;
- char date1[DATELEN];
- char date2[20];
- char date3[20];
- char time1[20];
- EXEC SQL END DECLARE SECTION;
-
- printf("\n=============== TEST OF DATE FORMATS ==============\n");
-
- EXEC SQL
- select getdate(), ord_date,
- convert(char(8),ord_date,3),
- substring(convert(char(26),ord_date),13,7)
- INTO :date1, :date2, :date3, :time1 FROM sales
- WHERE stor_id='6380' and ord_num='6871' and title_id='BU1032';
-
- if (SQLCODE == 0) {
- printf("\n");
- printf("Full Date: %s\n", date1);
- printf("Without Time: %s\n", date2);
- printf("Format 3 Date: %s\n", date3);
- printf("Time only: %s\n", time1);
- } else {
- ErrorHandler();
- }
-
- }
-
- void printline()
- {
- char dprice[11];
- char droyalty[6];
-
- if (pricenul < 0)
- strcpy(dprice, "No Price ");
- else
- sprintf(dprice, "%10.2f", price);
-
- if (royaltynul < 0)
- strcpy(droyalty, "None ");
- else
- sprintf(droyalty, "%5ld", royalty);
-
- printf("%6s %10s %5s %26s\n",
- title_id, dprice, droyalty, pubdate);
-
- }
-
-
- void print_t_rec()
- {
- char dprice[11];
- char droyalty[6];
-
- if (tr_ind.pricenul < 0)
- strcpy(dprice, "No Price ");
- else
- sprintf(dprice, "%10.2f", t_rec.price);
-
- if (tr_ind.royaltynul < 0)
- strcpy(droyalty, "None ");
- else
- sprintf(droyalty, "%5ld", t_rec.royalty);
-
- printf("%6s %10s %5s %26s\n",
- t_rec.title_id, dprice, droyalty, t_rec.pubdate);
-
- }
-
-
- // Check that given string is '9', '9', [0-9], [0-9]
-
- #define ISNUM(c) ((c) >= '0' && (c) <= '9')
-
- unsigned validId( char *pubid )
- {
- unsigned rc = 0; // return code
-
- if ( *pubid++ == '9' && *pubid++ == '9') {
- // passed first part - check remaining characters
- char ch3 = *pubid++;
- char ch4 = *pubid++;
- if (ISNUM(ch3) && ISNUM(ch4)) {
- // just check that 4 characters is all we have
- if (*pubid == '\0') {
- rc = 1;
- }
- }
- }
- return rc;
- }
-