过程或函数“uspExportGetMailinfoTest”需要参数“@CUSTOMER”,但未提供该参数。我错过了啥?

Posted

技术标签:

【中文标题】过程或函数“uspExportGetMailinfoTest”需要参数“@CUSTOMER”,但未提供该参数。我错过了啥?【英文标题】:Procedure or function 'uspExportGetMailinfoTest' expects parameter '@CUSTOMER', which was not supplied. What am I missing?过程或函数“uspExportGetMailinfoTest”需要参数“@CUSTOMER”,但未提供该参数。我错过了什么? 【发布时间】:2021-12-22 03:25:35 【问题描述】:

我在 C# Winforms 中使用 Visual Studio 2017。该项目基于从 VB6 到 C# 的转换,但现在我遇到了一个错误,它说我没有提供参数。但据我所见,我似乎有。

我遇到的错误是:

过程或函数“uspExportGetMailinfoTest”需要参数“@CUSTOMER”,但未提供。

我不知道是因为我的 C# 代码还是我在 SQL 中遗漏了一些东西。我想知道是否有人可以描述我做错了什么。我也总是愿意接受任何简化我的代码的建议。

C#:

SqlConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["ConString"].ConnectionString);

public bool getMailInfo(string sCustomer, ref string sMailTo, ref string sSubject, ref string sMsg)

    try
    
        SqlDataAdapter commSql = null;
 
        DataSet ds = new DataSet();

        db.Open();

        string sSql = "uspExportGetMailinfoTest";
                
        SqlCommand cmd = new SqlCommand("uspExportGetMailinfoTest", db);
        cmd.CommandType = CommandType.StoredProcedure;

        cmd.Parameters.AddWithValue("@CUSTOMER", sCustomer);

        cmd.ExecuteNonQuery();
              
        commSql = new SqlDataAdapter(sSql, db);
        commSql.Fill(ds, "list");

        if (ds.Tables["list"].Rows.Count > 0)
        
            cmd.Parameters.AddWithValue("mailto", sMailTo);
            cmd.Parameters.AddWithValue("subject", sSubject);

            cmd.ExecuteNonQuery();
            db.Close();
        
        else
        
            sMsg = "getMailInfo returns blank";
            db.Close();
        

        return true;
    
    catch (Exception ex)
    
        MessageBox.Show(ex.Message);
        throw;
    

此存储过程正在从另一个存储过程中恢复“客户密钥”。然后根据它获得的密钥来决定哪个客户将收到邮件。

存储过程:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[uspExportGetMailinfoTest] 
    @CUSTOMER AS nvarchar(50)
AS
    IF @CUSTOMER IN ('200600', '200600-SEK', '200600-USD', '200602', '200603', '200604', '200606') --2021-01-19 added 200606 --added ,'200603','200604' 20017-04-28
    BEGIN
        SELECT
            '\\XYXYX\MansTest' AS mailto,
            'DELIVERY TO XYXYX' AS subject                  
    END

【问题讨论】:

提示:你不想要 ExecuteNonQuery() 你大概想要 ExecuteReader() ........有成千上万的例子...... 还有please don't use AddWithValue() - it's lazy and dangerous。 【参考方案1】:

如果你想使用带参数的数据适配器,你需要传递一个SqlCommand对象,里面有参数。

您的代码还有很多其他问题:

所有 Sql 对象都需要在 using 块中 不缓存连接对象,需要时创建,使用using 处理。请注意,如果您有 using 块,则无需调用 Close() 您正在调用ExecuteNonQuery(多次),但没有返回结果 单行结果不会在参数中返回,它是一个结果集 您可以从DataSet 中读取该行,但实际上使用DataReader 更容易 不要使用AddWithValue,明确指定参数类型和长度 连接打开时不要使用MessageBox 阻止。
public bool getMailInfo(string sCustomer, ref string sMailTo, ref string sSubject, ref string sMsg)

    try
    
        using (SqlConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["ConString"].ConnectionString))
        using (SqlCommand cmd = new SqlCommand("uspExportGetMailinfoTest", db) CommandType = CommandType.StoredProcedure)
        
            cmd.Parameters.Add("@CUSTOMER", SqlDbType.NVarChar, 50).Value = sCustomer;
            db.Open();
            using (var reader = cmd.ExecuteReader())
            
                if (reader.Read())
                
                    sMailTo = (string)reader["mailto"];
                    sSubject = (string)reader["subject"];
                
                else
                
                    sMsg = "getMailInfo returns blank";
                

                return true;
            
        
    
    catch (Exception ex)
    
        MessageBox.Show(ex.Message);
        throw;
    

对于多行,您可以使用while (reader.Read())

对于单行单列结果,可以去掉阅读器,使用cmd.ExecuteScalar()

【讨论】:

非常感谢您的回答,这对我很有帮助。很好的解释,这对我将来真的很方便。简单易写!【参考方案2】:

AddWithValue 替换了采用 String 和 Object 的 SqlParameterCollection.Add 方法。采用字符串和对象的 Add 重载已被弃用,因为可能与采用 String 和 SqlDbType 枚举值的 SqlParameterCollection.Add 重载存在歧义,其中通过字符串传递整数可能被解释为参数值或对应的 SqlDbType 值。每当您想通过指定参数的名称和值来添加参数时,请使用 AddWithValue。 改为使用:

    cmd.Parameters.Add("@CUSTOMER", SqlDbType.NVarChar, 50);
    cmd.Parameters["@CUSTOMER"].Value = sCustomer;

【讨论】:

感谢您的解释,但我仍然遇到同样的错误?不过我以后会用你的例子。

以上是关于过程或函数“uspExportGetMailinfoTest”需要参数“@CUSTOMER”,但未提供该参数。我错过了啥?的主要内容,如果未能解决你的问题,请参考以下文章

VBA的宏显示“子过程或函数未定义”

VB中子程序或函数未定义是啥意思

存储过程或函数需要未提供的参数

调用包中的过程或函数

为啥线程过程应该是静态或成员函数

如何在运行时获取过程或函数名称?