【问题标题】:Stored Procedure, can you help me?存储过程,你能帮我吗?
【发布时间】:2008-12-15 09:27:35
【问题描述】:

下面是我的存储过程。我想使用存储过程从 tbl_member 中选择所有日期行并插入 2 个表。但这是行不通的。有人可以帮助我吗?

Create PROCEDURE sp_test
AS
BEGIN
    SET NOCOUNT ON;

    Declare @A Varchar(255), @B Varchar(255), @C Varchar(255), @D int

    Declare Table_Cursor Cursor 
    For select A, B, C from tbl_Member Open Table_Cursor 
        Fetch Next From Table_Cursor 
        Into @A, @B, @C While(@@Fetch_Status=0)

    Begin Exec(
        'insert into NewMember (A, B, C, D) values (@A, @B, @C, @D)
        set @D = @@IDENTITY
        Insert into MemberId (Mid) VALUES(@D)   
    )
    Fetch Next From Table_Cursor Into @A, @B, @C End Close Table_Cursor
    Deallocate Table_Cursor
END
GO

【问题讨论】:

  • 您在“插入”之前有一个 ' 而在之后没有。
  • 你绝对应该学会正确缩进你的代码。真的很难看出这里有一个 while 循环,因为你在其他语句之间隐藏了 while 和 end 在行中间。

标签: sql sql-server stored-procedures


【解决方案1】:

我在这里看到的第一件事是您在不需要时使用光标。您可以将第一个查询重写为:

INSERT INTO NewMember(A, B, C, D)
SELECT A, B, C, D
FROM tbl_member

然后,我将有一个针对插入标识列的 NewMember 的 INSERT 触发器。

create trigger myInsertTrigger
on newmember
for insert
as
insert into memberid(mid)
select <<identity_column>> from inserted

顺便说一句 - 使用 @@IDENTITY 来获取插入的标识是个坏主意。请改用 SCOPE_IDENTITY 函数。

【讨论】:

    【解决方案2】:

    请特别注意Pete 所说的@@identity。使用@@identity 不好的原因是,如果将触发器添加到插入另一个具有标识的表的表中,则返回的标识不是您刚刚插入的标识。这可能会导致可能几个月都无法解决的大量数据完整性问题。

    即使您保留了游标(我不建议这样做,游标是一种非常糟糕的插入方式,因为与 Pete 提供的基于集合的解决方案相比,它们非常慢),您的代码也无法插入如果列 D 是标识列,则为第一个表(我猜这是因为您稍后尝试将 D 分配给标识值)。那是因为您试图将一个值放入无法接受自动生成的值的列中。如果 D 是标识,则根本不要在插入中使用它,只需定义需要插入的列。如果 D 实际上是您的身份列,Pete 的解决方案也是如此。

    【讨论】:

      猜你喜欢
      • 2010-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-09
      • 2019-09-13
      • 2021-06-11
      相关资源
      最近更新 更多