过程或函数 'uspExportGetMailinfoTest' 需要未提供的参数“@CUSTOMER”。我错过了什么?
Procedure or function 'uspExportGetMailinfoTest' expects parameter '@CUSTOMER', which was not supplied. What am I missing?
我在 Visual Studio 2017 年使用 C# Winforms 工作。该项目基于从 VB6 到 C# 的转换,但现在我遇到了一个错误,它说我没有提供参数。但据我所知,我似乎有。
我遇到的错误是:
Procedure or function 'uspExportGetMailinfoTest' expects parameter '@CUSTOMER', which was not supplied.
我不知道是因为我的 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
AddWithValue
替换了接受字符串和对象的 SqlParameterCollection.Add
方法。采用字符串和对象的 Add 重载已被弃用,因为采用字符串和 SqlDbType 枚举值的 SqlParameterCollection.Add
重载可能存在歧义,其中传递带有字符串的整数可以被解释为参数值或相应的 SqlDbType 值。每当您想通过指定参数的名称和值来添加参数时,都可以使用 AddWithValue。
改用:
cmd.Parameters.Add("@CUSTOMER", SqlDbType.NVarChar, 50);
cmd.Parameters["@CUSTOMER"].Value = sCustomer;
如果你想使用带参数的数据适配器,你需要向它传递一个 SqlCommand
包含参数的对象。
您的代码还有很多其他问题:
- 所有 Sql 个对象需要在
using
个块中
- 不缓存连接对象,需要时创建,用
using
处理。请注意,如果您有 using
块,则无需调用 Close()
- 您正在调用
ExecuteNonQuery
(多次),return 没有结果
- 单行结果不会在参数中返回,它是一个结果集
- 您可以从
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())
对于单行单列结果,您可以删除 reader 并使用 cmd.ExecuteScalar()
我在 Visual Studio 2017 年使用 C# Winforms 工作。该项目基于从 VB6 到 C# 的转换,但现在我遇到了一个错误,它说我没有提供参数。但据我所知,我似乎有。
我遇到的错误是:
Procedure or function 'uspExportGetMailinfoTest' expects parameter '@CUSTOMER', which was not supplied.
我不知道是因为我的 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
AddWithValue
替换了接受字符串和对象的 SqlParameterCollection.Add
方法。采用字符串和对象的 Add 重载已被弃用,因为采用字符串和 SqlDbType 枚举值的 SqlParameterCollection.Add
重载可能存在歧义,其中传递带有字符串的整数可以被解释为参数值或相应的 SqlDbType 值。每当您想通过指定参数的名称和值来添加参数时,都可以使用 AddWithValue。
改用:
cmd.Parameters.Add("@CUSTOMER", SqlDbType.NVarChar, 50);
cmd.Parameters["@CUSTOMER"].Value = sCustomer;
如果你想使用带参数的数据适配器,你需要向它传递一个 SqlCommand
包含参数的对象。
您的代码还有很多其他问题:
- 所有 Sql 个对象需要在
using
个块中 - 不缓存连接对象,需要时创建,用
using
处理。请注意,如果您有using
块,则无需调用Close()
- 您正在调用
ExecuteNonQuery
(多次),return 没有结果 - 单行结果不会在参数中返回,它是一个结果集
- 您可以从
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())
对于单行单列结果,您可以删除 reader 并使用 cmd.ExecuteScalar()