我在使用代码生成的特定T-SQL查询时遇到了问题。
下面是代码,第一个DECLARE
块是从代码发送的,因此这些值会发生变化。
XML业务与将CSV NVARCHAR
转换为临时表格有关。
-- DECLARE BLOCK IS SENT BY CODE FROM DIALOG BOX
DECLARE @IdString NVARCHAR(MAX) ='F6LC1'
DECLARE @pm_StartDate DATETIME ='20180201'
-- END DECLARE BLOCK
DECLARE @listOfIds table(entityId nvarchar(50));
DECLARE @x XML
SELECT @x = CAST('<A>'+ REPLACE(REPLACE(@IdString,' ',''),',','</A><A>')+ '</A>' AS XML)
INSERT INTO @listOfIds
SELECT t.value('.', 'NVARCHAR(50)') AS inVal
FROM @x.nodes('/A') AS x(t)
DECLARE @pm_StartDateTrim NVARCHAR(MAX) = LEFT(CONVERT(NVARCHAR(MAX),@pm_StartDate,112),6)
DECLARE @intStartDate INT = CAST(@pm_StartDateTrim AS INT)
SELECT @pm_StartDate
SELECT @pm_StartDateTrim
SELECT @intStartDate
SELECT gl.[ACCTNUM]
,acc.[ACCTNAME]
,gl.[ENTITYID]
,CONVERT(INT,gl.[PERIOD]) AS periodConverted
,gl.[ACTIVITY]
,bldg.[BLDGNAME]
,bldg.[BLDGGLA]
,gl.[BALFOR]
FROM [dbo].[GLSUM] AS gl
INNER JOIN [dbo].[BLDG] AS bldg ON gl.[ENTITYID] = bldg.[BLDGID]
INNER JOIN [dbo].[GACC] AS acc ON gl.[ACCTNUM] = acc.[ACCTNUM]
WHERE gl.ENTITYID IN (SELECT entityId FROM @listOfIds)
AND gl.BASIS = 'A'
AND gl.ACTIVITY != 0
AND gl.PERIOD NOT LIKE '%[^0-9]%'
AND CONVERT(INT,gl.[PERIOD]) >= @intStartDate
ORDER BY gl.PERIOD ASC
我正在尝试仅包含PERIOD
大于或等于所提供的StartDate
的记录。
PERIOD
数据库中的数据仅为YYYYMM
,与201502
类似。
StartDate
提供的数据为DATETIME
,因此我转换为YYYYMM
进行比较。
我正在尝试同时使用INT
,因此我可以使用<
或>
或=
等进行比较。
所以,如果我留在第2行到最后一行AND CONVERT(INT,gl.[PERIOD]) >= @intStartDate
,那么我得到Conversion failed when converting the varchar value 'R2W274' to data type int.
问题在于我的数据中没有这样的值。
当我注释掉那一行时,我得到数据并且R2W274
在任何记录的任何字段中都找不到。{/ p>
我认为R2W274
值实际上在gl.ENTITYID
字段中,但在我的任何记录中都没有,通常只在数据库中。
所以,我不确定为什么这个查询甚至试图首先转换gl.ENTITYID
。
任何帮助?
更新
我在上面的WHERE
子句中添加了推荐的附加内容。我仍然得到同样的错误。
答案 0 :(得分:3)
请确保没有返回的数据:
select * from [dbo].[GLSUM] where [Period] = 'R2W274'
添加这样的try / catch块会有所帮助:
BEGIN TRY
-- Generate divide-by-zero error.
your select query comes here.
END TRY
BEGIN CATCH
-- Execute error retrieval routine.
print 'error';
END CATCH;
尝试/捕获块引用:https://docs.microsoft.com/en-us/sql/t-sql/language-elements/try-catch-transact-sql
我要做的是在where子句中删除这些数据:
WHERE gl.ENTITYID IN (SELECT entityId FROM @listOfIds)
AND gl.BASIS = 'A'
AND gl.ACTIVITY != 0
AND gl.[PERIOD] not like '%[^0-9]%'
AND CONVERT(INT,gl.[PERIOD]) >= @intStartDate
编辑:我原本期待where子句会修改它,感到惊讶的是它无法正常工作。请确保在包含转换的过滤器之前添加了过滤器。也许使用像这样的临时表会更安全:
select *
into #temp_glsum
from [dbo].[GLSUM] gl
WHERE gl.[PERIOD] not like '%[^0-9]%'
并在主查询中使用#temp_glsum
而不是[dbo].[GLSUM]