NanaKwame Ответов: 1

Sql insert с помощью курсора для


Please i need help to resolve my cursor script. I have used the same cursor script several times and is working fine. But i do not understand this one why is not working this time. I want sum individual overtime within the period the user will provide and insert it into a new table. I have to multiply overtime by salary per hour rate from a different table. I have not added the function part of the code to sum the overtime value because is working and even if comment that part the rest of the code is not able to insert into the table and i do not get any error message. Below is the script. I be grateful to get help. Thanks in advance.

Что я уже пробовал:

Именно это я и пытался сделать.
--Tables
Create Table EmployeeAttendanceRecords
(
       EmployeeID	     VarChar(10)Not Null,
       EmployeeName          VarChar(50)Not Null,
       OverTime              SmallInt,
       WorkingDate           DateTime
)

Create Table EmployeeDetails
(
    EmployeeID        VarChar(10),
    EmployeeName      VarChar(10),
    SalaryPerHour     Money
)

Create Table TestOverTime
(
	EmployeeID		VarChar(10)Not Null,
	EmployeeName		VarChar(50)Not Null,
	OverTime		Money
)

--Sample Data For Test
EMP001,John,1,01 JAN 2020
EMP002,Linda,1,01 JAN 2020
EMP003,Mark,2,01 JAN 2020

EMP001,John,1,02 JAN 2020
EMP002,Linda,2,02 JAN 2020
EMP003,Mark,1,02 JAN 2020

EMP001,John,1,03 JAN 2020
EMP002,Linda,1,03 JAN 2020
EMP003,Mark,1,03 JAN 2020

--Salary Per Hour
John  = 30
Linda = 25
Mark  = 27


--Stored Produre
Create Proc prcTestOverTime
(
        @StartDate		DateTime,
	@EndDate		DateTime
)
As
Begin
	Declare @OverTimeAmount		SmallInt,
		@EmployeeID		VarChar(10)

Begin
	Declare Cur Cursor For
		
	Select EmployeeID From EmployeeDetails
	Where EmployeeID = @EmployeeID
		
Open Cur
Fetch Next From Cur Into @EmployeeID
While @@Fetch_Status = 0
Begin
Select @OverTimeAmount = dbo.fnTestCalculateOverTime(@EmployeeID,@StartDate,@EndDate)
			
	Insert Into TestOverTime

	Select EmployeeID,
		EmployeeName,
		@OverTimeAmount
	From EmployeeAttendanceRecords
	Where EmployeeID = @EmployeeID
        And WorkingDate Between @StartDate And @EndDate

	Fetch Next From Cur Into @EmployeeID
End
Close Cur
Deallocate Cur;
End
End

1 Ответов

Рейтинг:
7

Maciej Los

Взгляните на приведенный ниже пример:

DECLARE @EmployeeAttendanceRecords Table (EmployeeID VarChar(10)Not Null, EmployeeName VarChar(50)Not Null, OverTime SmallInt, WorkingDate DateTime)
DECLARE @EmployeeDetails Table (EmployeeID VarChar(10), EmployeeName VarChar(10), SalaryPerHour Money)

--Sample Data For Test
INSERT INTO @EmployeeAttendanceRecords(EmployeeID, EmployeeName, OverTime, WorkingDate)
VALUES('EMP001' , 'John',1 ,'2020-01-01'),
('EMP002' , 'Linda', 1 ,'2020-01-01'),
('EMP003' , 'Mark', 2 ,'2020-01-01'),
('EMP001' , 'John', 1 ,'2020-01-02'),
('EMP002' , 'Linda', 2 ,'2020-01-02'),
('EMP003' , 'Mark', 1 ,'2020-01-02'),
('EMP001' , 'John', 1 ,'2020-01-03'),
('EMP002' , 'Linda', 1 ,'2020-01-03'),
('EMP003' , 'Mark', 1 ,'2020-01-03')


INSERT INTO @EmployeeDetails(EmployeeID, EmployeeName, SalaryPerHour)
VALUES('EMP001' , 'John', 30),
('EMP002' , 'Linda', 25),
('EMP003' , 'Mark', 27)


SELECT ear.EmployeeID, ear.EmployeeName, ear.TotalOT * ed.SalaryPerHour AS TotalSalary
	--, ear.WorkingMonth
