Delen via


Geplaatste Update- en Verwijderinstructies

Toepassingen kunnen de huidige rij in een resultatenset bijwerken of verwijderen met een geplaatste update- of verwijderinstructie. Geplaatste update- en delete-opdrachten worden door sommige gegevensbronnen ondersteund, maar niet door allemaal. Om te bepalen of een gegevensbron positioned update- en verwijderinstructies ondersteunt, roept een toepassing SQLGetInfo aan met de SQL_DYNAMIC_CURSOR_ATTRIBUTES1, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, SQL_KEYSET_CURSOR_ATTRIBUTES1 of SQL_STATIC_CURSOR_ATTRIBUTES1 InfoType (afhankelijk van het type cursor). Houd er rekening mee dat de ODBC-cursorbibliotheek gepositioneerde update- en verwijderinstructies simuleert.

Als u een positioned update- of delete-instructie wilt gebruiken, moet de toepassing een resultatenset maken met een SELECT FOR UPDATE-instructie. De syntaxis van deze instructie is:

SELECT [ALL | DISTINCT] select-list

FROMtable-reference-list

[WHEREsearch-condition]

TER WIJZIGING VAN [kolomnaam [,kolomnaam]...]

De toepassing plaatst de cursor vervolgens op de rij die moet worden bijgewerkt of verwijderd. U kunt dit doen door SQLFetchScroll aan te roepen om een rijset op te halen die de vereiste rij bevat en SQLSetPos aanroept om de cursor van de rijenset op die rij te plaatsen. De toepassing voert vervolgens de geplaatste update- of verwijderinstructie uit op een andere instructie dan de instructie die door de resultatenset wordt gebruikt. De syntaxis van deze instructies is:

UPDATEtabelnaam

SETcolumn-identifier= {expression | NULL}

[,kolom-id= {expressie | NULL}]...

WHERE CURRENT OFcursor-name

DELETE FROMtable-nameWHERE CURRENT OFcursor-name

U ziet dat voor deze instructies een cursornaam is vereist. De toepassing kan een cursornaam opgeven met SQLSetCursorName voordat u de instructie uitvoert waarmee de resultatenset wordt gemaakt of dat de gegevensbron automatisch een cursornaam kan genereren wanneer de cursor wordt gemaakt. In het laatste geval haalt de toepassing de cursornaam op voor gebruik in gepositioneerde update- en verwijderinstructies door SQLGetCursorName aan te roepen.

Met de volgende code kan een gebruiker bijvoorbeeld door de tabel Klanten bladeren en klantrecords verwijderen of hun adressen en telefoonnummers bijwerken. SqlSetCursorName wordt aanroepen om een cursornaam op te geven voordat de resultatenset van klanten wordt gemaakt en er drie instructiegrepen worden gebruikt: hstmtCust voor de resultatenset, hstmtUpdate voor een positioned update-instructie en hstmtDelete voor een positioned delete-instructie. Hoewel de code afzonderlijke variabelen kan binden aan de parameters in de positioned update-instructie, worden de rijensetbuffers bijgewerkt en worden de elementen van deze buffers gekoppeld. Hierdoor worden de rijensetbuffers gesynchroniseerd met de bijgewerkte gegevens.

#define POSITIONED_UPDATE 100  
#define POSITIONED_DELETE 101  
  
SQLUINTEGER    CustIDArray[10];  
SQLCHAR        NameArray[10][51], AddressArray[10][51],   
               PhoneArray[10][11];  
SQLINTEGER     CustIDIndArray[10], NameLenOrIndArray[10],   
               AddressLenOrIndArray[10],  
               PhoneLenOrIndArray[10];  
SQLUSMALLINT   RowStatusArray[10], Action, RowNum;  
SQLHSTMT       hstmtCust, hstmtUpdate, hstmtDelete;  
  
// Set the SQL_ATTR_BIND_TYPE statement attribute to use column-wise   
// binding. Declare the rowset size with the SQL_ATTR_ROW_ARRAY_SIZE   
// statement attribute. Set the SQL_ATTR_ROW_STATUS_PTR statement   
// attribute to point to the row status array.  
SQLSetStmtAttr(hstmtCust, SQL_ATTR_ROW_BIND_TYPE, SQL_BIND_BY_COLUMN, 0);  
SQLSetStmtAttr(hstmtCust, SQL_ATTR_ROW_ARRAY_SIZE, 10, 0);  
SQLSetStmtAttr(hstmtCust, SQL_ATTR_ROW_STATUS_PTR, RowStatusArray, 0);  
  
