質問

How can I INSERT values into SQL Server that are stored in a string[] such that some of the values should be disregarded in favor of the values stored in SQL Server as default constraints on the table? What do I need to pass(e.g. NULL or something else) to use those defaults?

Currently, I add all the defaults in my code, and it is getting bulky.

Below is my code:

if (value == "") value = "0";

string insert = "INSERT INTO " + table + " (" + columns + ") VALUES (" + atColumns + ")";

using (SqlConnection connect = new SqlConnection(connection))
{                               
    using (SqlCommand command = new SqlCommand(insert, connect))
    {
        //adds values to corresponding parameters
        for (int i = 0; i < table_cols.Length; i++)
        {
            command.Parameters.AddWithValue("@" + table_cols[i], table_vals[i]);
        }

        foreach (SqlParameter Parameter in command.Parameters)
        {
            if (Convert.ToString(Parameter.Value) == "")
            {
                Parameter.Value = DBNull.Value;
            }
        }

        connect.Open();
        command.ExecuteNonQuery();
        response = "Success";
        return response;

If a specific Parameter.Value is not-null and has a default set by SQL Server, this code will not work with null.

In SQL Server, this gets handled by omitting the value in your insert statement (this omission triggers inserting the default value for the table, whereas providing null produces errors).

役に立ちましたか?

解決 5

I actually used the INFORMATION_SCHEMA.COLUMNS table to pull back from SQL Server all of the Column Defaults. Then I just organized the defaults into a string[] and looped through it to insert defaults rather than nulls (some defaults are null).

他のヒント

If you want SQL Server to use the default value constraint for the column then don't include the column as part of the insert parameters.

Example:

--From SQL Server
CREATE TABLE Orders
(
     Id INT IDENTITY PRIMARY KEY
    ,Amount INT NOT NULL
    ,Cost MONEY NOT NULL
    ,SaleDate DATE NOT NULL DEFAULT GETUTCDATE()
);



//From C#
public int Insert(decimal cost, int amount)
{
    using (var connection = new SqlConnection(connectionString))
    {
        var command = connection.CreateCommand();
        //Don't specify the SaleDate and it will insert the current time
        command.CommandText = "INSERT INTO Orders(Amount, Cost) VALUES(@Amount, @Cost); SELECT SCOPE_IDENTITY();";
        command.Parameters.AddWithValue("@Amount", amount);
        command.Parameters.AddWithValue("@Cost", cost);

        using(var reader = command.ExecuteReader())
        {
            if(reader.Read())
                return Convert.ToInt32(reader[0]);
        }
    }

    return 0;
}

If you want to use a parameters list in your C# code then just keep the parameter names grouped with their values and if the value is null and it has a default value then just skip it.

Passing in a NULL tells SQL that you want a NULL in that column overriding the default. If you want to pass something in pass in the keyword DEFAULT. I wrote an article, "keyword DEFAULT", about the usage:

The DEFAULT keyword causes the default value (from the constraint) to be inserted into the column.

Just remember that when you pass in DEFAULT don't put quotes around it. That makes it the string DEFAULT rather than the keyword DEFAULT.

The only other way of doing it I can think of would be triggers based your approach (and you're better off coding it at that point).

However, if you alter your approach to use stored procedures, you can do your value handling natively in SQL, otherwise you're stuck coding it into your app... might i recommend Ternary statements for your example: http://msdn.microsoft.com/en-us/library/ty67wk28%28v=vs.80%29.aspx .

If you include a column in the column list, it will try and insert the value you give, it. It will not assume that NULL means "just insert the default value".

If you don't want to insert a value into that column, don't include it in your column list (or value list, obviously).

While it may seem more efficient to loop through the table columns and be agnostic of the column name, type, etc. In the long run you may be better off handling each column explicitly so you can choose whether or not to use a default, verify the value, etc.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top