2012-05-09 3 views
0

В моей хранимой процедуре я столкнулся со следующей проблемой - как я могу это исправить?Ошибка преобразования хранимых процедур при преобразовании значения varchar в тип данных int?

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, уровень 16, состояние 1, процедура RupeshTest, линия 4
Конверсия удалось при преобразовании VARCHAR значение '2,3,5,7,8' к типу данных int.

Хотя я понимаю проблему, но не могу ее исправить, может ли кто-то сказать мне, как я могу ее исправить.

+0

Формирование не работает. :( – NoviceToDotNet

+0

Я сталкиваюсь с проблемой при замене функции. – NoviceToDotNet

+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, проходят string к этому 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

На днях кто-то из MS объяснит мне, почему SQL Server *** все еще *** не имеет встроенного метод «split». –

+1

Важная озабоченность по поводу безопасности: OP, вероятно, должен быть уверен, что входная строка на самом деле не '1^2^3) DROP TABLE Студенты -^4' –

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)     

, кстати, нет никаких причин, чтобы отправить число с ^, а затем изменить его.

0

Вы могли бы заменить последнее условие с

AND CHARINDEX(CONCAT("^", CAST(AnswerValue AS CHAR), "^"), CONCAT("^", @Answer, "^")) 

Это не кажется совершенно правы, но это может сделать трюк.

отредактировал

Спасибо за поправки.

+0

' LOCATE'? в SQL Server? –

+0

Да, я просто подумал. Извините за это, я исправлю это – urraka

+0

LOCATE (MySQL) или CHARINDEX (MSSQL) не будет хорошим решением. SP будет терпеть неудачу, когда вход будет подобен RupeshTest 25, '112^233^225895^9967^1238' результат будет соответствовать 1,2,3,8,9,11,12,23,38 и т. Д. Комбинации –

Смежные вопросы