I'm using C# Winforms to INSERT some NULL or Empty values from the DataGridView to my SQL Server. But there is an error at this line.
cmd.Parameters.Add("@Status", SqlDbType.VarChar).Value = dataGridWork.Rows[i].Cells[1].Value.ToString();
System.NullReferenceException: 'Object reference not set to an instance of an object.'
Since it is expecting a value that is not NULL (Please do correct me if I'm wrong). This is the code for my INSERT query.
using (SqlConnection conn = new SqlConnection(@"Server=" + ip + "," + port + "; Database=records; User ID=" + sqlid + "; Password=" + sqlpass + ""))
{
conn.Open();
for (int i = 0; i < dataGridWork.Rows.Count; i++)
{
using (SqlCommand cmd = new SqlCommand(@"INSERT INTO [dbo].[workorder]
([Work Order]
,[Plate No.]
,[Date]
,[Status]
,[Work Description]
,[Labor Price]
,[Item]
,[Unit Price]
,[Qty]
,[Unit]
,[Item Price]
,[Mechanic]
,[Deposit])
VALUES
(@WOrder
,@Plate
,@Date
,@Status
,@WDesc
,@LPrice
,@Item
,@UPrice
,@Qty
,@Unit
,@IPrice
,@Mechanic
,@Deposit)", conn))
{
cmd.Parameters.Add("@WOrder", SqlDbType.VarChar).Value = "WRK" + Properties.Settings.Default.work;
cmd.Parameters.Add("@Plate", SqlDbType.VarChar).Value = plate;
cmd.Parameters.Add("@Date", SqlDbType.Date).Value = dataGridWork.Rows[i].Cells[0].Value.ToString();
cmd.Parameters.Add("@Status", SqlDbType.VarChar).Value = dataGridWork.Rows[i].Cells[1].Value.ToString();
cmd.Parameters.Add("@WDesc", SqlDbType.VarChar).Value = dataGridWork.Rows[i].Cells[2].Value.ToString();
cmd.Parameters.Add("@LPrice", SqlDbType.Decimal, 18).Value = Convert.ToDouble(dataGridWork.Rows[i].Cells[3].Value);
cmd.Parameters.Add("@Item", SqlDbType.VarChar).Value = dataGridWork.Rows[i].Cells[4].Value.ToString();
cmd.Parameters.Add("@UPrice", SqlDbType.Decimal, 18).Value = Convert.ToDouble(dataGridWork.Rows[i].Cells[5].Value);
cmd.Parameters.Add("@Qty", SqlDbType.Int).Value = dataGridWork.Rows[i].Cells[6].Value.ToString();
cmd.Parameters.Add("@Unit", SqlDbType.VarChar).Value = dataGridWork.Rows[i].Cells[7].Value.ToString();
cmd.Parameters.Add("@IPrice", SqlDbType.Decimal, 18).Value = Convert.ToDouble(dataGridWork.Rows[i].Cells[8].Value);
cmd.Parameters.Add("@Mechanic", SqlDbType.VarChar).Value = txtWMech.Text;
cmd.Parameters.Add("@Deposit", SqlDbType.Decimal, 18).Value = numWDepo.Value;
cmd.ExecuteNonQuery();
}
}
conn.Close();
Properties.Settings.Default.work = Properties.Settings.Default.work + 1;
}
Most of the columns can be null or empty. So I tried adding an If-Else for every SqlParameter that will be expecting NULL or empty. These are Status, WDesc, LPrice, Item, UPrice, Qty, Unit, and IPrice Parameters.
Now the whole parameter block is like this,
cmd.Parameters.Add("@WOrder", SqlDbType.VarChar).Value = "WRK" + Properties.Settings.Default.work;
cmd.Parameters.Add("@Plate", SqlDbType.VarChar).Value = plate;
cmd.Parameters.Add("@Date", SqlDbType.Date).Value = dataGridWork.Rows[i].Cells[0].Value;
if (dataGridWork.Rows[i].Cells[1].Value != null)
{
cmd.Parameters.Add(new SqlParameter("@Status", dataGridWork.Rows[i].Cells[1].Value));
}
else
{
cmd.Parameters.Add(new SqlParameter("@Status", DBNull.Value.ToString()));
}
if (dataGridWork.Rows[i].Cells[2].Value != null)
{
cmd.Parameters.Add(new SqlParameter("@WDesc", SqlDbType.VarChar)).Value = dataGridWork.Rows[i].Cells[2].Value.ToString();
}
else
{
cmd.Parameters.Add(new SqlParameter("@WDesc", DBNull.Value.ToString()));
}
if (dataGridWork.Rows[i].Cells[3].Value != null)
{
cmd.Parameters.Add(new SqlParameter("@LPrice", SqlDbType.Decimal, 18)).Value = Convert.ToDouble(dataGridWork.Rows[i].Cells[3].Value);
}
else
{
cmd.Parameters.Add(new SqlParameter("@LPrice", DBNull.Value));
}
if (dataGridWork.Rows[i].Cells[4].Value != null)
{
cmd.Parameters.Add(new SqlParameter("@Item", SqlDbType.VarChar)).Value = dataGridWork.Rows[i].Cells[4].Value.ToString();
}
else
{
cmd.Parameters.Add(new SqlParameter("@Item", DBNull.Value.ToString()));
}
if (dataGridWork.Rows[i].Cells[5].Value != null)
{
cmd.Parameters.Add(new SqlParameter("@UPrice", SqlDbType.Decimal, 18)).Value = Convert.ToDouble(dataGridWork.Rows[i].Cells[5].Value);
}
else
{
cmd.Parameters.Add(new SqlParameter("@UPrice", DBNull.Value));
}
if (dataGridWork.Rows[i].Cells[6].Value != null)
{
cmd.Parameters.Add(new SqlParameter("@Qty", SqlDbType.Int)).Value = dataGridWork.Rows[i].Cells[6].Value;
}
else
{
cmd.Parameters.Add(new SqlParameter("@Qty", DBNull.Value));
}
if (dataGridWork.Rows[i].Cells[7].Value != null)
{
cmd.Parameters.Add(new SqlParameter("@Unit", SqlDbType.VarChar)).Value = dataGridWork.Rows[i].Cells[7].Value.ToString();
}
else
{
cmd.Parameters.Add(new SqlParameter("@Unit", DBNull.Value.ToString()));
}
if (dataGridWork.Rows[i].Cells[8].Value != null)
{
cmd.Parameters.Add(new SqlParameter("@IPrice", SqlDbType.Decimal, 18)).Value = Convert.ToDouble(dataGridWork.Rows[i].Cells[8].Value);
}
else
{
cmd.Parameters.Add(new SqlParameter("@IPrice", DBNull.Value));
}
cmd.Parameters.Add("@Mechanic", SqlDbType.VarChar).Value = txtWMech.Text;
cmd.Parameters.Add("@Deposit", SqlDbType.Decimal, 18).Value = numWDepo.Value;
cmd.ExecuteNonQuery();
Now it can insert the values for every row inside my DataGridView. But is there a way how can I shorten or eliminate the If-Else statement? Or to make the code look cleaner?
cmd.Parameters.Add("@Status", SqlDbType.VarChar).Value = dataGridWork.Rows[i].Cells[1].Value?.ToString() ?? DBNull.Value;- the?after the value means "if not null, use this value" and the??means "if it is null, use this value"Convert.ToDouble(dataGridWork.Rows[i].Cells[3].Value ?? DBNull.Value);I have tried this but it returns an error0ornullto the DB? For the first case it would beConvert.ToDouble(dataGridWork.Rows[i].Cells[3].Value);?? DBNull.Valuefor numeric values. Just a normalParameters.Addwith a converted value.cmd.Parameters.Add("@LPrice", SqlDbType.Decimal, 18).Value = Convert.ToDouble(dataGridWork.Rows[i].Cells[3].Value);and it's working. It returns 0 forIntand 0.00 forDecimal. Thank you @stuartd