Вставьте текущий номер строки в таблицу SQL Server - PullRequest
1 голос
/ 25 января 2012

У меня есть следующая таблица в 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 голосов
/ 25 января 2012

Ваша функция 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

Я никогда не использовал это, поэтому я не могу сказать вам, хорошо это делать или нет.Это может быть разрушительным для производительности вашего запроса, я просто не знаю.

0 голосов
/ 13 февраля 2013

Это все не очень хорошая идея, но если вам ДЕЙСТВИТЕЛЬНО это нужно, попробуйте триггер:

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
0 голосов
/ 25 января 2012

Я согласен с комментариями, и вы должны изменить имя столбца 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

Если вам нужен более сложный подход - используйте триггер.

...