FROM (
	SELECT EmployeeID, EmployeeName
	--, CONVERT(DATE, DATEADD(DD, -DAY(WorkingDate), WorkingDate) +1) WorkingMonth
	, SUM(OverTime) TotalOT 
	FROM @EmployeeAttendanceRecords 
	GROUP BY EmployeeID, EmployeeName
	--, DATEADD(DD, -DAY(WorkingDate), WorkingDate) +1
	--INFO: uncomment above lines to get mothly salary
) ear INNER JOIN @EmployeeDetails ed ON ear.EmployeeID = ed.EmployeeID


То, что я пытаюсь сказать: вам не нужен курсор для такого требования. Теперь вы можете просто использовать INSERT INTO заявление вместе с SELECT.

[РЕДАКТИРОВАТЬ]

Цитата:
Я все еще сталкиваюсь с некоторыми проблемами при расчете заработной платы в час. В первых значениях, которые я использовал в коде, были, например, цели. Например, у вас может быть 5000 в качестве базовой зарплаты в месяц, и мне нужно значение в час для этой цифры, чтобы решить проблему сверхурочных.


В этом случае EmployeeDetails таблица должна ссылаться на другую таблицу, которая содержит информацию о том, сколько часов необходимо для ежедневной или ежемесячной зарплаты.
Видеть:
DECLARE @EmployeeAttendanceRecords Table (EmployeeID VarChar(10)Not Null, EmployeeName VarChar(50)Not Null, OverTime SmallInt, WorkingDate DateTime)
DECLARE @EmployeeDetails Table (EmployeeID VarChar(10), EmployeeName VarChar(10), Salary Money, EwtID INT)
DECLARE @ExpectedWorkingTime TABLE(EwtID INT IDENTITY(1,1), EwtDescription VARCHAR(150), EwtHours INT)

--helper table!
INSERT INTO @ExpectedWorkingTime (EwtDescription, EwtHours)
VALUES('Hour', 1), ('Daily', 8), ('Monthly', 28*8)
--if employee salary is per hour divide it by 1
--if employee salary is daily divide it by 8
--if employee salary is monthly divide it by 28*8

--Sample Data For Test
INSERT INTO @EmployeeAttendanceRecords(EmployeeID, EmployeeName, OverTime, WorkingDate)
VALUES('EMP001' , 'John',1 ,'2020-01-01'),
('EMP002' , 'Linda', 1 ,'2020-01-01'),
('EMP003' , 'Mark', 2 ,'2020-01-01'),
('EMP001' , 'John', 1 ,'2020-01-02'),
('EMP002' , 'Linda', 2 ,'2020-01-02'),
('EMP003' , 'Mark', 1 ,'2020-01-02'),
('EMP001' , 'John', 1 ,'2020-01-03'),
('EMP002' , 'Linda', 1 ,'2020-01-03'),
('EMP003' , 'Mark', 1 ,'2020-01-03')


INSERT INTO @EmployeeDetails(EmployeeID, EmployeeName, Salary, EwtID)
VALUES('EMP001' , 'John', 6720, 3),
('EMP002' , 'Linda', 200, 2),
('EMP003' , 'Mark', 27, 1)


SELECT ear.EmployeeID, ear.EmployeeName 
	--, ed.Salary, ewt.EwtDescription , ear.TotalOT , ewt.EwtHours
	, ear.TotalOT * (ed.Salary / ewt.EwtHours) AS TotalSalary
	--, ear.WorkingMonth
FROM (
	SELECT EmployeeID, EmployeeName
	--, CONVERT(DATE, DATEADD(DD, -DAY(WorkingDate), WorkingDate) +1) WorkingMonth
	, SUM(OverTime) TotalOT 
	FROM @EmployeeAttendanceRecords 
	GROUP BY EmployeeID, EmployeeName
	--, DATEADD(DD, -DAY(WorkingDate), WorkingDate) +1
	--INFO: uncomment above lines to get mothly salary
) ear INNER JOIN @EmployeeDetails ed ON ear.EmployeeID = ed.EmployeeID
	INNER JOIN @ExpectedWorkingTime ewt ON ed.EwtID = ewt.EwtID

Результат:
EmployeeID	EmployeeName	TotalSalary
EMP001	John	90,00
EMP002	Linda	100,00
EMP003	Mark	108,00


NanaKwame

Спасибо @Maciej Los за поддержку и очень благодарен за это. Я все еще сталкиваюсь с некоторыми проблемами при расчете заработной платы в час. В первых значениях, которые я использовал в коде, были, например, цели. Например, у вас может быть 5000 в качестве базовой зарплаты в месяц, и мне нужно значение в час для этой цифры, чтобы решить проблему сверхурочных. Я создал функцию, которая работает, но поскольку курсор не работает, я должен найти другой способ решения этой проблемы. И это то, что я сделал, но как бы застрял в данный момент.

