// BDE - (C) Copyright 1995 by Borland International // keyupdt.c #include "snipit.h" static pCHAR szTblName = "KEYUPDT"; // Field Descriptor used in creating a table. static SNIPFAR FLDDesc fldDesc[] = { { // Field 1 - FRSTNAME 1, // Field Number "ID", // Field Name fldFLOAT, // Field Type fldUNKNOWN, // Field Subtype 0, // Field Size ( 1 or 0, except // BLOb or CHAR field ) 0, // Decimal places ( 0 ) // computed 0, // Offset in record ( 0 ) 0, // Length in Bytes ( 0 ) 0, // For Null Bits ( 0 ) fldvNOCHECKS, // Validiy checks ( 0 ) fldrREADWRITE // Rights }, { // Field 2 - LASTNAME 2, "FRSTNAME", fldZSTRING, fldUNKNOWN, 10, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE }, { // Field 2 - LASTNAME 3, "LASTNAME", fldZSTRING, fldUNKNOWN, 12, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE }, { // Field 3 - Info1 4, "INFO1", fldZSTRING, fldUNKNOWN, 100, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE }, { // Field 4 - INFO2 5, "INFO2", fldZSTRING, fldUNKNOWN, 100, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE }, { // Field 2 - INFO3 6, "INFO3", fldZSTRING, fldUNKNOWN, 100, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE }, { // Field 2 - INFO4 7, "INFO4", fldZSTRING, fldUNKNOWN, 100, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE }, { // Field 2 - INFO5 8, "INFO5", fldZSTRING, fldUNKNOWN, 100, 0, 0, 0, 0, fldvNOCHECKS, fldrREADWRITE } }; // Index Descriptor - describes the index associated with the table. static IDXDesc IdxDesc = { { "KEYUPIDX" }, // Name 1, // Number { NULL }, // Tag name (dBASE only) { NULL }, // Optional format FALSE, // Primary? TRUE, // Unique? FALSE, // Descending? TRUE, // Maintained? FALSE, // SubSet? FALSE, // Expression index? NULL, // for QBE only 1, // Fields in key NULL, // Length in bytes FALSE, // Index out of date? 0, // Key Type of Expression { 1 }, // Array of field numbers { NULL }, // Key expression { NULL }, // Key Condition FALSE, // Case insensitive 0, // Block size in bytes 0 // Restructure number }; // Function prototypes static DBIResult CreateSQLTable(hDBIDb hDb, pCHAR pszTblName); static DBIResult AddRecord(hDBICur hCur, int i, pCHAR pszFirst, pCHAR pszLast, pCHAR pszInfo1, pCHAR pszInfo2, pCHAR pszInfo3, pCHAR pszInfo4, pCHAR pszInfo5); static const UINT16 uNumFields = sizeof(fldDesc) / sizeof (fldDesc[0]); //===================================================================== // Function: // KeyUpdate(); // // Description: // This example shows how to limit the fields that are used to // identify the record on the SQL Server. By default, all // fields of a record are compared to determine which record // to UPDATE or DELETE. Limiting the number of fields that are // used in the search will speed up performance, but could result // in data being overwritten. Data could be overwritten if another // user modifies a field value that is not a part of the unique // index for that table. // // The speed increase depends on a number of issues. In general, // the more fields in the table, and the smaller the key, the // faster it will be when only the key fields are used in the // search. // // Note: This functionality is only supported for SQL Databases. //===================================================================== void KeyUpdate (void) { DBIResult rslt; // Return value from IDAPI functions hDBIDb hDb; // Handle to the database hDBICur hCur; // Handle to the result set hDBIXact hTran = 0; // Transaction Handle UINT16 uLength; // Length of returned property CURProps TblProps; // Used to determine the size of the // Record buffer pBYTE pRecBuf = NULL; // Pointer to the record buffer CHAR szDbType[DBIMAXNAMELEN]; // Type of the connection CHAR szNewFirst[20] = "Joe"; // New First name Screen("*** Keyed update Example ***\r\n"); BREAK_IN_DEBUGGER(); Screen(" Initializing IDAPI..."); if (InitAndConnect2(&hDb) != DBIERR_NONE) { Screen("\r\n*** End of Example ***"); return; } rslt = DbiGetProp(hDb, dbDATABASETYPE, szDbType, sizeof(DBINAME), &uLength); ChkRslt(rslt, "GetProp"); // Make certain that the database supports this opperation. if (!strcmp(szDbType, "STANDARD")) { Screen(" Error - This example only works on SQL Databases."); CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } // Create the table if (CreateSQLTable(hDb, szTblName) != DBIERR_NONE) { CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } // Start a transaction to handle the update to the table rslt = DbiBeginTran(hDb, xilREADCOMMITTED, &hTran); if (ChkRslt(rslt, "BeginTran")) { rslt = DbiDeleteTable(hDb, szTblName, NULL); ChkRslt(rslt, "DeleteTable"); CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); return; } rslt = DbiOpenTable(hDb, szTblName, NULL, "KEYUPIDX", NULL, 0, dbiREADWRITE, dbiOPENSHARED, xltFIELD, TRUE, NULL, &hCur); ChkRslt(rslt, "OpenTable"); rslt = DbiGetCursorProps(hCur, &TblProps); ChkRslt(rslt, "GetCursorProps"); pRecBuf = (pBYTE)malloc(TblProps.iRecBufSize * sizeof(BYTE)); Screen("\r\n Get the 15th record in the cursor (set the current" " position in the cursor...)"); rslt = DbiGetRelativeRecord(hCur, 15, dbiWRITELOCK, pRecBuf, NULL); ChkRslt(rslt, "GetNextRecord"); rslt = DbiPutField(hCur, 2, pRecBuf, (pBYTE)szNewFirst); ChkRslt(rslt, "PutField"); Screen("\r\n Update using only the key fields and modified fields for" " comparison..."); rslt = DbiSetProp(hCur, curUPDLOCKMODE, updWHEREKEYCHG); ChkRslt(rslt, "SetProp"); Screen(" Modify the record..."); rslt = DbiModifyRecord(hCur, pRecBuf, TRUE); ChkRslt(rslt, "ModifyRecord"); Screen("\r\n Record updated..."); Screen("\r\n Close the cursor..."); rslt = DbiCloseCursor(&hCur); ChkRslt(rslt, "CloseCursor"); Screen(" Commit the changes..."); rslt = DbiEndTran(hDb, hTran, xendCOMMIT); ChkRslt(rslt, "EndTran"); rslt = DbiDeleteTable(hDb, szTblName, NULL); ChkRslt(rslt, "DeleteTable"); if (pRecBuf) { free(pRecBuf); } Screen(" Close the database and exit IDAPI..."); CloseDbAndExit(&hDb); Screen("\r\n*** End of Example ***"); } //===================================================================== // Function: // CreateSQLTable(hDb, pszTblName); // // Input: phDb - Pointer to the database handle. // pszTblName - The name of the table to create. // // Return: Result returned by IDAPI. // // Description: // This function will create a table and add records to that // table. //===================================================================== DBIResult CreateSQLTable (hDBIDb hDb, pCHAR pszTblName) { DBIResult rslt; // Value returned from IDAPI functions CRTblDesc crTblDesc; // Table Descriptor hDBICur hCur; // Cursor used for adding records int i; // Loop Counter hDBIXact hTran; // Transaction Handle // Initialize the Table Create Descriptor. memset(&crTblDesc, 0, sizeof(CRTblDesc)); strcpy(crTblDesc.szTblName, pszTblName); crTblDesc.iFldCount = uNumFields; crTblDesc.pfldDesc = fldDesc; crTblDesc.iIdxCount = 1; crTblDesc.pidxDesc = &IdxDesc; Screen(" Creating the table..."); rslt = DbiCreateTable(hDb, TRUE, &crTblDesc); if (ChkRslt(rslt, "CreateTable") != DBIERR_NONE) { return rslt; } rslt = DbiBeginTran(hDb, xilREADCOMMITTED, &hTran); ChkRslt(rslt, "BeginTran"); rslt = DbiOpenTable(hDb, pszTblName, NULL, NULL, NULL, 0, dbiREADWRITE, dbiOPENEXCL, xltFIELD, TRUE, NULL, &hCur); if (ChkRslt(rslt, "OpenTable") != DBIERR_NONE) { rslt = DbiEndTran(hDb, hTran, xendABORT); ChkRslt(rslt, "EndTran"); rslt = DbiDeleteTable(hDb, pszTblName, NULL); ChkRslt(rslt, "DeleteTable"); return rslt; } // Add records to the table. Screen(" Adding records to the table..."); for (i=0; i < 20; i++) { rslt = AddRecord(hCur, i, "Tom", "Smith", "Test data to Write to the table", "Test data to Write to the table", "Test data to Write to the table", "Test data to Write to the table", "Test data to Write to the table"); } rslt = DbiCloseCursor(&hCur); ChkRslt(rslt, "CloseTable"); rslt = DbiEndTran(hDb, hTran, xendCOMMIT); ChkRslt(rslt, "EndTran"); return rslt; } //===================================================================== // Function: // AddRecord (hDBICur hCur, pCHAR pFirst, pCHAR pLast) // pCHAR pszInfo1, pCHAR pszInfo2, pCHAR pszInfo3, // pCHAR pszInfo4, pCHAR pszInfo5) // // Input: hCur - The table handle // pFirst - First Name // pLast - Last Name // pszInfo1 - Data to write to the table // pszInfo2 - Data to write to the table // pszInfo3 - Data to write to the table // pszInfo4 - Data to write to the table // pszInfo5 - Data to write to the table // // Return: Result of adding the record to the table // // Description: // Insert a record into the table. //===================================================================== DBIResult AddRecord (hDBICur hCur, int i, pCHAR pszFirst, pCHAR pszLast, pCHAR pszInfo1, pCHAR pszInfo2, pCHAR pszInfo3, pCHAR pszInfo4, pCHAR pszInfo5) { DBIResult rslt; // Return value from IDAPI functions pBYTE pRecBuf; // Record buffer CURProps TblProps; // Table properties DFLOAT fTemp; // Temporary variable for the float. // Allocate a record buffer. rslt = DbiGetCursorProps(hCur, &TblProps); ChkRslt(rslt, "GetCursorProps"); pRecBuf = (pBYTE) malloc(TblProps.iRecBufSize * sizeof(BYTE)); if (pRecBuf == NULL) { Screen(" Error - Out of memory"); return DBIERR_NOMEMORY; } // Clear the record buffer, then add the data. rslt = DbiInitRecord(hCur, pRecBuf); ChkRslt(rslt, "InitRecord"); fTemp = i; rslt = DbiPutField(hCur, 1, pRecBuf, (pBYTE) &fTemp); ChkRslt(rslt, "PutField"); rslt = DbiPutField(hCur, 2, pRecBuf, (pBYTE) pszFirst); ChkRslt(rslt, "PutField"); rslt = DbiPutField(hCur, 3, pRecBuf, (pBYTE) pszLast); ChkRslt(rslt, "PutField"); rslt = DbiPutField(hCur, 4, pRecBuf, (pBYTE) pszInfo1); ChkRslt(rslt, "PutField"); rslt = DbiPutField(hCur, 5, pRecBuf, (pBYTE) pszInfo2); ChkRslt(rslt, "PutField"); rslt = DbiPutField(hCur, 6, pRecBuf, (pBYTE) pszInfo3); ChkRslt(rslt, "PutField"); rslt = DbiPutField(hCur, 7, pRecBuf, (pBYTE) pszInfo4); ChkRslt(rslt, "PutField"); rslt = DbiPutField(hCur, 8, pRecBuf, (pBYTE) pszInfo5); ChkRslt(rslt, "PutField"); rslt = DbiInsertRecord(hCur, dbiNOLOCK, pRecBuf); ChkRslt(rslt, "InsertRecord"); free(pRecBuf); return rslt; }