将当前行号插入SQL Server表

时间:2012-01-25 05:39:46

标签: sql-server sql-function

我在SQL Server中有以下表格

 CREATE TABLE [dbo].[tblTempPo](
    [TempPoID] [int] IDENTITY(1,1) NOT NULL,
    [guid]  AS ([dbo].[GetIdentity]()),
    [Qty] [int] NULL,
    [MobileBrandID] [int] NULL,
    [MobileID] [int] NULL
)

每次添加新行时,我都需要将当前行号插入guid列。我尝试使用以下功能,但它没有按预期工作。

ALTER FUNCTION GetIdentity() 
RETURNS INT AS
BEGIN
   RETURN (SELECT top 1 ROW_NUMBER() OVER(ORDER BY TempPoID asc)FROM tblTempPo)
END

3 个答案:

答案 0 :(得分:0)

我同意评论,您应该更改GUID列名称。如果你真的必须存储TempPoID列两次使用计算列。例如:

CREATE TABLE #tblTempPo (
    [TempPoID] [int] IDENTITY(1,1) NOT NULL,
    [second_id] AS TempPoID,
    [Qty] [int] NULL,
    [MobileBrandID] [int] NULL,
    [MobileID] [int] NULL
)

INSERT INTO #tblTempPo (Qty, MobileBrandID, MobileID) VALUES 
(10, 10, 15), (20, 23, 45), (55, 23, 12), (10, 1, 1)

SELECT * FROM #tblTempPo

DROP TABLE #tblTempPo

如果您需要更复杂的方法 - 请使用触​​发器。

答案 1 :(得分:0)

您的函数GetIdentity()可能总是返回1,但这不是肯定的,因为您使用的select top 1...没有order by子句。
如果您想要row_number()返回的最高值,则需要添加order by 1 desc,这与执行SELECT count(*) from tblTempPo相同。

修复此类GetIdentity()对您的情况没有太大帮助,因为[guid] AS ([dbo].[GetIdentity]())会为您提供每次查询表时评估的计算列,而不是插入新行。对于所有行,您将始终具有相同的值。

您可以使用将TempPoID作为参数作为计算列的函数。

CREATE FUNCTION GetIdentity(@P int) 
RETURNS INT AS
BEGIN
   RETURN (SELECT rn
           FROM (SELECT TempPoID,
                        ROW_NUMBER() OVER(ORDER BY TempPoID ASC) AS rn
                 FROM tblTempPo) AS T
           WHERE TempPoID = @P)
END

表格定义:

CREATE TABLE [dbo].[tblTempPo](
    [TempPoID] [int] IDENTITY(1,1) NOT NULL primary key,
    [guid] as dbo.GetIdentity(TempPoID),
    [Qty] [int] NULL,
    [MobileBrandID] [int] NULL,
    [MobileID] [int] NULL

我从来没有用过这个,所以我不能告诉你这是不是一件好事。它可能对您的查询性能造成破坏性,我只是不知道。

答案 2 :(得分:0)

这都不是一个好主意,但如果你真的需要它,请尝试触发:

create table [dbo].[tblTempPo](
[TempPoID] [int] identity(1,1) NOT NULL,
[guid]  int,
[Qty] [int] NULL,
[MobileBrandID] [int] NULL,
[MobileID] [int] NULL
)
go

create trigger [dbo].[tblTempPo_Trig] on [dbo].[tblTempPo] instead of insert as
declare @cnt int
select @cnt = count(*)
from [dbo].[tblTempPo] with(nolock)
insert into [dbo].[tblTempPo]([guid], [Qty], [MobileBrandID], [MobileID])
select @cnt+row_number() over (order by [TempPoID]), [Qty], [MobileBrandID], [MobileID] from inserted
go

insert into [dbo].[tblTempPo]([Qty], [MobileBrandID], [MobileID]) values (0, 0,0), (0, 0,0), (0, 0,0), (0, 0,0)
insert into [dbo].[tblTempPo]([Qty], [MobileBrandID], [MobileID]) values (0, 0,0), (0, 0,0), (0, 0,0), (0, 0,0)

select * from [dbo].[tblTempPo]

go
drop table [dbo].[tblTempPo]
go