代码之家  ›  专栏  ›  技术社区  ›  MedicineMan

在数据库中创建新行后,我应该将主键返回到该行还是数据传输对象?

  •  2
  • MedicineMan  · 技术社区  · 16 年前

    我有三层系统,SQL Server后端、手写数据访问层和使用存储过程。

    我有一张叫做EventTable的桌子。每一行都是一个“事件”。事件具有主键和开始日期。

    CREATE TABLE EventTable
    (
      ID INT IDENTITY(100,1) PRIMARY KEY,
      StartTime DateTime NOT NULL
    )
    

    有一个名为eventtable_create的存储过程。顺便说一句,create方法是否和书面的一样好?

    CREATE PROCEDURE Event_Create
        @NewID INT OUT
    AS
        DECLARE @START DATETIME
        SELECT @START = getdate() 
        INSERT INTO EventTable VALUES(@START, NULL)
        SELECT @NewID = MAX(ID) FROM EventTable
    GO
    

    数据访问层向调用者返回一个int,但它应该返回一个名为event的数据传输对象的实例吗?如果是这样的话,我是否应该同时返回新创建的ID和开始时间,以便数据访问层可以创建事件传输对象?

    4 回复  |  直到 16 年前
        1
  •  3
  •   Srikar Doddi    16 年前

    这完全取决于通过数据访问在域层中需要什么。由于您是通过从域层传递信息来创建此事件的,所以我假设您的域逻辑中已经有了大部分事件信息。在这种情况下,只要有一个ID,就可以将其作为事件对象的一部分填充。

    所以这一切都取决于您在域层中需要什么以及出于什么原因。

        2
  •  2
  •   Sean    16 年前

    至于你需要归还的东西,任何一种方法都可能奏效。正如共同主席所说,这要视情况而定。我倾向于自己回归这两种价值观。

    我将更改获取存储过程中标识列的方式。有几种方法可以得到它。

    而不是:从实验表中选择@newid=max(id)

    我会这样做: 设置@newid=@@标识

    设置@newid=scope_identity()

    以下是在线图书的摘录和一个例子。我可以帮助您决定使用哪个:

    例如,有两个表T1和T2,并且在T1上定义了一个插入触发器。当一行插入T1时,触发器将激发并在T2中插入一行。这个场景演示了两个范围:T1上的insert和由触发器进行的t2上的insert。

    假设T1和T2都有标识列,@@identity和scope\u identity将在T1的insert语句末尾返回不同的值。@@Identity将返回在当前会话中任何作用域中插入的最后一个Identity列值。这是在t2中插入的值。scope_identity()将返回插入T1中的标识值。这是在同一范围内发生的最后一次插入。如果在作用域中标识列中出现任何插入语句之前调用了函数,则scope_identity()函数将返回空值。

        3
  •  1
  •   John M Gant aman_novice    16 年前

    除非需要整个数据结构,否则应返回唯一的主键。默认情况下返回整个数据结构是浪费的,没有特定的原因。

        4
  •  0
  •   Abhishek    16 年前

    您不应该使用max(id)来检索新添加记录的主键。

    使用,@@标识代替。

    INSERT INTO tbl(...) VALUES(...);
    
    SELECT @@Identity as NewID;