0

我迫切需要关于这个的线索。我正在用 C++ CLI 编写它并使用 ADO 进行存储。我可以将逻辑放在 C++ 端或我调用的 SQL Server 2012 存储过程中。我有一张表,表示产品的物理(有序)堆栈。不是一张大桌子,最多20个项目。我收到一个部分列表,一条消息中最多包含 10 个项目,显示前 10 个项目的重新排序。

首先,我必须验证消息中最多 10 条是否已经在我的表中。为此,我将带有项目及其顺序的 TVP 上传到存储过程,然后在存储过程中,我对 EXCLUDE 执行 count(*)。如果计数为零,那么我必须重新排序我的表,以使 TVP 中的最多 10 个替换我最多 20 个表中的任何顺序,然后保持任何剩余部分的顺序。

我想说我尝试过一些东西并抱怨错误,但我什至无法理解一个起点。序列不起作用,因为它们不能包含 order by 子句。我不能进行简单的交换,因为我有一个充满值的表,而且我不知道正在交换什么(如果有的话)。我对 t-SQL 中的游标使用没有任何工作知识,所以我不知道从哪里开始。

我试过阅读 CTE,没有什么明显的。序列,太有限了。光标(下)有效。有人有更好的解决方案吗?请注意,这些表的定义是我来设置的,虽然表(此处为#TestTbl)具有检查约束以确保位置在 1 到 20 之间,但可以将其删除,并且可以将主键移动到同样唯一的外键 IDA ,美洲开发银行。

DROP TABLE #TestTbl;
GO

create table #TestTbl
(
    Position int not null,
    IDA int not null,
    IDB int not null,
    CONSTRAINT uc_FK UNIQUE (IDA, IDB),
    CONSTRAINT PK PRIMARY KEY (Position)
);

INSERT INTO #TestTbl (Position, IDA, IDB)
VALUES (1, 2, 3), (2, 3, 4), (3, 4, 5), (4, 5, 6), (5, 6, 7), (6, 6, 6);
SELECT * FROM #TestTbl
ORDER BY Position;
GO

DROP TABLE #TestTvp;
GO
create table #TestTvp
(
    Position int NOT NULL,
    IDA int NOT NULL,
    IDB int NOT NULL,
    CONSTRAINT PKA PRIMARY KEY (Position)
);

INSERT INTO #TestTvp (Position, IDA, IDB)
VALUES (1, 2, 3), (3, 3, 4), (2, 4, 5), (4, 5, 6)
SELECT * FROM #TestTvp
ORDER BY Position;
GO

drop table #NewTbl;
go

DECLARE @ID1 int;
DECLARE @ID2 int;
DECLARE @LastCount int;

DECLARE MyCurse CURSOR FOR
SELECT IDA, IDB
FROM #TestTbl
EXCEPT
SELECT IDA, IDB
FROM #TestTvp;

SELECT Position, IDA, IDB 
INTO #NewTbl
FROM #TestTvp;

SET @LastCount = @@ROWCOUNT;

OPEN MyCurse;
SET @LastCount = @LastCount + 1;
FETCH NEXT FROM MyCurse
INTO @ID1, @ID2;

WHILE @@FETCH_STATUS = 0
BEGIN
    INSERT INTO #NewTbl (Position, IDA, IDB)
    VALUES (@LastCount, @ID1, @ID2);

    SET @LastCount = @LastCount + 1;
    FETCH NEXT FROM MyCurse
    INTO @ID1, @ID2;
END;

CLOSE MyCurse;

DEALLOCATE MyCurse;

SELECT * FROM #NewTbl
ORDER BY Position;
GO
4

1 回答 1

0

我尝试过 CTE + ROW_NUMBER 方法:

declare @target table (
    ida int, idb int, position int)
insert @target values 
    (1, 1, 1), 
    (1, 2, 2),
    (1, 3, 3),
    (1, 4, 4),
    (2, 1, 5),
    (2, 2, 6)

declare @message table (
    ida int, idb int, position int)
insert @message values
    (2, 2, 1),
    (1, 2, 2)

;with result as (
    select 
        t.ida, t.idb, t.position, 
        row_number() over(order by p.prio asc, p.position asc) newPosition
    from @target t
    left join @message m on m.ida = t.ida and m.idb = t.idb
    cross apply (
        select 0 prio, m.position where m.position is not null union
        select 1 prio, t.position where m.position is null
    ) p
)
update result set position = newPosition

select * from @target order by position
于 2014-09-30T05:56:27.437 回答