我们正在从Oracle迁移到SQL Server,并且我正在从填充了BULK COLLECT INTO查询的表变量转换查询。我正在考虑使用游标(肯定对其他建议开放),但在处理查询的Oracle代码中,它使用Table_var.FIRST
.NEXT
和.LAST
。这是一些如何使用它们的示例代码。看来第一个/下一个/最后一个是为表var的记录提供索引。
TYPE Pers_DOB_LastInitial IS RECORD (
Person_ID Person.Person_ID%TYPE,
DOB Person.Birthdate%TYPE,
LastInitial VARCHAR2(1)
);
TYPE Dup_Table IS TABLE OF Pers_DOB_LastInitial INDEX BY BINARY_INTEGER;
Dup_Tab Dup_Table;
以及使用这些类型的函数:
FUNCTION Last_In_Group( pStart NUMBER, pDOB Person.Birthdate%TYPE, pLastInitial VARCHAR2 )
RETURN NUMBER IS
vResult NUMBER;
BEGIN
IF pStart = Dup_Tab.LAST THEN
RETURN pStart;
END IF;
vResult := pStart;
FOR vIndex IN pStart .. Dup_Tab.LAST LOOP
IF Dup_Tab.EXISTS( vIndex ) THEN
IF Dup_Tab( vIndex ).DOB = pDOB AND Dup_Tab( vIndex ).LastInitial = pLastInitial THEN
vResult := vIndex;
ELSE
EXIT;
END IF;
END IF;
END LOOP;
RETURN vResult;
END Last_In_Group;
我不需要为我完成编码,只需要指向正确的方向。我正在考虑使用游标,但我唯一熟悉的只是从T-SQL中的游标中获取下一条记录,并希望查看是否有相同的方法来引用游标(或临时表)的行索引)。
编辑:我刚发现以下内容并正在调查中。绝对愿意接受是否这是一条良好的追求途径,或者游标是否仍然更好。
http://www.sql-server-performance.com/2004/operations-no-cursors/2/
DECLARE @dupTab TABLE (
person_id numeric(8,0),
DOB date,
LastInitial char(1)
)
INSERT @dupTab
SELECT ...
答案 0 :(得分:0)
不是100%肯定您在问什么,但是您是否在Sql Server 2012中查看了新的LEAD,LAG,FIRST_VALUE和LAST_VALUE关键字?
答案 1 :(得分:0)
假设您的表名为Dup_Tab,而@DOB和@LastInitial是您传入函数的变量,这可能有用吗?
select PersonID from(
select
rank = row_number() over (order by DOB DESC, LastInitial DESC),
PersonID
from dup_tab where DOB=@DOB and LastInitial=@LastInitial
) subgroup
where rank=1
它只是使用窗口化的Rank()函数为每个记录分配一个基于DOB / LastInitial排序的行号,然后你选择rank = 1的行,给你一组人的最后一条记录特定的DOB和LastInitial。
答案 2 :(得分:0)
我将您的示例代码翻译成了SQL-Server对应代码。如果你想逐行处理,最好的方法就是使用FAST_FORWARD游标。
代码:
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[Last_In_Group]') AND xtype in (N'FN', N'IF', N'TF'))
drop function Last_In_Group
go
create function Last_In_Group(@pStart int, @pDOB date, @pLastInitial varchar(1))
returns int
AS
BEGIN
DECLARE @Dup_Tab TABLE(
Person_ID int,
DOB date,
LastInitial varchar(1)
)
-- populate the table with some data
insert @Dup_Tab values
(1, '31.12.2013', 'P'), (2, '24.12.2013', 'C'), (3, '24.12.2013', 'C')
declare @vResult int = 0,
@cDOB date,
@cLastInitial varchar(1)
if(@vResult = @pStart) return @pStart
set @vResult = @pStart
-- loop over your data with a fast cursor
declare cur cursor FAST_FORWARD for select DOB, LastInitial from @Dup_Tab
open cur
fetch next from cur
into @cDOB, @cLastInitial
while @@FETCH_STATUS = 0
begin
if(@cDOB = @pDOB and @cLastInitial = @pLastInitial)
set @vResult += 1
fetch next from cur
into @cDOB, @cLastInitial
end
return @vResult;
end
go
print dbo.Last_In_Group(1, '24.12.2013', 'C')
go
它可能无法作为上面的示例,但我希望这会给你一些提示,以便进一步发展。