存储过程,你能帮帮我吗?

时间:2008-12-15 09:27:36

标签: sql sql-server stored-procedures

以下是我的存储过程。我想使用存储过程从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

2 个答案:

答案 0 :(得分:8)

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

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函数。

答案 1 :(得分:3)

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

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