简体   繁体   中英

Insert new records and update existing recordes in SQL Server Stored procedure

i have a stored procedure make inserting a new recordes if these recordes dose not exist in the table and update for the recordes which exist. My problem is: when i exec this procedure every time it's inserting a new record even if this record is already exist and should update it. The only action of the procedure is only insert but no update.

That's the procedure which i talking about,

CREATE PROCEDURE [dbo].[P_Attendance_CheckTime]
@EMP_ID INT = null, /*Employee Source Code*/
@Trns_Typ nvarchar(50) = null,/*Transaction Type('Check In','Check Out')*/
@Trns_TS Datetime = null,/*Transaction Time Stamp*/
@OUT_TS Datetime = null,/*Attendance Out Time Stamp*/
@IN_TS Datetime = null,/*Attendance In Time Stamp*/
@EMP_Srgt  INT = null, /*Employee Surrogate Key INsert it into Var.*/
@Dt_Srgt INT  = null /*Date Surrogate Key INsert it into Var.*/
AS
BEGIN
SET NOCOUNT ON;
if  @Trns_Typ in ('Check In','Check Out') 
begin
SELECT @Emp_Srgt = EMP_Srgt from [dbo].[D_EMPLOYEE] where [EMP_SRC_CD] = @EMP_ID;
SELECT @DT_SRGT =[Dt_Srgt] from d_date where G_DT = replace(convert(varchar(12),@Trns_TS,112),'-','');
SELECT @OUT_TS = [ATND_EMP_OUT_TS], @IN_TS = [ATND_EMP_IN_TS]from [dbo].[F_ATTENDANCE]where [ATND_EMP_SRGT] = @EMP_Srgt and [ATND_DT_SRGT] = @Dt_Srgt;
    IF @@ROWCOUNT = 0 and @Trns_Typ = 'Check In' 
Insert Into [dbo].[F_ATTENDANCE] ([ATND_EMP_SRGT],
[ATND_EMP_IN_TS],[ATND_DT_SRGT],[ATND_CREATED_DATE],[ATND_TIME])
Values (@EMP_Srgt,@Trns_TS,@Dt_Srgt,Getdate(),
(convert(float,replace(left(convert(time,(@OUT_TS- @Trns_TS),103),5),':','.'))));
    ELSE IF @@ROWCOUNT = 0 and @Trns_Typ = 'Check Out' 
Insert Into [dbo].[F_ATTENDANCE] ([ATND_EMP_SRGT],
[ATND_EMP_Out_TS],[ATND_DT_SRGT],[ATND_CREATED_DATE],[ATND_TIME])
Values (@EMP_Srgt,@Trns_TS,@Dt_Srgt,Getdate(),
(convert(float,replace(left(convert(time,(@Trns_TS-@IN_TS ),103),5),':','.'))));
End;

    if (@Trns_Typ = 'Check In' and (@IN_TS is null or @IN_TS > @Trns_TS  )) 
    begin
update [dbo].[F_ATTENDANCE] set [ATND_EMP_IN_TS] = @Trns_TS
,[ATND_TIME]=convert(float,replace(left(convert(time,([ATND_EMP_OUT_TS] - @Trns_TS),103),5),':','.')),[ATND_LAST_MODIFIED_DATE] = getdate()
where [ATND_EMP_SRGT] = @EMP_Srgt and [ATND_DT_SRGT] = @Dt_Srgt;
    end;
   if @Trns_Typ = 'Check Out' and (@OUT_TS is null or @OUT_TS < @Trns_TS ) 
   begin
update [dbo].[F_ATTENDANCE] set [ATND_EMP_OUT_TS] = @Trns_TS
,[ATND_TIME] = convert(float,replace(left(convert(time,(@Trns_TS - [ATND_EMP_IN_TS]),103),5),':','.')),[ATND_LAST_MODIFIED_DATE] = getdate()
where [ATND_EMP_SRGT] = @EMP_Srgt and [ATND_DT_SRGT] = @Dt_Srgt;
   end;

End;

please help me to fix this issue thanks

I'd say it's @@ROWCOUNT a problem.

@@ROWCOUNT is very volatile, it changes after every statement. Save value of @@ROWCOUNT into an int variable immediatelly after the select, and use the variable with subsequent IFs. See the difference here:

create table #t (i int, j char);
insert #t values (1, 'a'), (2, 'b');

declare @m int;
select @m = i from #t where i = 1;
if @@rowcount = 0 
    select '1a';
else if @@rowcount = 0 
    select '1b';

declare @n int;
select @n = i from #t where i = 1;
declare @rc int = @@rowcount;
if @rc = 0 
    select '2a';
else if @rc = 0 
    select '2b';

drop table #t;

In your case something like this:

**declare @rc int;**
if  @Trns_Typ in ('Check In','Check Out') 
begin
SELECT @Emp_Srgt = EMP_Srgt from [dbo].[D_EMPLOYEE] where [EMP_SRC_CD] = @EMP_ID;
SELECT @DT_SRGT =[Dt_Srgt] from d_date where G_DT = replace(convert(varchar(12),@Trns_TS,112),'-','');
SELECT @OUT_TS = [ATND_EMP_OUT_TS], @IN_TS = [ATND_EMP_IN_TS]from [dbo].[F_ATTENDANCE]where [ATND_EMP_SRGT] = @EMP_Srgt and [ATND_DT_SRGT] = @Dt_Srgt;
**set @rc = @@ROWCOUNT;**
    IF **@rc = 0** and @Trns_Typ = 'Check In' 
Insert Into [dbo].[F_ATTENDANCE] ([ATND_EMP_SRGT],
[ATND_EMP_IN_TS],[ATND_DT_SRGT],[ATND_CREATED_DATE],[ATND_TIME])
Values (@EMP_Srgt,@Trns_TS,@Dt_Srgt,Getdate(),
(convert(float,replace(left(convert(time,(@OUT_TS- @Trns_TS),103),5),':','.'))));
    ELSE IF **@rc = 0** and @Trns_Typ = 'Check Out' 
Insert Into [dbo].[F_ATTENDANCE] ([ATND_EMP_SRGT],
[ATND_EMP_Out_TS],[ATND_DT_SRGT],[ATND_CREATED_DATE],[ATND_TIME])
Values (@EMP_Srgt,@Trns_TS,@Dt_Srgt,Getdate(),
(convert(float,replace(left(convert(time,(@Trns_TS-@IN_TS ),103),5),':','.'))));
End;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM