我迫切需要关于这个的线索。我正在用 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