Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 存储过程不';即使参数表示接受空值,也不允许空参数?_C#_Sql Server_Stored Procedures - Fatal编程技术网

C# 存储过程不';即使参数表示接受空值,也不允许空参数?

C# 存储过程不';即使参数表示接受空值,也不允许空参数?,c#,sql-server,stored-procedures,C#,Sql Server,Stored Procedures,我看到许多关于堆栈溢出的问题,其中没有一个涉及到我自己的问题 过程或函数需要未提供的参数 我创建了以下SQL Server存储过程: CREATE proc [dbo].[spAddCustomer] @cuName varchar(50), @cuAddress varchar(50), @cuMobile varchar(50), @cuImage image, @cityId int, @exist int output AS BEGIN

我看到许多关于堆栈溢出的问题,其中没有一个涉及到我自己的问题

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

我创建了以下SQL Server存储过程:

CREATE proc [dbo].[spAddCustomer]
    @cuName varchar(50),
    @cuAddress varchar(50),
    @cuMobile varchar(50),
    @cuImage image,
    @cityId int,
    @exist int output
AS
BEGIN
    IF NOT EXISTS(SELECT Cu_Mobile FROM tblCustomers WHERE Cu_Mobile = @cuMobile)
    BEGIN
        INSERT INTO tblCustomers (Cu_Name, Cu_Address, Cu_Mobile, Cu_Image, City_ID)
        VALUES (@cuName, @cuAddress, @cuMobile, @cuImage, @cityId)

        SET @exist = 1
    END
    ELSE
        SET @exist = 0
END
ALTER proc [dbo].[spAddCustomer]
@cuName varchar(50)=null,
@cuAddress varchar(50)=null,
@cuMobile varchar(50)= null,
@cuImage image= null,
@cityId int= null,
@exist int output
在我的数据访问层中,我有一个负责非查询命令的方法:

public static int ExecuteNonQuery(string query, CommandType type, params SqlParameter[] arr)
{
    int outParam;

    SqlCommand cmd = new SqlCommand(query, cn);
    cmd.Parameters.AddRange(arr);
    cmd.CommandType = type;

    int i = cmd.ExecuteNonQuery();

    foreach (SqlParameter param in arr)
    {
        if (param.Direction == ParameterDirection.Output)
        {
            outParam = (int)cmd.Parameters[param.ToString()].Value;
            return outParam;
        }
    }

    return i;
}
负责创建参数的方法:

public static SqlParameter CreateParameter(string name, SqlDbType type, object value, ParameterDirection pd = ParameterDirection.Input)
{
    SqlParameter pr = new SqlParameter();
    pr.ParameterName = name;
    pr.Direction = pd;
    pr.SqlDbType = type;
    pr.SqlValue = value;

    return pr;
}
这个方法在业务层中,从表示层传递参数

public static int spAddCustomer(string cusName, string cusAddress, string cusMobile, byte[] arrImg, int cityId)
{
    DataAccessLayer.Open();

    int i = DataAccessLayer.ExecuteNonQuery("spAddCustomer", CommandType.StoredProcedure,
        DataAccessLayer.CreateParameter("@cuName", SqlDbType.VarChar, cusName),
        DataAccessLayer.CreateParameter("@cuAddress", SqlDbType.VarChar, cusAddress),
        DataAccessLayer.CreateParameter("@cuMobile", SqlDbType.VarChar, cusMobile),
        DataAccessLayer.CreateParameter("@cuImage", SqlDbType.Image, arrImg),
        DataAccessLayer.CreateParameter("@cityId", SqlDbType.Int, cityId),
        DataAccessLayer.CreateParameter("@exist", SqlDbType.Int, null, ParameterDirection.Output));

    DataAccessLayer.Close();

    return i;
}
当用户单击“添加”时,一条新记录将插入表中(
tblCustomers

但是,当我单击添加按钮(传递空图像)时,我得到以下错误:

过程或函数“spAddCustomer”需要参数“@cuImage” 这是没有提供的


尽管有表
tblCustomers
接受空值

,但在创建参数时,您需要检查输入是否为空,并使用
DBNull.Value
。如果只将
null
作为参数传递,ADO.Net将忽略该参数

编辑:


您可以将该检查添加到自定义方法中
DataAccessLayer.CreateParameter()

我刚刚发现可以在存储过程中为参数设置默认值:

CREATE proc [dbo].[spAddCustomer]
    @cuName varchar(50),
    @cuAddress varchar(50),
    @cuMobile varchar(50),
    @cuImage image,
    @cityId int,
    @exist int output
AS
BEGIN
    IF NOT EXISTS(SELECT Cu_Mobile FROM tblCustomers WHERE Cu_Mobile = @cuMobile)
    BEGIN
        INSERT INTO tblCustomers (Cu_Name, Cu_Address, Cu_Mobile, Cu_Image, City_ID)
        VALUES (@cuName, @cuAddress, @cuMobile, @cuImage, @cityId)

        SET @exist = 1
    END
    ELSE
        SET @exist = 0
END
ALTER proc [dbo].[spAddCustomer]
@cuName varchar(50)=null,
@cuAddress varchar(50)=null,
@cuMobile varchar(50)= null,
@cuImage image= null,
@cityId int= null,
@exist int output
这就解决了我的问题!
这对于PictureBox中的空图像特别有用,因为我有一个检查空字符串的助手方法。

您是否在调试器中逐步检查了代码,以查看实际传入的值?您可以发布
CreateParameter
的代码吗?请注意,空
文本框的值为
String.empty
,而不是
null
!如果您将
转换为
null
,事情会变得更好吗?如果TextBox.Text=to string.Empty
DataAccessLayer.CreateParameter(@cuName),SqlDbType.VarChar)。Value=string.IsNullOrEmpty(cusName),最好这样做?值:cusName
ntext
text
image
数据类型。避免在新的开发工作中使用这些数据类型,并计划修改当前使用它们的应用程序。改用
nvarchar(max)
varchar(max)
varbinary(max)
。谢谢@marc_s,我知道
text
,但我不知道
image
DataAccessLayer.CreateParameter(“@cuName”,SqlDbType.VarChar,String.IsNullOrWhitespace(cusName)?DBNull.Value:cusName),
我宁愿修复DataAccessLayer.CreateParameter()方法本身检查空/空白参数,而不是使用三元运算符?:everytime。