Conversion failed when converting date and/or time from character string - sql-server

What I am doing is using own function, which is returning string, now I want this column for ordering, and while using it for ordering it is not ordering properly because its a string, when I tried to convert as datetime it causes an error.
Any help ?
Thanks a lot.
SELECT
b.CallId,
CONVERT(VARCHAR(25), b.ETADate, 103) as'ETADate',
dbo.getCallEntrySerialNoLastTranDateTime(b.CallEntrySerialNumbersId) AS 'closingDateTime'
FROM
CallEntry AS a, CallEntrySerialNumbers AS b
WHERE
a.ASPId = 2
AND a.CompanyId = 3
AND a.CallId= b.CallId
AND a.ProdCompanyId = 1
AND b.CallCaseId IS NOT NULL
AND b.CallCaseId NOT LIKE 'NA'
AND ProdCategoryid = 1
AND a.CallDateTime > dateadd(day, -30, getdate())
AND b.StatusId = 2
ORDER BY
dbo.getCallEntrySerialNoLastTranDateTime(b.CallEntrySerialNumbersId) ASC
// what I tried and causes above error is
ORDER BY
CONVERT(DATE, dbo.getCallEntrySerialNoLastTranDateTime(b.CallEntrySerialNumbersId)) asc
EDIT-added function
ALTER FUNCTION [dbo].[ASP_getCallEntrySerialNoLastTranDateTime]
(
#CallEntrySerialNumbersId bigint
)
RETURNS varchar(500)
AS
BEGIN
DECLARE #ReturnVal NVARCHAR(500);
begin
select #ReturnVal = ( select Top 1 CONCAT(CONVERT(VARCHAR(10),CallTranEndDateTime,103),' ',CONVERT(VARCHAR(10),CallTranEndDateTime,108)) from calltransactions
where CallEntrySerialNumbersId = #CallEntrySerialNumbersId AND CallTranTypeId = 3
order by CallTranId desc)
end;
RETURN #ReturnVal;
END

Try this one -
SET DATEFORMAT dmy
SELECT *
FROM (
SELECT
b.CallId
, ETADate = CONVERT(VARCHAR(25), b.ETADate, 103)
, closingDateTime = dbo.getCallEntrySerialNoLastTranDateTime(b.CallEntrySerialNumbersId)
FROM dbo.CallEntry a
JOIN dbo.CallEntrySerialNumbers b ON a.CallId = b.CallId
WHERE a.ASPId = 2
AND a.CompanyId = 3
AND a.ProdCompanyId = 1
AND ISNULL(b.CallCaseId, '') NOT LIKE 'NA'
AND ProdCategoryid = 1
AND a.CallDateTime > DATEADD(day, -30, GETDATE())
AND b.StatusId = 2
) d
ORDER BY CAST(d.closingDateTime AS DATE)
ALTER FUNCTION [dbo].[ASP_getCallEntrySerialNoLastTranDateTime]
(
#CallEntrySerialNumbersId BIGINT
)
RETURNS VARCHAR(30)
AS BEGIN
DECLARE #ReturnVal VARCHAR(30)
SELECT #ReturnVal = (
SELECT TOP 1 CONVERT(VARCHAR(10), CallTranEndDateTime, 103) + ' ' + CONVERT(VARCHAR(10), CallTranEndDateTime, 108)
FROM dbo.CallTransactions
WHERE CallEntrySerialNumbersId = #CallEntrySerialNumbersId
AND CallTranTypeId = 3
ORDER BY CallTranId DESC
)
RETURN #ReturnVal
END

Related

Use cross apply function

