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 BackFillNetwork Hours,
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.WeekProfileI D
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/fff4ef21e9964ab 8/f5ce136923ebffc 3?q=teddysnips& rnum=1&hl=en#f5 ce136923ebffc3>
The Stored Procedure that causes the error is here:
--*************** *************** *************** *************** *
CREATE PROCEDURE BackFillNetwork Hours
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.Duration Mins) 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 @TimesheetStrin g varchar(50)
DECLARE @Duration int
DECLARE @RequiredDurati on int
-- Set the correct date to 08:30 - by default the cast from the
cursor's select statement is midday
SET @TimesheetStrin g = @TimesheetDate + ' 08:30'
SET @NewWorkTime = CAST(@Timesheet String AS Datetime)
-- Need to find out how many hours the employee is scheduled to work
that day.
SET @RequiredDurati on = 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 < @RequiredDurati on
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 = @RequiredDurati on - @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
message. The Stored Procedure runs correctly about 1550 times, but
receive the following error three times:
Server: Msg 512, Level 16, State 1, Procedure BackFillNetwork Hours,
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.WeekProfileI D
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/fff4ef21e9964ab 8/f5ce136923ebffc 3?q=teddysnips& rnum=1&hl=en#f5 ce136923ebffc3>
The Stored Procedure that causes the error is here:
--*************** *************** *************** *************** *
CREATE PROCEDURE BackFillNetwork Hours
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.Duration Mins) 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 @TimesheetStrin g varchar(50)
DECLARE @Duration int
DECLARE @RequiredDurati on int
-- Set the correct date to 08:30 - by default the cast from the
cursor's select statement is midday
SET @TimesheetStrin g = @TimesheetDate + ' 08:30'
SET @NewWorkTime = CAST(@Timesheet String AS Datetime)
-- Need to find out how many hours the employee is scheduled to work
that day.
SET @RequiredDurati on = 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 < @RequiredDurati on
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 = @RequiredDurati on - @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
Comment