Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
As aplicações podem usar uma instrução posicional para atualizar ou eliminar a linha atual de um conjunto de resultados. As declarações posicionadas de atualização e eliminação são suportadas por algumas fontes de dados, mas não por todas. Para determinar se uma fonte de dados suporta instruções posicionadas de atualização e eliminação, uma aplicação chama SQLGetInfo com o SQL_DYNAMIC_CURSOR_ATTRIBUTES1, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, SQL_KEYSET_CURSOR_ATTRIBUTES1 ou SQL_STATIC_CURSOR_ATTRIBUTES1 InfoType (dependendo do tipo do cursor). Note que a biblioteca de cursores ODBC simula instruções de atualização e eliminação posicionais.
Para usar uma instrução de atualização ou eliminação posicionada, a aplicação deve criar um conjunto de resultados com a instrução SELECT FOR UPDATE. A sintaxe desta afirmação é:
SELECT [TODOS | DISTINTOS] select-list
Lista de referências de tabelaFROM
[c0>WHERE
PARA ATUALIZAÇÃO DE [nome da coluna [,nome da coluna]...]
A aplicação posiciona então o cursor na linha a atualizar ou eliminar. Pode fazê-lo chamando o SQLFetchScroll para recuperar um conjunto de linhas contendo a linha necessária e chamando o SQLSetPos para posicionar o cursor do conjunto de linhas nessa linha. A aplicação executa então a instrução de atualização ou eliminação posicionada numa instrução diferente daquela que está a ser utilizada pelo conjunto de resultados. A sintaxe destas afirmações é:
UPDATEnome-da-tabela
SETidentificador de coluna= {expressão | NULL}
[,identificador-coluna= {expressão | NULL}]...
ONDE A ATUAL DOnome do cursor
ELIMINAR donome da tabelaonde o nome do cursor é atual
Note que estas instruções requerem um nome de cursor. A aplicação pode especificar um nome de cursor com SQLSetCursorName antes de executar a instrução que cria o conjunto de resultados, ou pode permitir que a fonte de dados gere automaticamente um nome de cursor quando o cursor é criado. Neste último caso, a aplicação recupera esse nome do cursor para uso em instruções posicionadas de atualização e eliminação, chamando SQLGetCursorName.
Por exemplo, o código seguinte permite ao utilizador percorrer a tabela de Clientes e apagar registos de clientes ou atualizar os seus endereços e números de telefone. Chama SQLSetCursorName para especificar um nome de cursor antes de criar o conjunto de resultados dos clientes e utiliza três handles de instruções: hstmtCust para o conjunto de resultados, hstmtUpdate para uma instrução de atualização posicionada e hstmtDelete para uma instrução de eliminação posicionada. Embora o código pudesse associar variáveis separadas aos parâmetros na instrução de atualização posicional, ele atualiza os buffers de rowset e vincula os elementos desses buffers. Isto mantém os buffers de rowset sincronizados com os dados atualizados.
#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);