I have this cross apply query and I want to sum the result of it
CROSS APPLY
(SELECT
SUM(CASE WHEN [day] BETWEEN #FirstDay AND #LastDay
THEN 1 ELSE 0
END) AS UsedDays
FROM
Calendar c
WHERE
([day] >= r.[DateFrom]
AND [day] <= r.[DateTo]
AND [WorkDay] = 1)) calculateUsedDays
I have a request table that contains different requests from different people
and my point is to sum all of the days from the requests from a person.
The cross apply returns the sum of the days by every request from the requests table for every person.
For example:
person
John, usedDays - 5
John, - 7
Peter - 10
Peter - 5
..
And I want to sum these days and group by name of the person so that I can have all of the days by person.
Example:
John - 12
Peter - 15
I tried with sum and group by , but it returns error:
Each GROUP BY expression must contain at least one column that is not an outer reference
Thank you :))
Thank you guys,
I solved this, but now my problem is: Implicit conversion from data type datetime to int is not allowed. Use the CONVERT function to run this query.
This is my code
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [core].[ReportBalanceYearSearch]
#Year int = NULL,
#TypeOfLeaveGid int = NULL,
#IsActive int = NULL
AS
BEGIN
SET NOCOUNT ON
DECLARE #Err int
DECLARE #sql nvarchar (max), #paramlist nvarchar(max)
DECLARE #FirstDay datetime
DECLARE #LastDay datetime
DECLARE #typeLeaveGid INT, #typeCreditGid INT, #relLeaveToCreditGid INT
SET #FirstDay = DATEFROMPARTS ( #Year, 1, 1)
SET #LastDay = DATEFROMPARTS ( #Year, 12, 31)
SELECT #typeLeaveGid = gid FROM Nomenclature WHERE type = 'RequestType' and Code = 1
SELECT #typeCreditGid = gid FROM Nomenclature WHERE type = 'RequestType' and Code = 2
SELECT #relLeaveToCreditGid = gid FROM Nomenclature WHERE type = 'Relation' and Code = 6
SELECT #sql = '
SELECT u.[Name],
u.[DepartmentGid],
sum(calculateUsedDays.UsedDays - isnull(calculateCreditDays.CreditDaysInPeriod,0)) as [UsedDays],
ub.[Balance],
sum(calculateUsedDays.UsedDays - isnull(calculateCreditDays.CreditDaysInPeriod,0)) + ub.[Balance] as [TotalDaysInYear],
r.[LeaveTypeGid]
FROM [dbo].[Request] r
inner join [User] u on r.[UserGid] = u.[Gid]
inner join [UserBalance] ub on r.[UserGid] = ub.UserGid and ub.Year = #xYear
LEFT OUTER JOIN dbo.Request CRD
inner join Relations rel ON rel.RelID2 = CRD.Gid AND rel.RelType = #xrelLeaveToCreditGid
inner join Nomenclature nsc ON nsc.Gid = CRD.StatusGid
cross apply (SELECT
sum(case when [day] between COALESCE(#xFirstDay, [day]) AND COALESCE(#xLastDay, [day]) then 1 else 0 end) as CreditDaysInPeriod
FROM Calendar c
WHERE [day] >= crd.[DateFrom] AND [day] <= crd.[DateTo] AND [WorkDay] = 1 ) calculateCreditDays
ON rel.RelID1 = r.Gid
and CRD.TypeGid = #xtypeCreditGid
cross apply (SELECT
sum(case when [day] between #xFirstDay and #xLastDay then 1 else 0 end) as UsedDays
FROM Calendar c
WHERE ([day] >= r.[DateFrom] AND [day] <= r.[DateTo] AND [WorkDay] = 1))calculateUsedDays
where #xYear = DATEPART(year,r.[DateFrom]) and r.TypeGid = #xtypeLeaveGid and #xIsActive IS NULL OR u.[Active] = #xIsActive
group by u.[Name], u.[DepartmentGid],r.[LeaveTypeGid], ub.[Balance]'
SELECT #paramlist ='
#xTypeOfLeaveGid int,
#xFirstDay datetime,
#xYear int,
#xLastDay datetime,
#xtypeLeaveGid int,
#xrelLeaveToCreditGid int,
#xtypeCreditGid int,
#xIsActive bit'
EXEC sys.sp_executesql #sql, #paramlist,
#TypeOfLeaveGid,
#Year,
#IsActive,
#typeLeaveGid,
#relLeaveToCreditGid,
#typeCreditGid,
#FirstDay,
#LastDay
SET #Err = ##Error
RETURN #Err
END

How to replace a SQL While Loop with a Select

We have a procedure that uses the below While..Loop to calculate the total number of Days and Weeks paid for absences in our PayRoll System:
EDITED
Declare #Absences Table (slno int identity (1,1),AbsenceId int, ToDate datetime)
INSERT INTO #Absences (AbsenceID,ToDate)
Select AbsenceID, AB.ToDate
from t_Absence AB with (nolock)
Inner Join t_AbsenceCategory AB_CAT with (nolock) ON (AB.AbsenceCategoryID = AB_CAT.AbsenceCategoryID)
where (AB_CAT.IsSSP =1)
and ClientID = #ClientID
and AB.FromDate >= #SSPYearStart --D7830 SJH 21/10/2015
order BY AB.ToDate desc
Declare #AbsenceID INT, #iCtr INT, #maxRows int
Declare #FromDate datetime
SELECT #iCtr = 1, #maxRows = MAX(slno) FROM #Absences
Select #SSPDaysPaid = 0, #SSPweeksPaid = 0, #QualifyingDaysInWeek = 0
If IsNull(#maxRows,0) > 0 select #FromDate = FromDate from t_Absence where AbsenceID = (SELECT AbsenceID FROM #Absences WHERE slno = 1)
WHILE ( #ictr <= #maxRows )
BEGIN
SELECT #AbsenceID = AbsenceID
FROM #Absences
WHERE slno = #iCtr
--Print #AbsenceID
If Exists (Select TOP 1 1 from t_Absence where ToDate > DATEADD(dd,-56, #FromDate))
BEGIN
SELECT #SSPDaysPaid = #SSPDaysPaid + IsNull(A.SSPDays,0),
#FromDate = A.FromDate
from t_Absence A
where A.AbsenceID = #AbsenceID
print '#SSPDaysPaid=' + CAST(#SSPDaysPaid AS Varchar(3)) + ' in Absence ' + cast(#AbsenceID as varchar(6))
DECLARE #Monday int, #Tuesday int, #Wednesday int, #Thursday int, #Friday int, #Saturday int, #Sunday int
SELECT #Monday = QD.Monday, #Tuesday = QD.Tuesday, #Wednesday =QD.Wednesday, #Thursday =QD.Thursday,
#Friday = QD.Friday, #Saturday = QD.Saturday, #Sunday = QD.Sunday
from t_PayrollEmployeeSSPQualifyingDays QD
inner JOIN t_Absence A on A.ClientID = QD.ClientID and A.FromDate = QD.DateFrom AND A.ToDate = QD.DateTo
where A.ClientID = #ClientId
SET #QualifyingDaysInWeek = #Monday + #Tuesday + #Wednesday + #Thursday + #Friday + #Saturday + #Sunday
print '#QualifyingDaysInWeek = ' + cast(#QualifyingDaysInWeek as char(2))
END
SET #iCtr = #iCtr + 1
END
if #QualifyingDaysInWeek <> 0 Set #SSPWeeksPaid = #SSPDaysPaid/#QualifyingDaysInWeek Else Set #SSPWeeksPaid = 0
print '#SSPWeeksPaid=' + cast(#SSPWeeksPaid as varchar(2))
Select
BradfordFactor
, CSPFDEntitlement
, CSPHDEntitlement
, CSPDaysTaken
, HasContract
, CSPFullDaysTaken
, CSPHalfDaysTaken -- DevTask 112703 06/11/2012 SWB Start
, IsNull(#SSPDaysPaid,0) as 'SSPDaysPaid'
, IsNull(#SSPWeeksPaid,0) as 'SSPWeeksPaid'
from
fn_GetEmployeeBradfordFactor(#ClientID,DEFAULT,0, DEFAULT)
END
As I need to find out this information for several different persons I will have to execute this stored proc and loop once for each client Id (#ClientId) identified in the calling procedure ...
Is there an alternative to this loop and would it be worth it in terms of performance?
Based on the OP comment, no other value is needed from the loop, but #QualifyingDaysInWeek
#RicardoC : Well I don't need the prints (they're there for debugging and analysis) but I do need to sum the values #QualifyingDaysInWeek in for each record in the table #Absences
There appears to be no need for the loop at all.
Declare #Absences Table (slno int identity (1,1),AbsenceId int, ToDate datetime)
INSERT INTO #Absences (AbsenceID,ToDate)
Select AbsenceID, AB.ToDate
from t_Absence AB with (nolock)
Inner Join t_AbsenceCategory AB_CAT with (nolock) ON (AB.AbsenceCategoryID = AB_CAT.AbsenceCategoryID)
where (AB_CAT.IsSSP =1)
and ClientID = #ClientID
and AB.FromDate >= #SSPYearStart --D7830 SJH 21/10/2015
order BY AB.ToDate desc
DECLARE #QualifyingDaysInWeek INT
SELECT #QualifyingDaysInWeek = SUM(QD.Monday + QD.Tuesday + QD.Wednesday + QD.Thursday + QD.Friday + QD.Saturday + QD.Sunday)
FROM t_PayrollEmployeeSSPQualifyingDays QD
INNER JOIN t_Absence A ON A.ClientID = QD.ClientID
AND A.FromDate = QD.DateFrom
AND A.ToDate = QD.DateTo
WHERE A.ClientID = #ClientId;

Issue in T-SQL while checking null variable

I am writing a trigger in SQL Server like this
DECLARE #N_CATComp smallint, #EXON varchar(69), #DATEDEB varchar(15), #DATEFIN varchar(15)
SELECT
#N_CATComp = N_CATCompta,
#EXON =[Exon N°],
#DATEDEB = CONVERT(varchar(15), [Date début] , 103),
#DATEDEB = CONVERT(varchar(15), [Date début] , 103)
FROM INSERTED
IF (#N_CATComp =4) AND ( ISNULL(#EXON,'')='' OR ISNULL(#DATEDEB,'') ='' OR ISNULL(#DATEFIN,'') ='')
BEGIN
RAISERROR('false',11,1)
END
MY problem is that when #exon, #datedeb,#datefin are not null and catcomp=4 the raiserror appears which it shouldn't
i tried to elpace isnull by for example len(#EXON)=0 in this case ven if the values are null then the raiserror don't appears
Here is the same thing with all those scalar variables removed.
IF EXISTS
(
SELECT *
from inserted
where N_CATCompta = 4
AND
(
ISNULL([Exon N°], '') = ''
OR
ISNULL([Date début], '') = ''
)
)
RAISERROR('false',11,1)

Using maxrecursion in INSERT query

Thank you for looking at this.
I have two CTE tables that generate duty times, the calculations are convoluted so wont bother you with them.
Here is the SQL (Simplified)
DECLARE #StartDate Datetime -- Start Date for the Duties to be generated
DECLARE #PatternStartPoint int --Start Point in Pattern eg 3 -
DECLARE #PatternSize int --The length of the shift pattern
DECLARE #User int
SET #User = 1111;
SET #PatternSize = 3;
SET #DaysRequired=16; --Testing assume 16
SET #StartDate = DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE())); --for testing use today
SET #PatternStartPoint =3;
--Get Job Duty Pattern
WITH Pattern (P_DayNumber, P_DayType, P_Start, P_End)
AS
(
Select D_DayNumber,D_Type,D_Start,D_End
from dbo.Tbl_Jobs as J
join dbo.Tbl_Patterns as P
on J.J_PatternID = P.Pattern_ID
join dbo.Tbl_PatternDetails as D
on P.Pattern_ID=d.D_Pattern_ID
)
,
--Get DateList
Datelist (MyDate, DayNumber) AS
(
SELECT #StartDate AS MyDate, #PatternStartPoint as DayNumber
UNION ALL
Select MyDate + 1, (DayNumber+1) - (CAST((Daynumber+1)/(#PatternSize+.01) as int)*#PatternSize) --% (#PatternSize)
FROM Datelist
WHERE MyDate < (#Startdate + #DaysRequired)-1
)
INSERT INTO [IDAHO].[dbo].[Appointments]
([Subject]
,[Description]
,[Start]
,[End]
,[RoomID]
,[UserID]
)
(
SELECT
'Standard Work Pattern'
,'IDAHO Generated on ' + CONVERT(nvarchar(20),getdate())
,mydate + p.P_Start
,mydate + p.P_End
,1
,#User as A_User
FROM Datelist as d
join Pattern as p
on p.P_DayNumber=d.DayNumber
Where mydate + p.P_Start is not null
OPTION (MAXRECURSION 0)
)
I am getting an error with the MAXRECURSION line, if I remove the line and try to generate more than 100 'Duties' it errors (being the default value).
If I Change the last statement to a simple select it seems to work??? as shown below
DECLARE #StartDate Datetime -- Start Date for the Duties to be generated
DECLARE #PatternStartPoint int --Start Point in Pattern eg 3 -
DECLARE #PatternSize int --The length of the shift pattern
DECLARE #DaysRequired int --The length of the shift pattern
DECLARE #User int
SET #User=1111;
SET #PatternSize = 3;
SET #DaysRequired=160; --Testing assume 16
SET #StartDate = DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE())); --for testing use today
SET #PatternStartPoint =3;
--Get Job Duty Pattern
WITH Pattern (P_DayNumber, P_DayType, P_Start, P_End)
AS
(
Select D_DayNumber,D_Type,D_Start,D_End
from dbo.Tbl_Jobs as J
join dbo.Tbl_Patterns as P
on J.J_PatternID = P.Pattern_ID
join dbo.Tbl_PatternDetails as D
on P.Pattern_ID=d.D_Pattern_ID
)
,
--Get DateList
Datelist (MyDate, DayNumber) AS
(
SELECT #StartDate AS MyDate, #PatternStartPoint as DayNumber
UNION ALL
Select MyDate + 1, (DayNumber+1) - (CAST((Daynumber+1)/(#PatternSize+.01) as int)*#PatternSize) --% (#PatternSize)
FROM Datelist
WHERE MyDate < (#Startdate + #DaysRequired)-1
)
SELECT
'Standard Work Pattern'
,'IDAHO Generated on ' + CONVERT(nvarchar(20),getdate())
,mydate + p.P_Start
,mydate + p.P_End
,1
,#User as A_User
FROM Datelist as d
join Pattern as p
on p.P_DayNumber=d.DayNumber
Where mydate + p.P_Start is not null
OPTION (MAXRECURSION 0)
Have I put the command in the wrong place?
Why does it work with select but not insert?
Thank you
I think its because the CTE doesn't finally get assembled into a result set until the final select is run, which is why tour second query works. To make the insert work, try:
DECLARE #StartDate Datetime -- Start Date for the Duties to be generated
DECLARE #PatternStartPoint int --Start Point in Pattern eg 3 -
DECLARE #PatternSize int --The length of the shift pattern
DECLARE #DaysRequired int --The length of the shift pattern
DECLARE #User int
SET #User=1111;
SET #PatternSize = 3;
SET #DaysRequired=160; --Testing assume 16
SET #StartDate = DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE())); --for testing use today
SET #PatternStartPoint =3;
--Get Job Duty Pattern
INSERT INTO [IDAHO].[dbo].[Appointments]
([Subject]
,[Description]
,[Start]
,[End]
,[RoomID]
,[UserID]
)
select *
from
(
SELECT
'Standard Work Pattern' [Subject]
,'IDAHO Generated on ' + CONVERT(nvarchar(20),getdate()) [Description]
,mydate + p.P_Start [Start]
,mydate + p.P_End [End]
,1 [RoomID]
,#User [UserID]
FROM
(
SELECT #StartDate AS MyDate, #PatternStartPoint as DayNumber
UNION ALL
Select MyDate + 1, (DayNumber+1) - (CAST((Daynumber+1)/(#PatternSize+.01) as int)*#PatternSize) --% (#PatternSize)
FROM Datelist
WHERE MyDate < (#Startdate + #DaysRequired)-1
) as d
join
(
Select D_DayNumber,D_Type,D_Start,D_End
from dbo.Tbl_Jobs as J
join dbo.Tbl_Patterns as P
on J.J_PatternID = P.Pattern_ID
join dbo.Tbl_PatternDetails as D
on P.Pattern_ID=d.D_Pattern_ID
) as p
on p.P_DayNumber=d.DayNumber
Where mydate + p.P_Start is not null
) x;
That might work.
(Expanded as requested)
(Amended to remove CTEs)

Combine two select statements for date comparison

Hi I have the following statement:
DECLARE #currentWEEK INT
DECLARE #previousWEEK INT
DECLARE #CURRENDATE DATETIME
DECLARE #PREVIOUSDATE DATETIME
SET #PREVIOUSDATE = YEAR(DATEADD(YEAR, -1, GETDATE()))
SET #CURRENDATE = GETDATE()
SET #currentWEEK = RIGHT(DATENAME(wk,'2013-05-17 00:00:00.000'),2)
SET #previousWEEK = RIGHT(DATENAME(wk,'2012-05-17 00:00:00.000'),2)
SELECT COUNT(*)
FROM vevents
WHERE RIGHT(DATENAME(wk,dbo.vEvents.DateCreated),2) = #currentWEEK
AND
YEAR(dbo.vEvents.DateCreated) = YEAR(#CURRENDATE)
SELECT COUNT(*)
FROM vevents
WHERE RIGHT(DATENAME(wk,dbo.vEvents.DateCreated),2) = #previousWEEK
AND
YEAR(dbo.vEvents.DateCreated) = #PREVIOUSDATE
Essentially it compares a total for two dates within a given week, but I would like to combine the two select statements for given dates to return a single record set(eg CURRENTYEARCOUNT AND PREVIOUSYEARCOUNT)
Many thanks for your help
Try this one -
DECLARE
#currentWEEK INT
, #previousWEEK INT
, #CURRENDATE DATETIME
, #PREVIOUSDATE DATETIME
SELECT
#PREVIOUSDATE = YEAR(DATEADD(YEAR, -1, GETDATE()))
, #CURRENDATE = GETDATE()
, #currentWEEK = RIGHT(DATENAME(wk, '20130517'), 2)
, #previousWEEK = RIGHT(DATENAME(wk, '20120517'), 2)
SELECT
COUNT(CASE WHEN YEAR(e.DateCreated) = #PREVIOUSDATE THEN 1 END)
, COUNT(CASE WHEN YEAR(e.DateCreated) = YEAR(#CURRENDATE) THEN 1 END)
FROM dbo.vEvents e
WHERE RIGHT(DATENAME(wk, e.DateCreated), 2) = #currentWEEK

Resources