Объявите Таблицу @BasicSalaryDetails (EmployeeID VarChar(10),EmployeeName VarChar(50),BasicSalary Money)
Объявить Таблицу @MonthDays (MonthlyWorkingDays SmallInt)
Объявить Таблицу @DailyWorkingHours (ExpectedDailyWorkingHours SmallInt)

--Примеры данных для работы с ними
--Количество дней в месяце
MonthlyWorkingDays = 28

--Часы в течение дня
ExpectedDailyWorkingHours = 8

вставить в t_tmpEmployeeBasicSalary

Выберите MonthlyWorkingDays из MonthDays ma Union
Выберите da.ExpectedDailyWorkingHours * ma.MonthlyWorkingDays как MonthlyTotalHours из DailyWorkingHours da Union
(Выберите EmployeeID,EmployeeName,(BasicSalary/MonthlyTotalHours) Как BasicSalaryPerHour от EmployeeDetails da
Группировка По Полю "Кодсотрудника", EmployeeName)

После получения точного значения в час я могу использовать решение, которое вы мне предоставили. Спасибо.

Maciej Los

Существует ли какой-либо тег, который используется для определения месячной/ежедневной/часовой зарплаты для конкретного сотрудника?

NanaKwame

Нет, сэр, у меня нет никакой бирки для конкретного сотрудника. Если вы считаете, что это важно, пожалуйста, любезно направьте меня на это. Спасибо, что были здесь для меня.

Maciej Los

Пожалуйста, смотрите обновленный ответ.

Maciej Los

См. обновленный ответ.

NanaKwame

@Мачей Лос. Пожалуйста, дополнительный столбец EwtID, который вы добавили в таблицу EmployeeDetails, я хочу знать, является ли это столбцом идентификации или чем-то еще. Потому что я хочу реализовать этот код в своем проекте, но его не было в таблице EMPLOYEEDETAILS. Спасибо.

NanaKwame

Мацей Лос. Пожалуйста, дополнительный столбец EwtID, который вы добавили в таблицу EmployeeDetails, я хочу знать, является ли это столбцом идентификации или чем-то еще. Потому что я хочу реализовать этот код в своем проекте, но его не было в таблице EMPLOYEEDETAILS. Спасибо.

Maciej Los

Нет. Этот столбец имеет тип int. Внимательно посмотрите на мой ответ (объявление таблицы@EmployeeDetails).

NanaKwame

Пожалуйста, посмотрите на эту строку кода: INNER JOIN @ExpectedWorkingTime ewt ON ed.EwtID = ewt.EwtID вы можете видеть, что существует связь между таблицами EmployeeDetails и ExpectedWorkingTime для столбца EwtID. Итак, в образце данных для тестирования EmployeeDetails вы добавили эти данные столбца, а для ExpectedWorkingTime они были сгенерированы столбцом identity, и именно здесь я запутываюсь. Вставить в @EmployeeDetails(EmployeeID, EmployeeName, зарплата, EwtID)
Значения('EMP001' , 'John', 6720, 3),
('EMP002' , 'Linda', 200, 2),
('EMP003' , 'Mark', 27, 1)
Спасибо.

Maciej Los

Простите, но чего вы от меня ждете? Я бы посоветовал удалить ваш адрес электронной почты из-за спам-роботов.

NanaKwame

Мои проблемы-это новый столбец EwtID INT в таблице EmployeeDetails, потому что изначально он не был частью таблицы, и вы добавили его для достижения результата и очень цените его. Таблица уже имеет EmployeeID в качестве первичного ключа, поэтому добавление EwtID снова-это то, что я хочу понять. Спасибо.

Maciej Los

ОК. Как вы можете видеть, EwtID используется для хранения отношений с таблицей @ExpectedWorkingTime. EwtID-это первичный ключ для этой таблицы. Исходя из этого значения, я выбираю единицу времени (час, минута, месяц), чтобы умножить зарплату. Если зарплата в час, то умножьте на 1. Если это ежедневная зарплата, то умножьте на 8, если ежемесячно, то 28 дней * 8 часов каждый день.
Теперь это более ясно?

NanaKwame

Хорошо, спасибо, сэр. Я постараюсь обойти это и посмотреть.

Maciej Los

Удачи вам!