使用 CROSS APPLY 查询,尝试根据属性值获取字段
Query with CROSS APPLY, trying to get a field based on an attribute value
我尝试根据属性(文化)的值从 XML 服务器中存储为 XML 的表单中获取所有字段名称。实际上,我可以获得文本值,但它们被连接到 FieldName 列中。
XML 结构如下所示:
<Form>
<Field>
<Field Name="email" Type="text" ColumnSize="6">
<Localizations>
<Localization Culture="fr">
<Text>Adresse couriel</Text>
<Placeholder>Entrez votre adresse courriel</Placeholder>
</Localization>
<Localization Culture="fr">
<Text>Email</Text>
<Placeholder>Enter your email</Placeholder>
</Localization>
</Localizations>
</Field>
</Fields>
</Form>
SQL 查询:
DECLARE @language VARCHAR(2)
SET @language = 'en'
SELECT
c.query('data(@Name)') AS FieldUniqueName,
c.query('data(./Localizations/Localization/Text)') AS FieldName,
c.query('data(@Type)') AS FieldType
FROM dbo.Form Form CROSS APPLY FormContent.nodes('/Form/Fields/Field') x(c)
WHERE Id = @formId
AND FormContent.exist('/Form/Fields/Field/Localizations/Localization[@Culture=sql:variable("@language")]') = 1
结果如下:
FieldUniqueName | FieldName | FieldType
name | Nom Name | text
email | Adresse couriel Email | text
phone | Téléphone Phone Number| text
两种语言都在 FieldName 列中!
我也试过 :
...
c.value('data(./Localizations/Localization/Text)[1]', 'VARCHAR(100)') AS FieldName,
...
但我需要在 [1]
或 [2]
之间做出选择才能获得正确的语言...
好的,我找到了解决我的问题的答案!我没有使用 where 子句,而是更改了 FieldName 的 XPath。很有魅力:
DECLARE @language VARCHAR(2)
SET @language = 'en'
SELECT
c.query('data(@Name)') AS FieldUniqueName,
c.query('data(./Localizations/Localization[@Culture=sql:variable("@language")]/Text)') AS FieldName,
c.query('data(@Type)') AS FieldType
FROM dbo.Form Form CROSS APPLY FormContent.nodes('/Form/Fields/Field') x(c)
WHERE Id = @formId
除此之外,您提供的 XML(结构和 "fr" 都存在一些错误),您可以试试这个:
DECLARE @tbl TABLE(ID INT IDENTITY, FormContent XML);
INSERT INTO @tbl VALUES
(N'<Form>
<Fields>
<Field Name="email" Type="text" ColumnSize="6">
<Localizations>
<Localization Culture="fr">
<Text>Adresse couriel</Text>
<Placeholder>Entrez votre adresse courriel</Placeholder>
</Localization>
<Localization Culture="en">
<Text>Email</Text>
<Placeholder>Enter your email</Placeholder>
</Localization>
</Localizations>
</Field>
</Fields>
</Form>');
查询将 return loc 值取决于您的变量。
DECLARE @language VARCHAR(2)
SET @language = 'en'
SELECT
fld.value(N'@Name',N'nvarchar(max)') AS FieldUniqueName,
fld.value(N'@Type',N'nvarchar(max)') AS FieldType,
loc.value(N'(Text/text())[1]','nvarchar(max)') AS LocalText,
loc.value(N'(Placeholder/text())[1]','nvarchar(max)') AS LocalPlaceholder
FROM @tbl Form
CROSS APPLY FormContent.nodes(N'/Form/Fields/Field') AS A(fld)
CROSS APPLY A.fld.nodes(N'Localizations/Localization[@Culture=sql:variable("@language")]') B(loc)
WHERE Id = 1
我尝试根据属性(文化)的值从 XML 服务器中存储为 XML 的表单中获取所有字段名称。实际上,我可以获得文本值,但它们被连接到 FieldName 列中。
XML 结构如下所示:
<Form>
<Field>
<Field Name="email" Type="text" ColumnSize="6">
<Localizations>
<Localization Culture="fr">
<Text>Adresse couriel</Text>
<Placeholder>Entrez votre adresse courriel</Placeholder>
</Localization>
<Localization Culture="fr">
<Text>Email</Text>
<Placeholder>Enter your email</Placeholder>
</Localization>
</Localizations>
</Field>
</Fields>
</Form>
SQL 查询:
DECLARE @language VARCHAR(2)
SET @language = 'en'
SELECT
c.query('data(@Name)') AS FieldUniqueName,
c.query('data(./Localizations/Localization/Text)') AS FieldName,
c.query('data(@Type)') AS FieldType
FROM dbo.Form Form CROSS APPLY FormContent.nodes('/Form/Fields/Field') x(c)
WHERE Id = @formId
AND FormContent.exist('/Form/Fields/Field/Localizations/Localization[@Culture=sql:variable("@language")]') = 1
结果如下:
FieldUniqueName | FieldName | FieldType
name | Nom Name | text
email | Adresse couriel Email | text
phone | Téléphone Phone Number| text
两种语言都在 FieldName 列中!
我也试过 :
...
c.value('data(./Localizations/Localization/Text)[1]', 'VARCHAR(100)') AS FieldName,
...
但我需要在 [1]
或 [2]
之间做出选择才能获得正确的语言...
好的,我找到了解决我的问题的答案!我没有使用 where 子句,而是更改了 FieldName 的 XPath。很有魅力:
DECLARE @language VARCHAR(2)
SET @language = 'en'
SELECT
c.query('data(@Name)') AS FieldUniqueName,
c.query('data(./Localizations/Localization[@Culture=sql:variable("@language")]/Text)') AS FieldName,
c.query('data(@Type)') AS FieldType
FROM dbo.Form Form CROSS APPLY FormContent.nodes('/Form/Fields/Field') x(c)
WHERE Id = @formId
除此之外,您提供的 XML(结构和 "fr" 都存在一些错误),您可以试试这个:
DECLARE @tbl TABLE(ID INT IDENTITY, FormContent XML);
INSERT INTO @tbl VALUES
(N'<Form>
<Fields>
<Field Name="email" Type="text" ColumnSize="6">
<Localizations>
<Localization Culture="fr">
<Text>Adresse couriel</Text>
<Placeholder>Entrez votre adresse courriel</Placeholder>
</Localization>
<Localization Culture="en">
<Text>Email</Text>
<Placeholder>Enter your email</Placeholder>
</Localization>
</Localizations>
</Field>
</Fields>
</Form>');
查询将 return loc 值取决于您的变量。
DECLARE @language VARCHAR(2)
SET @language = 'en'
SELECT
fld.value(N'@Name',N'nvarchar(max)') AS FieldUniqueName,
fld.value(N'@Type',N'nvarchar(max)') AS FieldType,
loc.value(N'(Text/text())[1]','nvarchar(max)') AS LocalText,
loc.value(N'(Placeholder/text())[1]','nvarchar(max)') AS LocalPlaceholder
FROM @tbl Form
CROSS APPLY FormContent.nodes(N'/Form/Fields/Field') AS A(fld)
CROSS APPLY A.fld.nodes(N'Localizations/Localization[@Culture=sql:variable("@language")]') B(loc)
WHERE Id = 1