chtml
的 ntext
列:
<root>
<Phys>
<name>Doctor1</name>
<gender>M</gender>
<langF1><a title="English" href="/default.aspx?id=23">English</a></langF1>
</Phys>
</root>
<root>
<Phys>
<name>Doctor2</name>
<gender>F</gender>
<langF1><a title="French" href="/default.aspx?id=56">French</a></langF1>
</Phys>
</root>
临时表(tableStage
):
Name Gender Language 1
Doctor1 F French
Doctor2 M Spanish
存储过程,用于从登台表中的值更新表中的chtml
列:
ALTER PROCEDURE [dbo].[Pro]
(
@ProviderName varchar(200), -- "Doctor1" for example
@genderVal varchar(10),
@langID varchar(10),
@langTitle varchar(60),
@langUrl varchar(255),
@anchorLang varchar(255),
@langLinkXML xml,
)
AS
BEGIN
DECLARE @xml xml
Select @xml = cast([chtml] as xml) --cast the chtml column which is of ntext type
From [myDb].[dbo].[myTable] --to xml so we can update the nodes
Where [content_title] = @ProviderName
--Update gender val (if exists, update, otherwise insert)
Select @genderVal = t1.[Gender] From [myDb].[dbo].[tableStage] t1 --replace Value2 and table to the table which is updated through SSIS
Where t1.Name = @ProviderName
PRINT @genderVal
If @xml IS NOT NULL
BEGIN
Set @xml.modify('replace value of (/root/Physicians/gender/text())[1] with sql:variable("@genderVal")');
END
Else
BEGIN
PRINT 'NOT WORK'
END
/* ERROR for above is: "XQuery: Replacing the value of a node with an empty sequence is allowed only if '()' is used as the new value expression. The new value expression evaluated to an empty sequence but it is not '()'." instead of changing the gender to "F" */
--Update language one field (if exist, delete and add, otherwise just delete)
--get the language id from the temp language table which matches the language for the provider
Select @langID = t1.content_id From [myDb].[dbo].[zTempLanguageTable] t1
INNER JOIN [myDb].[dbo].[tableStage] t2 On t2.[Language 1] = t1.content_title
Where t2.Name = @ProviderName
If @langID != ''
BEGIN
--get the language title from the language id
Select @langTitle = t1.content_title From [myDb].[dbo].[zTempLanguageTable] t1
Where @langID = t1.content_id
--set the Url (which will be part static and part dynamic with the id)
Set @langUrl = '/default.aspx?id=' + @langID + '';
--delete the anchor entry
Set @xml.modify('delete /root/Physicians/langF1/a');
--create the XML for the node
Set @langLinkXML = (
Select @langTitle as 'a/@title',
@langUrl as 'a/@href',
'_blank' as 'a/@target',
@langTitle as 'a'
for xml path(''), type
);
-- insert the new/updated anchor node
Set @xml.modify('insert sql:variable("@langLinkXML") into (/root/Physicians/langF1)[1]');
END
Else
BEGIN
--delete the anchor entry
Set @xml.modify('delete /root/Physicians/langF1/a');
END
/* THE ABOVE CHANGE `chtml` to: "<root><Physicians><name>Doctor1</name><gender>M</gender></langF1></Phys></root>" instead of <root><Physicians><name>Doctor1</name><gender>M</gender><langF1><a title="French" href="/default.aspx?id=67">French</a></langF1></Phys></root> */
/* once all the node has been "temporarily" changed, update the table columns for the provider */
Update [myDb].[dbo].[myTable]
Set [chtml] = cast(cast(@xml as nvarchar(max)) as ntext) //change the type to `ntext` data type for the table.
Where [content_title] = @ProviderName
END
如何解决我遇到的两个问题:
/ *上面的错误是:“XQuery:用。替换节点的值 仅当'()'用作新值时才允许空序列 表达。新值表达式计算为空序列 但它不是'()'。“而不是将性别改为”F“* /
/ *上述更改chtml
:
“Doctor1M”
代替
Doctor1MFrench * /
答案 0 :(得分:2)
您可以按如下方式解决错误:
只需将其粘贴到一个空的查询窗口中,然后将该想法转移到您的代码中即可。这一点是评论的第二个DECLARE @genderVal
。将注释更改为其他DECLARE,您可以重现它。如果这是NULL,您将收到您描述的错误。这意味着:检查变量的值。它似乎是NULL。
请注意,我更正了错误的结束标签“Phys”并删除了内部“root”-tags ...
declare @xml XML=
'<root>
<Physicians>
<name>Doctor1</name>
<gender>M</gender>
<langF1>
<a title="English" href="/default.aspx?id=23">English</a>
</langF1>
</Physicians>
<Physicians>
<name>Doctor2</name>
<gender>F</gender>
<langF1>
<a title="French" href="/default.aspx?id=56">French</a>
</langF1>
</Physicians>
</root>';
select @xml;
--This will search for the physician with the name "Doctor1"... Dont' know if you need this... Your example could be meant with one XML-for each physician...
DECLARE @ProviderName varchar(200)='Doctor1';
--DECLARE @genderVal varchar(10)=NULL;
DECLARE @genderVal varchar(10)='F';
--Update Doctor1 with new @genderVal=NULL --> The error you described
SET @xml.modify('replace value of (/root/Physicians[name=sql:variable("@ProviderName")]/gender/text())[1] with sql:variable("@genderVal")');
select @xml;
编辑:更改语言
如果我理解正确,你不必费心,是否存在语言。你无论如何都要删除它
SET @xml.modify('delete (/root/Physicians[name=sql:variable("@ProviderName")]/langF1/a)[1]');
select @xml;
现在为“a”构建内部xml:
DECLARE @langTitle varchar(100)='French';
DECLARE @langLink varchar(100)='/default.aspx?id=56';
DECLARE @newLang XML='<a title="' + @langTitle + '" href="' + @langLink + '">' + @langTitle + '</a>';
可以将此内部xml插入现有节点:
SET @xml.modify('insert sql:variable("@newLang") into (/root/Physicians[name=sql:variable("@ProviderName")]/langF1)[1]');
select @xml;