Use INSERT within CASE statement in MSSQL - sql-server

I'm using MSSQL. Below is my sql code
DECLARE #CoursesAboutToExpire TABLE (CourseID BIGINT, ExpiryDate DATE, IsApplicableToAllInternalUser BIT)
INSERT INTO #CoursesAboutToExpire
SELECT CourseID, ExpiryDate, IsApplicableToAllInternalUser
FROM CMS_CoursesMaster CM
DECLARE #ApplicableUsersWithCourse TABLE (UserID BIGINT, CourseID BIGINT)
SELECT 1 ,
(CASE WHEN CAE.IsApplicableToAllInternalUser = 1
THEN (INSERT INTO #ApplicableUsersWithCourse SELECT UM.UserID, CAE.CourseID FROM TRC_UserMaster UM)
ELSE (INSERT INTO #ApplicableUsersWithCourse SELECT CAP.UserID, CAP.CourseID FROM CMS_CourseApplicabilityParameters CAP WHERE CAP.CourseID=CAE.CourseID)
) AS 2
FROM #CoursesAboutToExpire CAE
I'm trying to insert records on the basis *IsApplicableToAllInternalUser * column value using case statement. but it gives error.

Now you can just replace the CASE statement you are trying to execute, with the following INSERT INTO .. SELECT statements:
DECLARE #ApplicableUsersWithCourse TABLE (UserID BIGINT, CourseID BIGINT)
INSERT INTO #ApplicableUsersWithCourse
SELECT UM.UserID, CAE.CourseID
FROM TRC_UserMaster UM JOIN #CoursesAboutToExpire CAE ON UM.CourseID = CAE.CourseID
WHERE CAE.IsApplicableToAllInternalUser = 1
INSERT INTO #ApplicableUsersWithCourse
SELECT CAP.UserID, CAP.CourseID
FROM CMS_CourseApplicabilityParameters CAP JOIN #CoursesAboutToExpire CAE ON CAP.CourseID=CAE.CourseID
WHERE CAE.IsApplicableToAllInternalUser = 0
You can initially test the records you are going to insert by just executing the SELECT statements first. If it looks OK, you can insert the records.
This can also be written as follows:
INSERT INTO #ApplicableUsersWithCourse
SELECT UM.UserID, CAE.CourseID
FROM TRC_UserMaster UM JOIN #CoursesAboutToExpire CAE ON UM.CourseID = CAE.CourseID
WHERE CAE.IsApplicableToAllInternalUser = 1
UNION ALL
SELECT CAP.UserID, CAP.CourseID
FROM CMS_CourseApplicabilityParameters CAP JOIN #CoursesAboutToExpire CAE ON CAP.CourseID=CAE.CourseID
WHERE CAE.IsApplicableToAllInternalUser = 0

Below code worked for me.
DECLARE #CoursesAboutToExpire TABLE (CourseID BIGINT, ExpiryDate DATE, IsApplicableToAllInternalUser BIT)
INSERT INTO #CoursesAboutToExpire
SELECT CourseID, ExpiryDate, IsApplicableToAllInternalUser FROM CMS_CoursesMaster CM
DECLARE #ApplicableUsersWithCourse TABLE (UserID BIGINT, CourseID BIGINT)
INSERT INTO #ApplicableUsersWithCourse
SELECT UM.UserID, CAE.CourseID FROM TRC_UserMaster UM
CROSS JOIN #CoursesAboutToExpire CAE
WHERE CAE.IsApplicableToAllInternalUser = 1)
INSERT INTO #ApplicableUsersWithCourse
SELECT CAP.UserID, CAP.CourseID FROM CMS_CourseApplicabilityParameters CAP
INNER JOIN #CoursesAboutToExpire CAE ON CAP.CourseID=CAE.CourseID
WHERE CAE.IsApplicableToAllInternalUser = 0

Related

Column name or number of supplied values does not match table definition in a stored procedure

I'm trying to execute this stored procedure, the query throws an error:
Column name or number of supplied value does not match table definition.
What I would like to get from this stored procedure is one line of all columns.
Please help to solve the error.
ALTER PROCEDURE `uspx_MUL_Status`
#OrderNumber VARCHAR(20),
#SelectQty BIT,
#SelectDate DATE,
#oKey INT
AS
BEGIN
CREATE TABLE #TempStatus
(
OrderNum VARCHAR (20),
`QtéCom` SMALLINT,
`DateCom` DATE,
`QtéSelec` SMALLINT,
`DateSelec` DATE,
`QtéProd` SMALLINT,
DateProd DATE
)
INSERT INTO #TempStatus
-- Quantité commandée--
SELECT OrderNumber, SUM(`od.Quantity`), MAX(CreateDate)
FROM OrderDetail `od`
JOIN Orders o ON od.oKey =o.oKey
WHERE OrderNumber = #OrderNumber
GROUP BY CreateDate, OrderNumber
-- Quantité sélectionnée--
SET #SelectQty = 0
SET #SelectDate = NULL
SELECT #SelectQty = SUM(`sd.Quantity`), #SelectDate = MAX(`ReleaseDate`)
FROM ScheduleDetail `sd`
JOIN Orders o ON o.oKey =`sd.oKey`
JOIN Schedules s ON `sd.SchedID` = `s.SchedID` AND o.LocationID = s.LocationID
WHERE o.oKey = #oKey
GROUP BY ReleaseDate
UPDATE #TempStatus
SET `QtéSelec` = #SelectQty, `DateSelec` = #SelectDate
-- Quantité produite--
SET #SelectQty = 0
SET #SelectDate = NULL
SELECT
#SelectQty = SUM(`od.CompleteQuantity`),
#SelectDate = MAX(`o.CompleteDate`)
FROM OrderDetail `od`
JOIN Orders o ON o.oKey = od.oKey
WHERE o.oKey = #oKey
GROUP BY CompleteDate
UPDATE #TempStatus
SET `QtéProd` = #SelectQty, `DateProd` = #SelectDate
SELECT * FROM #TempStatus
END
EXEC `uspx_MUL_Status` #OrderNumber='TC19227', #SelectQty=0, #SelectDate=NULL, #oKey=42334
Specify the columns on this line:
INSERT INTO #TempStatus
Like this:
INSERT INTO #TempStatus (Column1, Column2, Column3, etc)

Avoid referring table two times in the WHERE clause

Following is a simplified version of my database in SQL Server 2005. I need to select employees based on business units. Each employee has home department, parent department and visiting department. Based on the department, business unit can be found out.
For an employee, if the HomeDeptID = ParentDeptID, then
#SearchBusinessUnitCD should be present for the VisitingDeptID.
If HomeDeptID <> ParentDeptID, then #SearchBusinessUnitCD should be
present for the ParentDeptID.
Following query works fine. But it has scan on the #DepartmentBusinesses table two times. Is there a way to use the table #DepartmentBusinesses only once by making it as a CASE statement or similar?
DECLARE #SearchBusinessUnitCD CHAR(3)
SET #SearchBusinessUnitCD = 'B'
--IF HomeDeptID = ParentDeptID, then #SearchBusinessUnitCD should be present for the VisitingDeptID
--IF HomeDeptID <> ParentDeptID, then #SearchBusinessUnitCD should be present for the ParentDeptID
CREATE TABLE #DepartmentBusinesses (DeptID INT, BusinessUnitCD CHAR(3))
INSERT INTO #DepartmentBusinesses
SELECT 1, 'A' UNION ALL
SELECT 2, 'B'
CREATE NONCLUSTERED INDEX IX_DepartmentBusinesses_DeptIDBusinessUnitCD ON #DepartmentBusinesses (DeptID,BusinessUnitCD)
DECLARE #Employees TABLE (EmpID INT, HomeDeptID INT, ParentDeptID INT, VisitingDeptID INT)
INSERT INTO #Employees
SELECT 1, 1, 1, 2 UNION ALL
SELECT 2, 2, 1, 3
SELECT *
FROM #Employees
WHERE
(
HomeDeptID = ParentDeptID
AND
EXISTS (
SELECT 1
FROM #DepartmentBusinesses
WHERE DeptID = VisitingDeptID
AND BusinessUnitCD = #SearchBusinessUnitCD)
)
OR
(
HomeDeptID <> ParentDeptID
AND
EXISTS (
SELECT 1
FROM #DepartmentBusinesses
WHERE DeptID = ParentDeptID
AND BusinessUnitCD = #SearchBusinessUnitCD
)
)
DROP TABLE #DepartmentBusinesses
Plan
SELECT *
FROM #Employees e
WHERE EXISTS (
SELECT 1
FROM #DepartmentBusinesses t
WHERE t.BusinessUnitCD = #SearchBusinessUnitCD
AND (
(e.HomeDeptID = e.ParentDeptID AND t.DeptID = e.VisitingDeptID)
OR
(e.HomeDeptID != e.ParentDeptID AND t.DeptID = e.ParentDeptID)
)
)
You can give this a try:
SELECT e.*
FROM #Employees AS e
INNER JOIN #DepartmentBusinesses AS d
ON (d.DeptID = e.VisitingDeptID AND e.HomeDeptID = e.ParentDeptID) OR
(d.DeptID = e.ParentDeptID AND e.HomeDeptID <> e.ParentDeptID)
WHERE d.BusinessUnitCD = #SearchBusinessUnitCD

Stored procedure not accepting any value

I have written a stored procedure based on a set of process, I'm just passing a single parameter as input to the procedure but it seems it is not taking the value. But when I give input value instead of parameter in the procedure it is working.
There is no mistake in the flow of process, but seems something missing in the procedure syntax end.
below is the stored procedure I used.
ALTER PROCEDURE [TransferIn]
#ponumber NVARCHAR = NULL
AS
BEGIN
--step 1 Delete Temp Pur_ID
IF EXISTS (
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'Pur_ID_IN')
DROP TABLE Pur_ID_IN;
-- =============================================
--step 2 select PO Number
--IF #ponumber IS NOT NULL
SELECT
ponumber, id
INTO Pur_ID_IN
FROM purchaseorder
WHERE potype IN (2, 4)
AND status = 0
AND ponumber = #ponumber;
-- =============================================
--step 3
--delete Temp. Tabel P_Test20_12_IN
IF EXISTS (
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'P_Test20_12_IN')
DROP TABLE P_Test20_12_IN;
-- =============================================
-- step 4 (Insert Data For Invoice To Temp Tabel After Group )
SELECT
ItemDescription, PurchaseOrderID,
SUM(QuantityOrdered) AS QuantityOrdered,
itemid, Price
INTO P_Test20_12_IN
FROM PurchaseOrderEntry
WHERE PurchaseOrderID IN (SELECT id FROM Pur_ID_IN)
GROUP BY
ItemDescription, StoreID, PurchaseOrderID,
itemid, Price;
--order by 3
-- =============================================
-- step 5 Delete Record From PurchaseOrderEntry
DELETE PurchaseOrderEntry
FROM PurchaseOrderEntry
WHERE PurchaseOrderID IN (SELECT id FROM Pur_ID_IN);
-- =============================================
INSERT INTO [W07].[dbo].[PurchaseOrderEntry] ([ItemDescription], [LastUpdated], [PurchaseOrderID], [QuantityOrdered], [ItemID], [Price])
SELECT
[ItemDescription],
GETDATE() AS [LastUpdated],
[PurchaseOrderID], [QuantityOrdered],
[ItemID], [Price]
FROM
P_Test20_12_IN;
END
Problem is
#ponumber nvarchar = null
change it to
#ponumber nvarchar(max) = null
Note:If you do NOT specify the size(char, nchar, varchar, nvarchar),
sql server will default to 1 character.
ALTER PROCEDURE [TransferIn]
(
#ponumber NVARCHAR(100)
)
AS BEGIN
SET NOCOUNT ON
IF OBJECT_ID('tempdb.dbo.#temp') IS NOT NULL
DROP TABLE #temp
CREATE TABLE #temp (id INT PRIMARY KEY)
INSERT INTO #temp (id)
SELECT /*DISTINCT*/ id
FROM dbo.purchaseorder
WHERE potype IN (2, 4)
AND [status] = 0
AND ponumber = #ponumber
IF OBJECT_ID('tempdb.dbo.#temp2') IS NOT NULL
DROP TABLE #temp2
SELECT ItemDescription,
PurchaseOrderID,
SUM(QuantityOrdered) AS QuantityOrdered,
itemid,
Price
INTO #temp2
FROM PurchaseOrderEntry
WHERE PurchaseOrderID IN (SELECT * FROM #temp)
GROUP BY ItemDescription,
StoreID, --?
PurchaseOrderID,
itemid,
Price;
DELETE PurchaseOrderEntry
FROM PurchaseOrderEntry
WHERE PurchaseOrderID IN (SELECT * FROM #temp)
INSERT INTO [W07].[dbo].[PurchaseOrderEntry] ([ItemDescription], [LastUpdated], [PurchaseOrderID], [QuantityOrdered], [ItemID], [Price])
SELECT [ItemDescription],
GETDATE() AS [LastUpdated],
[PurchaseOrderID],
[QuantityOrdered],
[ItemID],
[Price]
FROM #temp2
END

while loop to insert data into table in sql

declare #temp int,
#temp1 int,
#temp2 int,
#temp3 int,
#temp4 int,
#temp5 int,
#modid int,
#supid int,
#sid varchar(50)
begin tran
select * from StudentSupervisor;
select #temp = count(*) from Students s where s.IsLockedOut = '0' and s.IsGraduated = '0';
select #temp1 = count(*) from staffs st where st.IsLockedOut ='0';
set #temp5 = round(#temp/#temp1,0);
WHILE (select count(*) from students s where s.IsLockedOut ='0' and s.StudentId not in (select ss.StudentId from StudentSupervisor ss where s.StudentId = ss.StudentId and ss.IsApproved = 1)) != 0
BEGIN
select top 1 #sid = s.studentid from students s, StudentSupervisor ss where s.IsLockedOut ='0' and s.StudentId not in (select s.StudentId where s.StudentId = ss.StudentId and ss.IsApproved = 1);
select top 1 #supid = st.Staffid, #modid = st.moderatorid from Staffs st where st.IsLockedOut =0 and Quota <=#temp5;
insert into StudentSupervisor
(StudentId,SupervisorId,ModeratorId,IsApproved)
values
(#sid,#supid,#modid,1)
update Staffs set quota +=1 where staffs.StaffID = #supid;
END
select * from StudentSupervisor;
ROLLBACK tran
Hi all, i am quite stuck on this logic and i did search for solution but i get nothing after overnight work, let me clear with my situation now, first i would like to take count of student that not in studentsupervisor table or in studentsupervisor table but isapproved !=1, then i take the count of staff that quota is not more than total student / total staff,after that i would like to pump student together with staff into studentsupervisor table while they still available.. please let me know what wrong with my dynamic query, thanks
I am having trouble understanding your question. I think your loop condition should be:
WHILE (SELECT COUNT(*) from students WHERE StudentID NOT IN (SELECT StudentID FROM StudentSupervisor WHERE IsAppoved = 1)) <> 0
Depending on what you are trying to do in the loop, it will probably be possible to remove the loop. If you can update your question with more detail on what is happening in the loop and an example I will try to provide a more complete answer.
Update:
In that case I would also update the first line in the loop to:
select top 1 #sid = studentid from students WHERE IsLockedOut = 0 and StudentId NOT IN (SELECT StudentID FROM StudentSupervisor WHERE IsAppoved = 1);
Update2 Table variable option:
declare #temp int,
#temp1 int,
#temp2 int,
#temp5 int,
#PairCount int, --The number of students paired with a staff member.
#modid int,
#supid int,
#StaffQuotaNeed int, --The number of students the staff needs to be paired with to meet quota.
#sid varchar(50)
DECLARE #StaffToPair table
(
StaffID int NOT NULL,
ModeratorID int NOT NULL,
QuotaNeed int NOT NULL --The number of students the staff needs to be paired with to meet quota.
);
DECLARE #StudentsToPair table (StudentID int NOT NULL);
DECLARE #StudentsPaired table (StudentID int NOT NULL);
begin tran
select * from StudentSupervisor;
select #temp = count(*) from Students where IsLockedOut = '0' and IsGraduated = '0';
select #temp1 = count(*) from staffs where IsLockedOut ='0';
set #temp5 = round(#temp/#temp1 + .5, 0); --Round Up
INSERT INTO #StaffToPair (StaffID, ModeratorID, QuotaNeed)
SELECT StaffID, ModeratorID, #temp5 - Quota FROM Staffs WHERE IsLockedOut =0 AND Quota <#temp5;
INSERT INTO #StudentsToPair (StudentID)
SELECT StudentID from students WHERE IsLockedOut = 0 AND StudentId NOT IN (SELECT StudentID FROM StudentSupervisor WHERE IsAppoved = 1);
WHILE (SELECT COUNT(*) from #StudentsToPair) > 0 AND (SELECT COUNT(*) from #StaffToPair) > 0
BEGIN
SELECT TOP 1 #supid = Staffid, #modid = ModeratorID, #StaffQuotaNeed = QuotaNeed FROM #StaffToPair;
INSERT INTO StudentSupervisor (StudentID, SupervisorId, ModeratorId, IsApproved)
OUTPUT INSERTED.StudentID INTO #StudentsPaired(StudentID)
SELECT TOP (#StaffQuotaNeed) StudentID, #supid, #modid, 1 FROM #StudentsToPair;
DELETE FROM #StudentsToPair WHERE StudentID IN (SELECT StudentID FROM #StudentsPaired); --Delete paired students from table variable.
DELETE FROM #StaffToPair WHERE StaffID = #supid; --Delete paired staff from table variable.
SELECT #PairCount = COUNT(*) FROM #StudentsPaired;
UPDATE Staffs set Quota += #PairCount where staffs.StaffID = #supid;
END
select * from StudentSupervisor;
ROLLBACK tran
If the above does not work then please update your question to contain the table schema's so I can test it on my system.

SQL SERVER 2008 final select command with stored procedure

i guess it is trivial to get it done right .
in the screen-shot below each user(userid) has two results (which is a kind of a duplicate)
how can i fix query to get only one result per user
(each user can have 2 sets of "TimeIn" and "TimeOut" activities)
so if given user does have a second "entrance" but did not leave yet
i need only the first closed entrance/leave + second entrance/still working
here is the Stored Procedure
create table #tmp (tId int, UserId int,
TimeIn1 smalldatetime, [TimeOut1] smalldatetime,
TimeIn2 smalldatetime, [TimeOut2] smalldatetime, tId2 int,
ActiveDate smalldatetime, ReasonID int, Name nvarchar(100), ReasonType nvarchar(100),
TotalMins int)
insert into #tmp (tId, UserId, TimeIn1, TimeOut1, ActiveDate, ReasonID, Name, ReasonType)
SELECT
t1.tId, t1.UserId, t1.TimeIn, t1.[TimeOut], t1.ActiveDate, t1.ReasonID, tblCustomers.name,tblTimeReas.ReasonType
FROM tblTime t1
inner join tblTimeReas on t1.ReasonID = tblTimeReas.ReasonID
inner join tblCustomers on t1.UserId=tblCustomers.custID
where (t1.userid in (select custID from tblCustomers where Classification =35) )
and (DATEPART(DAY,t1.timein)= DATEPART(DAY,GETDATE()))
and (DATEPART(MONTH,t1.timein)= DATEPART(MONTH,GETDATE()))
and (DATEPART(YEAR,t1.timein)= DATEPART(YEAR,GETDATE()))
update #tmp
set tId2 = (select top 1 tId from
tblTime t2 where (userid in (select custID from tblCustomers where Classification =35)) and DATEDIFF(day,t2.timein,#tmp.timein1)=0
and t2.tId>#tmp.tId order by tId asc)
update #tmp
set TimeIn2 = (select TimeIn from tblTime where tId=tId2),
TimeOut2 = (select [TimeOut] from tblTime where tId=tId2)
update #tmp set TotalMins = (
isnull(DATEDIFF(minute,timein1,timeout1),0)+
isnull(DATEDIFF(minute,timein2,timeout2),0)
)
select * from #tmp order by TimeIn1
drop table #tmp
dont know how , i didn't take a course for sql server & databse but this is my final code for
much flexable filtering
create table #tmp (tId int, UserId int,
TimeIn1 smalldatetime, [TimeOut1] smalldatetime,
ActiveDate smalldatetime, ReasonID int, Name nvarchar(100), ReasonType nvarchar(100),
TotalMins int)
insert into #tmp (tId, UserId, TimeIn1, TimeOut1, ActiveDate, ReasonID, Name, ReasonType)
SELECT
t1.tId, t1.UserId, t1.TimeIn, t1.[TimeOut], t1.ActiveDate, t1.ReasonID, tblCustomers.name,tblTimeReas.ReasonType
FROM tblTime t1
inner join tblTimeReas on t1.ReasonID = tblTimeReas.ReasonID
inner join tblCustomers on t1.UserId=tblCustomers.custID
where (t1.userid in (select custID from tblCustomers where Classification Like '%,35%') )
and (DATEPART(DAY,t1.timein)= DATEPART(DAY,GETDATE()))
and (DATEPART(MONTH,t1.timein)= DATEPART(MONTH,GETDATE()))
and (DATEPART(YEAR,t1.timein)= DATEPART(YEAR,GETDATE()))
and TimeOut is null
update #tmp set TotalMins = (
isnull(DATEDIFF(minute,timein1,GETDATE()),0)
)
select *from #tmp order by TimeIn1
drop table #tmp

Resources