为什么我从 varchar 到 bigint 的转换不起作用?

Why is my conversion from varchar to bigint not working?

我正在尝试从 varchar 转换为 bigint,但不断得到

Error converting data type varchar to bigint.

这是我的语法:

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

这是 json 值的一部分,我从中获取子字符串:

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

所以当 INW: 是 '-' 时,我想插入 null 当 INW: 例如 16489 我想插入这个值(列是 bigint)

我也试过这样的:

CASE SUBSTRING(descr, CHARINDEX('INW: ', descr) + 5, LEN(descr)) 
WHEN '-' THEN NULL 
ELSE CAST(SUBSTRING(descr, CHARINDEX('INW: ', descr) + 5, 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, 1, 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, CHARINDEX('INW: ', descr) + 5, LEN(descr))) WHEN '-' THEN NULL ELSE (SELECT SUBSTRING(descr, CHARINDEX('INW: ', descr) + 5, LEN(descr))) END)
            from cte_a a
        End

有没有人知道如何让它工作?

如果你肯定这个位有效...

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

然后把它包在这个...

CAST(
    NULLIF(
        SUBSTRING(descr, CHARINDEX('INW: ', descr) + 5, LEN(descr)),
        '-'
    )
    AS BIGINT
)

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

编辑:

因为这不起作用,我只能得出结论,您的子字符串并不总是返回您期望的结果。

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

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

当您专注于 sql 部分以找出问题所在时,我也在努力帮助您修复 sql...

你在这里提供

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

这里的子字符串不是您所期望的,这就是它无法将其转换为 bigint 的原因。 您的子字符串逻辑实际上返回了一个字符串,就像您在以下屏幕截图中看到的我的本地模拟一样 -

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

修复是正确控制子串长度。 如果你知道这个数字是 5 个字符长度那么你 sql 可以重写为

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

如果不知道号码的长度,查询将是这样的

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

希望您在实际情况下理解问题和解决方法。

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

Error converting data type varchar to bigint.

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

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

它会给你两件事:

  • 首先,你的问题就解决了,好像函数的输入不能转换为bigint它会给你NULL
  • 其次,您可以隔离 NULL 值并查看是否存在与 - 不同的记录,您的验证未命中并可能产生错误