apache-camel - how to access column value of a result set - apache-camel

I have a camel route which does a select query from a table, then split the rows, then does something and then update rows of the same table.
<route>
<from uri="sql:SELECT ID,NAME,ADDRESS FROM TABLE WHERE SOMECOLUMN = 'Z'?consumer.delay=10000"/>
<split id="_split1">
<simple>body</simple>
<!-- DO SOMETHING -->
<to uri="sql:UPDATE TABLE WHERE ID = {ID FROM DE RESULT QUERY}?consumer.delay=10000"/>
</split>
How can i access to that column value without java objects?

Related

SQL Server XML - modify multiple elements

I have a SQL Server XML column with data like this:
<History>
<Entry>
.....
</Entry>
<Entry>
.....
</Entry>
</History>
I need to add a unique identifier to each Entry element, giving this result:
<History>
<Entry entryID="AAA">
.....
</Entry>
<Entry entryID="BBB">
.....
</Entry>
</History>
I have it working for the first occurrence of the Entry element but don't know how to apply it to all occurrences. Also, this entryID is a GUID and I don't know how to generate a new one for each row.
Here is how I update the first element.
declare #eventId varchar(64)
set #eventId = CONVERT(varchar(64),NEWID())
update Histories
set XmlHistory.modify('
insert attribute EntryID {sql:variable("#eventId")}
into (History/Entry)[1]
')
where HistoryID=285162
I also have query that selects the elements that need this attribute and do not already have it. This gives the primary key and the element I need to update. I can't get a unique element identifier to use for the element array index.
select h.id rowPK, m.c.query('.') theElement
from TheTable h
cross apply h.XMLColumn.nodes('History/Entry[not(#EntryID)]') m(c)
where XMLColumn.exist('(History/Entry)')= 1
Manipulating XML in SQL Server can be very difficult, if you have the option, any other option! you should apply the unique id's before loading this as XML to Sql Server. The best I could do was to shred the XML to a table variable, add the keys and then extract as an XML stream. I hope this helps ...
Note, this does check for duplicate keys so you would need to handle that and you will need to include any additional nodes or elements that you did not reference in the question.
declare #Histories table
(
HistoryID int,
XmlHistory xml
)
insert into #Histories values (285162, '
<History>
<Entry>
Entry 1
</Entry>
<Entry>
Entry 2
</Entry>
<Entry>
Entry 3
</Entry>
<Entry>
Entry 4
</Entry>
</History>');
declare #tmp table
(
EntryVal varchar(max),
EntryGuid varchar(64)
)
insert into #tmp(EntryVal, EntryGuid)
SELECT p1.value(N'.[1]','nvarchar(max)') AS EntryValue, CONVERT(varchar(64),NEWID())
from #Histories H1
outer apply H1.XmlHistory.nodes(N'/History/Entry') AS A(p1)
select EntryGuid as '#ID', EntryVal as "data()"
from #tmp
for XML PATH ('ENTRY'), root ('HISTORY');
The output should look like this
<HISTORY>
<ENTRY ID="1C5C9492-36C8-4E4E-9AE3-DF7E2F1C1948">
Entry 1
</ENTRY>
<ENTRY ID="9AC4BB5D-C471-4C89-947B-8C17D2BD446C">
Entry 2
</ENTRY>
<ENTRY ID="10A81C91-A58B-4846-A857-A14BFB7F9CB7">
Entry 3
</ENTRY>
<ENTRY ID="0E65D134-37A2-489C-8C72-5BE52D08D7B1">
Entry 4
</ENTRY>
</HISTORY>

how to filter xml elements for multiple values

XML is stored in a table in SQL server using xml data type.
CREATE TABLE MyTable(
i int primary key,
XmlField xml NULL
)
insert into MyTable(i, xmlField)
values(1, N'<root>
<Area1>
<Parent>
<Name>ParentJay</Name>
<Spouse>Janice</Spouse>
<child>John
<grandchild>Kate</grandchild>
<grandchild>Moss</grandchild>
<grandchild>Ruby</grandchild>
<grandchild>Violet</grandchild>
</child>
</Parent>
<Parent>
<Name>ParentMark</Name>
<Spouse>May</Spouse>
<child>Mary
<grandchild>Violet</grandchild>
<grandchild>Kate</grandchild>
<grandchild>jubi</grandchild>
</child>
</Parent>
<Parent>
<Name>ParentJoe</Name>
<Spouse>kim</Spouse>
<child>Kelly
<grandchild>Moss</grandchild>
<grandchild>Kate</grandchild>
</child>
</Parent>
<Parent>
<Name>ParentMike</Name>
<Spouse>Mia</Spouse>
<child>Mary
<grandchild>Jeff</grandchild>
<grandchild>jubi</grandchild>
<grandchild>Violet</grandchild>
</child>
</Parent>
</Area1>
</root>')
Problem: Get all the child nodes with grandchild names Kate and Moss
I have query to get the child element to filter by one grandchild Kate.
Is there a way to use and/or in the query to filter for multiple grandchild names(Kate and Moss).
declare #v varchar(20)
set #v='Kate'
SELECT
child = x.value('local-name(..)', 'varchar(50)'),
value = x.value('(..)', 'varchar(50)')
FROM MyTable
CROSS APPLY XmlField.nodes('/root/Area1/Parent/child/*[contains((.),sql:variable("#v"))] ' ) as T2(x)
Result
child value
child John KateMossRubyViolet
child Mary VioletKatejubi
child Kelly MossKate
Result looking for:
child value
child John KateMossRubyViolet
child Kelly MossKate
I think, you've placed your filter predicate on a level to deep...
You might use a query like this
SELECT grCh.query('.')
FROM mytable
CROSS APPLY xmlField.nodes('/root/Area1/Parent[child[grandchild="Kate" and grandchild="Moss"]]') A(grCh);
You can read this as: Dive into root -> Area1 -> Parent. At this level we need a predicate. Here we say: Is there a node <child>, which (one more predicate) has a grandchild named Kate and one Moss (you can use or as well).
You can introduce the values with sql:variable() or with sql:column() if you don't want to hardcode them literally.
Hope this helps...

How to update only that column which is modified in sql server table?

I am trying to insert data from XML string
<customer ID="1">
<Value HNAME="Holand" Revenue="12,7865"/>
<Value XNAME="Hemmer" Revenue="15,7865"/>
82 more "Value" child with different set of revenue and <AlphabetCombinations>NAME values.....
<customer>
If XML came with same ID in customer tag
<customer ID="1">
<Value HNAME="Holand" Revenue="12,7865"/>
<Value XNAME="Hemmer" Revenue="17,7425"/>
82 more "Value" child with different set of revenue and <AlphabetCombinations>NAME values.....
<customer>
Above XML value of Revenue is change for XNAME="Hemmer",I have to update value of only that column which is updated.there is 84 columns in my table,is there any query which update record for Customer ID =1 and update only modified column,I don't intended to update all the values again for customer.
Customer(ID,HNAME,XNAME,.....)

sql server - Combine single ids into range

I have a table that contains lots of integers. This table gets queried and the results end up being turned into xml. If the table contains for example the following items:
SELECT itemId FROM items WHERE enabled = true
1
2
3
5
The my final xml output after some processing would be:
<item id="1" />
<item id="2" />
<item id="3" />
<item id="5" />
The xml ends up being fairly large and alot of the items are actually ranges. What I would like to do is update my query to combine ranges (alot of these items are 'neighbours' so the xml generated would be quite a bit smaller). I'm trying to get the procedures results to be more like this:
1-3
5
So that the final XML looks something like this (if I can just change the procedure, the XML processing can stay the same):
<item id="1-3"/>
<item id="5"/>
I was thinking my best route may be to use a self join where table1.itemId = table2.itemId - 1 but I haven't been able to get it working. Does anyone have any suggestions on how I can go about this?
Would this help?
SELECT
MIN(ItemID)
,MAX(ItemID)
FROM
(
SELECT ItemID, RANK() OVER (ORDER BY ItemID) R FROM Items
) Tmp
GROUP BY
ItemID - R
I'd think this should do the trick: 1) order by itemID 2) use OVER...PARTITION to get row number 3) use it in a recursive Common Table Expression that joins a number to all others where anchor + row number equals the ItemID, thereby finding all sequential numbers 4) group by the anchor in an outer query and then use MIN and MAX to get the range.

SQL Server 2005 - searching for value in XML field

I'm trying to query a particular value in an XML field. I've seen lots of examples, but they don't seem to be what I'm looking for
Supposing my xml field is called XMLAttributes and table TableName, and the complete xml value is like the below:
<Attribute name="First2Digits" value="12" />
<Attribute name="PurchaseXXXUniqueID" value="U4RV123456762MBE79" />
(although the xml field will frequently have other attributes, not just PurchaseXXXUniqueID)
If I'm looking for a specific value in the PurchaseXXXUniqueID attribute name - say U4RV123456762MBE79 - how would I write the query? I believe it would be something like:
select *
from TableName
where XMLAttributes.value('(/path/to/tag)[1]', 'varchar(100)') = '5FTZP2QT8Z3E2MAV2D'
... but it's the path/to/tag that I need to figure out.
Or probably there's other ways of getting the values I want.
To summarize - I need to get all the records in a table where the value of a particular attribute in the xml field matches a value I'll pass to the query.
thanks for the help!
Sylvia
edit: I was trying to make this simpler, but in case it makes a difference - ultimately I'll have a temporary table of 50 or so potential values for the PurchaseXXXUniqueID field. For these, I want to get all the matching records from the table with the XML field.
This ought to work:
SELECT
(fields from base table),
Nodes.Attr.value('(#name)[1]', 'varchar(100)'),
Nodes.Attr.value('(#value)[1]', 'varchar(100)')
FROM
dbo.TableName
CROSS APPLY
XMLAttributes.nodes('/Attribute') AS Nodes(Attr)
WHERE
Nodes.Attr.value('(#name)[1]', 'varchar(100)') = 'PurchaseXXXUniqueID'
AND Nodes.Attr.value('(#value)[1]', 'varchar(100)') = 'U4RV123456762MBE79'
You basically need to join the base table's row against one "pseudo-row" for each of the <Attribute> nodes inside the XML column, and the pick out the individual attribute values from the <Attribute> node to select what you're looking for.
Something like that?
declare #PurchaseXXXUniqueID varchar(max)
set #PurchaseXXXUniqueID = 'U4RV123456762MBE79';
select * from TableName t
where XMLAttributes.exist('//Attribute/#value = sql:variable("#PurchaseXXXUniqueID")') = 1

Resources