如何在插入新行时通过触发器设置新的字段值

时间:2013-02-19 20:36:34

标签: sql sql-server-2008 triggers sql-server-2008-r2

我使用MsSQL服务器的应用程序非常难看。此应用程序正在从数据库中读取行并按键字段(ASC)对其进行排序。我想要的是用另一个字段(例如姓名或姓氏)对它们进行排序。我以为我可以这样做。 一开始我有这样的表(按姓氏排序):

id | name | surname  | sort_position
1  | John | Kowalski | 1
2  | Jack | Sparrow  | 2

当我在DB中插入新行时,我希望它看起来像这样:

id | name | surname  | sort_position
1  | John | Kowalski | 1
2  | Jack | Sparrow  | 3
3  | Kate | Nowacki  | 2

下次:

id | name | surname    | sort_position
1  | John | Kowalski   | 2
2  | Jack | Sparrow    | 4
3  | Kate | Nowacki    | 3
3  | Kate | Adamowicz  | 1    

甚至可能吗?我必须在MsSQL 2008中做到这一点......

1 个答案:

答案 0 :(得分:2)

从字面上看问题,给出样本数据:

CREATE TABLE dbo.Data
(
    id      integer NOT NULL IDENTITY PRIMARY KEY,
    name    nvarchar(30) NOT NULL,
    surname nvarchar(50) NOT NULL
);
GO
INSERT dbo.Data
    (name, surname)
VALUES
    (N'John', N'Kowalski'),
    (N'Jack', 'Sparrow');

添加动态sort_position的一种方法是使用VIEW窗口函数定义ROW_NUMBER

CREATE VIEW dbo.DataWithSurnameSortPosition
WITH SCHEMABINDING
AS
SELECT
    d.id,
    d.name,
    d.surname,
    sort_position =
        ROW_NUMBER() OVER (
            ORDER BY d.surname)
FROM dbo.Data AS d;

查询视图会得到如下输出:

SELECT
    dwssp.id,
    dwssp.name,
    dwssp.surname,
    dwssp.sort_position
FROM dbo.DataWithSurnameSortPosition AS dwssp;

╔════╦══════╦══════════╦═══════════════╗
║ id ║ name ║ surname  ║ sort_position ║
╠════╬══════╬══════════╬═══════════════╣
║  1 ║ John ║ Kowalski ║             1 ║
║  2 ║ Jack ║ Sparrow  ║             2 ║
╚════╩══════╩══════════╩═══════════════╝

添加新数据时:

INSERT dbo.Data
    (name, surname)
VALUES
    (N'Kate', N'Nowacki'),
    (N'Kate', 'Adamowicz');

视图查询返回:

╔════╦══════╦═══════════╦═══════════════╗
║ id ║ name ║  surname  ║ sort_position ║
╠════╬══════╬═══════════╬═══════════════╣
║  4 ║ Kate ║ Adamowicz ║             1 ║
║  1 ║ John ║ Kowalski  ║             2 ║
║  3 ║ Kate ║ Nowacki   ║             3 ║
║  2 ║ Jack ║ Sparrow   ║             4 ║
╚════╩══════╩═══════════╩═══════════════╝

您仍然无法依赖在此视图上以任何特定顺序返回行,而在查询引用视图的情况下没有ORDER BY子句。视图中的OVER子句ORDER BY 保证最终排序顺序。然而,sort_position将按照您似乎要遵循的顺序编号。

如果您需要相同的姓氏以获得相同的sort_position,请在视图中使用RANKDENSE_RANK代替ROW_NUMBER