Reputation: 227
Here is my description of my system and constraints. I have a MSSQL database that store xml files. These files are for use for my end users in my Windows Store App. Basically, a user creates a device configuration using this GUI's application, its converted to xml, and uploaded to the database. Each one of these xml configs represents a representation of a device configuration. I want to be able to assign a unique id for each unique configuration that will be consistent among all my users. This means if someone creates an identical device configuration using the app as someone else that uses the app that the XML unique ID for the device configuration will be the same. This is to say that the constituent parts that ultimately make the device configuration is what can be identified through one single value that I can store.
How do I go about creating this unique ID? What function can be run when creating my XML file to make is unique ID? Please describe the process for doing this.
Upvotes: 2
Views: 721
Reputation: 9292
Calculate a checksum over the xml document and index that so your future existence checks are fast.
Note, xml can be "equivalent" but not be equal as a string. If you only have one producer of the xml this might be a non-issue for you.
Heres a simple example:
create table dbo.Devices
(
DeviceId int identity(1,1) primary key,
Configuration xml,
ConfigurationChecksum as binary_checksum(cast(Configuration as varchar(max))),
constraint ck_Configuration unique(ConfigurationChecksum)
);
go
--insert new (OK)
insert into dbo.Devices(Configuration)
values('<root><Config>123</Config></root>');
--insert new (OK)
insert into dbo.Devices(Configuration)
values('<root><Config>456</Config></root>');
-- insert existing (Violation of UNIQUE KEY constraint 'ck_Configuration')
insert into dbo.Devices(Configuration)
values('<root><Config>456</Config></root>');
--check if exists (lookup will seek on our ck_Configuration index)
declare @x xml = '<root><Config>789</Config></root>'
declare @i int;
if exists(select 1 from dbo.Devices where ConfigurationChecksum = binary_checksum(cast(@x as varchar(max))))
begin
raiserror('Already exists!', 10, 1) with nowait;
end else
begin
insert into dbo.Devices(Configuration)
values(@x);
set @i = scope_identity();
raiserror('Created new config %d', 10, 1, @i) with nowait;
end
As mentioned by Shnugo, this will only work if the XML documents are exactly the same. If you need to constrain a subset of the XML document then you can still use the same strategy, but the checksum needs to be calculated over a subset of elements:
declare @x xml = '<root><Name>ABC</Name><Port>80</Port><Created>2001-01-01</Created></root>'
select @x.query('/*/*[local-name()=("Name","Port")]'), binary_checksum(cast(@x.query('/*/*[local-name()=("Name","Port")]') as varchar(max)))
To do that you need to wrap in a function and reference that from your constraint.
Upvotes: 2
Reputation: 67311
Easiest would be to do a simple concatenation of all relevant values,such as value1|value2|value3|value4
All these values in the given order must be unique.
If you want, you could either
NEWID()
) or an IDENTITY value to have an easy key to handle...Upvotes: 1