【问题标题】:Can't pass parameters to stored procedure: parameters not supplied无法将参数传递给存储过程:未提供参数
【发布时间】:2018-07-03 09:47:44
【问题描述】:

我有一个用于打印机碳粉库存的 WinForm 桌面应用程序。该数据库位于远程 SQL Server 上,仅由两个订单和交货表组成,库存数量仅通过跟踪订单和交货时间来计算。加上一堆包含制造商、型号、类别等的表格。

我有这个存储过程来提供订单表:

CREATE PROCEDURE [dbo].[spINSERTCARICO] (
    @MARCA VARCHAR(25),
    @MODELLO VARCHAR(25),
    @QTA INT,
    @OPERATORE CHAR(7),
    @CAUSALE VARCHAR(255))
AS
    DECLARE @MODELLOESATTO VARCHAR(25)
    SELECT @MODELLOESATTO = Modello FROM Modelli WHERE Modello = @MODELLO AND Marca = @MARCA
    INSERT INTO Carico 
        (Modello
        ,Qta
        ,DataCarico
        ,Operatore
        ,Note)
    VALUES
        (@MODELLOESATTO
        ,@QTA
        ,GETDATE()
        ,@OPERATORE
        ,@CAUSALE)

正在从这个方法执行:

public static int InsertCarico(string _marca, string _modello, string _causale, int _qta)
{
    int insert = 0;
    try
    {
        if (connection.State == ConnectionState.Closed) connection.Open();
        using (SqlCommand cmd = new SqlCommand("spINSERTCARICO", connection))
        {
            cmd.Parameters.Add("@MARCA", SqlDbType.VarChar).Value = _marca;
            cmd.Parameters.Add("@MODELLO", SqlDbType.VarChar).Value = _modello;
            cmd.Parameters.Add("@QTA", SqlDbType.Int).Value = _qta;
            cmd.Parameters.Add("@OPERATORE", SqlDbType.VarChar).Value = System.Environment.UserName;
            cmd.Parameters.Add("@CAUSALE", SqlDbType.VarChar).Value = _causale;
            cmd.ExecuteScalar();
        }
        return insert;
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        return 0;
    }
}

我总是得到错误

过程或函数“spINSERTCARICO”需要参数“@MARCA”, 没有提供。

但我真的不明白这是从哪里来的。在调试时,我可以看到所有变量都已设置,并且在 SSMS 上手动时,sproc 可以正常工作

EXEC spINSERTCARICO 'OLIVETTI','B0987',1,'_MYPIDN','PROVA'

问题出在哪里?

谢谢, 大卫。

【问题讨论】:

  • 设置CommandType。 cmd.CommandType = CommandType.StoredProcedure; 命令类型的默认值为 Text。
  • @user1672994 我不敢相信。我失去了一小时调试:(((

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


【解决方案1】:

CommandType 的默认值为文本。因此 SqlCommand 对象将提供的 SP 名称视为命令文本,直到您没有将其指定为 StoredProcedure 。所以将CommandType设置为cmd.CommandType = CommandType.StoredProcedure;

public static int InsertCarico(string _marca, string _modello, string _causale, int _qta)
{
    int insert = 0;
    try
    {
       if (connection.State == ConnectionState.Closed) connection.Open();
       using (SqlCommand cmd = new SqlCommand("spINSERTCARICO", connection))
       {
           cmd.CommandType = CommandType.StoredProcedure
           cmd.Parameters.Add("@MARCA", SqlDbType.VarChar).Value = _marca;
           cmd.Parameters.Add("@MODELLO", SqlDbType.VarChar).Value = _modello;
           cmd.Parameters.Add("@QTA", SqlDbType.Int).Value = _qta;
           cmd.Parameters.Add("@OPERATORE", SqlDbType.VarChar).Value = System.Environment.UserName;
           cmd.Parameters.Add("@CAUSALE", SqlDbType.VarChar).Value = _causale;
           insert = cmd.ExecuteScalar();
       }

       return insert;
   }
   catch (Exception ex)
   {
       Console.WriteLine(ex.Message);
       return 0;
   }
}

【讨论】:

    【解决方案2】:

    进行以下 2 项更改:

    cmd.CommandType = CommandType.StoredProcedure; // tell that's an SP
    
    cmd.Parameters.Add("@MARCA", SqlDbType.VarChar).Value = _marca;
    cmd.Parameters.Add("@MODELLO", SqlDbType.VarChar).Value = _modello;
    cmd.Parameters.Add("@QTA", SqlDbType.Int).Value = _qta;
    cmd.Parameters.Add("@OPERATORE", SqlDbType.VarChar).Value = System.Environment.UserName;
    cmd.Parameters.Add("@CAUSALE", SqlDbType.VarChar).Value = _causale;
    
    cmd.ExecuteNonQuery(); // don't expect any return value
    

    【讨论】:

    • 为什么不期待任何返回值?我用它来通知用户操作的成功/失败。有没有更好的办法?
    • @DavideVitali ExecuteScalar() 用于检索结果 SELECT 的第一个值,您的 SP 不会执行该值(它只是插入数据)。 SP 上足够严重的错误将弹出 SQL 异常并跳转到您的通用捕获。
    【解决方案3】:

    请尝试以下代码 -

    public static int InsertCarico(string _marca, string _modello, string _causale, int _qta)
    {
        int insert = 0;
        try
        {
            if (connection.State == ConnectionState.Closed) connection.Open();
            using (SqlCommand cmd = new SqlCommand("spINSERTCARICO", connection))
            {
                cmd.CommandType = CommandType.StoredProcedure;
    
                cmd.Parameters.Add("@MARCA", SqlDbType.VarChar).Value = _marca;
                cmd.Parameters.Add("@MODELLO", SqlDbType.VarChar).Value = _modello;
                cmd.Parameters.Add("@QTA", SqlDbType.Int).Value = _qta;
                cmd.Parameters.Add("@OPERATORE", SqlDbType.VarChar).Value = System.Environment.UserName;
                cmd.Parameters.Add("@CAUSALE", SqlDbType.VarChar).Value = _causale;
                cmd.ExecuteNonQuery();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return 0;
        }
    }
    

    您似乎错过了提供命令类型。

    【讨论】:

      【解决方案4】:

      我最好的猜测是确定

      _马卡

      不为null或为空并添加

      cmd.CommandType = CommandType.StoredProcedure;

      就在您的 using 语句下,不要期望返回值, 像这样

      using (SqlCommand cmd = new SqlCommand("spINSERTCARICO", connection))
      {
          cmd.CommandType = CommandType.StoredProcedure; //Add this
      
          cmd.Parameters.Add("@MARCA", SqlDbType.VarChar).Value = _marca;
          cmd.Parameters.Add("@MODELLO", SqlDbType.VarChar).Value = _modello;
          cmd.Parameters.Add("@QTA", SqlDbType.Int).Value = _qta;
          cmd.Parameters.Add("@OPERATORE", SqlDbType.VarChar).Value = System.Environment.UserName;
          cmd.Parameters.Add("@CAUSALE", SqlDbType.VarChar).Value = _causale;
      
          if(cmd.ExecuteNonQuery() > 0){
              //Change to this
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-05
        • 2010-11-07
        • 1970-01-01
        相关资源
        最近更新 更多