I have studied tons of documents on msdn including 'XML best practices ...' and found them very helpful. Stumbling along I have come to a complete stop ion the following 2 issues:
--------------------------
Issue 1.
I the mockup I am doing now, I have cloned the scenario for promoting an xml property to a computed column - it works fine. But when I try to create a primary index i get an error informing me that the index cannot be created because my user defined function computing the column is not deterministic.
Here my sql:
/* These ones are apparently not deterministic - how do I make them so */
create function dbo.getObjectType (@xData xml)
returns char(30)
as
begin
declare @Ret char(30)
select @Ret = @xData.value('/object[1]/@type', 'char(30)')
return @Ret
end
create function dbo.getObjectId (@xData xml)
returns char(30)
as
begin
declare @Ret char(30)
select @Ret = @xData.value('/object[1]/@id', 'char(30)')
return @Ret
end
[Type] AS ([dbo].[getObjectType]([externalXml]))
,[Id] AS ([dbo].[getObjectId]([externalXml]))
,[externalXml] [xml] NOT NULL
) ON [PRIMARY]
CREATE UNIQUE NONCLUSTERED INDEX [idx_tbBusinessObject_Primary] ON [dbo].[tbBusinessObject]
(
[Type] ASC,
[Id] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = OFF) ON [PRIMARY]
Msg 2729, Level 16, State 1, Line 1
Column 'Type' in table 'dbo.tbBusinessObject' cannot be used in an index or statistics or as a partition key because it is non-deterministic.
I am unable to create a unque index on the columns Type and Id - can anybody help
------------------------
Issue 2:
Following the examples in XML best practise I have succeeded in creating a trigger to insert reference rows in another table when a new row is inserted in the tbBusinessObject table above - works fine. However, I can't get the delete trigger to compile. The xml column (externalXml) is not accessible.
Here is my sql:
/* Insert trigger works as a dream */
create trigger trg_tbBusinessObject_Ins_Reference
on dbo.tbBusinessObject
for insert
as
begin
insert into dbo.tbBusinessObjectReference
select
r.parentType
,r.parentId
,r.childType
,r.childId
,r.referenceType
from
inserted as i cross apply dbo.getReferences(i.Type, i.Id, i.externalXml) as r
end
/* Delete trigger, doesn't compile */
create trigger trg_tbBusinessObject_Del_Reference
on dbo.tbBusinessObject
for delete
as
begin
delete dbo.tbBusinessObjectReference
where
childType = dbo.getObjectType(deleted.externalXml)
and childId = dbo.getObjectId(deleted.externalXml)
end
The errors are:
Msg 4104, Level 16, State 1, Procedure trg_tbBusinessObject_Del_Reference, Line 7
The multi-part identifier "deleted.externalXml" could not be bound.
Msg 4104, Level 16, State 1, Procedure trg_tbBusinessObject_Del_Reference, Line 7
The multi-part identifier "deleted.externalXml" could not be bound.
What do I do wrong
-----------------------------
The xml involved in both issues:
insert into dbo.tbBusinessObject (externalXml) values (
'<object type="KONTO" id="0000000001">
<system>
<references>
<object type="KUNDE" id="0987654321">OWNER</object>
<object type="KUNDE" id="0987654322">EMPOWERED</object>
</references>
</system>
<data>
<kokode>010101</kokode>
<balance>100000</balance>
<periods>
<balance type="STMT">100000</balance>
<balance type="INTEREST">999900</balance>
</periods>
</data>
</object>'
)
Any help much appreciated. I am in a great hurry to get this working.
Thx in advance
Lars Kjarsgaard

