2013-05-23 4 views
1

Pour une procédure stockée, j'obtiens l'exception/erreur suivante.La conversion a échoué lors de la conversion de la valeur varchar 'AL-DMK2_1' en type de données int

"La conversion a échoué lors de la conversion de la valeur varchar AL-DMK2_1 en type de données int."

procédure stockée:

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 

Appeler procédure stockée:

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(); 
     } 
    } 

Observations:

lorsque le paramètre de sortie est réglée sur @RequestCount, la procédure retourne avec succès @RequestCount.

Mais si une autre valeur varchar est tentée de sortir, l'exception avec l'erreur susmentionnée est levée. L'exécution échoue à la ligne command.ExecuteNonQuery().

Aucune des solutions fournies en ligne n'a fonctionné pour cette erreur. Appréciez votre aide!

Merci!

+1

Qu'est-ce que vous have est une erreur ** SQL **, pas C#. L'erreur elle-même semble plutôt explicite - vous essayez de convertir un 'VARCHAR' qui a des lettres à un' INT'. – Tim

+4

Remarque: vous ne devez pas ** utiliser ** le préfixe 'sp_' pour vos procédures stockées. Microsoft a [réservé ce préfixe pour son propre usage (voir * Naming Stored Procedures *)] (http://msdn.microsoft.com/en-us/library/ms190669%28v=sql.105%29.aspx), et vous courez le risque d'un conflit de noms dans le futur. [Il est également mauvais pour les performances de votre procédure stockée] (http://www.sqlperformance.com/2012/10/t-sql-queries/sp_prefix). Il vaut mieux éviter simplement 'sp_' et utiliser autre chose comme préfixe - ou pas de préfixe du tout! –

Répondre

5

Si vous retournez quoi que ce soit à partir d'une procédure stockée, elle doit pouvoir être jeté à un int comme type de retour de SqlCommand.ExecuteNonQuery() est un int (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executenonquery.aspx) et la déclaration RETURN dans SQL Server procs stockées ne doit être utilisé pour revenir valeurs entières (http://msdn.microsoft.com/en-us/library/ms174998.aspx), donc pourquoi ExecuteNonQuery a un type de retour de int, sinon ce serait object.

Vous êtes presque là, tout simplement se débarrasser de la déclaration de retour dans la procédure stockée de sorte qu'il ressemble à ceci:

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 

Et modifier votre code C# à ceci:

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

En note, il n'est pas strictement nécessaire d'appeler manuellement 'SqlConnection.Close()' à l'intérieur d'un bloc 'using' car la méthode disposer fait la même chose que close, ou appelle close, ou quelque chose comme ça .... De toute façon ce n'est pas 100% nécessaire si vous voulez vous enregistrer une ligne de code =] – Sean

+0

Juste décompilé 'System.Data' pour savoir lequel il était. Les appels 'Dispose'' Close': 'protected override void Dispose (boolisation) {if (disposing) {this._userConnectionOptions = (DbConnectionOptions) null; this._poolGroup = (DbConnectionPoolGroup) null; this.Fermer(); } this.DisposeMe (disposition); base.Dispose (disposition); } ' – Sean

+0

Merci !!! cela a bien fonctionné:) ... et vous avez soulevé un concept très important des déclarations SP RETURN. –

Questions connexes