Atualizando conjuntos de linhas
Uma operação de banco de dados muito básico for atualização, ou gravar dados para o armazenamento de dados.Em OLE DB, o mecanismo de atualização é simples: seu aplicativo de consumidor define os valores dos membros de dados limite e, em seguida, grava esses valores para o conjunto de linhas; o consumidor solicita que o provedor atualização o armazenamento de dados.
Os consumidores podem executar os seguintes tipos de atualizações nos dados do conjunto de linhas: configuração valores da coluna dentro de uma linha, inserindo uma linha e excluir uma linha.Para executar essas operações, o modelo de banco de dados OLE DB classe CRowset implementa o IRowsetChange interface e substitui os seguintes métodos de interface:
SetData altera os valores de coluna em uma linha de um conjunto de linhas; é equivalente ao comando SQL atualização.
Inserir insere uma linha em um conjunto de linhas; é equivalente ao comando SQL INSERT.
Excluir exclui linhas de um conjunto de registros; ele é equivalente ao comando DELETE do SQL.
Suporte a operações de atualização
Quando você cria um consumidor com o ATL OLE DB consumidor assistente, você pode oferecer suporte as operações de atualização, selecionando um ou mais de três caixas de seleção alterar, Inserir, and Excluir.Se você selecionar esses, o assistente modifica o código apropriadamente para dar suporte o tipo de alterações que você escolher.No entanto, se você não usar o assistente, você precisará definir as seguintes propriedades do conjunto de linhas para VARIANT_TRUE para oferecer suporte a atualizações:
DBPROPVAL_UP_CHANGE permite que você altere os valores dos dados em uma linha.
DBPROPVAL_UP_INSERT permite que você inserir uma linha.
DBPROPVAL_UP_DELETE permite que você excluir uma linha.
Você conjunto sistema autônomo propriedades da seguinte forma:
CDBPropSet ps(DBPROPSET_ROWSET);
ps.AddProperty(DBPROP_IRowsetChange, true)
ps.AddProperty(DBPROP_UPDATABILITY, DBPROPVAL_UP_CHANGE | DBPROPVAL_UP_INSERT | DBPROPVAL_UP_DELETE)
As operações de excluir, inserção ou alterar podem falhar se uma ou mais colunas não é gravável.Modifique o MAP de cursor para corrigir o problema.
Dados de configuração em linhas
CRowset::SetData define valores de dados em uma ou mais colunas da linha corrente.O código a seguir define os valores dos membros de dados limite nas colunas "Nome" e "Unidades em estoque" da tabela Produtos e, em seguida, chamadasSetData para escrever os valores para a linha centésimo do conjunto de linhas:
// Instantiate a rowset based on the user record class
CTable<CAccessor<CProductAccessor> > product;
CSession session;
// Open the rowset and move to the 100th row
product.Open(session, "Product", &ps, 1); // ps is the property set
product.MoveToBookmark(&bookmark, 0); // Assume that bookmark is set to 100th row
// Change the values of columns "Name" and "Units in Stock" in the current row of the Product table
_tcscpy_s( product.m_ProductName, product.m_sizeOfProductName,
_T( "Candle" ) );
product.m_UnitsInStock = 10000;
// Set the data
HRESULT hr = product.SetData( );
Inserir linhas em conjuntos de linhas
CRowset::Insert cria e inicializa uma nova linha usando os dados de o acessador.Inserir cria uma totalmente nova linha após a linha corrente; você precisa especificar se deseja incrementar a linha corrente para a próxima linha ou deixá-la inalterada.Para fazer isso, configuração o bGetRow parâmetro:
HRESULT Insert(int nAccessor = 0, bool bGetRow = false)
False (o valor padrão) Especifica que a linha corrente é incrementado para a próxima linha (caso no qual ele aponta para a linha inserida).
True Especifica que a linha corrente permanecer onde está.
O código a seguir define os valores dos membros de dados acoplados às colunas da tabela Produtos e, em seguida, chama Inserir para inserir uma nova linha com esses valores depois da linha centésimo do conjunto de linhas.É recomendável que você defina todos os valores de coluna para evitar dados indefinidos na nova linha:
// Instantiate a rowset based on the user record class
CTable<CAccessor<CProductAccessor> > product;
CSession session;
// Open the rowset and move to the 100th row
product.Open(session, "Product", &ps, 1); // ps is the property set
product.MoveToBookmark(&bookmark, 0); // Assume that bookmark is set to 100th row
// Set the column values for a row of the Product table, then insert the row
product.m_ProductID = 101;
_tcscpy_s( product.m_ProductName, product.m_sizeOfProductName,
_T( "Candle" ) );
product.m_SupplierID = 27857;
product.m_CategoryID = 372;
_tcscpy_s( product.m_QuantityPerUnit, product.m_sizeOfQuantityPerUnit,
_T( "Pack of 10" ) );
product.m_UnitPrice = 20;
product.m_UnitsInStock = 10000;
product.m_UnitsOnOrder = 5201;
product.m_ReorderLevel = 5000;
product.m_Discontinued = false;
// You must also initialize the status and length fields before setting/inserting data
// Set the column status values
m_dwProductIDStatus = DBSTATUS_S_OK;
m_dwProductNameStatus = DBSTATUS_S_OK;
m_dwSupplierIDStatus = DBSTATUS_S_OK;
m_dwCategoryIDStatus = DBSTATUS_S_OK;
m_dwQuantityPerUnitStatus = DBSTATUS_S_OK;
m_dwUnitPriceStatus = DBSTATUS_S_OK;
m_dwUnitsInStockStatus = DBSTATUS_S_OK;
m_dwUnitsOnOrderStatus = DBSTATUS_S_OK;
m_dwReorderLevelStatus = DBSTATUS_S_OK;
m_dwDiscontinuedStatus = DBSTATUS_S_OK;
// Set the column length value for column data members that are not fixed-length types.
// The value should be the length of the string that you are setting.
m_dwProductNameLength = 6; // "Candle" has 6 characters
m_dwQuantityPerUnitLength = 10; // "Pack of 10" has 10 characters
// Insert the data
HRESULT hr = product.Insert( );
Para obter um exemplo mais detalhado, consulte CRowset::Insert.
Para obter mais informações sobre como definir os membros de dados de status e o comprimento, consulte Campo status dados Members in acessadores gerado pelo Assistente.
Exclusão de linhas de conjuntos de linhas
CRowset::excluir exclui a linha corrente do conjunto de linhas.O código a seguir chama Excluir para remover a linha centésimo do conjunto de linhas:
// Instantiate a rowset based on the user record class
CTable<CAccessor<CProductAccessor> > product;
CSession session;
// Open the rowset and move to the 100th row
product.Open(session, "Product", &ps, 1); // ps is the property set
product.MoveToBookmark(&bookmark, 0); // Assume that bookmark is set to 100th row
// Delete the row
HRESULT hr = product.Delete( );
Atualizações imediatas e adiadas
A menos que você especifique o contrário, chamadas para o SetData, Inserir, and Excluir métodos atualizar imediatamente o armazenamento de dados.Você pode, entretanto, adiar atualizações para que o consumidor armazena todas as alterações em um cache local e, em seguida, transfere-los para os dados armazene quando você telefonar um dos seguintes métodos de atualização:
CRowset::Update transfere qualquer alteração feita à linha corrente desde a última busca ou pendentecorrenteização telefonar on it.
CRowset::UpdateAll transfere todas as alterações feitas em todas as linhas desde a última busca ou pendentesAtualização telefonar on it.
Observe que a atualização, conforme usado pelos métodos de atualização, tem o significado específico de fazer alterações no comando e não é deve ser confundido com o comando UPDATE do SQL (SetData é equivalente ao comando UPDATE do SQL).
Atualizações adiadas são úteis, por exemplo, em situações sistema autônomo uma série de transações bancárias; se uma transação for cancelada, você pode desfazer a alterar, porque você não enviar a série de alterações até após um último compromisso.Além disso, o provedor pode incluir as alterações em uma rede telefonar, que é mais eficiente.
Para oferecer suporte a atualizações adiadas, você deve conjunto o DBPROP_IRowsetChange propriedade juntamente com as propriedades descrito em "Suporte operações de atualização":
pPropSet->AddProperty(DBPROP_IRowsetUpdate, true);
Quando você telefonar Atualização or UpdateAll, os métodos transferência as alterações do cache local para o armazenamento de dados e, em seguida, limpe o cache local. Como atualização transfere alterações somente para a linha corrente, é importante que seu aplicativo controlar de quais linha para atualização e quando atualizá-lo.O exemplo a seguir mostra como atualização duas linhas consecutivas:
// Instantiate a rowset based on the user record class
CTable<CAccessor<CProductAccessor> > product;
CSession session;
// Open the rowset and move to the 100th row
product.Open(session, "Product", &ps, 1); // ps is the property set
product.MoveToBookmark(&bookmark, 0); // Assume that bookmark is set to 100th row
// Change the values of columns "Name" and "Units in Stock" in the 100th row of the Product table
_tcscpy_s( product.m_ProductName, product.m_sizeOfProductName,
_T( "Wick" ) );
product.m_UnitsInStock = 10000;
HRESULT hr = product.SetData( ); // No changes made to row 100 yet
product.Update(); // Update row 100 now
// Change the values of columns "Name" and "Units in Stock" in the 101st row of the Product table
product.MoveNext( );
_tcscpy_s( product.m_ProductName, product.m_sizeOfProductName
_T( "Wax" ) );
product.m_UnitsInStock = 500;
HRESULT hr = product.SetData( ); // No changes made to row 101 yet
product.Update(); // Update row 101 now
Para garantir que as alterações pendentes sejam transferidas, você deve chamar Atualização antes de passar para outra linha.No entanto, quando isso é entediante ou ineficiente, por exemplo, quando seu aplicativo precisa atualizar centenas de linhas, você pode usar UpdateAll Para atualizar todas as linhas ao mesmo tempo.
Por exemplo, se o primeiro Atualização telefonar estava faltando no código acima, a linha 100 permaneceria inalterada, enquanto linha 101 seria alterada.Após esse ponto, seu aplicativo teria que chamar UpdateAll ou mova de volta à linha 100 e telefonar Atualização para aquela linha a ser atualizado.
Finalmente, um motivo principal para adiar alterações é ser capaz de desfazê-las. De chamadaCRowset::desfazer reverte o estado do cache de alterar local para o estado do armazenamento de dados antes que qualquer alterar pendente foram feitas.É importante observar que Desfazer não reverter o estado do cache local, uma etapa (o estado anterior somente a alterar mais recente); em vez disso, esta opção limpa o cache local para aquela linha.Além disso, Desfazer afeta somente a linha corrente.