The original question was - how to attach a sequence number to a set of rows which are extracted from an xml string.
Updated script below. Adopted from the solution provided by user @T N .
I just need to know whether this script is correct or am i doing anything wrong.
Note:- this seems to produce the correct result though!
Update:06/25/24 - I am still looking for an answer.
CREATE TABLE [dbo].[UseSequence](
[UId] [bigint] NOT NULL,
[Version] [int] NOT NULL,
[Speed] [int] NOT NULL,
[TrainType] [int] NOT NULL,
[HeadEnd] [int] NOT NULL,
[Restricted] [int] NOT NULL,
[Sequence] [int] NOT NULL
);
DECLARE
@BulletindataText nvarchar(max)
,@BulletinDataXml XML
,@BulletinSpeedsXml xml
,@DigitalUID bigint
,@Version int;
;
Set @BulletindataText = '<BulletinData>
<Bul>
<BulletinSpeeds>
<BulletinSpeedRestriction>
<Speed >30</Speed>
<TrainType Numeric="2">Passenger</TrainType>
<HeadEndOnlySpeedRestriction Numeric="2">No</HeadEndOnlySpeedRestriction>
<RestrictedSpeed Numeric="2">No</RestrictedSpeed>
</BulletinSpeedRestriction>
<BulletinSpeedRestriction>
<Speed >30</Speed>
<TrainType Numeric="1">Freight</TrainType>
<HeadEndOnlySpeedRestriction Numeric="2">No</HeadEndOnlySpeedRestriction>
<RestrictedSpeed Numeric="2">No</RestrictedSpeed>
</BulletinSpeedRestriction>
<BulletinSpeedRestriction>
<Speed >30</Speed>
<TrainType Numeric="3">Intermodal</TrainType>
<HeadEndOnlySpeedRestriction Numeric="2">No</HeadEndOnlySpeedRestriction>
<RestrictedSpeed Numeric="2">No</RestrictedSpeed>
</BulletinSpeedRestriction>
<BulletinSpeedRestriction>
<Speed >30</Speed>
<TrainType Numeric="6">Commuter</TrainType>
<HeadEndOnlySpeedRestriction Numeric="2">No</HeadEndOnlySpeedRestriction>
<RestrictedSpeed Numeric="2">No</RestrictedSpeed>
</BulletinSpeedRestriction>
<BulletinSpeedRestriction>
<Speed >30</Speed>
<TrainType Numeric="5">TiltTrain</TrainType>
<HeadEndOnlySpeedRestriction Numeric="2">No</HeadEndOnlySpeedRestriction>
<RestrictedSpeed Numeric="2">No</RestrictedSpeed>
</BulletinSpeedRestriction>
<BulletinSpeedRestriction>
<Speed >30</Speed>
<TrainType Numeric="4">HighSpeedPassenger</TrainType>
<HeadEndOnlySpeedRestriction Numeric="2">No</HeadEndOnlySpeedRestriction>
<RestrictedSpeed Numeric="2">No</RestrictedSpeed>
</BulletinSpeedRestriction>
</BulletinSpeeds>
</Bul>
</BulletinData>'
;
SET @BulletinDataXml = cast(@BulletinDataText as xml)
SET @BulletinSpeedsXml = @BulletinDataXml.query('<BulletinSpeeds> {for $x in /BulletinData/Bul/BulletinSpeeds/child::* return $x} </BulletinSpeeds>');
-- Insert 1
Set @DigitalUID = 104;
Set @Version = 1;
-- Insert 2
--Set @DigitalUID = 104;
--Set @Version = 2;
INSERT INTO [dbo].[BulletinSpeedRestrictionUseSequence]
(DigitalUID
,[Version]
,Speed
,TrainType
,HeadEndOnlySpeedRestriction
,RestrictedSpeed,
[Sequence]
)
SELECT @DigitalUID,
@Version,
a.c.value('Speed[1]','int') as 'Speed',
a.c.value('TrainType[1]/@Numeric','int') as 'TrainType',
a.c.value('HeadEndOnlySpeedRestriction[1]/@Numeric','int') as 'HeadEndOnlySpeedRestriction',
a.c.value('RestrictedSpeed[1]/@Numeric','int') as 'RestrictedSpeed',
row_number() over (partition by @DigitalUID, @Version order by a.c) AS SequenceNum
FROM @BulletinSpeedsXml.nodes('/BulletinSpeeds/BulletinSpeedRestriction') a(c)
;
Result
| DigitalUID | Version | Speed | TrainType | HeadEndOnlySpeedRestriction | RestrictedSpeed | Sequence |
|---|---|---|---|---|---|---|
| 104 | 1 | 30 | 2 | 2 | 2 | 1 |
| 104 | 1 | 30 | 1 | 2 | 2 | 2 |
| 104 | 1 | 30 | 3 | 2 | 2 | 3 |
| 104 | 1 | 30 | 6 | 2 | 2 | 4 |
| 104 | 1 | 30 | 5 | 2 | 2 | 5 |
| 104 | 1 | 30 | 4 | 2 | 2 | 6 |
| 104 | 2 | 30 | 2 | 2 | 2 | 1 |
| 104 | 2 | 30 | 1 | 2 | 2 | 2 |
| 104 | 2 | 30 | 3 | 2 | 2 | 3 |
| 104 | 2 | 30 | 6 | 2 | 2 | 4 |
| 104 | 2 | 30 | 5 | 2 | 2 | 5 |
| 104 | 2 | 30 | 4 | 2 | 2 | 6 |
row_number() over (order by (select 1))? Apparently you have to trick Sql Server into sorting by a constant here. Usually this errors for good reason, but in this case I would assume the order to remain the same as in the file?ROW_NUMBER()function along with an underspecifiedORDER BYconstraint. These assume that the generated numbers will reflect the original data order, but this is not guaranteed. It may seem true most or all of the time with small data sets, but as data scales up, the optimizer is free to use parallel operations, hash tables, and possibly other processing techniques that no longer preserve this assumed order.