将varchar值转换为数据类型int时,存储过程转换失败?

时间:2012-05-09 06:45:57

标签: c# asp.net sql-server tsql stored-procedures

在我的存储过程中,我遇到了以下问题 - 我该如何解决这个问题?

CREATE PROC RupeshTest(@QueID int, @Answer varchar(250)) as
BEGIN
   DECLARE @STR varchar(4000) 

   SELECT @STR = COALESCE(@str + ';','') + AnswerText     
   FROM SurveyQuestionAnswerTypes 
   WHERE AnswerType = (SELECT AnswerType 
                       FROM SurveyQuestions 
                       WHERE QuestionID = CAST(@QueId AS VARCHAR(4))) 
                         AND AnswerValue IN (REPLACE(@Answer,'^',','))
END

我跑的时候

RupeshTest 25, '2^3^5^7^8' 

我收到以下错误

  

Msg 245,Level 16,State 1,Procedure RupeshTest,Line 4
  将varchar值'2,3,5,7,8'转换为数据类型int时,转换失败。

虽然我理解了这个问题,但无法解决问题,但有些人可以告诉我如何解决它。

3 个答案:

答案 0 :(得分:2)

这不会起作用,因为形成的最终查询是:

SELECT @STR = COALESCE(@str + ';','') + AnswerText     
   FROM SurveyQuestionAnswerTypes 
   WHERE AnswerType = (SELECT AnswerType 
                       FROM SurveyQuestions 
                       WHERE QuestionID = CAST(@QueId AS VARCHAR(4))) 
                         AND AnswerValue IN ('2,3,5,7,8')

你想要这样的地方:

SELECT @STR = COALESCE(@str + ';','') + AnswerText     
   FROM SurveyQuestionAnswerTypes 
   WHERE AnswerType = (SELECT AnswerType 
                       FROM SurveyQuestions 
                       WHERE QuestionID = CAST(@QueId AS VARCHAR(4))) 
                         AND AnswerValue IN (2,3,5,7,8)

我建议您创建一个UDF String_To_Table,将该字符串传递给该UDF并用于IN子句。

String_To_Table UDF:

CREATE FUNCTION [dbo].[String_To_Table]
                    (@string      VARCHAR(4000),
                     @delimiter CHAR(1) = ';')
         RETURNS @tbl TABLE (ord INT IDENTITY(1, 1) NOT NULL,
                             token     VARCHAR(500)) AS

   BEGIN
      DECLARE @pos      int,
              @textpos  int,
              @chunklen smallint,
              @tmpstr   varchar(4000),
              @leftover varchar(4000),
              @tmpval   varchar(4000)

      SET @textpos = 1
      SET @leftover = ''
      WHILE @textpos <= datalength(@string)
      BEGIN
         SET @chunklen = 4000 - datalength(@leftover)
         SET @tmpstr = @leftover + substring(@string, @textpos, @chunklen)
         SET @textpos = @textpos + @chunklen

         SET @pos = charindex(@delimiter, @tmpstr)

         WHILE @pos > 0
         BEGIN
            SET @tmpval = ltrim(rtrim(left(@tmpstr, @pos - 1)))
            INSERT @tbl (token) VALUES(@tmpval)
            SET @tmpstr = substring(@tmpstr, @pos + 1, len(@tmpstr))
            SET @pos = charindex(@delimiter, @tmpstr)
         END

         SET @leftover = @tmpstr
      END

    IF ltrim(rtrim(@leftover)) <> ''
        INSERT @tbl(token) VALUES (ltrim(rtrim(@leftover)))


 RETURN
   END

然后您可以更改您的SP,如下所示:

CREATE PROC RupeshTest(@QueID int, @Answer varchar(250)) as
BEGIN
   DECLARE @STR varchar(4000) 

   SELECT @STR = COALESCE(@str + ';','') + AnswerText     
   FROM SurveyQuestionAnswerTypes 
   WHERE AnswerType = (SELECT AnswerType 
                       FROM SurveyQuestions 
                       WHERE QuestionID = CAST(@QueId AS VARCHAR(4))) 
                         AND AnswerValue IN (SELECT Token FROM dbo.String_To_Table(@Answer,'^'))
END

答案 1 :(得分:1)

您在这里遇到的问题是部分AnswerValue IN (2,3,5,7,8)以及如何使其成为有效的SQL,因为这些值是整数列表,您将它们作为字符串。对我来说,一个技巧是使所有SQL命令成为一个字符串并执行它:

DECLARE @SQLQuery AS varchar(4000)

SET SQLQuery = 
'SELECT AnswerText '
+ ' FROM SurveyQuestionAnswerTypes '
+ ' WHERE AnswerType = (SELECT AnswerType '
                   + ' FROM SurveyQuestions '
                   + ' WHERE QuestionID = ' + CAST(@QueId AS VARCHAR(4))) 
                    + ' AND AnswerValue IN (' + (REPLACE(@Answer,'^',',')) + ')'


EXECUTE(@SQLQuery)                  
顺便说一句,没有理由用^发送数字然后改变它。

答案 2 :(得分:0)

您可以用

替换最后一个条件
AND CHARINDEX(CONCAT("^", CAST(AnswerValue AS CHAR), "^"), CONCAT("^", @Answer, "^"))

这似乎并不完全正确,但它可能会成功。

<强>编辑

感谢您的更正。