次のSQL XMLから "DATE"値を取得するSQLクエリを生成しようとしています。
私はこのようなことを試しましたが、概念を理解しているとは思いません。
select
xConfig.value('(/SearchjobConfig/QueryString/SearchCriteria/ExpressionSet/SimpleAttributeExpression) [1]','nvarchar(max)')
from
Job
テキストとしてのXMLは次のとおりです。
<SearchJobConfig>
<QueryID>1072</QueryID>
<QueryString>
<SearchCriteria name="Search query" >
<ExpressionSet logicalOperator="AND">
<SimpleAttributeExpression displayName="Date" npmPropertyId="4" searchOperation="GREATER_EQUAL" dataType="string" caseSensitive="false">2019-06-01T04:00:00</SimpleAttributeExpression>
<SimpleAttributeExpression displayName="Date" npmPropertyId="4" searchOperation="LESS_EQUAL" dataType="string" caseSensitive="false">2019-06-13T03:59:59</SimpleAttributeExpression>
<SimpleAttributeExpression displayName="Class" npmPropertyId="1056" searchOperation="EQUALS" dataType="int32" caseSensitive="false">65</SimpleAttributeExpression>
</ExpressionSet>
</SearchCriteria>
</QueryString>
</SearchJobConfig>
予想される出力は日付になります:
2019-06-01T04:00:00
2019-06-13T03:59:59
そして、同じ行で結果を得るには何が必要でしょうか。例:
date_val_start date_val_end 2019-06-01T04:00:00 2019-06-13T03:59:59
SQL Server 2012 Enterprise Editionを使用しています。
これはあなたが望むものを手に入れますか?
DECLARE @x XML = '
<SearchJobConfig>
<QueryID>1072</QueryID>
<QueryString>
<SearchCriteria name="Search query" >
<ExpressionSet logicalOperator="AND">
<SimpleAttributeExpression displayName="Date" npmPropertyId="4" searchOperation="GREATER_EQUAL" dataType="string" caseSensitive="false">2019-06-01T04:00:00</SimpleAttributeExpression>
<SimpleAttributeExpression displayName="Date" npmPropertyId="4" searchOperation="LESS_EQUAL" dataType="string" caseSensitive="false">2019-06-13T03:59:59</SimpleAttributeExpression>
<SimpleAttributeExpression displayName="Class" npmPropertyId="1056" searchOperation="EQUALS" dataType="int32" caseSensitive="false">65</SimpleAttributeExpression>
</ExpressionSet>
</SearchCriteria>
</QueryString>
</SearchJobConfig>
'
DECLARE @Job TABLE(xConfig XML)
INSERT @Job ( xConfig )
VALUES ( @x )
SELECT j.*
, ca.c.value('text()[1]', 'VARCHAR(30)') AS date_val
FROM @Job AS j
CROSS APPLY j.xConfig.nodes('/SearchJobConfig/QueryString/SearchCriteria/ExpressionSet/SimpleAttributeExpression') AS ca(c)
WHERE ca.c.exist('@displayName[.= "Date"]') = 1;
すべてを1行で取得するには、次のようにします。
SELECT *
FROM
(
SELECT STUFF(
(SELECT N' ' + ca.c.value('text()[1]', 'NVARCHAR(MAX)')
FROM @Job AS j
CROSS APPLY j.xConfig.nodes('/SearchJobConfig/QueryString/SearchCriteria/ExpressionSet/SimpleAttributeExpression') AS ca(c)
WHERE ca.c.exist('@displayName[.= "Date"]') = 1
FOR XML PATH(N''), TYPE ).value(N'.[1]', N'NVARCHAR(MAX)'), 1, 1, N'')
) AS x(date_val);
同じ行で異なる列の日付値が必要な場合は、nodes()
を使用してExpressionSet
ノードごとに1行を取得し、属性displayName
およびsearchOption
in value()
を使用して、開始日と終了日を取得します。
declare @x xml = '
<SearchJobConfig>
<QueryID>1072</QueryID>
<QueryString>
<SearchCriteria name="Search query" >
<ExpressionSet logicalOperator="AND">
<SimpleAttributeExpression displayName="Date" npmPropertyId="4" searchOperation="GREATER_EQUAL" dataType="string" caseSensitive="false">2019-06-01T04:00:00</SimpleAttributeExpression>
<SimpleAttributeExpression displayName="Date" npmPropertyId="4" searchOperation="LESS_EQUAL" dataType="string" caseSensitive="false">2019-06-13T03:59:59</SimpleAttributeExpression>
<SimpleAttributeExpression displayName="Class" npmPropertyId="1056" searchOperation="EQUALS" dataType="int32" caseSensitive="false">65</SimpleAttributeExpression>
</ExpressionSet>
</SearchCriteria>
</QueryString>
</SearchJobConfig>
';
declare @Job table(xConfig xml);
insert @Job (xConfig) values (@x);
select T.X.value('(SimpleAttributeExpression
[
@displayName = "Date" and
@searchOperation = "GREATER_EQUAL"
]/text())[1]', 'datetime') as date_val_start,
T.X.value('(SimpleAttributeExpression
[
@displayName = "Date" and
@searchOperation = "LESS_EQUAL"
]/text())[1]', 'datetime') as date_val_end
from @Job as j
cross apply j.xConfig.nodes('/SearchJobConfig/QueryString/
SearchCriteria/ExpressionSet') as T(X);
結果:
date_val_start date_val_end
2019-06-01 04:00:00.000 2019-06-13 03:59:59.000
XMLから複数の値を取得したいが、XPathにそれらのfirst(#1)のみを返すように指示するとします。
/ SearchjobConfig / QueryString / SearchCriteria / ExpressionSet / SimpleAttributeExpression [ 1 ]
\___/
Returns indexed item #1 _/
このインデックス句を失うと、bothの値が、入力XML内に出現する順序で返されます。
さらに読む: https://www.w3schools.com/xml/xpath_syntax.asp
それらを単一の行に入れる限り...それは[ほぼ確実に]おそらく可能ですが、それらのうち2つだけのために努力する価値がありますか? YMMV。