C# 将varchar值“AL-DMK2_1”转换为数据类型int时,转换失败

C# 将varchar值“AL-DMK2_1”转换为数据类型int时,转换失败,c#,sql-server,stored-procedures,C#,Sql Server,Stored Procedures,对于存储过程,我得到以下异常/错误 将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 a

对于存储过程,我得到以下异常/错误

将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();
         }
    }
调用存储过程:

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值,则抛出具有上述错误的异常。在命令行中执行失败。ExecuteOnQuery

在线提供的任何解决方案都无法解决此错误。 谢谢你的帮助


谢谢

如果从存储过程返回任何内容,它必须能够转换为int,因为SqlCommand的返回类型。ExecuteOnQuery是int,SQL Server存储过程中的return语句只能用于返回整数值,因此为什么ExecuteOnQuery的返回类型为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();
     }
}

如果从存储过程返回任何内容,则必须能够将其强制转换为int,因为SqlCommand的返回类型。ExecuteOnQuery是int,并且SQL Server存储过程中的return语句应仅用于返回整数值,因此为什么ExecuteOnQuery的返回类型为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();
     }
}

您遇到的是一个SQL错误,而不是C。错误本身似乎是不言自明的—您正在尝试将包含字母的VARCHAR转换为INT。请注意:您不应该在存储过程中使用sp_uu前缀。微软已经这样做了,而且你确实有可能在将来的某个时候发生名称冲突。最好只是简单地避免使用sp_u,并使用其他东西作为前缀——或者根本不使用前缀!您遇到的是一个SQL错误,而不是C。错误本身似乎是不言自明的—您正在尝试将包含字母的VARCHAR转换为INT。请注意:您不应该在存储过程中使用sp_uu前缀。微软已经这样做了,而且你确实有可能在将来的某个时候发生名称冲突。最好只是简单地避免使用sp_u,并使用其他东西作为前缀——或者根本不使用前缀!作为旁注,严格来说,不需要手动调用SqlConnection.Close在using块内部,因为dispose方法与Close方法相同,或者调用Close,或者类似的方法。。。。无论如何,如果你想为自己保存一行代码,它不是100%需要的=]只要反编译System.Data来找出它是哪一行。Dispose调用Close:protected override void Disposebool disposing{如果disposing{this.\u userConnectionOptions=DbConnectionOptions null;this.\u poolGroup=DbConnectionPoolGroup null;this.Close;}this.disposemedDisposing;base.Disposedisposing;}谢谢!!!这很有效:……您提出了SP RETURN语句的一个非常重要的概念。对于close vs dispose注释,您是否建议改用dispose?using block为您调用dispose,您会注意到,对于任何未实现IDisposable接口的对象,您都不能使用using block。我应该更清楚地指出=]作为旁注,严格来说,没有必要手动调用SqlConnection.Close在using块内部,因为dispose方法的作用与Close相同,或者它调用Close,或者诸如此类。。。。无论如何,如果你想为自己保存一行代码,它不是100%需要的=]只要反编译System.Data来找出它是哪一行。Dispose调用Close:protected override void Disposebool disposing{如果disposing{this.\u userConnectionOptions=DbConnectionOptions null;this.\u poolGroup=DbConnectionPoolGroup null;this.Close;}this.disposemedDisposing;base.Disposedisposing;}谢谢!!!这很有效:……您提出了SP RETURN语句的一个非常重要的概念。对于close vs dispose注释,您是否建议改用dispose?using block为您调用dispose,您会注意到,对于任何未实现IDisposable接口的对象,您都不能使用using block。我应该说得更清楚些