为什么我从varchar转换为bigint无效?

问题描述

我正在尝试从varchar转换为bigint,但是一直在获取

将数据类型varchar转换为bigint时出错。

这是我的语法:

CASE SUBSTRING(descr,CHARINDEX('INW: ',descr) + 5,LEN(descr)) 
WHEN '-' THEN NULL 
ELSE CONVERT(bigint,SUBSTRING(descr,LEN(descr))) 
END

这是json值的一部分,该值从以下子字符串中获取

{
         "lat": "52.650000","lon": "5.730000","name": "NAGELE","cmt": "PROV: FLEVOLAND,INW: -","desc": "PROV: FLEVOLAND,"sym": "Medium City"
      },{
         "lat": "52.670000","lon": "5.600000","name": "URK",INW: 16489",

所以当INW:为'-'时,我想插入null 当INW:例如16489时,我要插入此值(列为bigint)

我也这样尝试过:

CASE SUBSTRING(descr,LEN(descr)) 
WHEN '-' THEN NULL 
ELSE CAST(SUBSTRING(descr,LEN(descr)) AS bigint) 
END

这是我的JSON对象循环:

begin
            declare @_StateProvinceID int = (NEXT VALUE FOR [Sequences].[StateProvinceID])
            Insert into [Application].[StateProvinces] (StateProvinceID,StateProvinceCode,StateProvinceName,CountryID,SalesTerritory)
            values(@_StateProvinceID,UPPER(SUBSTRING (@StateProvince,1,2)),@StateProvince,@_CountryID,@_SalesTerritory)

            declare @_Innerjson VARCHAR(MAX) = @json
            DECLARE @wpt VARCHAR(MAX);
            SET @wpt = JSON_QUERY(@_Innerjson,'$.wpt');

            ;with cte_a as (
            SELECT UPPER(SUBSTRING (@StateProvince,2))[StateProvinceCode],@StateProvince [StateProvince],* FROM  
            OPEnjsON ( @wpt )  
            WITH (name varchar(max) '$.name',lat varchar(max) '$.lat',lon varchar(max) '$.lon',descr varchar(max) '$.desc'))

            Insert Into [Application].[Cities] (StateProvinceID,CityName,Location,LatestRecordedPopulation)
            select @_StateProvinceID,a.name,geography::Point(lat,lon,4326),(CASE (SELECT SUBSTRING(descr,LEN(descr))) WHEN '-' THEN NULL ELSE (SELECT SUBSTRING(descr,LEN(descr))) END)
            from cte_a a
        End

有人知道如何使它工作吗?

解决方法

如果您 肯定 ,则该位有效...

SUBSTRING(descr,CHARINDEX('INW: ',descr) + 5,LEN(descr)) 

然后将其包装在此...

CAST(
    NULLIF(
        SUBSTRING(descr,LEN(descr)),'-'
    )
    AS BIGINT
)

请务必确保您的原始代码段总是首先提供您想要的内容。特别是它永远不会给人意想不到的空间,等等。

编辑:

由于这不起作用,我只能得出结论,您的子字符串并非总是返回您所期望的。

请同时显示 两者 输入字符串(descr 以下结果...(作为对您问题的编辑。)

'>' + SUBSTRING(descr,LEN(descr)) + '<' 
,

好吧,您确定将正确的值传递给Cast / convert函数,但是您得到了:

Error converting data type varchar to bigint.

在这种情况下,最简单的方法是使用TRY_CONVERT函数。像这样:

CASE SUBSTRING(descr,LEN(descr)) 
WHEN '-' THEN NULL 
ELSE TRY_CONVERT(bigint,SUBSTRING(descr,LEN(descr))) 
END

它将给您两件事:

  • 首先,您的问题将得到解决,好像该函数的输入无法转换为bigint一样,它将为您提供NULL
  • 第二秒,您可以隔离NULL的值,看看是否有与-不同的记录,您的验证未命中并可能产生错误
,

当您专注于sql部分以查找错误之处时,我也在尝试帮助您修复sql ...

您在此处提供了

CASE SUBSTRING(descr,LEN(descr)) 
WHEN '-' THEN NULL 
ELSE CONVERT(bigint,LEN(descr))) 
END

这里不是您期望的子字符串,这就是为什么它不能将其转换为bigint。 如下面的屏幕截图所示,您的子字符串逻辑实际上返回了一个类似于我的本地模拟的字符串- enter image description here

现在看看为什么不能将其转换为bigint。

解决方法是正确控制子字符串的长度。 如果您知道数字为5个字符的长度,则可以将sql重写为

CASE SUBSTRING(descr,1) 
WHEN '-' THEN NULL 
ELSE CONVERT(bigint,5)) 
END

如果数字的长度未知,查询将是这样

CASE SUBSTRING(descr,CHARINDEX('",',@someString,@someString)) - CHARINDEX('INW: ',@someString) - 5))) 
END

希望您能根据实际情况了解问题和解决方法。