2016-08-18 33 views
2

我看到堆棧溢出了很多問題,他們不感動我自己的問題即使參數表示接受空值,存儲過程也不允許空參數?

procedure or function expects parameter which was not supplied

我創造了這個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 

在我的數據訪問層我有這樣的方法,該方法負責非查詢命令:

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

private void btnAU_Click(object sender, EventArgs e) 
{ 
    byte[] imgArr; 

    if (PbCustomer.Image == null) 
      imgArr = null; 
    else 
    { 
     MemoryStream ms = new MemoryStream(); 
     PbCustomer.Image.Save(ms, PbCustomer.Image.RawFormat); 
     imgArr = ms.ToArray(); 
    } 

    int cityId = int.Parse(cmbCities.SelectedValue.ToString()); 

    try 
    { 
     int exist = CustomerClass.spAddCustomer(txtName.Text, txtAddress.Text, txtMobile.Text, imgArr, cityId); 

     if (exist == 1) 
     { 
      MessageBox.Show("A new customer has been saved"); 
      txtAddress.Text = txtMobile.Text = txtName.Text = ""; 
      PbCustomer.Image = null; 
     } 
     else 
      MessageBox.Show("A customer with the same mobile number\nalready exists, add new number!"); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
} 

但是,當我點擊Add按鈕(傳遞null圖像),我得到這個錯誤:

procedure or function 'spAddCustomer' expects parameter '@cuImage' which was not supplied

儘管表tblCustomers接受空值

+0

您是否已經逐步調試器中的代碼以查看實際傳入的值?你可以發佈'CreateParameter'的代碼嗎? – Tim

+0

什麼是DataAccessLayer.CreateParameter? – Eris

+0

也檢查你的開始和結束'{}'他們似乎沒有排隊 – MethodMan

回答

0

我才發現,我可以在存儲過程中參數的默認值:

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的空圖像特別有用,因爲我有一個幫助程序方法來檢查空字符串。

7

你需要檢查你的輸入無效,並使用DBNull.Value當你創建的參數。如果您僅將null作爲參數傳遞 - ADO.Net將忽略該參數。

編輯:

您可以添加支票到您的自定義的方法DataAccessLayer.CreateParameter()

+2

'DataAccessLayer.CreateParameter(「@ cuName」,SqlDbType.VarChar,String.IsNullOrWhitespace(cusName)?DBNull.Value:cusName),' –

+4

我寧願修復DataAccessLayer.CreateParameter()方法本身來檢查null/whitespace參數使用三元運算符?:每次。 –

相關問題