Value method of xml data type not deterministic, xml column not accessible in 'deleted' table
jtiede
Hi Lars
This is strange. What version of SQL Server 2005 are you running this under
I am running the following T-SQL in my current CTP16 build (yeah, I know, I need to upgrade to RTM on my laptop) and it works without giving an error:
create
function dbo.getObjectType (@xData xml)returns char(30)
with schemabinding
as
begin
declare @Ret char(30)
select @Ret = @xData.value('/object[1]/@type', 'char(30)')
return @Ret
end
go
create
function dbo.getObjectId (@xData xml)returns char(30)
with schemabinding
as
begin
declare @Ret char(30)
select @Ret = @xData.value('/object[1]/@id', 'char(30)')
return @Ret
end
go
CREATE
TABLE [dbo].[tbBusinessObject]([Type] AS ([dbo].[getObjectType]([externalXml]))
,[Id] AS ([dbo].[getObjectId]([externalXml]))
,[externalXml] [xml] NOT NULL
) ON [PRIMARY]
go
create
trigger trg_tbBusinessObject_Del_Referenceon dbo.tbBusinessObject
for delete
as
begin
delete dbo.tbBusinessObjectReference
where childType = deleted.Type
and childId = deleted.Id
end
Can you run the above against an empty database and let me know whether it works
Thanks
Michael
Fata1Attack
I downloaded the msi but it complains that I don't have the .NET framework version 2.0 and refuses to install. I do have the version 2.0 beta installed. What's wrong
thx
Lats
Nagendra123
Hi Michael
For issue 1: That set me right on the track.
For issue 2:
I have created the 2 functions with schema-binding, but still cannot get the trigger to compile:
create function dbo.getObjectId (@xData xml)
returns char(30)
with schemabinding
as
begin
declare @Ret char(30)
select @Ret = @xData.value('/object[1]/@id', 'char(30)')
return @Ret
end
GO
create function dbo.getObjectType (@xData xml)
returns char(30)
with schemabinding
as
begin
declare @Ret char(30)
select @Ret = @xData.value('/object[1]/@type', 'char(30)')
return @Ret
end
GO
What puzzles me is the fact that I cannot - in the trigger - reference the column externalXml in the deleted table. In fact I cannot refer any columns in the deleted table. This fails as well:
create trigger trg_tbBusinessObject_Del_Reference
on dbo.tbBusinessObject
for delete
as
begin
delete dbo.tbBusinessObjectReference
where
childType = deleted.Type
and childId = deleted.Id
end
go
Msg 4104, Level 16, State 1, Procedure trg_tbBusinessObject_Del_Reference, Line 7
The multi-part identifier "deleted.Type" could not be bound.
Msg 4104, Level 16, State 1, Procedure trg_tbBusinessObject_Del_Reference, Line 7
The multi-part identifier "deleted.Id" could not be bound.
It is surely a gigantic new world for an old MVS host dinosaur like me - I am greatly impressed and assured be the speed of your response. I will get there in the end!
Thx a million
Lars
ThewEEsCOT
I ran your code on an empty database - it worked fine. Why is doesn't work onmy own (mockup) database is a mystery. Anyway, I am not too concerned, it is after all a mockup and I have decided to rely on stored procedures for tasks like this rather than triggers.
Speaking of which: Can you direct me towards an online reference for stored procedures
I am still on the Sql Server 2005 CTP (me too, I need to upgrade). This the contents of my about dialog:
Microsoft SQL Server Management Studio (expires in 348 days) 9.00.1116.00
Microsoft Analysis Services Client Tools 2000.090.1116.00
Microsoft Data Access Components (MDAC) 2000.085.1117.00 (xpsp_sp2_rtm.040803-2158)
Microsoft MSXML 2.6 3.0 4.0 5.0 6.0
Microsoft Internet Explorer 6.0.2900.2180
Microsoft .NET Framework 2.0.50215.44
Operating System 5.1.2600
Thank you
Lars
CrystalDeveloper
Re 1: In order to make your function deterministic, you need to provide schema-binding:
create
function dbo.getObjectType (@xData xml)returns char(30)
with schemabinding
as
begin
declare @Ret char(30)
select @Ret = @xData.value('/object[1]/@type', 'char(30)')
return @Ret
end
go
create function dbo.getObjectId (@xData xml)
returns char(30)
with schemabinding
as
begin
declare @Ret char(30)
select @Ret = @xData.value('/object[1]/@id', 'char(30)')
return @Ret
endRe 2: Making the two functions schema-bound seems to take care of your trigger definition issue.
Good luck with your project!
Best regards
Michael
ARMS
You can download Books Online at http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx
Best regards
Michael
Greg P
Best regards
Michael