I have been tasked with creating a service broker using Xquery to handle tracking changes on a collection of tables. I have figured out how to pass the messages (xml of column names and the updated and deleted tables for the statements). The aim is to get the list of column names and then compare the like column for each updated/deleted row and not a change.
Here is a sample of the XML:
<Update xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<TableName>
<ID>2414</ID>
<fkEvent>2664</fkEvent>
<fkType xsi:nil="true" />
<Description>Phil Test 3</Description>
<DTS>2011-04-04T14:01:36.533</DTS>
<uID>192204FA-612F-46F4-A6CB-1B4D53769A81</uID>
<VersionID xsi:nil="true" />
<UpdateDateTime>2011-04-04T14:04:31.013</UpdateDateTime>
<DeleteFlag>0</DeleteFlag>
<Updated>0</Updated>
<Owner>42</Owner>
<CreatedBy>42</CreatedBy>
</TableName>
</Update>
Generated by:
SET @xml1 = (SELECT * FROM TableName ORDER BY ID DESC FOR XML AUTO, ELEMENTS XSINIL, ROOT('MsgEnv'))
I have the following code:
WHILE @cnt <= @totCnt BEGIN
SELECT @child = @ColNames.query('/Columns/name[position()=sql:variable("@cnt")]')
SET @CurrentCol = REPLACE(REPLACE(CAST(@child AS VARCHAR(500)), '<name>', ''), '</name>', '')
PRINT @CurrentCol
WHILE @updateCnt <= @updateCntTotal BEGIN
SELECT @childUpdate = @xml1.query('/Update/TableName/sql:variable("@CurrentCol")')
PRINT CAST(@childUpdate AS VARCHAR(MAX))
WHILE @deleteCnt <= @deleteCntTotal BEGIN
SELECT @deleteCnt = @deleteCnt + 1
END
SET @deleteCnt = 1
SELECT @updateCnt = @updateCnt + 1
END
SET @updateCnt = 1
SELECT @cnt = @cnt + 1
END
The trouble I am having is dynamically setting the column name for this statement:
SELECT @childUpdate = @xml1.query('/Update/TableName/sql:variable("@CurrentCol")')
I have tried a few different variations using the sql:variable. Is it not possible to do this? I'd like to be able to do this dynamically as there are lots of tables we need to "audit" changes on.
Edit 1:
SELECT @childUpdate = @xml1.query('/Update/TableName/*[name() = sql:variable("@CurrentCol")]')
Yields this error (including the . in the () has a similar effect.
Msg 2395, Level 16, State 1, Line 34
XQuery [query()]: There is no function '{http://www.w3.org/2004/07/xpath-functions}:name()'