sql server (alternate):
I am attempting to execute the Stored Procedure at the foot of this
message. The Stored Procedure runs correctly about 1550 times, but
receive the following error three times:
Server: Msg 512, Level 16, State 1, Procedure BackFillNetworkHours,
Line 68
Subquery returned more than 1 value. This is not permitted when the
subquery follows =, !=, <, <= , >, >= or when the subquery is used as
an expression.
I've done some digging, and the error message is moderately
self-explanatory.
The problem is that there is no Line 68 in the Stored Procedure. It's
the comment line:
-- Need to find out how many hours the employee is scheduled etc.
Also, there are no duplicate records in the Employee table nor the
WeeklyProfile table. At least I assume so - if the following SQL to
detect duplicates is correct!
SELECT E.*
FROM
Employee E
join
(select EmployeeID
from
Employee
Group by EmployeeID
having count(*) > 1) as E2
On
(E.EmployeeID = E2.EmployeeID)
SELECT
W.*
FROM
WeekProfile W
join
(Select
WeekProfileID
FROM
WeekProfile
GROUP BY
EmployeeID, MondayHours, WeekProfileID
HAVING COUNT(*) > 1) AS W2
ON
W.WeekProfileID = W2.WeekProfileID
NOTE: In the second statement, I have tried for MondayHours thru
FridayHours.
Anyone got any ideas? The TableDefs are set up in this thread:
<
http://groups-beta.google.com/group/comp.databases.ms-sqlserver/browse_frm/thread/fff4ef21e9964ab8/f5ce136923ebffc3?q=teddysnips&rnum=1&hl=en#f5ce136923ebffc3>
The Stored Procedure that causes the error is here:
--*************************************************************
CREATE PROCEDURE BackFillNetworkHours
AS
DECLARE @EmployeeID int
DECLARE @TimesheetDate DateTime
DECLARE @NumMinutes int
DECLARE @NetworkCode int
-- Get the WorkID corresponding to Project Code 2002
SELECT
@NetworkCode = WorkID
FROM
[Work]
WHERE
(WorkCode = '2002')
-- Open a cursor on a SELECT for all Network Support Employees where
any single workday comprises fewer than 7.5 hours
DECLARE TooFewHours CURSOR FOR
SELECT
EmployeeID,
CONVERT(CHAR(8), Start, 112) AS TimesheetDate,
SUM(NumMins) AS TotalMins
FROM
(SELECT
TI.EmployeeID,
W.WorkCode,
TI.Start AS Start,
SUM(TI.DurationMins) AS NumMins
FROM
TimesheetItem TI LEFT JOIN
[Work] W ON TI.WorkID = W.WorkID
WHERE EXISTS
(SELECT
*
FROM
Employee E
WHERE
((TI.EmployeeID = E.EmployeeID) AND
(E.DepartmentID = 2)))
GROUP BY TI.EmployeeID, TI.Start, W.WorkCode) AS x
GROUP BY
EmployeeID,
CONVERT(char(8), Start, 112)
HAVING
SUM(NumMins) < 450
ORDER BY
EmployeeID,
CONVERT(CHAR(8), Start, 112)
-- Get the EmployeeID, Date and Number of Minutes from the cursor
OPEN TooFewHours
FETCH NEXT FROM TooFewHours INTO @EmployeeID, @TimesheetDate,
@NumMinutes
WHILE (@@FETCH_STATUS=0)
BEGIN
DECLARE @NewWorkTime datetime
DECLARE @TimesheetString varchar(50)
DECLARE @Duration int
DECLARE @RequiredDuration int
-- Set the correct date to 08:30 - by default the cast from the
cursor's select statement is midday
SET @TimesheetString = @TimesheetDate + ' 08:30'
SET @NewWorkTime = CAST(@TimesheetString AS Datetime)
-- Need to find out how many hours the employee is scheduled to work
that day.
SET @RequiredDuration = CASE (DATEPART(dw, @NewWorkTime))
WHEN 1 THEN
(SELECT CAST((60 * SundayHours) AS int) FROM WeekProfile WHERE
(EmployeeID = @EmployeeID))
WHEN 2 THEN
(SELECT CAST((60 * MondayHours) AS int) FROM WeekProfile WHERE
(EmployeeID = @EmployeeID))
WHEN 3 THEN
(SELECT CAST((60 * TuesdayHours) AS int) FROM WeekProfile WHERE
(EmployeeID = @EmployeeID))
WHEN 4 THEN
(SELECT CAST((60 * WednesdayHours) AS int) FROM WeekProfile WHERE
(EmployeeID = @EmployeeID))
WHEN 5 THEN
(SELECT CAST((60 * ThursdayHours) AS int) FROM WeekProfile WHERE
(EmployeeID = @EmployeeID))
WHEN 6 THEN
(SELECT CAST((60 * FridayHours) AS int) FROM WeekProfile WHERE
(EmployeeID = @EmployeeID))
WHEN 7 THEN
(SELECT CAST((60 * SaturdayHours) AS int) FROM WeekProfile WHERE
(EmployeeID = @EmployeeID))
END
IF @NumMinutes < @RequiredDuration
BEGIN
-- Set the Start for the dummy work block to 08:30 + the number of
minutes the employee has already worked that day
SET @NewWorkTime = DateAdd(minute, @NumMinutes, @NewWorkTime)
-- Set the duration for the dummy work block to be required duration
less the amount they've already worked
SET @Duration = @RequiredDuration - @NumMinutes
-- Now we have the correct data - insert into table.
INSERT INTO TimesheetItem
(EmployeeID,
Start,
DurationMins,
WorkID)
VALUES
(@EmployeeID,
@NewWorkTime,
@Duration,
@NetworkCode)
END
FETCH NEXT FROM TooFewHours INTO @EmployeeID, @TimesheetDate,
@NumMinutes
END
CLOSE TooFewHours
DEALLOCATE TooFewHours
GO
--*************************************************************
Thanks
Edward