// Bind arrays to the CustID, Name, Address, and Phone columns.  
SQLBindCol(hstmtCust, 1, SQL_C_ULONG, CustIDArray, 0, CustIDIndArray);  
SQLBindCol(hstmtCust, 2, SQL_C_CHAR, NameArray, sizeof(NameArray[0]),  
            NameLenOrIndArray);  
SQLBindCol(hstmtCust, 3, SQL_C_CHAR, AddressArray, sizeof(AddressArray[0]),  
         AddressLenOrIndArray);  
SQLBindCol(hstmtCust, 4, SQL_C_CHAR, PhoneArray, sizeof(PhoneArray[0]),  
            PhoneLenOrIndArray);  
  
// Set the cursor name to Cust.  
SQLSetCursorName(hstmtCust, "Cust", SQL_NTS);  
  
// Prepare positioned update and delete statements.  
SQLPrepare(hstmtUpdate,  
   "UPDATE Customers SET Address = ?, Phone = ? WHERE CURRENT OF Cust",  
   SQL_NTS);  
SQLPrepare(hstmtDelete, "DELETE FROM Customers WHERE CURRENT OF Cust", SQL_NTS);  
  
// Execute a statement to retrieve rows from the Customers table.  
SQLExecDirect(hstmtCust,  
   "SELECT CustID, Name, Address, Phone FROM Customers FOR UPDATE OF Address, Phone",  
   SQL_NTS);  
  
// Fetch and display the first 10 rows.  
SQLFetchScroll(hstmtCust, SQL_FETCH_NEXT, 0);  
DisplayData(CustIDArray, CustIDIndArray, NameArray, NameLenOrIndArray, AddressArray,  
            AddressLenOrIndArray, PhoneArray, PhoneLenOrIndArray, RowStatusArray);  
  
// Call GetAction to get an action and a row number from the user.  
while (GetAction(&Action, &RowNum)) {  
   switch (Action) {  
  
      case SQL_FETCH_NEXT:  
      case SQL_FETCH_PRIOR:  
      case SQL_FETCH_FIRST:  
      case SQL_FETCH_LAST:  
      case SQL_FETCH_ABSOLUTE:  
      case SQL_FETCH_RELATIVE:  
         // Fetch and display the requested data.  
         SQLFetchScroll(hstmtCust, Action, RowNum);  
         DisplayData(CustIDArray, CustIDIndArray, NameArray, NameLenOrIndArray,  
                     AddressArray, AddressLenOrIndArray, PhoneArray,  
                     PhoneLenOrIndArray, RowStatusArray);  
         break;  
  
      case POSITIONED_UPDATE:  
         // Get the new data and place it in the rowset buffers.  
         GetNewData(AddressArray[RowNum - 1], &AddressLenOrIndArray[RowNum - 1],  
                     PhoneArray[RowNum - 1], &PhoneLenOrIndArray[RowNum - 1]);  
  
         // Bind the elements of the arrays at position RowNum-1 to the   
         // parameters of the positioned update statement.  
         SQLBindParameter(hstmtUpdate, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,  
                           50, 0, AddressArray[RowNum - 1], sizeof(AddressArray[0]),  
                           &AddressLenOrIndArray[RowNum - 1]);  
         SQLBindParameter(hstmtUpdate, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,  
                           10, 0, PhoneArray[RowNum - 1], sizeof(PhoneArray[0]),  
                           &PhoneLenOrIndArray[RowNum - 1]);  
  
         // Position the rowset cursor. The rowset is 1-based.  
         SQLSetPos(hstmtCust, RowNum, SQL_POSITION, SQL_LOCK_NO_CHANGE);  
  
         // Execute the positioned update statement to update the row.  
         SQLExecute(hstmtUpdate);  
         break;  
  
      case POSITIONED_DELETE:  
         // Position the rowset cursor. The rowset is 1-based.  
         SQLSetPos(hstmtCust, RowNum, SQL_POSITION, SQL_LOCK_NO_CHANGE);  
  
         // Execute the positioned delete statement to delete the row.  
         SQLExecute(hstmtDelete);  
         break;  
   }  
}  
  
// Close the cursor.  
SQLCloseCursor(hstmtCust);