代码之家  ›  专栏  ›  技术社区  ›  Bodhi

将varchar值“T70001”转换为数据类型int时,转换失败?

  •  0
  • Bodhi  · 技术社区  · 6 年前

    使用以下查询时,我收到了上述错误

     SELECT  b.*,E.SSNO
      FROM [SRV-RVS].[dbo].[CARD] b
      INNER JOIN [SRV-RVS].dbo.EMP e
      on b.EMPID=E.SSNO 
      WHERE E.SSNO LIKE 't%' 
    

    我正在尝试连接这两个表,这里我的EMPID与SSNO相同,但它在开头有一个字符。

    希望你收到了

    当做

    3 回复  |  直到 6 年前
        1
  •  1
  •   Igor    6 年前

    您可以转换 EMPID 到a varchar 并添加 'T' join子句中的字符。

    SELECT  b.*,E.SNO
    FROM [SRV-RVS].[dbo].[CARD] b INNER JOIN [SRV-RVS].dbo.EMP e ON ('T' + REPLACE(STR(CAST(b.EMPID as varchar(9)), 9), SPACE(1), '0')) = E.SSNO 
    WHERE E.SNO LIKE 't%' 
    

    其他注释

    • 我猜测了varchar的长度,但SSN通常总是9位数。如果存储掩码/空格字符,如 - 在您的 SSNO 列此代码将不起作用。
    • 在那里有代码,以0填充以0开头的SSN编号的id,因为int-to-string不会自动填充0。
    • 如果数据集很大,可能会导致性能问题。
    • 实际上,模式一开始就不应该将SSN转换为int(数字)。它应该保持为varchar字段,理想情况下也不要设置为另一个表上的主键。

    再次(从最后一个项目符号继续),更改架构或添加计算列。目前这是一个糟糕的设计。

        2
  •  1
  •   Gordon Linoff    6 年前

    修复您的表,以便执行联接。此答案的其余部分假设您使用的是SQL Server(基于问题中代码的语法)。

    我鼓励您:

    alter table emp
        add column ssno as ( cast(stuff(empid, 1, 1, '') as int) );
    

    或任何匹配的类型。您甚至可以在此基础上建立索引。

    那么您的代码就不必记住关于 empid ssno .

        3
  •  1
  •   Ven    6 年前

    通过从字符串中提取数值来连接表,以便它在Id列上匹配。只要行数据中没有任何其他意外,它就会返回结果。这是通过在一开始就消除角色来实现的。

      SELECT  b.*,E.SSNO
      FROM [SRV-RVS].[dbo].[CARD] b
      INNER JOIN [SRV-RVS].dbo.EMP e
      on right(b.EMPID, len(b.EMPID) - (PatIndex('%[0-9]%', b.EMPID )-1) ) 
         =right(E.SSNO, len(E.SSNO) - (PatIndex('%[0-9]%', E.SSNO )-1) )