Member 12314309 Ответов: 1

Хранимая процедура , случай, когда условие не выполняется


I amupdating INTIme and OUTTime in a table of Employee attendance using Update store Procedure,INTIME and OUTTIME is getting updated in a table ,but further query for calculating Hours and OT,OTAmount and Late which is base on case when condition is not working .


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

<pre>Update EmployeesAttendance 

set  EmployeesAttendance.INTIME=@INTime,
EmployeesAttendance.OUTTIME=@OUTTIME,

 EmployeesAttendance.Hours= ( (DATEDIFF(Hour,OUTTIME,INTIME))),  
  EmployeesAttendance.Days =(  CASE WHEN  EmployeesAttendance.Hours >= EmployeeDetails.Dhour THEN 1
    WHEN  EmployeesAttendance.Hours = 0 THEN 0
    WHEN  EmployeesAttendance.Hours >= 6 THEN 0.5 end),
    EmployeesAttendance.OT=(CASE WHEN  EmployeesAttendance.Hours > EmployeeDetails.Dhour then  
    EmployeesAttendance.Hours - EmployeeDetails.Dhour else 0 End),
    EmployeesAttendance.OTAmount =(CASE when EmployeeDetails.OTEntitled = 'Yes' 
     AND EmployeesAttendance .Hours >= EmployeeDetails.Dhour 
THEN (( EmployeesAttendance.Hours - EmployeeDetails.Dhour) * 100) else 0 END ),   
   EmployeesAttendance.Time=( Convert(varchar(10),EmployeesAttendance.INTIME,108)),
   EmployeesAttendance.Late=(Case When Convert(Time, EmployeesAttendance .INTIME,108) > EmployeeDetails.LTime Then 1 else 0
    end)    
    From  EmployeeDetails 
		INNER Join EmployeesAttendance ON EmployeeDetails.EmpId = EmployeesAttendance.EmpID
  --  Order by EmployeeDetails.EmpID asc 
    where EmployeesAttendance.AttIDS=@AttIDS
end

MadMyche

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

1 Ответов

Рейтинг:
8

Wendelius

