解释此SQL错误“将varchar数据类型转换为datetime数据类型导致值超出范围”
这是我存储的程序;当我执行它时,我得到以下错误 Msg 242,16级,状态3,程序TRN\u Hold\u GetData,第45行 将varchar数据类型转换为datetime数据类型导致值超出范围解释此SQL错误“将varchar数据类型转换为datetime数据类型导致值超出范围”,sql,sql-server,Sql,Sql Server,这是我存储的程序;当我执行它时,我得到以下错误 Msg 242,16级,状态3,程序TRN\u Hold\u GetData,第45行 将varchar数据类型转换为datetime数据类型导致值超出范围 XML 17-3-2017中的日期时间可以用两种不同的方式进行解释,其中一种是17个月的第3天无效。确保在XML中使用符合XML标准YYYY-MM-DDThh:MM:ss的显式日期格式,正如Phillip所建议的那样,您确实应该使用通用格式的日期时间字符串。但是,如果您没有控制权,则应正确处理
XML 17-3-2017中的日期时间可以用两种不同的方式进行解释,其中一种是17个月的第3天无效。确保在XML中使用符合XML标准YYYY-MM-DDThh:MM:ss的显式日期格式,正如Phillip所建议的那样,您确实应该使用通用格式的日期时间字符串。但是,如果您没有控制权,则应正确处理转换模式:
ALTER PROCEDURE [dbo].[TRN_Hold_GetData]
@XMLSearch XML = '<DocumentElement><TRN_Hold_GetData_Custom><HoldId>0</HoldId><FromDate>17-3-2017</FromDate><ToDate>17-2-2017</ToDate></TRN_Hold_GetData_Custom></DocumentElement>'
AS
BEGIN
DECLARE @HoldId INT = 0,
@HoldNo VARCHAR(50) = '',
@Party VARCHAR(100) = '',
@StoneNo VARCHAR(50) = '',
@FromDate VARCHAR(50) = '',
@ToDate VARCHAR(50) = '',
@HoldStatus VARCHAR(20) = '',
@FilterQry NVARCHAR(MAX) = '',
@FinalQry NVARCHAR(MAX) = ''
SELECT
@HoldNo = doc.col.value('HoldNo[1]', 'VARCHAR(50)'),
@Party = doc.col.value('Party[1]', 'VARCHAR(MAX)'),
@StoneNo = doc.col.value('StoneNo[1]', 'VARCHAR(MAX)'),
@FromDate = doc.col.value('FromDate[1]', 'VARCHAR(11)'),
@ToDate = doc.col.value('ToDate[1]', 'VARCHAR(11)'),
@HoldStatus = doc.col.value('HoldStatus[1]', 'VARCHAR(20)')
FROM
@XMLSearch.nodes('/DocumentElement/TRN_Hold_GetData_Custom') doc(col)
SELECT
convert(varchar(11), cast(OnHoldDate as datetime), 103),
ISNULL(TH.HoldId, '') AS HoldId,
ISNULL(TH.HoldNo, '') AS HoldNo,
ISNULL(TH.PartyId, '') AS PartyId,
ISNULL(MP.Party, '') AS Party,
ISNULL(TH.OnHoldDate, '') AS HoldDate,
ISNULL(TH.ExpReleaseDays, '') AS ExpReleaseDays,
ISNULL(TH.ExpReleaseDate, '') AS ExpReleaseDate,
ISNULL(TH.TotalPkt, '') AS TotalPkt,
ISNULL(TH.TotalCts, '') AS TotalCts,
HOLDSTONE, RELEASESTONE,
ISNULL(TH.TotalAmount, '') AS TotalAmount,
ISNULL(TH.HoldById, '') AS HoldById,
ISNULL(TH.Remark, '') AS Remark,
ISNULL(MEmp.firstname, '') + ' ' + ISNULL(MEmp.middlename, '') + ' ' + ISNULL(MEmp.lastname, '') AS HoldUser,
ISNULL(MEmp.firstname, '') + ' ' + ISNULL(MEmp.middlename, '') + ' ' + ISNULL(MEmp.lastname, '') AS UnHoldUser
FROM
dbo.TRN_Hold TH WITH ( NOLOCK )
INNER JOIN
( SELECT SUM(CASE WHEN HoldStatus = 0 THEN 1
ELSE 0
END) AS HOLDSTONE, SUM(CASE WHEN HoldStatus = 1 THEN 1
ELSE 0
END) AS RELEASESTONE, HoldId
FROM TRN_Hold_Detail
GROUP BY HoldId ) AS THD ON TH.HoldId = THD.HoldId
INNER JOIN TRN_Hold_Detail AS HDD WITH ( NOLOCK ) ON HDD.HoldId = THD.HoldId
INNER JOIN mst_Stone AS MS WITH ( NOLOCK ) ON HDD.StoneId = MS.Stone_id
LEFT JOIN MST_Party MP ON TH.PartyId = MP.party_id
LEFT JOIN MST_Employee MEmp ON TH.HoldById = MEmp.employee_id
WHERE HoldNo = (
CASE WHEN @HoldNo = '' or @HoldNo is null THEN HoldNo ELSE @HoldNo END ) AND
convert(varchar(11),cast(OnHoldDate as datetime),101)
between
CASE WHEN @FromDate= ''
THEN OnHoldDate
ELSE convert(varchar(11),@FromDate,101)
END
AND
CASE WHEN @ToDate = ''
THEN OnHoldDate
ELSE convert(varchar(11),@ToDate,101)
END
print @FromDate
print @ToDate
--????????????????????????????????????????????????????????????????
--AND ( CASE WHEN convert(varchar(50),cast(@FromDate as datetime),103)= ''
-- THEN convert(varchar(50),cast(@FromDate as datetime),103)
-- ELSE OnHoldDate
-- END ) >= convert(varchar(50),cast(@FromDate as datetime),103)
--AND ( CASE WHEN convert(varchar(50),cast(@ToDate as datetime),103) = ''
-- THEN convert(varchar(50),cast(@ToDate as datetime),103)
-- ELSE OnHoldDate
-- END ) <= convert(varchar(50),cast(@ToDate as datetime),103)
--????????????????????????????????????????????????????????????????
--AND ( @StoneNo = '' OR ms.Stone_no = @stoneNo )
-- --realse
--AND ((@HoldStatus = 'RELEASE' AND ISNULL(THD.HOLDSTONE, 0) = 0 AND ISNULL(THD.RELEASESTONE, 0) <> 0)
-- --Hold
--OR ( @HoldStatus = 'HOLD' AND ISNULL(THD.HOLDSTONE, 0) <> 0 AND ISNULL(THD.RELEASESTONE, 0) = 0)
-- --Partial
--OR (@HoldStatus = 'PARTIAL' AND ISNULL(THD.HOLDSTONE, 0) <> 0 AND ISNULL(THD.RELEASESTONE, 0) <> 0 )
--OR @HoldStatus = 'ALL'
-- )
-- print @FromDate
-- print convert(nvarchar(20), @FromDate ,106)
--print convert(nvarchar(20), @ToDate ,103)
--OnHoldDate between (case when @FromDate ='' then OnHoldDate else @FromDate end)
--and (case when @ToDate = '' then OnHoldDate else @ToDate end)
END
OnHoldDate的值是多少?@mayurgnu我想复制粘贴html解析失败了。传入的XMLSearch变量表面上看起来不是有效的XML,因此不太可能是可测试的。或者添加一个SQL fiddle并参考问题中的内容。为什么要声明像@FromDate这样的变量,而这些变量显然是与日期相关的字符串??您应该始终使用最合适的数据类型—在这里,如果只是日期,则应使用DATE;如果是日期和时间,则应使用DATETIME23
declare @dAsStr varchar(max) = '17-3-2017'
select convert(datetime, @dAsStr, 105)