mercredi 30 janvier 2019

How to insert an opposite value(of a previous value of a column) if a condition is met in SQL-Server?

I'm working on an attendance sheet project for a store with 11 employees. Employees will clock in and clock out in their pre-determined times. I have a problem with shifts. I want to find a way for the system to figure out if the last line recorded was in the morning shift, the subsequent line should be in evening shift and vice versa.

The structure of my program is this: I have a button on my program for employees to determine the morning shift or the evening shift with a boolean variable. I have a text box, which when an employeeId/memberId is entered in it and pressed enter, it will process the eligibility of that memberId with a stored procedure with this logic: memberIds who 1. have clockedIn but have not ClockedOut (union with) 2.members who are generally in our tbl_attendanceMembers but have not entered in the attendance sheet are eligible to be entered in the textbox. Store these two in a medium table called tbl_availableMembers.

CREATE PROCEDURE duplicateCheck3

    @inputdate date

    AS

    BEGIN
            DELETE FROM tbl_availableMembers

    Insert into tbl_availableMembers SELECT memberId
                FROM tbl_attendancemembers
                WHERE memberId NOT IN
                (SELECT memberId 
                 FROM tbl_attendanceSheet
                 WHERE DATE = @InputDate)
            UNION
                SELECT memberId from tbl_attendancesheet
                WHERE [date] = @InputDate
                AND [clockin] IS NOT NULL
                AND [clockout] IS NULL
    END

Then in C# I will read the values of tbl_availableMembers everytime a memberId has entered the textbox like this:

SqlCommand sqlcmdread_availablemembers = new SqlCommand("select * from tbl_availablemembers", sqlcon);
                    SqlDataReader sqldr_availablemembers = sqlcmdread_availablemembers.ExecuteReader();
                    while (sqldr_availablemembers.Read())
                    {
                        if (sqldr_availablemembers[1].ToString() == textBoxX1.Text)
                        {
                            member_available = true;
                            break;
                        }
                    }

And if the entered id in the textbox is equal to the ones that are read, it goes through a stored procedure like this:

 CREATE PROCEDURE InputClockStacks
        @QmemberId nvarchar(20),
        @InputName nvarchar(20),
        @DateString nvarchar(100),
        @InputDate date,
        @InputShift Bit,
        @InputTime time(7),
        @EnterDist nvarchar(50),
        @EnterDelay time(7),
        @ExitDist nvarchar(50),
        @ExitDelay time(7)
    AS

    UPDATE [dbo].[tbl_attendanceSheet]
    SET [clockout] = @InputTime, [exitdelay]=@ExitDelay, ExitDist=@ExitDist
    WHERE MemberId = @QmemberId
    AND [date] = @InputDate
    AND [clockin] IS NOT NULL
    AND [clockout] IS NULL

    IF @@ROWCOUNT = 0 
    BEGIN

        INSERT INTO tbl_attendanceSheet(MemberId,name,datestring,date,morning_shift,clockIn,EnterDist,EnterDelay)
        VALUES (@QmemberId,  @InputName,@DateString, @InputDate, @InputShift, @InputTime,@EnterDist,@EnterDelay)

    END

It basically, has the following logic: if the ClockOut column is null and clockIn column is not null it means the employee has to only exit one's workplace so the system should insert the time into ClockOut column. Otherwise, it means that the employee has not even come to work so it should insert a new row with clockIn and ClockOut.

The logic of tbl_availableMembers has a problem. The problem is that if a member has clockedIn and out in the morning shift, the duplicateCheck3 stored procedure will not let him/her to clockIn in the evening shift.

I want to implement a logic like this:

SELECT * FROM tbl_attendanceSheet
WHERE date = @inputDate  // to get all users who have clocked in and(or) out 
                            in the given date or current date.
IF morning_shif is true, only allow him/ her to ClockIn in the evening shift

or this logic: allow every employee to occupy only two rows in the attendance sheet table. one for clocking in and out in the morning shift and one for clocking in and out in the evening shift.

or this logic: find a way for the system to figure out if the last line recorded was in the morning shift, the subsequent line should be in evening shift and vice versa.

At last, I want to thank you all for your remindings of SQL-injection, I will fix it later. and Thank You for your time

My tables:

CREATE TABLE [dbo].[tbl_attendanceSheet] (
    [Id]            INT            IDENTITY (1, 1) NOT NULL,
    [MemberId]      INT            NULL,
    [name]          NVARCHAR (20)  NULL,
    [date]          DATE           NULL,
    [datestring]    NVARCHAR (100) NULL,
    [morning_shift] BIT            NOT NULL,
    [clockin]       TIME (7)       NULL,
    [clockout]      TIME (7)       NULL,
    [HouresWorked]  AS             (CONVERT([time],dateadd(millisecond,datediff(second,[clockin],[clockout])*(1000),(0)))),
    [EnterDist]     NVARCHAR (50)  NULL,
    [EnterDelay]    TIME (7)       NULL,
    [ExitDist]      NVARCHAR (50)  NULL,
    [ExitDelay]     TIME (7)       NULL,
    [desc]          NVARCHAR (150) NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC),
    FOREIGN KEY ([MemberId]) REFERENCES [dbo].[tbl_attendanceMembers] ([memberId])
);

and

CREATE TABLE [dbo].[tbl_attendanceMembers] (
    [memberId]      INT            IDENTITY (101000, 10) NOT NULL,
    [name]          NVARCHAR (20)  NULL,
    [branchId]      INT            NULL,
    [isOpener]      BIT            NULL,
    [cellularphone] NVARCHAR (20)  NULL,
    [exp]           NVARCHAR (100) NULL,
    [address]       NVARCHAR (100) NULL,
    CONSTRAINT [PK_tbl_attendanceMembers] PRIMARY KEY CLUSTERED ([memberId] ASC)
);

and

CREATE TABLE [dbo].[tbl_availableMembers] (
    [Id]       INT IDENTITY (1, 1) NOT NULL,
    [memberId] INT NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC)
);

What I have searched, myself:

Change value in a 2-value column to its opposite only if a condition in another column is met Its different but has a similar Idea But I can't understand the answer he marked as solution.

Is there an elegant way to Invert a Bit value in an SQL insert Statement? It is really good, But I don't know how to implement it.

Thank you for your time.

Aucun commentaire:

Enregistrer un commentaire