Sql 需要将order by放入使用xml节点的游标声明中

Sql 需要将order by放入使用xml节点的游标声明中,sql,sql-server,xml,Sql,Sql Server,Xml,因此,我试图使用游标将一些xml插入到SQL数据库中,我想在游标声明中加入一个“orderby”语句,否则优化程序会决定将所有节点按字母顺序排列 我的游标声明是: declare cur1 cursor local for select P.DescriptionId, N.Description from ( select T.C.value('.', 'nvarchar(max)') as Description

因此,我试图使用游标将一些xml插入到SQL数据库中,我想在游标声明中加入一个“orderby”语句,否则优化程序会决定将所有节点按字母顺序排列

我的游标声明是:

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
我试图插入:

order BY P.$IDENTITY
根据要求-以下是整个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
这些数据与一个名为Positions_Descriptions的表中的一个职务(或职位)相关,该表如下所示:

DescriptionId Description

1                    test

2                    abc
PositionId  SectionId  DescriptionId OrderNumber

1               1               1              1

1               1               2              2
问题是,如果您有(例如)类似的东西:

@TheRole = "<descriptions><description>test</description><description>abc</description></descriptions>"
而不是这个:

PositionId  SectionId  DescriptionId OrderNumber

1               1               1              1

1               1               2              2

如果没有ORDERBY子句,您的行可以以优化器认为合适的任何方式返回

在您的例子中,这意味着列
OrderNumber
可能与XML中元素的顺序不匹配

使用
行号()
节点()提取的XML元素排序有一个技巧。有关更多信息,请参阅

使用此游标定义,您的行将按照存储在XML中的顺序进行处理

将cur1游标声明为本地
选择
描述,描述
从(
选择
T.C.值(‘’,‘nvarchar(最大)’)作为说明,
(按T.C.顺序)上方的行号()为rn
从@TheRole.nodes('/descriptions/description')作为T(C)
)as N
左侧外部连接位置描述为P on N.Description=P.Description
N.rn订购

米凯尔·埃里克森已经谈到了订购问题。无需使用Cusror即可将INSERT插入到表中(不包括任何重复项),方法是在INSERT中添加WHERE EXISTS子句。选择可过滤掉已存在的内容

像这样:

INSERT INTO PositionsDescriptions( Description )
SELECT  T.C.value('.', 'nvarchar(max)')
FROM    @TheRole.nodes('/descriptions/description') as T(C)
WHERE   NOT EXISTS 
        (
            SELECT * From PositionsDescriptions N
            WHERE T.C.value('.', 'nvarchar(max)') = N.Description
        )

如果需要防止同一源中的重复,可以在外部选择中添加一个DISTINCT。

为什么插入顺序很重要?还有,为什么你认为你需要一个光标?这很重要,因为现在节点是按字母顺序保存的-我不想要这个。我只想让它们按照给定的顺序保存。我需要一个游标,因为我必须检查每个描述,以确保它不在数据库的表中。这两个都没有意义。再说一遍,你为什么需要按顺序排列?您是否知道SQL server本身不会以任何顺序保留或返回行?此外,无需使用游标即可防止重复插入。向我们展示过程的其余部分,我们将向您展示如何进行。好的-我已经用整个SP和一些更多信息编辑了这个问题。希望这更有意义?我已经编辑了你的标题。请参阅“”,其中的共识是“不,他们不应该”。
INSERT INTO PositionsDescriptions( Description )
SELECT  T.C.value('.', 'nvarchar(max)')
FROM    @TheRole.nodes('/descriptions/description') as T(C)
WHERE   NOT EXISTS 
        (
            SELECT * From PositionsDescriptions N
            WHERE T.C.value('.', 'nvarchar(max)') = N.Description
        )