2013-05-23 3 views
1

저장 프로 시저의 경우 다음과 같은 예외/오류가 발생합니다.varchar 값 'AL-DMK2_1'을 데이터 유형 int로 변환 할 때 변환이 실패했습니다

"varchar 값 AL-DMK2_1을 데이터 유형 int로 변환 할 때 변환이 실패했습니다."

저장 프로 시저 :

ALTER PROCEDURE dbo.sp_generateNewRequestId 
(
@Customer varchar(50), 
@Network_Type varchar(25), 
@Market_Name varchar(50), 

@NewRequestId varchar(50) OUTPUT 
) 

AS 

Begin 

Declare @MarketCode as varchar(10); 
Declare @CustomerPrefix as varchar(10); 

SET @MarketCode = (select Market_Code from Customer_Market_Details where Customer =  @Customer and Network_Type = @Network_Type and Market_Name = @Market_Name); 

SET @CustomerPrefix = (select Customer_Prefix from Customer_Market_Details where Customer = @Customer and Network_Type = @Network_Type and Market_Name = @Market_Name); 

Declare @RequestIDPrefix as varchar(20); 

SET @RequestIdPrefix = @CustomerPrefix + @MarketCode + '_'; 

-- Count how many requests you already have with the same request ID Prefix. 

Declare @RequestCount as int; 

SET @RequestCount = (Select count (*) from request_details where request_id like @RequestIdPrefix + '%'); 
SET @NewRequestId = @RequestIdPrefix + CAST ((@RequestCount + 1) AS varchar); 

While (Exists (Select * from request_details where request_id = @NewRequestId)) 
Begin 
SET @RequestCount = @RequestCount + 1; 
SET @NewRequestId = @RequestIdPrefix + CAST ((@RequestCount + 1) AS varchar); 
end 

RETURN @NewRequestId; 

END 

호출 저장 프로 시저 :

using (SqlConnection connection = new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings["dbString"].ConnectionString)) 
    { 
     using (SqlCommand command = new SqlCommand("dbo.sp_generateNewRequestId", connection)) 
     { 
      command.Parameters.AddWithValue("@Customer", customer); 
      command.Parameters.AddWithValue("@Network_Type", technology); 
      command.Parameters.AddWithValue("@Market_Name", market); 
      command.Parameters.Add("@NewRequestId", SqlDbType.VarChar).Direction = ParameterDirection.Output; 
      command.Parameters["@NewRequestId"].Size = 50; 
      command.CommandType = CommandType.StoredProcedure; 
      connection.Open(); 
      command.ExecuteNonQuery(); 
      connection.Close(); 
     } 
    } 

관찰 :

출력 매개 변수가 @RequestCount로 설정

, 절차가 성공적으로 @RequestCount가 반환합니다.

그러나 다른 varchar 값을 출력하려고하면 앞에서 설명한 오류가 발생하여 예외가 발생합니다. 실행은 라인 command.ExecuteNonQuery()에서 실패합니다.

이 오류로 인해 온라인으로 제공된 모든 솔루션이 없습니다. 귀하의 도움에 감사드립니다!

감사합니다. 저장 프로 시저에서 아무것도 반환하는 경우 SqlCommand.ExecuteNonQuery()의 반환 형식이 int (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executenonquery.aspx) 및 SQL Server 저장 발동의 RETURN 문은 반환 할 수 있어야대로

+1

당신 have ** SQL ** 오류가 아니라 C#입니다. 오류 자체는 오히려 자명하다. 글자를 가진'VARCHAR '을'INT'로 변환하려고한다. – Tim

+4

