运行一存储过程时报错,提示无法插入重复值,违法了Pk_mxz_mx约束。
该表有五个联合主键。
但是诡异的是,我将此数据库备份后,还原至一个新库,存储过程居然执行过去了,但是原来那个库死活执行不过去。ps,两个数据库在同一台服务器上。
急求各位高手解惑,不胜感激

解决方案 »

  1.   

    SET QUOTED_IDENTIFIER ON 
    GO
    SET ANSI_NULLS ON 
    GOALTER      proc  SPZY_JieZhuan
       @InvoiceSys       bit,          --使用发票管理系统吗    
    @dtcw bit, --使用动态床位吗
       @ClearYjk bit, --结转后预交款清为零
       @zyh              char(10),    --住院号
       @czy                 varchar(20),   --操作员
       @InvoiceNo         char(20)   output,        --出院发票号
       @BalanceCash         decimal(18,2), --现金退款
       @BalanceCheque       decimal(18,2),  --支票退款
       @OweMoney       decimal(18,2), --出院欠款
       @jzje decimal(18,2), --结转金额
       @dzlx varchar(10), --打折类型
       @dzhhf        decimal(18,2), --折后花费
       @zhf DECIMAL(18,2), --总花费
       @jzrq DATETIME, --结转日期
       @fgfy INT, --分割费用
       @errmsg        varchar(100) output --错误信息
       
       as
       --2010.9.30 ksr  增加按时间分费用结转功能
       set lock_timeout 15000
       SET DEADLOCK_PRIORITY low
       SET XACT_ABORT ON   declare @InHosDT  datetime
       declare @InKsDT  datetime
       declare @OutHosDT  datetime
       declare @InHosDays  int
    declare @BedNo varchar(20)
       declare @sql         nvarchar(1000) --错误信息
       declare @sjlyzd     varchar(500)
       declare @xjyjk      varchar(20)
       declare @zpyjk      varchar(20)
       declare @brqf      varchar(20)
       declare @FeeType     varchar(20) --费用类别
       declare @jkjy       decimal(18,2) 
       declare @sbje       decimal(18,2) 
       declare @pub1       decimal(18,2)    declare @Invoice bit    --是否需要领用新发票   declare @xjzf       decimal(18,2) --普通病人为折后花费,医保病人为现金支付部分
       declare @zhzf       decimal(18,2) --普通病人为0,医保病人为帐户支付部分
       declare @tczf       decimal(18,2) --普通病人为0,医保病人为统筹支付部分      set @pub1 = 0
       set @jkjy = 0
       set @sbje = 0
       set @errmsg = '出院失败'   --中途结转清零后是否记录结转余额
       SET @OutHosDT=@jzrq
       select @FeeType = 费用类别,@InKsDT=入科日期,@InHosDT = 入院日期,@xjyjk=现金预交款,@zpyjk=支票预交款,@brqf=0,@jkjy = 现金预交款+支票预交款-@dzhhf,@BedNo=科床号
    from brda where 住院号=@zyh
       IF @@ROWCOUNT < 1  
          BEGIN
             SET @ERRMSG = '未检测到在院基本档案信息!'
             RETURN -1
          END select @pub1=count(*) from zy_cyzh where 住院号=@zyh and 入院日期=@InHosDT
    if @pub1>0 begin
    set @errmsg = '该患者是出院招回患者,不能结转!'
    return -1
    end   --业务规则检测,欠费不能结转
    /*
       if cast( @jzje as decimal(18,2)) < 0  begin
    set @errmsg = '该患者欠费,不能结转!请办理预交款业务充值!'
    return -1
    end
    */
    --应退现金
       --set @BalanceCash = @jzje
       -- 2005.1.7屏蔽掉下面计算退现金的算法。因为导致结算交款报表中的 交款-打折后花费<>余额.,出错了
    /*
       set @BalanceCash = 0
       if cast( @jzje as decimal(18,2)) > 0 begin
          if @ClearYjk = 1 --结转后的brda表中的预交款为0,表示将多余的现金退给病人了
    set @BalanceCash = @jzje
    end 
    */
      
    --检测医保病人的结算信息
        select top 1 @xjzf = zfze,@tczf = tcgzze,@zhzf = xyzfze from zyjk where zyh=@zyh   and ryrq=@InHosDT
    if @xjzf IS NULL
    begin
    set @xjzf = '0'
    end
    if @tczf IS NULL
    begin
    set @tczf = '0'
    end
    if @zhzf IS NULL
    begin
    set @zhzf = '0'
    end
    IF @jkjy<0 AND @ClearYjk = 1 BEGIN
    SET @sbje = -1*@jkjy - @OweMoney
    END
       ---------------------------------开启事务
       begin  TRAN
           IF @fgfy=1  
           begin
       --结转日期费用分割
       update mxz  set 入院日期=@OutHosDT where 住院号=@zyh and 入院日期 =@InHosDT AND 日期>=@OutHosDT
       update mxz_tf set 入院日期=@OutHosDT where 住院号=@zyh and 入院日期 =@InHosDT AND 退费时间>=@OutHosDT    
       UPDATE cfy_mx SET 入院日期=@OutHosDT 
       where EXISTS(
    SELECT 住院号 
    FROM CFY 
    WHERE CFY.住院号=cfy_mx.住院号 
    AND CFY.入院日期=cfy_mx.入院日期
    AND CFY.明细帐号=cfy_mx.明细帐号
    AND CFY.日期>=@OutHosDT
    )
       UPDATE cfy_tf_mx SET 入院日期=@OutHosDT 
       WHERE EXISTS(
    SELECT 住院号 
    FROM cfy_tf 
    WHERE cfy_tf.住院号=cfy_tf_mx.住院号 
    AND cfy_tf.入院日期=cfy_tf_mx.入院日期
    AND cfy_tf.明细帐号=cfy_tf_mx.明细帐号
    AND cfy_tf.退费时间>=@OutHosDT
    )
       update cfy  set 入院日期=@OutHosDT where 住院号=@zyh and 入院日期 =@InHosDT AND 日期>=@OutHosDT 
       update cfy_tf set 入院日期=@OutHosDT where 住院号=@zyh and 入院日期 =@InHosDT AND 退费时间>=@OutHosDT       
    END
       --费用校验
           select @pub1=sum(金额) from mxz where 住院号=@zyh and 入院日期=@InHosDT and 记帐类型<>'交款' and 记帐类型<>'作废'
       if @pub1 <> @zhf
      begin
     set @errmsg = '处方明细表中的花费与基本档案表中的花费信息不符!'
     return -1
      end
       if  @InvoiceSys = 1 -------------使用发票管理系统
          begin
              --检测发票号有效性
              update fp_zy set 当前票号=@InvoiceNo  where   发票类型='出院发票' and 领用操作员=rtrim(@czy) and @InvoiceNo between 起始票号 and 终止票号 
              if @@ROWCOUNT < 1  begin
                 set @errmsg = '更新发票信息失败!发票出库表中没有相关信息,发票号'+@InvoiceNo
                 rollback tran
                 return -1
              end     
          end
       else begin         ---------------不使用发票管理系统 --不使用发票管理,操作员用自己发票,必须更新fpk,保存当前最大发票号 
    update fpk set InvoiceNoUse = @InvoiceNo where 操作员=@czy and @InvoiceNo between 起始票号 and 终止票号
          end
       ----------------------------------更新fpmxk
       set @sjlyzd = dbo.sjlyzd(2)
       set @sql = 'insert into fpmxk(现金预交款,支票预交款,交款结余,现金退款,支票退款,病人欠费,操作员,日期,发票号,作废,住院号,入院日期,办理类型,费用类别,病人类型,结转余额,花费,补交现金,打折后花费,tc,zh,xj,'
       set @sql = @sql+@sjlyzd +') '
       set @sql = @sql+ 'select ' +@xjyjk+','+@zpyjk+','+cast(@jkjy as char)+','+cast (@BalanceCash as varchar)+','+cast (@BalanceCheque as varchar)+','+@brqf+','''+@czy+''',getdate(),'''
       set @sql = @sql+@InvoiceNo+''',0,住院号,入院日期,''中途结转'','''+@FeeType+''','''+@dzlx+''','+cast(@jzje as char)+','+cast(@zhf as char)+','+cast(@sbje as char)+','+cast(@dzhhf as char)+','
       set @sql = @sql+cast(@tczf as char)+','+cast(@zhzf as char)+','+cast(@xjzf as char)+','
       set @sql = @sql+   @sjlyzd
       set @sql = @sql+ ' from brzz where 住院号='''+@zyh +''''+' and 入院日期='''+CONVERT (char(10),@InHosDT,120)+''''
       exec(@sql)
    if @@rowcount = 0 or  @@error<> 0  begin
              set @errmsg = '发票明细表未更新!'
              rollback tran
              return -1        
    end
    --print @sql   select @InHosDays=天数 from brjs where 住院号=@zyh AND InHosDT=@InHosDT
      --把brzz的信息导出到jz表中
         set @sql = 'insert into jz (住院号,入院日期,现金预交款,支票预交款,花费,折后花费,结转余额,操作员,日期,结转日期,入科日期,'+dbo.sjlyzd(2)
         set @sql = @sql+') select 住院号,入院日期,'+@xjyjk+','+@zpyjk+','+cast (@zhf as varchar)+','+cast(@dzhhf as varchar)+','+cast(@jzje as char)+','''+@czy+''',getdate(),'''+cast (@OutHosDT as char(10))+''','''+cast (@InKsDT as char(10))+''','+dbo.sjlyzd(2)
         set @sql = @sql+' from brzz where 住院号='''+@zyh+''''+' and 入院日期='''+CONVERT (char(10),@InHosDT,120)+''''
         exec(@sql)
         if @@error<> 0 
            begin
               set @errmsg = '中途结转时总帐信息导出失败!'
               rollback tran
               return -1        
            end
    --ksr edit 2006.2.22
    update jz set 住院科室=brda.住院科室 from brda where jz.住院号=@zyh and jz.入院日期=@InHosDT and brda.住院号 = jz.住院号     if @@error<> 0 
            begin
               set @errmsg = '中途结转信息表更新失败!'
               rollback tran
               return -1        
            end      -- 更新brzz各字段为0
    set @sql = 'update brzz set '+dbo.sjlyzd(71)
    set @sql = @sql+',入院日期='''+CONVERT (char(10),@OutHosDT,120)+''''
          set @sql=  @sql+' where 住院号='''+@zyh+''''+' and 入院日期='''+CONVERT (char(10),@InHosDT,120)+''''
    print @sql
          exec(@sql)
         
      --brda 用一句话就可以了,jzye已经算出了正确的结转数据,即结转后的brda中的预交款的值。
      --   if @ClearYjk = 1 
      --      update brda set 入院日期=@OutHosDT,花费=0,支票预交款=0,现金预交款=0,余额=0,出院=0 where 住院号=@zyh
      --   else
      --计算新花费 分割后的
      SELECT @zhf=ISNULL(SUM(金额),0) FROM mxz WHERE 住院号=@zyh AND 入院日期=@OutHosDT AND 记帐类型<>'交款' and 记帐类型<>'作废'
       update brda set 入院日期=@OutHosDT,花费=@zhf,支票预交款=0,现金预交款=@jzje,出院=0,余额=@jzje where 住院号=@zyh --结转后的滚动费用处理,
    --1.使用动态床位:结算前若有滚动费,结算后有床,必须grgdf和cwxx更新入院日期
    if @dtcw = 1 begin --使用动态床位
    if @BedNo<>'' begin
    update grgdf set 入院日期=@OutHosDT where 住院号=@zyh and 入院日期=@InHosDT
    update cwxx set 入院日期=@OutHosDT where 住院号=@zyh and 入院日期=@InHosDT
    end
    end else begin
    update grgdf set 入院日期=@OutHosDT where 住院号=@zyh and 入院日期=@InHosDT
    end

       commit transaction
       set @errmsg = '出院办理成功'
       return 0GO
    SET QUOTED_IDENTIFIER OFF 
    GO
    SET ANSI_NULLS ON 
    GO
      

  2.   

    单独执行其中的代码
    UPDATE cfy_mx SET 入院日期=@OutHosDT 
               where EXISTS(
                    SELECT 住院号 
                    FROM CFY 
                    WHERE CFY.住院号=cfy_mx.住院号 
                        AND CFY.入院日期=cfy_mx.入院日期
                        AND CFY.明细帐号=cfy_mx.明细帐号
                        AND CFY.日期>=@OutHosDT
                        )提示影响0行