I want to remove the #temp1 from my query and use it as another table varible that work same as it is working using #temp1 table.
Here is my query
DROP TABLE #temp1
;WITH cteSales AS(
SELECT BillDate,
BillNo,
'-' AS NarrationNumber,
TotalAmount,
0 AS ReceivedAmount
FROM SalesMaster
WHERE SalesMaster.ClientID = #ClientID
AND SalesMaster.BillDate BETWEEN #FromDate AND #ToDate
UNION ALL
SELECT [Date] AS BillDate,
SalesAccount.BillNo,
SalesAccount.NarrationNumber,
0 AS TotalAmount,
Amount AS ReceivedAmount
FROM SalesAccount
LEFT JOIN SalesMaster sm
ON sm.BillNo = SalesAccount.BillNO
WHERE sm.ClientID = #ClientID
AND sm.BillDate BETWEEN #FromDate AND #ToDate
), cteFormattedSales AS(
SELECT ROW_NUMBER() OVER(ORDER BY BillNo ASC, BillDate ASC) AS RowNum,
*
FROM cteSales
)
SELECT cfs1.RowNum,
cfs1.BillDate,
cfs1.BillNo,
cfs1.NarrationNumber,
cfs1.TotalAmount,
cfs1.ReceivedAmount,
(cfs1.TotalAmount - cfs1.ReceivedAmount) AS DueAmount INTO #temp1
FROM cteFormattedSales cfs1
DECLARE #BillDate date,
#PrevBillNo INT,
#NextBillNo INT,
#NarrationNumber VARCHAR(15),
#TotalAmount DECIMAL(18, 2),
#ReceivedAmount DECIMAL(18, 2),
#NextDue DECIMAL(18, 2),
#PrevDue DECIMAL(18, 2)
DECLARE #finalTable TABLE(
BillDate date,
BillNo INT,
NarrationNumber NVARCHAR(15),
TotalAmount DECIMAL(18, 2),
ReceivedAmount DECIMAL(18, 2),
DueAmount DECIMAL(18, 2)
)
DECLARE #TotalRecords INT,
#Counter INT = 1,
#CarryOverAmount DECIMAL(18, 2)
SELECT #TotalRecords = COUNT(*)
FROM #temp1
SELECT #BillDate = t.BillDate,
#PrevBillNo = t.BillNo,
#NarrationNumber = t.NarrationNumber,
#TotalAmount = t.TotalAmount,
#ReceivedAmount = t.ReceivedAmount,
#PrevDue = t.DueAmount
FROM #temp1 t
WHERE t.RowNum = #Counter
WHILE #Counter <= #TotalRecords
BEGIN
SELECT #BillDate = t.BillDate,
#NextBillNo = t.BillNo,
#NarrationNumber = t.NarrationNumber,
#TotalAmount = t.TotalAmount,
#ReceivedAmount = t.ReceivedAmount,
#NextDue = t.DueAmount
FROM #temp1 AS t
WHERE t.RowNum = #Counter
IF (#Counter = 1)
SET #CarryOverAmount = #TotalAmount
SET #PrevDue = #CarryOverAmount - #ReceivedAmount
IF #PrevBillNo <> #NextBillNo
BEGIN
SET #PrevBillNo = #NextBillNo
SET #CarryOverAmount = #TotalAmount + #PrevDue
SET #PrevDue = 0
END
INSERT INTO #finalTable
(
BillDate,
BillNo,
NarrationNumber,
TotalAmount,
ReceivedAmount,
DueAmount
)
VALUES
(
#BillDate,
#PrevBillNo,
#NarrationNumber,
#TotalAmount,
#ReceivedAmount,
CASE
WHEN #NarrationNumber = '-' THEN #CarryOverAmount
ELSE #PrevDue
END
)
IF #PrevBillNo = #NextBillNo
BEGIN
IF #Counter > 1
BEGIN
SET #CarryOverAmount = CASE
WHEN #NarrationNumber = '-' THEN #CarryOverAmount
+ #PrevDue
ELSE #CarryOverAmount - #ReceivedAmount
END
END
END
SET #Counter = #Counter + 1
END
SELECT *
FROM #finalTable
Here the code that i get error on invalid ReceivedAmount
SELECT #BillDate = t.BillDate,
#PrevBillNo = t.BillNo,
#NarrationNumber = t.NarrationNumber,
#TotalAmount = t.TotalAmount,
#ReceivedAmount = t.ReceivedAmount,
#PrevDue = t.DueAmount
FROM #Temp1 t
WHERE t.RowNum = #Counter
WHILE #Counter <= #TotalRecords
BEGIN
SELECT #BillDate = t.BillDate,
#NextBillNo = t.BillNo,
#NarrationNumber = t.NarrationNumber,
#TotalAmount = t.TotalAmount,
#ReceivedAmount = t.ReceivedAmount,
#NextDue = t.DueAmount
FROM #Temp1 AS t
WHERE t.RowNum = #Counter
You need to do just 3 steps:
A. DECLARE table variable
-- correct types of columns
DECLARE #temp1 TABLE(
RowNum int
,BillDate datetime
,BillNo int
,NarrationNumber int
,TotalAmount money
,RecievedAmount money
,DueAmount money
)
B. Rewrite SELECT ... INTO -> INSERT INTO .. SELECT
INSERT INTO #temp1
SELECT cfs1.RowNum,
cfs1.BillDate,
cfs1.BillNo,
cfs1.NarrationNumber,
cfs1.TotalAmount,
cfs1.ReceivedAmount,
(cfs1.TotalAmount - cfs1.ReceivedAmount) AS DueAmount
FROM cteFormattedSales cfs1
... etc ...
C. Replace all #temp1 to #temp1
Related
I'm trying to generate free blocks for workers and work fine if the working hours are like 08:00 to 16:00. But when I change the working hours to 07:30 to 15:30 it doesn't act as I want it to. If my task length is 1 hour/60 minutes, the first available time will be 8.00, which was supposed to be 7:30.
Any suggestions about how I can resolve this issue?
Output:
expected to be starting at 7:30, 8:30 etc
stored procedure
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[ProcedureGenerateFreetimeForOneStakeholder]
(
#EmployeeId uniqueidentifier,
#NumberOfDaysBeforeBooking int,
#NumberOfDays int,
#Rebuild int
)
AS
DECLARE #workHours TABLE (
[CompanyKeyValuePairSettingsId] uniqueidentifier,
[Value] nvarchar(249)
)
DECLARE #CompanyId uniqueidentifier = (select top 1 CompanyId from tblStakeholder where StakeholderId = #EmployeeId)
SET #NumberOfDaysBeforeBooking =(select [value] FROM tblCompanyToCompanyKeyValuePairSettings WHERE CompanyId = #CompanyId AND CompanyKeyValuePairSettingsId = '06B546A9-C47E-4A8B-AE13-E3F9F0C87DEC')
SET #NumberOfDays =(select [value] FROM tblCompanyToCompanyKeyValuePairSettings WHERE CompanyId = #CompanyId AND CompanyKeyValuePairSettingsId = '87C6406F-BC47-4F42-B58B-450C9F4EBC9E')
-- Insert user work time to #workHours
INSERT INTO #workHours ([CompanyKeyValuePairSettingsId], [Value]) (SELECT s.[CompanyKeyValuePairSettingsId], s.[Value] FROM [dbo].[tblCompanyToCompanyKeyValuePairSettings] as s
INNER JOIN [dbo].[tblCompanyKeyValuePairSettings] as p on s.[CompanyKeyValuePairSettingsId] = p.CompanyKeyValuePairSettingsId
WHERE p.[Section] = 'workingHours' and [CompanyId] = #CompanyId and p.[CompanyKeyValuePairSettingsId] not in (
SELECT [IsOverwriteTo]
FROM [dbo].[tblCompanyUserKeyValuePairSettings]
INNER JOIN [dbo].[tblCompanyUserToStakeholderIdKeyValuePairSettings] on [tblCompanyUserKeyValuePairSettings].[CompanyUserKeyValuePairSettingsId] = [tblCompanyUserToStakeholderIdKeyValuePairSettings].[CompanyUserKeyValuePairSettingsId]
WHERE Section = 'WorkingHours' AND IsOverwriteTo is not null and StakeholderId = #EmployeeId))
INSERT INTO #workHours ([CompanyKeyValuePairSettingsId], [Value] ) (SELECT [IsOverwriteTo], [tblCompanyUserToStakeholderIdKeyValuePairSettings].[Value]
FROM [dbo].[tblCompanyUserKeyValuePairSettings]
INNER JOIN [dbo].[tblCompanyUserToStakeholderIdKeyValuePairSettings] on [tblCompanyUserKeyValuePairSettings].[CompanyUserKeyValuePairSettingsId] = [tblCompanyUserToStakeholderIdKeyValuePairSettings].[CompanyUserKeyValuePairSettingsId]
WHERE Section = 'WorkingHours' AND IsOverwriteTo is not null and StakeholderId = #EmployeeId)
declare #TimeSlots table (
StartTime [nchar](5) NOT NULL,
EndTime [nchar](5) NOT NULL
)
DECLARE #Today DateTime = CONVERT (date, DATEADD(day, 0, GETDATE()))
DECLARE #FirstDay DateTime = CONVERT (date, DATEADD(day, #NumberOfDaysBeforeBooking, GETDATE()))
DECLARE #Last DateTime = CONVERT (date, DATEADD(day, #NumberOfDays,GETDATE()))
DECLARE #current DateTime = CONVERT (date, DATEADD(day, 0, GETDATE()))
DECLARE #MinuteBeginDay int
DECLARE #MinuteEndDay int
DECLARE #MinuteAssignmentBegin int
DECLARE #MinuteAssignmentEnd int = 1440;
if(#Rebuild = 1)
Begin
DELETE FROM [dbo].[tblEmployeeFreetime] WHERE [StakeholderId] = #EmployeeId
End
if(#Rebuild = 0)
Begin
DELETE FROM [dbo].[tblEmployeeFreetime] WHERE [StakeholderId] = #EmployeeId and [StartTime] <= #FirstDay
End
-- Insert blocked time
WHILE (#current <= #FirstDay)
BEGIN
INSERT INTO #TimeSlots (StartTime,EndTime) values ('23:59','23:59')
set #MinuteBeginDay = (select CONVERT(INT, (SELECT SUBSTRING((select top (1) StartTime from #TimeSlots), 1, 2))) * 60 + CONVERT(INT, (SELECT SUBSTRING((select top (1) StartTime from #TimeSlots), 4, 5))))
set #MinuteEndDay = (select CONVERT(INT, (SELECT SUBSTRING((select top (1) EndTime from #TimeSlots), 1, 2))) * 60 + CONVERT(INT, (SELECT SUBSTRING((select top (1) EndTime from #TimeSlots), 4, 5))))
set #MinuteAssignmentBegin = 30
While (#MinuteAssignmentBegin < #MinuteAssignmentEnd - #MinuteAssignmentBegin)
Begin
INSERT INTO [dbo].[tblEmployeeFreetime] ([StakeholderId], StartTime,EndTime,[AssignmentLength])
(select #EmployeeId, #current , DATEADD(minute, #MinuteEndDay, #current),#MinuteAssignmentBegin)
SET #MinuteAssignmentBegin = #MinuteAssignmentBegin + 30
End
DELETE FROM #TimeSlots
Set #current = CONVERT (date, DATEADD(day, 1, #current))
End
-- Insert free time on workdays and weekends
SET #current = CONVERT (date, DATEADD(day, 1, (SELECT TOP (1) [EndTime] FROM [dbo].[tblEmployeeFreetime] where [StakeholderId] = #EmployeeId order by [EndTime] desc)))
Declare #SetTime datetime
while (#current <= #Last)
Begin
declare #str VARCHAR(MAX)
set #str = FORMAT(#current, 'dddd')
-----
declare #StartSlot nvarchar(5) = (SELECT w.Value FROM #workHours as w
INNER JOIN tblCompanyKeyValuePairSettings as s on w.[CompanyKeyValuePairSettingsId] = s.[CompanyKeyValuePairSettingsId] where s.Name Like #str + 'StartTime%')
declare #EndSlot nvarchar(5) = (SELECT w.Value FROM #workHours as w
INNER JOIN tblCompanyKeyValuePairSettings as s on w.[CompanyKeyValuePairSettingsId] = s.[CompanyKeyValuePairSettingsId] where s.Name Like #str + 'EndTime%')
INSERT INTO #TimeSlots (StartTime,EndTime) VALUES (#StartSlot,#EndSlot)
----
set #MinuteBeginDay = (select CONVERT(INT, (SELECT SUBSTRING((select top (1) StartTime from #TimeSlots), 1, 2))) * 60 + CONVERT(INT, (SELECT SUBSTRING((select top (1) StartTime from #TimeSlots), 4, 5))))
set #MinuteEndDay = (select CONVERT(INT, (SELECT SUBSTRING((select top (1) EndTime from #TimeSlots), 1, 2))) * 60 + CONVERT(INT, (SELECT SUBSTRING((select top (1) EndTime from #TimeSlots), 4, 5))))
set #MinuteAssignmentBegin = 30
While (#MinuteAssignmentBegin < #MinuteAssignmentEnd - #MinuteAssignmentBegin)
Begin
INSERT INTO [dbo].[tblEmployeeFreetime] ([StakeholderId], StartTime,EndTime,[AssignmentLength]) (select #EmployeeId, #current , DATEADD(minute, #MinuteBeginDay, #current),#MinuteAssignmentBegin)
if #StartSlot != #EndSlot
begin
set #SetTime = DATEADD(minute, #MinuteEndDay - #MinuteAssignmentBegin, #current)
INSERT INTO [dbo].[tblEmployeeFreetime] ([StakeholderId], StartTime,EndTime,[AssignmentLength]) (select #EmployeeId, #SetTime, DATEADD(minute, 1439, #current),#MinuteAssignmentBegin)
end
set #MinuteAssignmentBegin = #MinuteAssignmentBegin + 30
End
delete from #TimeSlots
Set #current = CONVERT (date, DATEADD(day, 1, #current))
End
Due to performance perspective I just need to remove loop and using some joins or other solution to update the data in #Result table and get the same result which return by loop.
Scalar function:
CREATE FUNCTION [MultiplyerScl]
(#a INT, #b INT)
RETURNS INT
AS
BEGIN
DECLARE #i AS INT = 2
DECLARE #Value AS INT
IF (#b % #a = 0)
BEGIN
SET #Value = #b
END
ELSE
BEGIN
WHILE (1=1)
BEGIN
IF((#b * #i) % #a = 0)
BEGIN
SET #Value = #b * #i
BREAK;
END
ELSE
BEGIN
SET #i = #i + 1
END
END
END
RETURN #Value
END
Table design and its value.
CREATE TABLE #NUM (Groupid INT, GroupValue INT)
INSERT INTO #NUM
VALUES (1, 8), (1, 9), (1, 23), (2, 5), (2, 5), (2, 10)
Main for loop logic.
SELECT
Groupid,
GroupValue,
MaxValue = MAX(GroupValue) OVER (PARTITION BY Groupid),
MaxCount = COUNT(1) OVER(),
RID = ROW_NUMBER() OVER (ORDER BY groupid)
INTO
#Result
FROM
#NUM
DECLARE #i AS INT = 1
DECLARE #RawCnt AS INT = (SELECT MAX(MaxCount) FROM #Result)
DECLARE #iGroupid INT
DECLARE #iGroupvalue INT
DECLARE #iMaxValue INT
WHILE(#i <= #RawCnt)
BEGIN
SELECT
#iGroupid = Groupid,
#iGroupvalue = Groupvalue,
#iMaxValue = MaxValue
FROM
#Result
WHERE
RID = #i
UPDATE #Result
SET MaxValue = dbo.[MultiplyerScl](#iGroupvalue, #iMaxValue)
WHERE Groupid = #iGroupid
SET #i = #i + 1
END
SELECT * FROM #Result
Try this out
SELECT
Groupid,
GroupValue,
MaxValue = MAX(GroupValue) OVER (PARTITION BY Groupid),
MaxCount = COUNT(1) OVER(),
RID = ROW_NUMBER() OVER (ORDER BY groupid)
INTO
#Result
FROM
#NUM
;WITH Res AS
(
SELECT Groupid, e.Groupvalue, dbo.[MultiplyerScl](Groupvalue, e.MaxValue) AS
MaxValue, 1 AS i
FROM #Result e
UNION ALL
--recursive execution
SELECT e.Groupid, m.Groupvalue, dbo.[MultiplyerScl](e.Groupvalue, m.MaxValue) AS MaxValue, m.i + 1 AS i
FROM #Result e
INNER JOIN Res m ON e.Groupid = m.Groupid
WHERE dbo.[MultiplyerScl](e.Groupvalue, m.MaxValue) > m.MaxValue
)
SELECT Groupid, MAX(MaxValue) AS MaxValue
INTO #FinalResult
FROM Res
GROUP BY Groupid
UPDATE re
SET re.MaxValue = ire.MaxValue
FROM #FinalResult ire
INNER JOIN #Result re ON re.Groupid = ire.Groupid
SELECT * FROM #Result
I need to split a string by delimiters |, then for every value obtained, I need to insert same in the name field like so:
INSERT INTO Monitoring (UserId, Name, DateCreated)
VALUES (#UserId, 'abc', getdate())
VALUES (#UserId, 'def', getdate()) etc...
Below is my code to split the string.
DECLARE #SplitStringTable TABLE (Value nvarchar(MAX) NOT NULL)
DECLARE #StringToSplit nvarchar(MAX) = 'abc|def|gh|ijj'
DECLARE #SplitEndPos int
DECLARE #SplitValue nvarchar(MAX)
DECLARE #SplitDelim nvarchar(1) = '|'
DECLARE #SplitStartPos int = 1
SET #SplitEndPos = CHARINDEX(#SplitDelim, #StringToSplit, #SplitStartPos)
WHILE #SplitEndPos > 0
BEGIN
SET #SplitValue = SUBSTRING(#StringToSplit, #SplitStartPos, (#SplitEndPos - #SplitStartPos))
INSERT #SplitStringTable (Value) VALUES (#SplitValue)
SET #SplitStartPos = #SplitEndPos + 1
SET #SplitEndPos = CHARINDEX(#SplitDelim, #StringToSplit, #SplitStartPos)
END
BEGIN TRANSACTION T1
DECLARE #i int = 0
WHILE #i < #SplitEndPos
BEGIN
INSERT INTO Monitoring (UserId, Name, DateCreated)
VALUES (#UserId, #Name, getdate())
SET #i = #i + 1
END
COMMIT TRANSACTION T1
Any help please, how shall I proceed?
There are many split/parsing functions out there.
Assume variables:
Declare #UserID int = 1
Declare #String varchar(max)='abc|def'
Insert Into Monitoring (UserId,Name,DateCreated)
Select UserID = #UserID
,Name = Key_Value
,DateCreated = GetDate()
From [dbo].[udf-Str-Parse](#String,'|')
The following would be inserted
UserID Name DateCreated
1 abc 2016-09-26 17:31:24.107
1 def 2016-09-26 17:31:24.107
The UDF if needed
CREATE FUNCTION [dbo].[udf-Str-Parse] (#String varchar(max),#Delimiter varchar(10))
Returns Table
As
Return
(
Select Key_PS = Row_Number() over (Order By (Select null))
,Key_Value = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>'+ Replace(#String,#Delimiter,'</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
);
EDIT
By the way, if you just run the parse function alone, you would get the following:
Declare #String varchar(max)='abc|def'
Select * From [dbo].[udf-Str-Parse](#String,'|')
-- Returns
Key_PS Key_Value
1 abc
2 def
Can I create a view or function using the below query? It uses temp tables. I am not able to create either a view or function.
--TEmp table--
IF OBJECT_ID('tempdb..#Enquiries') IS NOT NULL
DROP TABLE #Enquiries
GO
CREATE TABLE #Enquiries
(ID INT,PID INT,Name VARCHAR(50),Enquiries INT,EnquiryDate datetime)
INSERT INTO #Enquiries
SELECT ROW_NUMBER()
OVER (ORDER BY ProjectName) AS Row, (SELECT top 1 ITEM FROM DBO.split(e.InterestedProjects,',')) as Projects,P.ProjectName,COUNT(CAST(EnquiryDate AS DATE)) AS Enquiries,CAST(EnquiryDate AS DATE) AS EnquiryDate
FROM tbl_Enquiry e INNER JOIN
tbl_Projects AS P ON P.ProjectId = (SELECT TOP 1 ITEM FROM DBO.split(e.InterestedProjects,','))
WHERE e.IsActive=1 and e.isdeleted=0 AND p.IsActive=1 AND p.IsDeleted=0 AND P.ProjectId IN (SELECT TOP 1 ITEM FROM DBO.split(e.InterestedProjects,','))
GROUP BY e.InterestedProjects,P.ProjectName,CAST(EnquiryDate AS DATE)
--SiteVisits
IF OBJECT_ID('tempdb..#SiteVisit') IS NOT NULL
DROP TABLE #SiteVisit
GO
CREATE TABLE #SiteVisit
(ID INT,PID INT,Name VARCHAR(50),Sitevisits INT,PickUpDatetime datetime)
INSERT INTO #SiteVisit
SELECT ROW_NUMBER() OVER (ORDER BY ProjectName) AS Row,s.ProjectId,p.ProjectName As Name,count(sd.PickUpDatetime) AS Sitevisits,CAST(PickUpDatetime AS DATE) AS PickUpDatetime FROM tbl_SiteVisit s
INNER JOIN tbl_SiteVisitDetails sd ON s.SiteVisitId=sd.SiteVisitId
INNER JOIN tbl_Projects p ON p.ProjectId=s.ProjectId
WHERE s.IsActive=1 and s.isdeleted=0 AND sd.isactive=1 AND sd.isdeleted=0
GROUP BY s.ProjectId,sd.PickUpDatetime,p.ProjectName,CAST(PickUpDatetime AS DATE)
--Bookings
IF OBJECT_ID('tempdb..#Bookings') IS NOT NULL
DROP TABLE #Bookings
GO
CREATE TABLE #Bookings
(ID INT,PID INT,Name VARCHAR(50),Bookings INT,BookingDate datetime,Revenue money,Area float)
INSERT INTO #Bookings
SELECT ROW_NUMBER() OVER (ORDER BY ProjectName) AS Row, u.ProjectId AS ProjectId,p.ProjectName,count(u.ProjectId) AS Bookings,CAST(b.BookingDate AS DATE) AS BookingDate,SUM(b.TotalAmount) AS [Revenue],SUM(u.UnitArea) AS [Area] FROM tbl_Bookings b
INNER JOIN tbl_Unit u ON b.UnitId=u.UnitId
INNER JOIN tbl_Projects p on p.ProjectId=u.ProjectId
WHERE b.IsActive=1 AND b.IsDeleted=0 and u.IsActive=1 AND u.IsDeleted=0 AND u.Status = 'B'
GROUP BY u.ProjectId,p.ProjectName,CAST(b.BookingDate AS DATE),b.TotalAmount,u.UnitArea
--ORDER BY u.ProjectId
IF OBJECT_ID('tempdb..#T1') IS NOT NULL
DROP TABLE #T1
create TABLE #T1 (
PrimaryNo INT,
EnquiryDate Date,
Enquiries INT,
SiteVisits INT,
Bookings INT,
Revenue Money,
Area Float,
PID INT,
ProjectName nvarchar(max)
)
INSERT INTO #T1(PrimaryNo,EnquiryDate,Enquiries,PID,ProjectName)
SELECT ID,EnquiryDate,sum(enquiries) AS Enquiries,PID,Name FROM #Enquiries GROUP BY id,pid,Name,enquirydate
DECLARE #SVDate date
DECLARE #SV11 INT
DECLARE #BookingDate Date
DECLARE #Bookings11 INT
DECLARE #Revenue11 MONEY
DECLARE #Area11 FLOAT
DECLARE #intFlag_pw11 INT
SET #intFlag_pw11 = 1
DECLARE #TableCntw11 INT
DECLARE #Date Date
DECLARE Cur_SiteVisit CURSOR FAST_FORWARD FOR
SELECT PickUpDatetime FROM #SiteVisit
OPEN Cur_SiteVisit
FETCH NEXT FROM Cur_SiteVisit INTO #Date
DECLARE #ProjectId INT
DECLARE #Count INT = 1
WHILE ##FETCH_STATUS = 0
BEGIN
SET #ProjectId = (SELECT PID FROM #SiteVisit WHERE ID = #Count)
SET #SVDate = ISNULL((SELECT CAST(PickUpDatetime AS DATE) FROM #SiteVisit
WHERE CAST(PickUpDatetime AS DATE) = #Date AND PID = #ProjectId
GROUP BY PickUpDatetime),'-')
SET #SV11 = ISNULL((SELECT Sitevisits FROM #SiteVisit
WHERE CAST(PickUpDatetime AS DATE) = #Date AND PID = #ProjectId
GROUP BY Sitevisits),0)
EXEC ('UPDATE #T1 SET SiteVisits = ' + #SV11 + ' WHERE EnquiryDate = ' + ''''+ #SVDate +''' AND PID =' + #ProjectId)
FETCH NEXT FROM Cur_SiteVisit INTO #Date
SET #Count = #Count + 1
END
CLOSE Cur_SiteVisit
DEALLOCATE Cur_SiteVisit
--For Bookings
DECLARE #Date1 Date
DECLARE Cur_Bookings CURSOR FAST_FORWARD FOR
SELECT BookingDate FROM #Bookings
OPEN Cur_Bookings
FETCH NEXT FROM Cur_Bookings INTO #Date1
DECLARE #ProjectId1 INT
DECLARE #Count1 INT = 1
WHILE ##FETCH_STATUS = 0
BEGIN
SET #ProjectId1 = (SELECT PID FROM #Bookings WHERE ID = #Count1)
SET #Bookings11 = ISNULL((SELECT TOP 1 Bookings FROM #Bookings
WHERE CAST(BookingDate AS DATE) = #Date1 AND PID = #ProjectId1
GROUP BY Bookings),0)
SET #BookingDate = ISNULL((SELECT TOP 1 CAST(BookingDate AS DATE) FROM #Bookings
WHERE CAST(BookingDate AS DATE) = #Date1 AND PID = #ProjectId1
GROUP BY CAST(BookingDate AS DATE)),'-')
SET #Revenue11 = ISNULL((SELECT TOP 1 Revenue FROM #Bookings
WHERE CAST(BookingDate AS DATE) = #Date1 AND PID = #ProjectId1
GROUP BY Revenue),0)
SET #Area11 = ISNULL((SELECT TOP 1 Area FROM #Bookings
WHERE CAST(BookingDate AS DATE) = #Date1 AND PID = #ProjectId1
GROUP BY Area),0)
EXEC ('UPDATE #T1 SET Bookings = ' + #Bookings11 + ',Revenue=' + #Revenue11 + ',Area = ' + #Area11 + ' WHERE EnquiryDate = ' + '''' + #BookingDate + ''' AND PID =' + #ProjectId1)
FETCH NEXT FROM Cur_Bookings INTO #Date1
SET #Count1 = #Count1 + 1
END
CLOSE Cur_Bookings
DEALLOCATE Cur_Bookings
Select * from #T1
You can't create a view from that, if only because you're doing a number of inserts and other actions. A view is created from a single query.
With regard to user-defined functions: you cannot use dynamic SQL, which you are doing:
EXEC ('UPDATE #T1 SET Bookings = ' + #Bookings11 + ',Revenue=' + #Revenue11 +
',Area = ' + #Area11 + ' WHERE EnquiryDate = ' + '''' + #BookingDate +
''' AND PID =' + #ProjectId1)
You also can't use temp tables. Both of these limitations are documented here: http://msdn.microsoft.com/en-us/library/ms191320.aspx.
But, you can do all of these things in a stored procedure. It is also possible to direct the output of a stored procedure to a temp table or table variable, allowing you to use the output in another query:
INSERT INTO dbo.MyTable
(MyTableId, Column1, Column2) -- arbitrary-chosen column names
EXEC dbo.MyStoredProcedure
SELECT *
FROM dbo.MyTable
WHERE Column1 = 'Some Value'
Finally, you might be able to rework your SQL to work with table variables rather than temp tables, which are allowed. It also looked to me like your dynamic SQL didn't need to be dynamic, so you might be able to eliminate that as well.
Hope this helps.
I have this SQL query which is valid but always times out.
CREATE PROCEDURE Sibm_getstudentdivisionattendancereport2 (
#course_id INT,
--#Subject_Id int,
#academic_year INT,
#division_id INT,
#semister_id INT,
#fromdate1 DATETIME,
#todate1 DATETIME)
AS
BEGIN
DECLARE #fromdate VARCHAR(100)
DECLARE #todate VARCHAR(100)
SET #fromdate=CONVERT(VARCHAR(10), #fromdate1, 105)
SET #todate=CONVERT(VARCHAR(10), #todate1, 105)
CREATE TABLE #getstudentmarks
(
id INT NOT NULL,
roll_no VARCHAR(100),
stud_id INT,
stud_name VARCHAR(200),
stud_last_name VARCHAR(200),
subject_name VARCHAR(200),
marks INT,
student_id INT,
division_id INT,
division VARCHAR(50),
attended VARCHAR(12),
exempted VARCHAR(12),
total_attendance VARCHAR(12),
attendancepercentage VARCHAR(30),
subject_id INT
)
CREATE TABLE #getstudentmarks1
(
id INT IDENTITY(1, 1) NOT NULL,
roll_no VARCHAR(100),
stud_id INT,
stud_name VARCHAR(200),
stud_last_name VARCHAR(200),
subject_name VARCHAR(200),
marks INT,
student_id INT,
division_id INT,
division VARCHAR(50),
attended VARCHAR(12),
exempted VARCHAR(12),
total_attendance VARCHAR(12),
attendancepercentage VARCHAR(30),
subject_id INT
)
CREATE TABLE #divisionlist
(
division_id INT
)
CREATE TABLE #getstudent_attended
(
id INT IDENTITY(1, 1) NOT NULL,
student_id INT,
exempted VARCHAR(12),
attended VARCHAR(12)
)
DECLARE #Total_Lectures INT
DECLARE #Student_Id INT
DECLARE #TotalConductedLecture INT
DECLARE #TotalExempted INT
INSERT INTO #getstudentmarks1
(roll_no,
student_id,
stud_name,
stud_last_name)
SELECT DISTINCT( SA.roll_no ),
SA.student_id AS id,
SR.first_name,
SR.last_name
FROM tblstudent_academic_record SA,
tblstudent_record SR
WHERE SR.student_id = SA.student_id
AND SR.student_id IN (SELECT SAR.student_id
FROM tblstudent_academic_record SAR
INNER JOIN tblcoursesemester_subject_student
CSS
ON SAR.student_id = CSS.student_id
AND SAR.current_record = 1
AND SAR.course_id = #course_id
AND
SAR.semister_id = #semister_id
AND
SAR.division_id = #division_id
AND
SAR.academic_year = #academic_year)
CREATE TABLE #temp
(
id INT,
subject_name VARCHAR(100)
)
DECLARE #Master_Id INT
SET #Master_Id = 0
IF EXISTS(SELECT *
FROM tblcoursesemester_main
WHERE academic_year = #Academic_Year
AND course_id = #Course_Id
AND semester_id = #semister_id)
BEGIN
SET #Master_Id = (SELECT TOP 1 cs_id
FROM tblcoursesemester_main
WHERE academic_year = #Academic_Year
AND course_id = #Course_Id
AND semester_id = #semister_id)
END
INSERT INTO #temp
SELECT id,
subject_name
FROM tblsubject
WHERE id IN (SELECT subject_id
FROM tblcoursesemester_subject
WHERE is_archieve IS NULL
AND cs_id = #Master_Id)
AND isarchive IS NULL
ORDER BY subject_name
DECLARE #tempid INT
DECLARE #sub VARCHAR(max)
DECLARE c1 CURSOR FOR
SELECT student_id
FROM #getstudentmarks1
OPEN c1
FETCH next FROM c1 INTO #Student_Id
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE c2 CURSOR FOR
SELECT id
FROM #temp
OPEN c2
FETCH next FROM c2 INTO #tempid
WHILE ##FETCH_STATUS = 0
BEGIN
UPDATE #getstudentmarks1
SET subject_name = (SELECT subject_name
FROM #temp
WHERE id = #tempid),
subject_id = #tempid
WHERE student_id = #Student_Id
FETCH next FROM c2 INTO #tempid
END
CLOSE c2
DEALLOCATE c2
FETCH next FROM c1 INTO #Student_Id
END
CLOSE c1
DEALLOCATE c1
--select * from #TEMP
--SET IDENTITY_INSERT #GetStudentMarks1 ON
INSERT INTO #getstudentmarks
(id,
roll_no,
stud_id,
stud_name,
stud_last_name,
subject_name,
marks,
student_id,
division_id,
division,
attended,
exempted,
total_attendance,
attendancepercentage,
subject_id)
SELECT #getstudentmarks1.id,
roll_no,
stud_id,
stud_name,
stud_last_name,
#temp.subject_name,
marks,
student_id,
division_id,
division,
attended,
exempted,
total_attendance,
attendancepercentage,
#temp.id
FROM #getstudentmarks1
CROSS JOIN #temp
-- select * from #GetStudentMarks cross join #TEMP
--SET IDENTITY_INSERT #GetStudentMarks1 OFF
--select * from #GetStudentMarks
---------calculate percentage-------------------
INSERT INTO #divisionlist
SELECT divisionid
FROM tblschedulemaster
WHERE academicyear = #academic_year
AND courseid = #Course_Id
AND semesterid = #Semister_Id
DECLARE #subject_id INT
DECLARE c1 CURSOR FOR
SELECT student_id
FROM #getstudentmarks
OPEN c1
FETCH next FROM c1 INTO #Student_Id
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE c3 CURSOR FOR
SELECT subject_id
FROM #getstudentmarks
OPEN c3
FETCH next FROM c3 INTO #subject_id
WHILE ##FETCH_STATUS = 0
BEGIN
-- GET TOTAL LECTURES OF EACH STUDENT
SELECT #Total_Lectures = Count([id])
FROM tblfacultyschedule
WHERE subjectid = #subject_id
AND sch_mas_id IN (SELECT [id]
FROM tblschedulemaster
WHERE academicyear = #academic_year
AND courseid = #Course_Id
AND semesterid = #Semister_Id
AND divisionid IN (
-- Changed Divisions list Query Starts
SELECT
divisionid
FROM
tblschedulemaster
WHERE
id IN (SELECT DISTINCT
sch_mas_id
FROM
tblfacultyschedule
WHERE
[date] >= #fromdate
AND [date] <= #todate
AND
id IN (SELECT DISTINCT
schedule_id
FROM
tblstudentattendence
WHERE
student_id = #Student_Id
AND schedule_id IN (SELECT
id
FROM
tblfacultyschedule
WHERE
subjectid =
#subject_id
AND
sch_mas_id IN(SELECT
id
FROM
tblschedulemaster
WHERE
academicyear =
#academic_year
AND
courseid =
#Course_Id
AND
semesterid
=
#Semister_Id))
))
-- Changed Divisions list Query Ends
))
AND COALESCE(other_activity, '') NOT LIKE '%LUNCH%'
--print 'subject id'
--print #subject_id
--print 'totol att'
--print #Total_Lectures
-- Total Conducted Lectures
SET #TotalConductedLecture =
(SELECT
COALESCE(Count(is_attended), 0) AS Attended
FROM tblstudentattendence
WHERE student_id = #Student_id
AND is_attended = 'YES'
AND
schedule_id IN (SELECT [id]
FROM
tblfacultyschedule
WHERE
[date] >= #fromdate
AND [date] <= #todate
AND subjectid = #subject_id
AND
sch_mas_id IN (SELECT [id]
FROM
tblschedulemaster
WHERE
academicyear = #academic_year
AND courseid = #course_id
AND semesterid = #semister_id
AND divisionid IN (SELECT
division_id
FROM
#divisionlist))
AND
COALESCE(other_activity, '')
NOT
LIKE
'%LUNCH%'
AND
subjectid IN (SELECT DISTINCT
subject_id
FROM
tblcoursesemester_subject
WHERE
cs_subject_id IN (SELECT
cs_subject_id
FROM
tblcoursesemester_subject_student
WHERE
cs_subject_id IN (SELECT
cs_subject_id
FROM
tblcoursesemester_subject
WHERE
cs_id IN (SELECT cs_id
FROM
tblcoursesemester_main
WHERE
academic_year = #academic_year
AND course_id = #course_id
AND semester_id = #semister_id
)
AND is_archieve IS NULL)
AND student_id = #Student_id
AND is_archieve IS NULL)
AND is_archieve IS NULL)))
--print 'attended'
-- print #TotalConductedLecture
-- NOW COUNT Exempted LECTURES
SET #TotalExempted=
(SELECT COALESCE(Count(is_attended), 0) AS
Attended
FROM tblstudentattendence
WHERE student_id = #Student_id
AND is_attended = 'EXEMPTED'
AND schedule_id IN (SELECT [id]
FROM
tblfacultyschedule
WHERE
[date] >= #fromdate
AND [date] <= #todate
AND subjectid =
#subject_id
AND sch_mas_id IN (SELECT
[id]
FROM
tblschedulemaster
WHERE
academicyear =
#academic_year
AND
courseid =
#course_id
AND
semesterid =
#semister_id
AND
divisionid IN (
SELECT
division_id
FROM
#divisionlist))
AND
COALESCE(other_activity, '') NOT
LIKE
'%LUNCH%'
AND
subjectid IN (SELECT DISTINCT
subject_id
FROM
tblcoursesemester_subject
WHERE
cs_subject_id IN (SELECT
cs_subject_id
FROM
tblcoursesemester_subject_student
WHERE
cs_subject_id IN (SELECT
cs_subject_id
FROM
tblcoursesemester_subject
WHERE
cs_id IN (SELECT cs_id
FROM
tblcoursesemester_main
WHERE
academic_year = #academic_year
AND course_id = #course_id
AND semester_id = #semister_id
)
AND is_archieve IS NULL)
AND student_id = #Student_id
AND is_archieve IS NULL)
AND is_archieve IS NULL)))
-- print 'not attended'
-- print #TotalExempted
UPDATE #getstudentmarks
SET #getstudentmarks.total_attendance = #Total_Lectures,
#getstudentmarks.attended = #TotalConductedLecture,
#getstudentmarks.exempted = #TotalExempted
WHERE student_id = #Student_Id
AND subject_id = #subject_id
FETCH next FROM c3 INTO #subject_id
END
CLOSE c3
DEALLOCATE c3
FETCH next FROM c1 INTO #Student_Id
END
CLOSE c1
DEALLOCATE c1
-- CURSOR ENDS
--select * from #GetStudentMarks
UPDATE #getstudentmarks
SET #getstudentmarks.division = tbldivision.division
FROM #getstudentmarks,
tbldivision
WHERE #getstudentmarks.division_id = tbldivision.division_id
UPDATE #getstudentmarks
SET #getstudentmarks.attended = #getstudent_attended.attended
FROM #getstudentmarks,
#getstudent_attended
WHERE #getstudentmarks.student_id = #getstudent_attended.student_id
UPDATE #getstudentmarks
SET #getstudentmarks.exempted = #getstudent_attended.exempted
FROM #getstudentmarks,
#getstudent_attended
WHERE #getstudentmarks.student_id = #getstudent_attended.student_id
UPDATE #getstudentmarks
SET attended = Isnull(attended, '0')
UPDATE #getstudentmarks
SET exempted = Isnull(exempted, '0')
UPDATE #getstudentmarks
SET total_attendance = Isnull(total_attendance, '0')
--UPDATE #GetStudentMarks SET #GetStudentMarks.AttendancePercentage=CAST(CAST((CAST(#GetStudentMarks.Attended AS NUMERIC(32,2)) * 100)/CAST(#GetStudentMarks.Total_Attendance AS NUMERIC(32,2)) AS NUMERIC(32,2)) AS VARCHAR(30))
--WHERE #GetStudentMarks.Total_Attendance <> '0'
UPDATE #getstudentmarks
SET
#getstudentmarks.attendancepercentage = Cast(
Cast(
Cast(( Cast(#getstudentmarks.attended AS NUMERIC(32, 2)) * 100 ) +
(
Cast(
#getstudentmarks.exempted AS
NUMERIC(32, 2)) *
100 ) AS NUMERIC(32, 2)) /
Cast
(
#getstudentmarks.total_attendance AS
NUMERIC(
32, 2)) AS NUMERIC(32, 2)) AS
VARCHAR
(30))
WHERE #getstudentmarks.total_attendance <> '0'
--+ '' + '%'
UPDATE #getstudentmarks
SET attendancepercentage = Isnull(attendancepercentage, '0.00')
--UPDATE #GetStudentMarks SET #GetStudentMarks.AttendancePercentage = '0 %' WHERE #GetStudentMarks.AttendancePercentage IS NULL
-------------end calculation---------------------
DECLARE #Roll_No VARCHAR(20),
#Stud_Id VARCHAR(20),
#Stud_Name VARCHAR(200),
#Subject_Name VARCHAR(200),
#Stud_Last_Name VARCHAR(200),
#AttendancePercentage VARCHAR(200)
-- select * from #GetStudentMarks
DECLARE #cntColm INT
SELECT #cntColm = Count(roll_no)
FROM #getstudentmarks
GROUP BY roll_no
CREATE TABLE #subject
(
sub_name VARCHAR(200)
)
INSERT INTO #subject
(sub_name)
SELECT DISTINCT( subject_name )
FROM #getstudentmarks
--print #cntColm
CREATE TABLE #getmarkssheet
(
student_id VARCHAR(100),
roll_no VARCHAR(100),
student_name VARCHAR(200)
)
--select * from #Subject
--------------- Cursor To add Columns As a Subject Name-------------------
-- print'text'
DECLARE #Stubject VARCHAR(max)
DECLARE curaddcol CURSOR FOR
SELECT sub_name
FROM #subject
OPEN curaddcol
FETCH next FROM curaddcol INTO #Stubject
WHILE ##FETCH_STATUS = 0
BEGIN
--print #Stubject
DECLARE #column VARCHAR(max)
SELECT #column = Replace(#Stubject, '&', '')
SELECT #column = Replace(#column, 'and', '')
SELECT #column = Replace(#column, '.', '')
SELECT #column = Replace(#column, ',', '')
SELECT #column = Replace(#column, ' ', '')
SELECT #column = Replace(#column, '-', '')
SELECT #column = Replace(#column, '(', '')
SELECT #column = Replace(#column, ')', '')
SELECT #column = Replace(#column, '/', '')
SELECT #column = Replace(#column, '//', '')
SELECT #column = Replace(#column, '\', '')
SELECT #column = Replace(#column, ':', '')
--print 'columnname' + #column
IF( #column <> '' )
BEGIN
EXEC('ALTER TABLE #GetMarksSheet ADD ' + #column +
' VARCHAR(max)')
--print #column
END
SET #cntColm=#cntColm - 1
FETCH next FROM curaddcol INTO #Stubject
END
---------------------------- Cursor Ends------------------------------------------
DECLARE cursubject CURSOR FOR
SELECT roll_no,
student_id,
stud_name,
stud_last_name,
subject_name,
attendancepercentage
FROM #getstudentmarks
OPEN cursubject
FETCH next FROM cursubject INTO #Roll_No, #Stud_Id, #Stud_Name,
#Stud_Last_Name, #Subject_Name, #AttendancePercentage
-- while #cntColm >0
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #ColName VARCHAR(max)
SELECT #ColName = Replace(#Subject_Name, '&', '')
SELECT #ColName = Replace(#ColName, 'and', '')
SELECT #ColName = Replace(#ColName, ',', '')
SELECT #ColName = Replace(#ColName, '.', '')
SELECT #ColName = Replace(#ColName, ' ', '')
SELECT #ColName = Replace(#ColName, '-', '')
SELECT #ColName = Replace(#ColName, '(', '')
SELECT #ColName = Replace(#ColName, ')', '')
SELECT #ColName = Replace(#ColName, '/', '')
SELECT #ColName = Replace(#ColName, '//', '')
SELECT #ColName = Replace(#ColName, '\', '')
SELECT #ColName = Replace(#ColName, ':', '')
DECLARE #MarkInPer VARCHAR(max)
SET #MarkInPer=Cast(#AttendancePercentage AS VARCHAR(max))
IF NOT EXISTS (SELECT student_id
FROM #getmarkssheet
WHERE student_id = #Stud_Id)
BEGIN
DECLARE #FullName VARCHAR(400)
--print #AttendancePercentage
--print #ColName+'----' +Cast(#MarkInPer as varchar(max)) +'----'
-- select #MarkInPer=COALESCE(#MarkInPer,0)
-- print #Roll_No + 'roll num'
EXEC('insert into #GetMarksSheet(Student_Id,'+ #ColName +
') values ('+
#Stud_Id +','+#MarkInPer + ')')
-- print #Stud_Name
UPDATE #getmarkssheet
SET student_name = #Stud_Name
WHERE student_id = #Stud_Id
--exec('UPDATE #GetMarksSheet SET Student_Name='+#Stud_Name +' where Roll_No='+#Roll_No)
END
ELSE
EXEC('UPDATE #GetMarksSheet SET '+ #ColName +' = '+#MarkInPer +
' where Student_Id='+#Stud_Id)
SET #cntColm=#cntColm - 1
FETCH next FROM cursubject INTO #Roll_No, #Stud_Id, #Stud_Name,
#Stud_Last_Name, #Subject_Name, #AttendancePercentage
END
SELECT *
FROM #getmarkssheet
END
Ouch. Do it without temp tables and try it in one statement. It looks doable.
Your approach kills the query optimizer's ability to optimize because you give it detailed steps including a (OUCH) cursoer which means single processor loop behavior as you DEMAND it.
This is NOT sql, this is a perversion - sql deals with sets.
I am sure you CAN describ the result in one statement, without the use of temporary tables, and the result may surprise you performance wise ;)