Sql 需要将order by放入使用xml节点的游标声明中
因此,我试图使用游标将一些xml插入到SQL数据库中,我想在游标声明中加入一个“orderby”语句,否则优化程序会决定将所有节点按字母顺序排列 我的游标声明是: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
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
)