【发布时间】:2011-03-09 17:14:32
【问题描述】:
当您将记录插入到具有标识列的表中时,您可以使用 SCOPE_IDENTITY() 来获取该值。在存储过程的上下文中,这是返回标识值的推荐方式:
- 作为输出参数
SET @RETURN_VALUE = SCOPE_IDENTITY() - 作为标量
SELECT SCOPE_IDENTITY() - 另一种方式?
各有优缺点?
【问题讨论】:
标签: sql-server stored-procedures
当您将记录插入到具有标识列的表中时,您可以使用 SCOPE_IDENTITY() 来获取该值。在存储过程的上下文中,这是返回标识值的推荐方式:
SET @RETURN_VALUE = SCOPE_IDENTITY()
SELECT SCOPE_IDENTITY()
各有优缺点?
【问题讨论】:
标签: sql-server stored-procedures
另一种选择是作为存储过程的返回值(不过我不建议这样做,因为这通常最适合错误值)。
我已经将它包括在插入单行的情况下,以防存储过程被其他 SQL 过程和无法使用 OUTPUT 参数的前端(我相信 .NET 中的 IBATIS ):
CREATE PROCEDURE My_Insert
@col1 VARCHAR(20),
@new_identity INT OUTPUT
AS
BEGIN
SET NOCOUNT ON
INSERT INTO My_Table (col1)
VALUES (@col1)
SELECT @new_identity = SCOPE_IDENTITY()
SELECT @new_identity AS id
RETURN
END
当从其他存储过程 IMO 调用时,输出参数在 T-SQL 中更易于使用,但某些编程语言对输出参数的支持较差或不支持,并且可以更好地处理结果集。
【讨论】:
这一切都取决于您的客户端数据访问层。许多 ORM 框架依赖于在插入操作期间显式查询 SCOPE_IDENTITY。
如果您完全控制了数据访问层,那么可以说将 SCOPE_IDENTITY() 作为输出参数返回更好。将返回结果包装在结果集中会增加不必要的元数据开销来描述结果集,并使处理请求结果的代码变得复杂。
如果您更喜欢结果集返回,那么再次使用 OUTPUT 子句可能会更好:
INSERT INTO MyTable (col1, col2, col3)
OUTPUT INSERTED.id, col1, col2, col3
VALUES (@col1, @col2, @col3);
通过这种方式,您可以获得 整个 插入的行,包括默认列和计算列,并且您会获得一个结果集,其中包含插入的每一行的一行,这与面向集合的批量插入一起正常工作。
总的来说,当返回 SCOPE_IDENTITY() 作为结果集时,我看不到一个案例。
【讨论】:
我更喜欢将标识值作为输出参数返回。 SP的结果应该表明它是否成功。值 0 表示 SP 成功完成,非零值表示错误。此外,如果您需要进行更改并从 SP 返回一个附加值,您无需进行任何更改,只需添加一个附加输出参数。
【讨论】:
SELECT 一个额外的专栏并不难。我知道您可以将输入参数设为可选(使用默认值);输出参数呢?如果不能,更改SELECT 会更容易,因为除非您需要,否则您可能会忽略额外的列。尽管如此,我认为输出参数是没有结果集开销的“正确”方式。
作为记录集或输出参数。后者的开销较小,我倾向于使用它而不是单个列/行记录集。
如果我希望 >1 行,我会使用 OUTPUT 子句和记录集
返回值通常用于错误处理。
【讨论】:
SELECT IDENT_CURRENT('databasename.dbo.tablename') AS your identity column;
【讨论】: