【问题标题】:Conversion failed when converting the varchar value to data type int in sql在sql中将varchar值转换为数据类型int时转换失败
【发布时间】:2013-07-08 05:28:50
【问题描述】:

我编写了应该返回值的存储过程-

J1
J2
J3

我有一个名为Journal_Entry 的表。当表的行数为 0 时,它会给出结果J1,但随着行数的增加,它会显示错误-

"Conversion failed when converting the varchar value 'J' to data type int."

#这里的Voucher_No 是要保存结果的列。

代码是这样的-

CREATE PROC [dbo].[getVoucherNo]
AS
BEGIN
    DECLARE @Prefix VARCHAR(10)='J'
    DECLARE @startFrom INT=1
    DECLARE @maxCode VARCHAR(100)
    DECLARE @sCode INT
    IF((SELECT COUNT(*) FROM dbo.Journal_Entry) > 0)
    BEGIN
        SELECT @maxCode = CAST(MAX(CAST(SUBSTRING(Voucher_No,LEN(@startFrom)+1,LEN(Voucher_No)- LEN(@Prefix)) AS INT)) AS varchar(100)) FROM dbo.Journal_Entry;
        SET @sCode=CAST(@maxCode AS INT)
        SELECT  @Prefix + LEN(CAST(@maxCode AS VARCHAR(10))+1) + CAST(@maxCode AS VARCHAR(100))
    END
    ELSE
    BEGIN
        SELECT(@Prefix + CAST(@startFrom AS VARCHAR)) 
    END

END

【问题讨论】:

  • 如果可能的话,最好将前缀和数字存储在单独的列中 - 它使上述代码更容易编写。如果前缀始终为J,则根本不需要存储。如果你真的需要的话,你总是可以创建一个计算列,将它们组合成一个列。
  • 我也很难理解为什么您要将CAST MAX 结果返回varchar,只是为了,在下一行,@ 987654331@它回int
  • 实际上我需要结果为 J1,J2 以便它可以在应用程序中显示为凭证号,也可以存储在单列中。
  • 您的数据库结构不应围绕您的显示格式 要求。从逻辑上讲,数字和前缀是您要对其执行处理的两个单独的数据项 - 它们应该位于单独的列中。

标签: sql-server tsql sqldatatypes


【解决方案1】:

您的问题接缝位于此处:

SELECT @maxCode = CAST(MAX(CAST(SUBSTRING(Voucher_No,LEN(@startFrom)+1,LEN(Voucher_No)- LEN(@Prefix)) AS INT)) AS varchar(100)) FROM dbo.Journal_Entry;
SET @sCode=CAST(@maxCode AS INT)

正如错误所说,您将包含字母“J”的字符串转换为INT,显然这是不可能的。

要么修复SUBSTRING,要么不将字母“J”存储在数据库中,仅在读取时添加它。

【讨论】:

    【解决方案2】:

    试试这个 -

    CREATE PROC [dbo].[getVoucherNo]
    AS BEGIN
    
         DECLARE 
                @Prefix VARCHAR(10) = 'J'
              , @startFrom INT = 1
              , @maxCode VARCHAR(100)
              , @sCode INT
    
         IF EXISTS(
              SELECT 1 
              FROM dbo.Journal_Entry
         ) BEGIN
    
              SELECT @maxCode = CAST(MAX(CAST(SUBSTRING(Voucher_No,LEN(@startFrom)+1,ABS(LEN(Voucher_No)- LEN(@Prefix))) AS INT)) AS varchar(100)) 
              FROM dbo.Journal_Entry;
    
              SELECT @Prefix + 
                   CAST(LEN(LEFT(@maxCode, 10) + 1) AS VARCHAR(10)) + -- !!! possible problem here
                   CAST(@maxCode AS VARCHAR(100))
    
         END
         ELSE BEGIN
    
              SELECT (@Prefix + CAST(@startFrom AS VARCHAR)) 
    
         END
    
    END
    

    【讨论】:

    • CAST 截断来自@maxCode 的值,因此CAST(@maxCode AS VARCHAR(10) 等于LEFT(@maxCode, 10)
    【解决方案3】:

    线

    SELECT  @Prefix + LEN(CAST(@maxCode AS VARCHAR(10))+1) + CAST(@maxCode AS VARCHAR(100))
    

    错了。

    @Prefix'J'LEN(...anything...)int,因此类型不匹配。


    在我看来,你确实想做,

    SELECT
            @maxCode = MAX(
                CAST(SUBSTRING(
                    Voucher_No,
                    @startFrom + 1,
                    LEN(Voucher_No) - (@startFrom + 1)) AS INT)
        FROM
            dbo.Journal_Entry;
    
    SELECT  @Prefix + CAST(@maxCode AS VARCHAR(10));
    

    但是,我不能说。如果您在数据之前和之后进行说明,那会有所帮助。

    【讨论】:

      【解决方案4】:

      问题位于下一行

      SELECT  @Prefix + LEN(CAST(@maxCode AS VARCHAR(10))+1) + CAST(@maxCode AS VARCHAR(100))
      

      改用这个

      SELECT  @Prefix + CAST(LEN(CAST(@maxCode AS VARCHAR(10))+1) AS VARCHAR(100)) + CAST(@maxCode AS VARCHAR(100))
      

      完整代码:

      CREATE PROC [dbo].[getVoucherNo]
      
      AS
      
      BEGIN
      
          DECLARE @Prefix VARCHAR(10)='J'
      
          DECLARE @startFrom INT=1
      
          DECLARE @maxCode VARCHAR(100)
      
          DECLARE @sCode INT
      
          IF((SELECT COUNT(*) FROM dbo.Journal_Entry) > 0)
          BEGIN
              SELECT @maxCode = CAST(MAX(CAST(SUBSTRING(VoucharNo,LEN(@startFrom)+1,LEN(VoucharNo)- LEN(@Prefix)) AS INT))+1 AS varchar(100)) FROM dbo.Journal_Entry;
              SET @sCode=CAST(@maxCode AS INT)
              SELECT  @Prefix + CAST(LEN(CAST(@maxCode AS VARCHAR(10))+1) AS VARCHAR(100)) + CAST(@maxCode AS VARCHAR(100))
          END
          ELSE
          BEGIN
              SELECT(@Prefix + CAST(@startFrom AS VARCHAR)) 
          END
      END
      

      【讨论】:

      • 编辑后它工作但为什么它在前缀'J'后添加数字?
      • @droid_rush,这个答案与我的答案相同,只是一个小时后。 stackoverflow.com/a/17568151/659190.
      【解决方案5】:

      我收到了同样的错误信息。就我而言,这是由于没有使用引号。

      虽然该列应该只有数字,但它是一个 Varchar 列,其中一行包含一个字母。

      所以我这样做了:

      select * from mytable where myid = 1234
      

      虽然我应该这样做:

      select * from mytable where myid = '1234'
      

      如果该列包含所有数字,则转换会成功,但在这种情况下不会。

      【讨论】:

        猜你喜欢
        • 2018-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-01
        • 2012-04-10
        • 1970-01-01
        相关资源
        最近更新 更多