循环遍历列以检查 SQL 服务器中的转换是否成功

Looping through a column to check if a cast succeeds in SQL Server

我正在尝试检查整个列是否为 varchar 并确保它可以转换为浮动。我有一个像这样的光标部分:

        DECLARE @CastFailed BIT

        SET @CastFailed = (SELECT SUM(CASE WHEN TRY_CAST(@ColumnName AS FLOAT) IS NULL THEN 1
            ELSE 0 END) AS CastResult)

        -- Look at this
        PRINT @CastFailed

        IF @CastFailed > 0
        BEGIN

            PRINT 'ERROR: ' + @ColumnName + ' cannot be converted to FLOAT type'

            SET @HasErrors = 1
   
        END
        ELSE
        BEGIN

            PRINT 'The cast has passed.'

        END

出于某种原因,它总是返回 1。我已经在游标的前一部分(未显示但在上面)中验证了传入的列 (@ColumnName) 在任何时候都不是 NULL。

我需要查明@ColumnName 的所有 CAST 到 FLOAT 是否都有效。游标循环遍历 table 列,一一引入 FETCH @ColumnName。我错过了什么?

这是一个可以避免游标和动态 SQL 的选项。它将动态地 UNPIVOT 您的数据和 return 无法转换为 float

的列

(兼容 2008 和 2012)

例子

Declare @YourTable Table (id int,[Col1] varchar(50),[Col2] varchar(50))  
Insert Into @YourTable Values 
 (1,'1e6','ABC')  -- This Col2 will fail Conversion
,(2,'5.5','25')
,(3,'50.25','0')

Select C.Col
      ,Failed = count(*)
 from  @YourTable A
 Cross Apply ( values ( convert(xml,(Select A.* for XML RAW)) ) )B(XMLData)
 Cross Apply ( 
                Select Col   = xAttr.value('local-name(.)', 'varchar(100)')
                      ,Value = xAttr.value('.','varchar(max)')
                 From  XMLData.nodes('//@*') xNode(xAttr)
             ) C
 Where Col in ('Col1','Col2')  -- Or you can Exclude Columns ...  Where Col NOT in ('id','OtherCols','ToExclude')
   and try_convert(float,value) is null
 Group BY C.Col

结果

Col     Failed
Col2    1

简单:

DECLARE @t TABLE (txt VARCHAR(100));
INSERT  @t VALUES ('ABC123'),('100.00'),('100'),('11.222.333'),('00');

DECLARE @CastFailed BIT = 
  (SELECT ISNULL(MAX(1),0) FROM @t AS t WHERE TRY_CAST(t.Txt AS FLOAT) IS NULL);

SELECT CastFailed = @CastFailed;

为了更好的表现...

DECLARE @t TABLE (txt VARCHAR(100));
INSERT  @t VALUES ('ABC123'),('100.00'),('100'),('11.222.333'),('00');

DECLARE @CastFailed BIT = 
  (ISNULL((SELECT TOP(1) 1 FROM 
    (SELECT 1 FROM @t AS t WHERE TRY_CAST(t.Txt AS FLOAT) IS NULL) AS x(x)),0));

SELECT CastFailed = @CastFailed;