繁体   English   中英

使用带CONVERT或CAST的WHERE子句的T-SQL查询

[英]T-SQL Query using WHERE clause with CONVERT or CAST

我在代码中生成的特定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.我会得到Conversion failed when converting the varchar value 'R2W274' to data type int.

问题是我的数据中没有这样的值。

当我注释掉那一行时,我得到的数据和R2W274在任何记录的任何字段中都找不到。

我相信R2W274值实际上在gl.ENTITYID字段中,但在我的任何记录中都没有,通常只在DB中。

所以,我不确定为什么这个查询甚至试图首先转换gl.ENTITYID

有帮助吗?

更新:

我在上面的WHERE子句中添加了推荐的附加内容。 我仍然得到同样的错误。

请确保没有返回的数据:

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;

Try / 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]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM