I am trying to update CertificateIssuers field shown in the XML output below
Query:
SELECT Settings FROM Sites
Output:
<ClientOperationalSettings>
<Version>5.00.8740.1002</Version>
<SecurityConfiguration>
<SecurityModeMask>0</SecurityModeMask>
<SecurityModeMaskEx>480</SecurityModeMaskEx>
<HTTPPort>80</HTTPPort>
<HTTPSPort>443</HTTPSPort>
<CertificateStoreName/>
<CertificateIssuers>CN=Mars-M-CA-CA-1; DC=Mars; DC=Local</CertificateIssuers>
<CertificateSelectionCriteria>SubjectAttr:OU=London</CertificateSelectionCriteria>
<CertificateSelectFirstFlag>1</CertificateSelectFirstFlag>
<PKICertOptions>1</PKICertOptions>
<SiteSigningCert>308202ED308201D5A0030201020210129F196B3060FF94418BEA860E8DD712300D06092A864886F70D01010B05003016311430120603550403130B53697465205365727665723020170D3138303933303031353534395A180F32313138303930373031353534395A3016311430120603550403130B536974652053657276657230820122300D06092A864886F70D01010105000382010F003082010A0282010100B2B3E6757D8E4DF7977F061543CF629B9129C337D373945A4FFE4625D557370FA21B6E03C09AE692A32A6B783BE2C19E3FEC965054F9A54BFDDB7C4B23E45456353EEA9D14FCA5EF58DCDECA3EEB9B7D589162DD87005799D473BB1518398C638217986780CCE8DFB778A84915019700BAF53AB3205730060911D7EEF17C4EDE904953EAEB8BAEBC85CAAFE82F121FC16A9316DB09E94D76A01F61A2129F4F807ADCB68270410393D9BD2E435C253683B013677EFFEBF09EE6BAC25D9AA21742142A58A1E2EAF09BD75C07BA18B85080F6700245461734AB9A466B56BE7D7F2F8E07D62AA75253B8A2839777E7C0A6DC6FF575164232EB05B3C9EA2CFC3531C30203010001A3353033301B0603551D110414301282104D2D5030312E4D6172732E4C6F63616C30140603551D25040D300B06092B060104018237650B300D06092A864886F70D01010B050003820101004AAAD78752D9650694401B43191B0BD586B48A96990C68B40673444C878032CDB7E8113E7344E7FD47DF18FF0DE51F8396B5F670AA5998BE34E6F91BAA79593D5578FB54A3EDABA20E14FE4B5D2736E5FB234F4FED7BA53972A5462682B67A1B3DD6FD2599DBFF0DE49B99C44C1003932816784F06D47C69584DA61C9E026EB2B1730920A06B9296FE69141CCCA1677A52AF644E5834D429F4810340FB6FB30B061A3555F4C3E506B960496CF10E54145384B1A6FE87A1FB26EB078246D132DD509F82180B0CDD9AF485329159F2145CBA6B55A36777558F2901B30B9974739640C4B8DCDF0319C9A10EEF4EAA33B74E7F54CE5C6F313DCB4FF7EEA1FA6453A5</SiteSigningCert>
</SecurityConfiguration>
<AADConfig Version="1.0">
<Tenants/>
</AADConfig>
</ClientOperationalSettings>
I found XML from SQL column: Cannot call methods on nvarchar(max) and I am able to query the value like below
Query:
SELECT cast([Sites].[Settings] as xml).query('data(ClientOperationalSettings/SecurityConfiguration/CertificateIssuers)') FROM [dbo].[Sites]
Output:
(No column name)
CN=Mars-M-CA-CA-1; DC=Mars; DC=Local
but how to I update the CN to lets say to below for example
<CertificateIssuers>CN=Mars Planet; DC=Mars; DC=Local</CertificateIssuers>
You can try the following query.
UPDATE
dbo.Sites
SET
Settings.modify('replace value of (/ClientOperationalSettings/SecurityConfiguration/CertificateIssuers/text())[1] with "CN=Mars Planet; DC=Mars; DC=Local"')
WHERE ....
Related
I have a column that holds xml data in SQL Server. I have 2 values in my column, the data looks like this:
<StoreSurvey>
<BankName>United Security</BankName>
<BusinessType>BM</BusinessType>
</StoreSurvey>
and this :
<StoreSurvey>
<AnnualSales>2000</AnnualSales>
<BankName>United Security</BankName>
<BusinessType>BM</BusinessType>
</StoreSurvey>
As you can see these two values has a different on AnnualSales. How can I write a query to return the records with AnnualSales=2000?
Sorry I am so new in XML data type.
As your is question is not clear whether you are asking to join both the result sets or filter the record where Annual sales = 2000
here is the example basing on assumed data
Declare #XmlStr XML;
SET #XmlStr='<StoreSurvey>
<AnnualSales>2000</AnnualSales>
<BankName>United Security</BankName>
<BusinessType>BM</BusinessType>
</StoreSurvey>
<StoreSurvey>
<BankName>United Security</BankName>
<BusinessType>BM</BusinessType>
</StoreSurvey>';
Script where you can only get Annual sales = 2000
SELECT
[Table].[Column].value('AnnualSales[1]', 'int') as 'AnnualSales ',
[Table].[Column].value('BankName[1]', 'varchar(20)') as 'BankName',
[Table].[Column].value('BusinessType[1]', 'varchar(50)') as 'BusinessType'
FROM
#XmlStr.nodes('/StoreSurvey') as [Table]([Column])
WHERE
[Table].[Column].value('(AnnualSales[1])[1]', 'int') = 2000
I have a SQL table called: tblDataPermit
One column contains XML Data and is called: XmlDataField
In SQL Report Builder I am trying pull the data from the Text1Size50 node as shown in the sample xml data below. In this case it would be "Kirby Vacuum"
If I use:
SELECT
tblDataPermit.XmlDataField
FROM
tblDataPermit
It will produce all content in the XmlDataField as shown below. I only want it to show "Kirby Vacuum".
I have also tried this:
SELECT tblDataPermit.XmlDataField.value('(/Text1Size50/#Text1Size50)[1]', 'VARCHAR(50)') AS Result from dbo.tblDataPermit
WHERE ApplicationNumber = '00000002'
ORDER BY Result desc
I get a NULL value.
Here is a sample of the Xml data field:
--<XmlDataField xmlns="MgmsSchema/Business_Information_Detail_Entry" ApplicationNumber="00000865">
<Text1Size50>Kirby Vacuum</Text1Size50>
<Text2Size50>Lowes</Text2Size50>
</XmlDataField>--
I have this xml value in a CLOB column in Oracle 11g:
<Energy xmlns="http://euroconsumers.org/notifications/2009/01/notification">
<Gender>M</Gender>
<FirstName>MAR</FirstName>
<Name>VAN HALL</Name>
<Email/><Telephone>000000000</Telephone>
<InsertDate>2013-10-09</InsertDate>
</Energy>
I want to update the value of InserDate for several rows.
I was using next below sql command:
update tmp_tab_noemail_test p1
set p1.sce_msg = updatexml(xmltype(p1.sce_msg),
'//Energy/InsertDate/text()','Not Valid').getClobVal()
But is not working.
Do you have some ideas to modify only the values of the xml tag of InsertDate?
Thanks in advances
You have a namespace in your top-level Energy node, so you aren't matching without; the UPDATEXML documentation shows you can optionally supply a namespace string.
So you can do this, using your example data:
create table tmp_tab_noemail_test (sce_msg clob);
insert into tmp_tab_noemail_test values (
'<Energy xmlns="http://euroconsumers.org/notifications/2009/01/notification">
<Gender>M</Gender>
<FirstName>MAR</FirstName>
<Name>VAN HALL</Name>
<Email/><Telephone>000000000</Telephone>
<InsertDate>2013-10-09</InsertDate>
</Energy>');
update tmp_tab_noemail_test p1
set p1.sce_msg = updatexml(xmltype(p1.sce_msg),
'/Energy/InsertDate/text()','Not Valid',
'xmlns="http://euroconsumers.org/notifications/2009/01/notification"').getClobVal();
After which you end up with:
select sce_msg from tmp_tab_noemail_test;
SCE_MSG
--------------------------------------------------------------------------------
<Energy xmlns="http://euroconsumers.org/notifications/2009/01/notification"><Gender>M</Gender><FirstName>MAR</FirstName><Name>VAN HALL</Name><Email/><Telephone>000000000</Telephone><InsertDate>Not Valid</InsertDate></Energy>
Or with slightly less scrolling:
select XMLQuery('//*:InsertDate' passing XMLType(sce_msg) returning content) as insertdate
from tmp_tab_noemail_test;
INSERTDATE
--------------------------------------------------------------------------------
<InsertDate xmlns="http://euroconsumers.org/notifications/2009/01/notification">Not Valid</InsertDate>
You could also wildcard the update:
update tmp_tab_noemail_test p1
set p1.sce_msg = updatexml(xmltype(p1.sce_msg),
'/*:Energy/*:InsertDate/text()','Not Valid').getClobVal();
... but it's probably better to specify the namespace.
I have a SQL Server table with an XML column, and it contains data something like this:
<Query>
<QueryGroup>
<QueryRule>
<Attribute>Integration</Attribute>
<RuleOperator>8</RuleOperator>
<Value />
<Grouping>OrOperator</Grouping>
</QueryRule>
<QueryRule>
<Attribute>Integration</Attribute>
<RuleOperator>5</RuleOperator>
<Value>None</Value>
<Grouping>AndOperator</Grouping>
</QueryRule>
</QueryGroup>
</Query>
Each QueryRule will only have one Attribute, but each QueryGroup can have many QueryRules. Each Query can also have many QueryGroups.
I need to be able to pull all records that have one or more QueryRule with a certain attribute and value.
SELECT *
FROM QueryBuilderQueries
WHERE [the xml contains any value=X where the attribute is either Y or Z]
I've worked out how to check a specific QueryRule, but not "any".
SELECT
Query
FROM
QueryBuilderQueries
WHERE
Query.value('(/Query/QueryGroup/QueryRule/Value)[1]', 'varchar(max)') like 'UserToFind'
AND Query.value('(/Query/QueryGroup/QueryRule/Attribute)[1]', 'varchar(max)') in ('FirstName', 'LastName')
You can use two exist(). One to check the value and one to check Attribute.
select Q.Query
from dbo.QueryBuilderQueries as Q
where Q.Query.exist('/Query/QueryGroup/QueryRule/Value/text()[. = "UserToFind"]') = 1 and
Q.Query.exist('/Query/QueryGroup/QueryRule/Attribute/text()[. = ("FirstName", "LastName")]') = 1
If you really want the like equivalence when you search for a Value you can use contains().
select Q.Query
from dbo.QueryBuilderQueries as Q
where Q.Query.exist('/Query/QueryGroup/QueryRule/Value/text()[contains(., "UserToFind")]') = 1 and
Q.Query.exist('/Query/QueryGroup/QueryRule/Attribute/text()[. = ("FirstName", "LastName")]') = 1
According to http://technet.microsoft.com/pl-pl/library/ms178030%28v=sql.110%29.aspx
"The XQuery must return at most one value"
If you are quite certain that for example your XML has let's say maximum 10 QueryRules you could maybe use WHILE to loop everything while droping your results into temporary table?
maybe below can help you anyway
CREATE TABLE #temp(
Query type)
DECLARE #i INT
SET #i = 1
WHILE #i >= 10
BEGIN
INSERT INTO #temp
SELECT
Query
FROM QueryBuilderQueries
WHERE Query.value('(/Query/QueryGroup/QueryRule/Value)[#i]', 'varchar(max)') LIKE 'UserToFind'
AND Query.value('(/Query/QueryGroup/QueryRule/Attribute)[#i]', 'varchar(max)') IN ('FirstName', 'LastName')
#i = #i + 1
END
SELECT
*
FROM #temp
It's a pity that the SQL Server (I'm using 2008) does not support some XQuery functions related to string such as fn:matches, ... If it supported such functions, we could query right inside XQuery expression to determine if there is any. However we still have another approach. That is by turning all the possible values into the corresponding SQL row to use the WHERE and LIKE features of SQL for searching/filtering. After some experiementing with the nodes() method (used on an XML data), I think it's the best choice to go:
select *
from QueryBuilderQueries
where exists( select *
from Query.nodes('//QueryRule') as v(x)
where LOWER(v.x.value('(Attribute)[1]','varchar(max)'))
in ('firstname','lastname')
and v.x.value('(Value)[1]','varchar(max)') like 'UserToFind')
I have a SQL query to get data from SQL Server 2012:
select dbo.TRIM(cfProj.cfProjId) as "cfProjId",
dbo.TRIM(cfProj.cfAcro) as "cfAcro",
(SELECT cfLangCode as "#cfLangCode", cfTrans as "#cfTrans", cfProjTitle.cfTitle
FROM dbo.cfProjTitle
WHERE dbo.cfProjTitle.cfProjId = dbo.cfProj.cfProjId
FOR XML PATH('cfTitle'), type)
from cfProj FOR XML PATH('cfProj')
This SQL returns data structure like:
<cfProj>
<cfProjId>00001111</cfProjId>
<cfAcro>222</cfAcro>
<cfTitle cfLangCode="ru" cfTrans="h">
<cfTitle>some title here</cfTitle>
</cfTitle>
</cfProj>
But I want get XML structure without second nested "cfTitle" element:
<cfProj>
<cfProjId>00001111</cfProjId>
<cfAcro>222</cfAcro>
<cfTitle cfLangCode="ru" cfTrans="h">some title here</cfTitle>
</cfProj>
Difference in this line: <cfTitle cfLangCode="ru" cfTrans="h">some title here</cfTitle>
Any ideas how I can get desirable result?
If you don't need multiple cfTitle elements, you can use marc_s solution, but if you do - you can try this:
select
p.cfProjId,
p.cfAcro,
(
select
pt.cfLangCode as [#cfLangCode],
pt.cfTrans as [#cfTrans],
pt.cfTitle as [text()]
from cfProjTitle as pt
where pt.cfProjId = p.cfProjId
for xml path('cfTitle'), type
)
from cfProj as p
for xml path('cfProj')
sql fiddle demo