Есть несколько вещей, которые могли бы вам помочь.


  • Используйте CTE для запроса данных для обновления и использования этой таблицы в UPDATE заявление. Другими словами, создайте запрос, который возвращает данные, которые вы собираетесь использовать в качестве исходных данных. Что-то вроде следующего псевдо-примера
    ;WITH SourceQuery (OutTime, InTime, Hours, Days)
      SELECT ....
      FROM EmployeesAttendance ea, EmployeeDetails ed
      WHERE ...
    )
    UPDATE ea
        SET Hours = sq.Hours, ...
    FROM EmployeesAttendance ea, SourceQuery  sq
    WHERE ...

    Такая структура позволяет легко увидеть, какие значения будут введены в систему. SET клаузула Ан UPDATE заявление



  • Столбец часов, зачем вычислять его в таблице. Было бы гораздо надежнее и проще, если бы вы использовали вычисляемый столбец[^] Что-то вроде
    ALTER TABLE EmployeesAttendance 
       ADD Hours AS DATEDIFF(Hour, OUTTIME, INTIME)



  • Значения во время выполнения обновления, если я правильно понимаю ваши намерения, вы пытаетесь использовать промежуточные результаты вычислений в своем заявлении. Глядя на следующую часть
    ...
    EmployeesAttendance.Hours= ( (DATEDIFF(Hour,OUTTIME,INTIME))),  
      EmployeesAttendance.Days =(  CASE WHEN  EmployeesAttendance.Hours >= EmployeeDetails.Dhour THEN 1
    ...

    Когда оператор выполняется, столбец EmployeesAttendance.Hours содержит исходное значение до тех пор, пока оператор не будет завершен. Даже если вы вычисляете Hours в предыдущей части, во время выполнения, значения столбцов являются исходными значениями, А не промежуточными результатами. Я думаю, что именно поэтому вы говорите, что CASE структура не работает



  • То же самое относится и к переменным. Глядя на следующую часть
    ...
    set  EmployeesAttendance.INTIME=@INTime,
         EmployeesAttendance.OUTTIME=@OUTTIME,
         EmployeesAttendance.Hours= ( (DATEDIFF(Hour,OUTTIME,INTIME))),
    ...

    Даже если вы присвоили значения из переменных, вычисление для столбца Hours это будет сделано с использованием исходных значений из записи, а не с использованием вновь назначенных значений. Поэтому, если вы хотите использовать новые значения, вам следует написать
    ...
    set  EmployeesAttendance.INTIME=@INTime,
         EmployeesAttendance.OUTTIME=@OUTTIME,
         EmployeesAttendance.Hours= ( (DATEDIFF(Hour,@OUTTIME,@INTime))),
    ...

    Но опять же, использование CTE в качестве основы для операции обновления упростило бы ситуацию.


Member 12314309

Wndelius ,я использовал cte, но он просто вводил INTIME и OUTTIME и больше ничего не делал...получите много путаницы об этом ,,,мольбы обзор ниже кода SP

Изменить процедуру [dbo].[GetMachineAttendanceFinal7]
@INTIME Datetime,
@OUTTIME Datetime,
@AttIDS int
АС

НАЧАТЬ

УСТАНОВИТЕ NOCOUNT ON;


--;С датами (ReportingDate)
--КАК (
-- Выберите конвертировать(дата, '2018-11-26 00:00:00.000', 120) как отчетная дата
-- СОЮЗ ВСЕХ
-- Выберите DATEADD(day, 1, d.ReportingDate)
-- От даты d
-- Куда.ReportingDate &ЛТ; преобразование(дата, '2018-12-25 00:00:00.000', 120))

;С CTE в качестве
(
выберите EmployeeDetails.EmpID,EmployeeDetails.EmpName,EmployeeDetails.Без Названия,EmployeeDetails.Empcur,EmployeeDetails.Дхур,Наемные Работники.LTime from EmployeeDetails where Empcur='Join'
),
Еатт
Как
(
Выберите EmployeesAttendance.AttIDS,EmployeesAttendance.Отчетная Дата,Штат Сотрудников.Дата,Штат Сотрудников.Дни,Служащие На Службе.Empid В,EmployeesAttendance.Часы Работы,Штат Сотрудников.Интайм,служащие на месте.Внеурочное время,сотрудники работают.Опаздываю,Служащие Уходят.Время,Сотрудники, Внимание.OTAmount От EmployeesAttendance
)
,cte2
как

(
Выберите EAtt.AttIDS,EATT.ReportingDate,EATT.Дата,EATT.Days,EATT.EmpID,
Еатт.Часов,EATT.ИНТАЙМ,ИАТТ.OUTTIME,EATT.Поздно,ИАТТ.Время,ЭАТТ.Отамаунт

ОТ EATT

),
cteFinal как (
выберите cte.EmpID,cte2.ReportingDate,cte2.Date,cte2.Интайм,cte2.OUTTIME,

DATEDIFF(Hour, @INTIME, @OUTTIME) как [часы]
, Случай, когда cte2.[Часы] >= 8, затем 1
Когда cte2.[Часы] = 0, затем 0
Когда cte2.[Часы] >= 6, затем 0,5 заканчиваются как [Дни],
Случай, когда cte2.[Часы] > CTE.Дхур, затем cte2.[Часы] - CTE.Дхур, иначе 0 конец как от,
Случай когда
КТОС.OTEntitled = 'Yes' и cte2.[Часы] >= CTE.Дхур
Затем (( cte2.[Часы] - 8) * 100) else 0 END AS OTAMount,
Convert(varchar(10), cte2.INTIME,108) как [время],
Случай, когда преобразование(время, cte2.INTIME,108) > cte.LTime тогда 1 еще 0 конец как поздно
от cte
Левое соединение cte2 на cte2.EmpId= cte.EmpID
)
Обновление cte2
Установите cte2.INTIME = @INTIME,
cte2.OUTTIME=@OUTTIME,
cte2.Часы=Часы
где именно cte2.AttIDS=@AttIDS

Wendelius

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

Рассмотреть следующее

WITH cte2 (.....)
UPDATE ea
SET InTime = c.InTime,
    Hours = c.Hours,
    ...
FROM EmployeeAttendance ea, cte2 c
WHERE ea.EmpID = c.EmpID

Member 12314309

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

Wendelius

Всегда пожалуйста!