简体   繁体   中英

C# DBNull.Value Inserting 0

I am trying to insert data into a SQL table. The data types I am having issues with are nullable floats. When the NULL values are inserted they change to 0. How can I keep them NULL.

private void InsertStatisticsData(DataTable dt)
{
    //check isin periodicity and As of Date
    foreach(DataRow row in dt.Rows)
    {
        DataTable queryResultTable = SQL.Query($@"SELECT * FROM Statistics
                                                WHERE [CodeID] = '{row["CodeID"]}' 
                                                AND [Periodicity] = '{row["Periodicity"]}'
                                                AND [As of Date] = '{row["As of Date"]}'");

        if(queryResultTable.Rows.Count == 0)
        {
            //Check for Null Values 
            for(int i = 0; i < row.ItemArray.Count(); i++)
            {
                if (Convert.ToString(row[i]) == "")                        
                    row[i] = (object)DBNull.Value;                        
            }
            //Insert Data Into DataBase
            SQL.NonQuery($@"INSERT INTO Statistics
                        VALUES ('{row["CodeID"]}' ,
                                '{row["Volatility"]}',
                                '{row["Beta"]}',
                                '{row["Info Ratio"]}',
                                '{row["Tracking"]}',
                                '{row["Drawdown"]}',
                                '{row["Periodicity"]}',
                                '{row["As of Date"]}')");
        }
    }
}

Nonquery Function:

public static void NonQuery(string query, string databaseName = "Database", string serverAddress = "server-name", int commandTimeout = 30)
{
    string connString = $"Server = {serverAddress}; Database = {databaseName}; Trusted_Connection = True";
    using (SqlConnection sqlConn = new SqlConnection(connString))
    using (SqlCommand cmd = new SqlCommand(query, sqlConn))
    {
        sqlConn.Open();
        cmd.CommandTimeout = commandTimeout;
        cmd.ExecuteNonQuery();
    }
}

You need to make sure your database column structure contains NULL types where you actually need them. Also make sure you don't have any default constraints set, which automatically values the columns to 0 when null is assigned.

if(Convert.ToString(null) == "")

will be evaluated as false.

so below code won't get executed

row[i] = (object)DBNull.Value; 

on a side note, you should use SqlParameters instead of appending values in a string.

This may seem a little heavy handed and bloaty, but if you use parameters (and you really, truly should), I have an extention method I use in my project to take any command object and loop through the parameters to turn a .NET null into a DbNull:

private static void ProcessNullParameters(this DbCommand command)
{
    foreach (DbParameter param in command.Parameters)
    {
        if (param.Value == null)
            param.Value = DBNull.Value;
    }
}

This way, if your native object returns a null value, you can call the extention method against the command object. I couldn't tell what your SQL object was in your example (a framework of some type?), but presumably, somewhere behind the scenes something like this would be going on:

SqlCommand cmd = new SqlCommand("insert into Statistics values (@Code, @Volatility)", conn);
cmd.Parameters.Add("@Code", SqlDbType.VarChar);
cmd.Parameters.Add("@Volatility", SqlDbType.Decimal);

foreach (DataRow dr in dt.Rows)
{
    cmd.Parameters[0].Value = dr["Code"];
    cmd.Parameters[1].Value = dr["Volatility"];

    // And here you convert your nulls to DbNull
    cmd.ProcessNullParameters();

    cmd.ExecuteNonQuery();
}

The alternative would be to do this on every value declaration that is nullable.

cmd.Parameters[0].Value = dr["Code"] ?? DbNull.Value
cmd.Parameters[1].Value = dr["Volatility"] ?? DbNull.Value;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM