So I am trying to insert some xml into my SQL database using a cursor and I would like to put an 'order by' statement into the cursor declaration, otherwise the optimiser decides to put all the nodes into alphabetical order.
My cursor declaration is:
declare cur1 cursor local for
select
P.DescriptionId, N.Description
from (
select
T.C.value('.', 'nvarchar(max)') as Description
from @TheRole.nodes('/descriptions/description') as T(C)
) as N
left outer join PositionsDescriptions as P on N.Description = P.Description
I tried to insert:
order BY P.$IDENTITY
As requested - here is the entire SP:
@Title nvarchar(50),
@Location nvarchar(50),
@ShortDescription nvarchar(max),
@MaximumSalary nvarchar(max) = null,
@StatusId int,
@DepartmentId int,
@SubDepartmentId int = null,
@TheRole xml = null,
@Essentials xml = null,
@Desirable xml = null
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @PositionId as int
--DESCRIPTION TABLES
DECLARE @TableRole TABLE(Description nvarchar(MAX), OrderNumber int)
--DECLARE @TableRole TABLE(RowID int not null primary key identity(1,1), Description nvarchar(MAX), OrderNumber int)
DECLARE @TableEssentials TABLE(RowID int not null primary key identity(1,1), Description nvarchar(MAX), OrderNumber int)
DECLARE @TableDesirable TABLE(RowID int not null primary key identity(1,1), Description nvarchar(MAX), OrderNumber int)
DECLARE @RowsToProcess int,
@CurrentRow int,
@Description nvarchar(MAX),
@OrderNumber int,
--DESCRIPTIONS
@DescriptionId int
set @OrderNumber = 1
-- POSITIONS
if @SubDepartmentId = 0
SET @SubDepartmentId = NULL
INSERT INTO Positions (Title, Location, Description, MaximumSalary, StatusId, SubDepartmentId, DepartmentId, Published, LastUpdatedDate)
VALUES (@Title, @Location, @ShortDescription, @MaximumSalary,@StatusId, @SubDepartmentId, @DepartmentId, GETDATE(), GETDATE())
SET @PositionId = scope_identity()
-- POSITIONSDESCRIPTIONS AND POSITIONS_DESCRIPTIONS
-- TheRole
declare cur1 cursor local for
select
P.DescriptionId, N.Description
from (
select
T.C.value('.', 'nvarchar(max)') as Description
from @TheRole.nodes('/descriptions/description') as T(C)
) as N
left outer join PositionsDescriptions as P on N.Description = P.Description
open cur1
while 1 = 1
begin
fetch cur1 into @DescriptionId, @Description
if @@fetch_status <> 0 break
if @DescriptionId is null
begin
insert into PositionsDescriptions (Description)
select @Description
select @DescriptionId = scope_identity()
end
insert INTO Positions_Descriptions(PositionId, SectionId, DescriptionId, OrderNumber)
VALUES (@PositionId, 1, @DescriptionId, @OrderNumber)
set @OrderNumber = @OrderNumber + 1
end
close cur1
deallocate cur1
-- Essentials
declare cur1 cursor local fast_forward for
select
P.DescriptionId, N.Description
from (
select
T.C.value('.', 'nvarchar(max)') as Description
from @Essentials.nodes('/descriptions/description') as T(C)
) as N
left outer join PositionsDescriptions as P on P.Description = N.Description
open cur1
while 1 = 1
begin
fetch cur1 into @DescriptionId, @Description
if @@fetch_status <> 0 break
if @DescriptionId is null
begin
insert into PositionsDescriptions (Description)
select @Description
select @DescriptionId = scope_identity()
end
insert INTO Positions_Descriptions(PositionId, SectionId, DescriptionId, OrderNumber)
VALUES (@PositionId, 2, @DescriptionId, @OrderNumber)
set @OrderNumber = @OrderNumber + 1
end
close cur1
deallocate cur1
-- Desirable
declare cur1 cursor local fast_forward for
select
P.DescriptionId, N.Description
from (
select
T.C.value('.', 'nvarchar(max)') as Description
from @Desirable.nodes('/descriptions/description') as T(C)
) as N
left outer join PositionsDescriptions as P on P.Description = N.Description
Declare @DesirablesOrderNumber int = 1
open cur1
while 1 = 1
begin
fetch cur1 into @DescriptionId, @Description
if @@fetch_status <> 0 break
if @DescriptionId is null
begin
insert into PositionsDescriptions (Description)
select @Description
select @DescriptionId = scope_identity()
end
insert INTO Positions_Descriptions(PositionId, SectionId, DescriptionId, OrderNumber)
VALUES (@PositionId, 3, @DescriptionId, @OrderNumber)
set @OrderNumber = @OrderNumber + 1
end
close cur1
deallocate cur1
END
If there is a better way than a cursor, I'd love to know! This is someone else's code I'm trying to fix and I'm new to SQL so apologies if I'm a little slow.
For more information, the tables mentioned above are PositionsDescriptions and Positions_Descriptions.
PositionsDescriptions that would look something like this:
DescriptionId Description
1 test
2 abc
And this data is related to a job (or position) in a table called Positions_Descriptions, that would look something like this:
PositionId SectionId DescriptionId OrderNumber
1 1 1 1
1 1 2 2
The problem is that if you have (for example) something like this:
@TheRole = "<descriptions><description>test</description><description>abc</description></descriptions>"
then the information is not stored in that order. But stored so that the descriptions come back in alphabetical order.
In other words you get this
PositionId SectionId DescriptionId OrderNumber
1 1 2 1
1 1 1 2
And not this:
PositionId SectionId DescriptionId OrderNumber
1 1 1 1
1 1 2 2