【问题标题】:Stored procedures to insert and then update the table based on identity column基于标识列插入然后更新表的存储过程
【发布时间】:2021-07-07 21:18:15
【问题描述】:

我有一个用例,我需要为审计表创建 2 个存储过程(插入数据、更新记录)。

第一个 SP 将 12 列数据中的 6 列插入表中,并自动生成我需要返回并存储在 Azure 数据工厂中的变量中的 ID,但由于某种原因,我无法获得该值。我收到一条错误消息,说存储过程没有返回任何值,不确定我缺少什么。

在此之后,下一个管道将在 Azure 数据工厂中运行,一旦运行完成,我需要从数据工厂获取输出值,并使用管道运行后生成的剩余 6 条记录更新同一个表。

下面是我的表架构

CREATE TABLE [gds].[TBL_SF_INTEGRATION_AUDIT](
[SF_Integration_Audit_ID] [int] IDENTITY(5000,1) NOT NULL,
[Integration_Batch_ID] [int] NULL,
[Pipeline_Run_StartDT] [datetime] NULL,
[Source_Schema] [varchar](1000) NOT NULL,
[Source_Object] [varchar](1000) NOT NULL,
[Target_Entity] [varchar](500) NOT NULL,
[Target_Load] [varchar](1000) NOT NULL,
[Source_Rows_Selected] [int] NULL,
[Batch_Count] [int] NULL,
[Successful_Batch_Count] [int] NULL,
[Failed_Batch_Count] [int] NULL,
[Successful_Inserted_Rows] [int] NULL,
[Failed_Rows] [int] NULL,
[Pipeline_Run_EndDT] [datetime] NULL

我创建了一个插入存储过程和一个更新存储过程。我正在使用Scope_Identity() 获取标识列的最新值,但我收到一条错误消息,指出存储过程没有返回任何值。

ALTER PROCEDURE [dbo].[SP_Insert_Into_IntegrationAudit]
(
    -- Add the parameters for the stored procedure here 
    @Integration_Batch_ID int,
    @Pipeline_Run_StartDT datetime,
    @Source_Schema varchar(1000),
    @Source_Object varchar(1000), 
    @Target_Entity varchar(500), 
    @Target_Load varchar(1000),
    @SF_Integration_Audit_ID int out
)
AS
BEGIN

    -- Insert statements for procedure here
   INSERT INTO gds.TBL_SF_INTEGRATION_AUDIT
   (Integration_Batch_ID, Pipeline_Run_StartDT, Source_Schema, Source_Object,
   Target_Entity, Target_Load)
   VALUES (@Integration_Batch_ID, @Pipeline_Run_StartDT, @Source_Schema,
           @Source_Object, @Target_Entity, @Target_Load)

    SET @SF_Integration_Audit_ID = SCOPE_IDENTITY()
    RETURN @SF_Integration_Audit_ID 


END

对于更新 SP,我不确定如何从第一个存储过程传递 ID,以便 SQL 知道应该插入/更新新数据的正确行?我已根据建议更改了 SP 以进行更新。

ALTER PROCEDURE [dbo].[SP_Update_IntegrationAudit]
(
    -- Add the parameters for the stored procedure here
    @Source_Rows_Selected int,
    @Batch_Count int,
    @Successful_Batch_Count int,
    @Failed_Batch_Count int,
    @Successful_Inserted_Rows int, 
    @Failed_Rows int, 
    @Pipeline_Run_EndDT datetime,
    @SF_Integration_Audit_ID int
)

AS
BEGIN

    -- Insert statements for procedure here
   UPDATE gds.TBL_SF_INTEGRATION_AUDIT
   SET Source_Rows_Selected = @Source_Rows_Selected, 
    Batch_Count = @Batch_Count,
    Successful_Batch_Count = @Successful_Batch_Count,
    Failed_Batch_Count = @Failed_Batch_Count,
    Successful_Inserted_Rows = @Successful_Inserted_Rows, 
    Failed_Rows = @Failed_Rows, 
    Pipeline_Run_EndDT = @Pipeline_Run_EndDT
    WHERE SF_Integration_Audit_ID = @SF_Integration_Audit_ID

END
GO

任何帮助将不胜感激!谢谢!!

【问题讨论】:

  • 根据问题指南,请不要发布代码、数据、错误消息等的图像 - 复制或键入问题中的文本。请保留将图像用于图表或演示渲染错误,无法通过文本准确描述的事情。
  • “...我需要返回并存储在 Azure 数据工厂中的变量中的 ID” - 您已经回答了自己的问题。您需要存储 ID 并将其与要更新的值一起传递。由于您没有提供有关系统这一部分的任何信息,因此我们无法提供太多帮助。我还应该指出,SP 的返回值不是用于传递数据,而是用于传递 SP 运行的状态。您应该使用输出参数。
  • 旁注:您应该不为您的存储过程使用sp_ 前缀。微软有reserved that prefix for its own use (see Naming Stored Procedures),你确实会在未来某个时候冒着名称冲突的风险。 It's also bad for your stored procedure performance。最好只是简单地避免sp_ 并使用其他东西作为前缀 - 或者根本不使用前缀!
  • 感谢@marc_s 的提示,我会做出改变的。
  • @DaleK 我已经用文本更新了我的帖子并添加了表格模式。我是 SQL Server 的新手,也是编写存储过程的新手,所以如果您可以查看我的表架构并提供任何进一步的反馈,我们将非常感谢您的帮助。

标签: sql-server stored-procedures ssms sqlparameter azure-data-factory-pipeline


【解决方案1】:

首先,绝对是的,scope_identity 是获取 Id 值的正确方法。

您说您正在存储从您的第一个过程调用返回的 Id 值(我假设该列称为 Id 您不提供表架构),因此您可以在第二个过程中包含一个参数它 (@Id int) 并将它与您已经提供的其他值一起传递 - 您的评论表明您将这样做?

然后在您的第二个程序中,您只需

update gds.TBL_SF_INTEGRATION_AUDIT set
<columns=@values>
where id=@id

捕获Identity 的另一种方法是使用output 子句将identity value 与其他相关值一起捕获到一个单独的表中。

您可以执行以下操作

insert into gds.TBL_SF_INTEGRATION_AUDIT (<columns>) 
output inserted.Id, inserted.Integration_Batch_Id into <another table> -- or any other columns needed
values (<values>)

然后您可以通过join 使用已知值来查找生成的Id。

【讨论】:

  • 感谢@Stu 的反馈。我根据您的建议进行了更改,但收到存储过程未返回任何值的错误。如果您可以再看一遍,我已经添加了我的表模式。再次感谢您的帮助
  • 2 个问题 - 当您运行第一个过程时,您如何捕获 return 值,并且在您的表模式上,SF_Integration_Audit_ID 大概是 identity 的唯一键
  • 是 SF_Integration_Audit_ID 是唯一的自动生成字段,它是一个身份。我正在使用以下代码来捕获返回值,不确定它是否是正确的方法 SET SF_Integration_Audit_ID = SCOPE_IDENTITY() RETURN SF_Integration_Audit_ID。验证检查不允许我在参数前面的符号处附加
  • 是的,你做得对。您的程序将return 该值。不过,我不知道您是如何调用第一个程序的。大概来自客户端代码,在这种情况下,您将需要捕获返回的值。如果你是从另一个 Sql 过程调用你的第一个过程或使用 SSMS 进行测试,你会exec @returnedvalue = SP_Insert_Into_IntegrationAudit
  • 哦,这就是你的意思。我在 Azure 数据工厂中使用从 Lookup 活动获取输出的 Set Variable 活动将其作为变量调用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-13
  • 2016-11-07
相关资源
最近更新 更多