我已经使用T-SQL完成了一些基本的XML查询,但我不确定如何解决这个问题。
我想查询表中特定XML属性具有请求值的所有行。
这是我的表架构:
CREATE TABLE [dbo].[Applications_Submissions]
(
[Id] [int] IDENTITY(1,1) NOT NULL,
[SubmissionGuid] [uniqueidentifier] NOT NULL,
[TestMode] [bit] NOT NULL,
[SubmissionID] [int] NOT NULL,
[Status] [int] NOT NULL,
[ProcessId] [int] NOT NULL,
[Version] [int] NOT NULL,
[ReturnUrl] [nvarchar](1000) NULL,
[Applications] [xml] NOT NULL,
[CreatedByUser] [int] NOT NULL,
[DateCreated] [datetime] NOT NULL,
[DateDeleted] [datetime] NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [FG_Applications]
) ON [FG_Applications] TEXTIMAGE_ON [FG_Applications]
[Application]
列中存储的XML数据结构如下:
<Submission xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Id="15" TestMode="false" SubmissionId="15" Status="0" ProcessId="0" Version="1" CreatedByUser="2" DateCreated="2016-09-28T15:08:25.667" DateDeleted="0001-01-01T00:00:00">
<ReturnUrl>/Register/RegistrationData/Register/1094/1/[SGUID]</ReturnUrl>
<SubmissionGuid>f1891c84-1fda-41b4-a78b-605bfdcaf45a</SubmissionGuid>
<Applications>
<Application ApplicationID="15" ApplicationName="Test Form">
<FriendlyUrl>test-form-1234</FriendlyUrl>
<Pages>
<Page PageId="16" ApplicationId="15" ViewOrder="0">
<PageTitle>Page 1</PageTitle>
<Fields>
<Field FieldId="26" FieldType="10" ViewOrder="0">
<FieldTitle>Who are you</FieldTitle>
<FieldValues>Jeffrey</FieldValues>
<FieldsResponses />
<PossibleFieldValues />
</Field>
<Field FieldId="27" FieldType="0" ViewOrder="0">
<FieldTitle>Why are you here?</FieldTitle>
<FieldValues />
<FieldsResponses />
<PossibleFieldValues />
</Field>
<Field FieldId="28" FieldType="5" ViewOrder="0">
<FieldTitle>Pick any</FieldTitle>
<FieldsResponses>
<FieldsResponse FieldResponseId="19" LinkToApplication="0" ViewOrder="0" Selected="false">
<Response>One</Response>
</FieldsResponse>
<FieldsResponse FieldResponseId="20" LinkToApplication="12" ViewOrder="0" Selected="false">
<Response>Two</Response>
</FieldsResponse>
<FieldsResponse FieldResponseId="21" LinkToApplication="0" ViewOrder="0" Selected="false">
<Response>Three</Response>
</FieldsResponse>
</FieldsResponses>
<PossibleFieldValues />
</Field>
</Fields>
</Page>
<Page PageId="17" ApplicationId="15" ViewOrder="0">
<PageTitle>Page 2</PageTitle>
<Fields>
<Field FieldId="29" FieldType="6" ViewOrder="0">
<FieldTitle>Agreement</FieldTitle>
<FieldsResponses>
<FieldsResponse FieldResponseId="22" LinkToApplication="16" ViewOrder="0" Selected="false">
<Response>I agree</Response>
</FieldsResponse>
<FieldsResponse FieldResponseId="23" LinkToApplication="16" ViewOrder="0" Selected="false">
<Response>I disagree</Response>
</FieldsResponse>
</FieldsResponses>
<PossibleFieldValues />
</Field>
</Fields>
</Page>
</Pages>
</Application>
</Applications>
</Submission>
我想根据存储在ApplicationID
节点中的<Application>
属性获取表行。每个<Submission>
可以有多个<Application>
个节点。
这样做的最佳方式是什么?
非常感谢你!
答案 0 :(得分:1)
最好的是xml.exist()
。但是这将从不快速...如果你需要更频繁或更多的行数,你应该将ApplicationID与实际的rowID一起提取到一个辅助表中。这可以在触发器中完成。
但你可以试试这个:
- 模拟表
DECLARE @Applications_Submissions TABLE(Id INT IDENTITY NOT NULL,TestText VARCHAR(MAX),Applications XML);
- 插入两个模拟行
INSERT INTO @Applications_Submissions VALUES
('Contains ApplicationID 15, 16 and 100'
,N'<Submission xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Id="15" TestMode="false" SubmissionId="15" Status="0" ProcessId="0" Version="1" CreatedByUser="2" DateCreated="2016-09-28T15:08:25.667" DateDeleted="0001-01-01T00:00:00">
<Applications>
<Application ApplicationID="15" ApplicationName="Test Form">
<FriendlyUrl>blah 15</FriendlyUrl>
</Application>
<Application ApplicationID="16" ApplicationName="Test Form">
<FriendlyUrl>blah 16</FriendlyUrl>
</Application>
<Application ApplicationID="100" ApplicationName="Test Form">
<FriendlyUrl>blah 100</FriendlyUrl>
</Application>
</Applications>
</Submission>')
,('Contains ApplicationID 15, 17 and 200'
,N'<Submission xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Id="15" TestMode="false" SubmissionId="15" Status="0" ProcessId="0" Version="1" CreatedByUser="2" DateCreated="2016-09-28T15:08:25.667" DateDeleted="0001-01-01T00:00:00">
<Applications>
<Application ApplicationID="15" ApplicationName="Test Form">
<FriendlyUrl>blah 15</FriendlyUrl>
</Application>
<Application ApplicationID="17" ApplicationName="Test Form">
<FriendlyUrl>blah 17</FriendlyUrl>
</Application>
<Application ApplicationID="200" ApplicationName="Test Form">
<FriendlyUrl>blah 200</FriendlyUrl>
</Application>
</Applications>
</Submission>');
- 这就是你要搜索的内容
--Try different values (15 returns both rows, 16, 100 or 200 just one row and any other value none
DECLARE @ApplicationID INT=15;
- 这是查询
- Btw:我使用wildcard-namespace来避免与你的实际命名空间混淆......
SELECT Id
,TestText
--This is just to show, how you would fetch a value from the given ApplicationID
,Applications.value('(/*:Submission/*:Applications/*:Application[(@*:ApplicationID)[1] eq sql:variable("@ApplicationID")]/*:FriendlyUrl)[1]','nvarchar(max)')
FROM @Applications_Submissions
WHERE Applications.exist('/*:Submission/*:Applications/*:Application[(@*:ApplicationID)[1] eq sql:variable("@ApplicationID")]')=1