사이드 노트 : 저장 프로 시저에'sp_' 접두사를 사용하지 말아야합니다 **. Microsoft는 [자체 저장을 위해이 접두어를 예약했습니다 (* 저장 프로 시저 명명 * 참조)] (http://msdn.microsoft.com/en-us/library/ms190669%28v=sql.105%29.aspx) 및 당신은 미래에 언젠가 이름 충돌의 위험을 감수해야합니다. [저장 프로 시저 성능에 좋지 않습니다.] (http://www.sqlperformance.com/2012/10/t-sql-queries/sp_prefix). 'sp_'를 피하고 다른 것을 접두어로 사용하는 것이 가장 좋습니다. –

답변

5

것은, int에 캐스트 할 수 있어야합니다 정수 값 (http://msdn.microsoft.com/en-us/library/ms174998.aspx)입니다. 따라서 ExecuteNonQuery의 반환 유형은 int입니다. 그렇지 않으면 object이됩니다.

은 다음과 같습니다 있도록 거의 단순히 저장된 프로 시저에서 return 문을 제거하고이에

ALTER PROCEDURE dbo.sp_generateNewRequestId 
(
@Customer varchar(50), 
@Network_Type varchar(25), 
@Market_Name varchar(50), 

@NewRequestId varchar(50) OUTPUT 
) 

AS 

Begin 

Declare @MarketCode as varchar(10); 
Declare @CustomerPrefix as varchar(10); 

SET @MarketCode = (select Market_Code from Customer_Market_Details where Customer =  @Customer and Network_Type = @Network_Type and Market_Name = @Market_Name); 

SET @CustomerPrefix = (select Customer_Prefix from Customer_Market_Details where Customer = @Customer and Network_Type = @Network_Type and Market_Name = @Market_Name); 

Declare @RequestIDPrefix as varchar(20); 

SET @RequestIdPrefix = @CustomerPrefix + @MarketCode + '_'; 

-- Count how many requests you already have with the same request ID Prefix. 

Declare @RequestCount as int; 

SET @RequestCount = (Select count (*) from request_details where request_id like @RequestIdPrefix + '%'); 
SET @NewRequestId = @RequestIdPrefix + CAST ((@RequestCount + 1) AS varchar); 

While (Exists (Select * from request_details where request_id = @NewRequestId)) 
Begin 
SET @RequestCount = @RequestCount + 1; 
SET @NewRequestId = @RequestIdPrefix + CAST ((@RequestCount + 1) AS varchar); 
end 

END 

그리고 당신의 C# 코드를 수정 :

string newRequestID = ""; 

using (SqlConnection connection = new SqlConnection(System.Web.Configuration.WebConfigurationManager.ConnectionStrings["dbString"].ConnectionString)) 
{ 
    using (SqlCommand command = new SqlCommand("dbo.sp_generateNewRequestId", connection)) 
    { 
     command.Parameters.AddWithValue("@Customer", customer); 
     command.Parameters.AddWithValue("@Network_Type", technology); 
     command.Parameters.AddWithValue("@Market_Name", market); 
     command.Parameters.Add("@NewRequestId", SqlDbType.VarChar).Direction = ParameterDirection.Output; 
     command.Parameters["@NewRequestId"].Size = 50; 
     command.CommandType = CommandType.StoredProcedure; 
     connection.Open(); 
     command.ExecuteNonQuery(); 

     newRequestID = (string)command.Parameters["@NewRequestId"].Value; 

     connection.Close(); 
    } 
} 
+0

참고로, dispose 메소드가 close와 같거나 close, 또는 이와 비슷한 것을 호출하기 때문에 수동으로'using' 블록 내부에서'SqlConnection.Close()'를 수동으로 호출 할 필요는 없습니다. 어쨌든 코드 라인을 스스로 저장하고 싶다면 100 % 필요하지 않다.] – Sean

+0

'System.Data' 파일을 디 컴파일하면 어떤 파일인지 알 수있다. 'Dispose'는'Close'를 호출합니다 : protected override void Dispose (bool disposing) {if (disposing) {this._userConnectionOptions = (DbConnectionOptions) null; this._poolGroup = (DbConnectionPoolGroup) null; this.Close(); } this.DisposeMe (disposing); base.Dispose (disposing); }' – Sean

+0

감사합니다 !!! 이것은 잘 작동했다 :) ... 그리고 당신은 SP RETURN 문장의 매우 중요한 개념을 제기했다. close vs dispose comment에 대해 –

관련 문제