ICommandTree::SetCommandTree

[This is preliminary documentation and subject to change.]

Sets a command object's command tree, replacing the existing one or replacing a text command specified with ICommandText. The provided command tree is copied into the command object; thus, the consumer may delete the original tree or text without affecting the command object. Most error checking is deferred until one of the validation methods, optimization (see ICommandPrepare), or the ICommand::Execute method are invoked. This method only verifies that the command tree can indeed be copied into the command object's space.

HRESULT SetCommandTree(
  DBCOMMANDTREE ** ppRoot, 
  DBCOMMANDREUSE dwCommandReuse, 
  BOOL fCopy 
);
 

Parameters

ppRoot
[in] The root of the command tree.
dwCommandReuse
[in] A bitmask that specifies whether state from the previous command is retained. If state that was not previously specified is marked for reuse, the flag is ignored and no error occurs. See ICommandText::SetCommandText for a description of these flags.
fCopy
[in] If TRUE, the command tree is copied, and the caller retains ownership of the command tree's memory. If FALSE, the provider takes the entire tree, without copying, and set the caller's root pointer to a null pointer. When the command object needs to deallocate the tree, it will call IMalloc::Free once for each node in the tree.

If fCopy is FALSE, the consumer must not change the command tree without another call to SetCommandTree. The affect of any such changes is undefined. In particular, the provider can assume that the command tree has not changed between the calls that use the tree, such as SetCommandTree, ICommandValidate::ValidateSyntax or ValidateCompletely, ICommandPrepare::Prepare, and ICommand::Execute.

Return Value

S_OK
The method succeeded.
E_FAIL
A provider-specific error occurred.
E_INVALIDARG
pRoot was a null pointer. dwCommandReuse was invalid.
DB_E_OBJECTOPEN
A rowset was open on the command object.

Comments

The following example shows how to build and set a simple command.

hr = pICreateCommand->CreateCommand(IID_ICommand,
                                    (IUnknown **) &pICommand);
pICreateCommand->Release();
 
// Build a command for the following query:
//    SELECT * FROM CUSTOMERS ORDER BY CITY
CreateSelectNode(&pctSelect);
CreateProjectListAnchor(&pctPLListAnchor);
 
pctSelectNode->pctFirsChild = pctPLListAnchor;
 
CreateProjectListNode("*", &pctPLListNode);
CreateFromListAnchor(&pctFListAnchor);
CreateFromListNode("CUSTOMERS", &pctFLNode);
 
pctPLListAnchor->pctFirstChild = pctPLListNode;
pctPLListAnchor->pctNextSibling = pctFListAnchor;
 
CreateSortListAnchorNode(&pctSLAnchor);
CreateSortListElementNode("ascending",&pctSLNode);
CreateScalarIdNode("CITY", &pctScalar);
 
pctFListAnchor->pctFirstChild = pctFLNode;
pctFListAnchor->pctNextSibling = pctSLAnchor;
 
pctSLAnchor->pctFirstChild = pctSLNode;
pctSLNode->pctFirstChild = pctScalar;
 
// Get  ICommandTree Interface
hr = pICommand->QueryInterface(IID_ICommandTree,
                               (IUnknown **) &pICommandTree);
 
// Set Command Tree in Command Object
pICommandTree->SetCommandTree(&pctSort, FALSE);
pICommandTree->Release();
 

The functions used to create the various nodes (e.g. CreateSelectNode) are simple wrappers that set values in the DBCOMMANDTREE structure; they are not part of the OLE DB specification. For example, the code for CreateFromListNode might be:

void CreateFromListNode(
   PWSTR           szFromList,
   DBCOMMANDTREE ** ppctFLNode);
{
   // Allocate DBCOMMANDTREE structure. Place pointer to it in
   // *ppctFLNode. Code not shown.
 
   *ppctFLNode->op             = DBOP_from_list;
   *ppctFLNode->hrOperatorOk   = S_OK;
   *ppctFLNode->hrContextOk    = S_OK;
   *ppctFLNode->pctFirstChild  = NULL;
   *ppctFLNode->pctNextSibling = NULL;
   *ppctFLNode->eKind          = DBVALUEKIND_NAME;
   *ppctFLNode->pwszName       = szFromList;
}