【问题标题】:SQL stored procedure works but with errorsSQL 存储过程有效但有错误
【发布时间】:2011-12-12 11:48:59
【问题描述】:

我的表有 3 个主键:CODE_TARIF, UNITEMODE_LIV

我编写了一个存储过程来复制和粘贴,但使用不同的MODE_LIV

例如:如果当我使用输入 MODE_LIV =3 运行此存储过程时,表 T_TARIFMODE_LIV = 2, 中已经有 2 行,我将有 4 行。

ALTER PROCEDURE [dbo].[Copy_Tarif]
    -- Add the parameters for the stored procedure here
  @MODE_LIV int
AS
BEGIN
    DECLARE @CODE_TARIF varchar(15)
    DECLARE @ZONE int
    DECLARE @UNITE int
    DECLARE @LIBELLE varchar(30)

    DECLARE @TR_DEB int
    DECLARE @TR_FIN int
    DECLARE @MONTANT decimal(18,2)


    DECLARE tarif_cursor CURSOR FOR     
    SELECT CODE_TARIF, ZONE, UNITE, LIBELLE, TR_DEBUT, TR_FIN, MONTANT
    FROM T_TARIF

    OPEN tarif_cursor;

    FETCH NEXT FROM tarif_cursor 
    INTO  @CODE_TARIF, @ZONE, @UNITE, @LIBELLE,  @TR_DEB, @TR_FIN, @MONTANT;

    WHILE @@FETCH_STATUS = 0
    BEGIN
        INSERT INTO [T_TARIF]
           ([CODE_TARIF]
           ,[ZONE]
           ,[UNITE] 
           ,[MODE_LIV]         
           ,[LIBELLE]
           ,[TR_DEBUT]
           ,[TR_FIN]
           ,[MONTANT]

           )
     VALUES
           (@CODE_TARIF
           ,@ZONE
           ,@UNITE   
           ,@MODE_LIV       
           ,@LIBELLE
           ,@TR_DEB
           ,@TR_FIN
           ,@MONTANT

           )

        FETCH NEXT FROM tarif_cursor
        INTO  @CODE_TARIF, @ZONE, @UNITE, @LIBELLE,  @TR_DEB, @TR_FIN, @MONTANT;



    END
END

它可以工作,但会出现错误,请参阅视频:Strange Stored Procedure

提前谢谢你, 史蒂夫

【问题讨论】:

  • 请描述错误。我不是特别想看视频来弄清楚你的问题在问什么!
  • 感谢您的回复,它插入了数据但返回错误vialotion主键。
  • 您的游标 SELECT 的结果集可能包含 MODE_LIV 已经等于目标值 @MODE_LIV 的行。或者可能存在具有相同CODE_TARIFUNITE 但不同MODE_LIV 的行。所以我的意思是,您应该向游标 SELECT 添加一些过滤(或者,更好的是,按照@gbn 的建议添加到 INSERT 语句的 SELECT 部分)

标签: sql stored-procedures while-loop


【解决方案1】:

猜测...

您正在使用 ISO 游标语法。这默认为不 INSENSITIVE 。这意味着当你插入行时,当你 FETCH 时你会得到你刚刚插入的行等等。

从 DECLARE CURSOR

DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR

定义一个游标,该游标制作数据的临时副本以供游标使用。对游标的所有请求都是从 tempdb 中的这个临时表中回答的;因此,对基表所做的修改不会反映在对该游标进行的提取返回的数据中,并且该游标不允许修改。 使用 ISO 语法时,如果省略 INSENSITIVE,则提交的删除和对基础表的更新(由任何用户)会反映在后续提取中。

无论如何,你所需要的就是:无需循环

 INSERT INTO [T_TARIF]
       ([CODE_TARIF]
       ,[ZONE]
       ,[UNITE] 
       ,[MODE_LIV]         
       ,[LIBELLE]
       ,[TR_DEBUT]
       ,[TR_FIN]
       ,[MONTANT])
 SELECT 
       [CODE_TARIF]
       ,[ZONE]
       ,[UNITE] 
       ,@MODE_LIV       
       ,[LIBELLE]
       ,[TR_DEBUT]
       ,[TR_FIN]
       ,[MONTANT]
 FROM
      [T_TARIF]
      

【讨论】:

  • @user609511:您不需要循环:SQL 旨在处理多行
  • 感谢您的回复,我尝试使用DECLARE tarif_cursor INSENSITIVE CURSOR FOR,但仍然出错。我需要循环,因为我插入了超过 1 行。我不知道怎么办?我必须从表中选择 *,然后我把它放到临时变量中?
  • 我尝试不使用循环 -> 我只插入了 1 行。
  • 我按照你的回答,但仍然得到:Violation de la contrainte PRIMARY KEY 'PK_T_TARIF'
  • @user609511:当然。表示CODE_TARIF、UNITE、MODE_LIV的组合已经存在
猜你喜欢
  • 1970-01-01
  • 2020-06-26
  • 2019-10-01
  • 2016-06-13
  • 2018-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多