I'm performing a simple insert into an SQL database. The query is parametrised but when I call the method which performs this insert I may not always want to populate each parameter.
As follows:
using (var sqlconnection = new SqlConnection(Globals.AFWideSettings.SqlConnectionString))
{
sqlconnection.Open();
using (
var sqlcommand =
new SqlCommand(
"insert into DataActions (afuser, aftable, changetype, originaldata, newdata) values (#afuser, #aftable, #changetype, #originaldata, #newdata);",
sqlconnection))
{
sqlcommand.Parameters.Add(new SqlParameter("afuser", userActions.AfUser));
sqlcommand.Parameters.Add(new SqlParameter("aftable", userActions.AfTable));
sqlcommand.Parameters.Add(new SqlParameter("changetype", userActions.ChangeType));
sqlcommand.Parameters.Add(new SqlParameter("originaldata", userActions.OriginalData));
sqlcommand.Parameters.Add(new SqlParameter("newdata", userActions.NewData));
sqlcommand.ExecuteNonQuery();
}
sqlconnection.Close();
}
}
If I was testing for Null information coming out of the database I would do something like:
Id = getRecords.IsDBNull(0) ? -1 : getRecords.GetInt32(0)
Is there a equivalent way of doing this on sqlparameters ? I'm stumped.
(I know I could test each item individually, I just want to be efficient)
Many thanks
Well, you have to populate each parameter because it's in your SQL (unless you want to dynamically remove fields/values which would be messy).
I would just use the NULL coalesce operator (??) when setting the parameter values:
sqlcommand.Parameters.Add(
new SqlParameter("afuser", userActions.AfUser ?? {insert default value here} ));
Okay, so the basic syntax is as follows:
CREATE PROCEDURE NameOfProcedure
/*
I like to put modification history, purpose for the procedure and stuff like that in here.
It's not required though
*/
(
#afuser NVARCHAR(255) DEFAULT NULL
,#aftable INT DEFAULT NULL
Do this for all your variables, I've shown an example of an integer field and an nvarchar field but use whatever the datatype is. The DEFAULT NULL bit is the part that says if no value is specified, use NULL.
)
AS
BEGIN
INSERT INTO DataActions (afuser, aftable, changetype, originaldata, newdata)
VALUES (#afuser, #aftable, #changetype, #originaldata, #newdata)
END
you could do it using the DBNull value
I would recommend using Parameters.AddWithValue() Method for example see the code below
sqlcommand.Parameters.AddWithValue("#afuser", userActions.AfUser ?? (object)DBNull.Value);
MSDN SqlParameterCollection.AddWithValue Method
Related
My query is supposed to add an additional column "_DisableAccounting" to the "Settings_Global" table, specifying a DEFAULT value using a SQLiteParemeter.
ALTER TABLE Settings_Global ADD COLUMN `_DisableAccounting` BOOL NOT NULL DEFAULT #defaultValue;
When the SQLiteCommand is executed, #defaultValue should be replaced by the supplied parameter.
// ....
SQLiteParameter defaultValueParam = null;
if (defaultValue != null) {
query += " DEFAULT #defaultValue`";
defaultValueParam = new SQLiteParameter { ParameterName = "#defaultValue", Value = defaultValue };
}
query += ";";
using (SQLiteCommand cmd = _Connection.CreateCommand()) {
cmd.CommandText = query;
if (defaultValueParam != null) {
cmd.Parameters.Add(defaultValueParam);
}
cmd.ExecuteNonQuery();
}
// ....
However, I get the error "'SQL logic error or missing database near
#defaultValue": syntax error'". So it seems that the command is never replacing #defaultValue with the actual value.
Why isn't this working? I am doing essentially the same with MySQL (my application can optionally use MySQL) and it is working.
You appear to have a spurious grave accent. That is #defaultValue is followed grave accent, when it likely shouldn't be.
Try changing
ALTER TABLE Settings_Global ADD COLUMN `_DisableAccounting` BOOL NOT NULL DEFAULT #defaultValue`;
to
ALTER TABLE Settings_Global ADD COLUMN `_DisableAccounting` BOOL NOT NULL DEFAULT #defaultValue;
or to
ALTER TABLE Settings_Global ADD COLUMN `_DisableAccounting` BOOL NOT NULL DEFAULT `#defaultValue`;
When doing ALTER TABLE, SQLite does not modify the column definition in any way and just inserts it directly at the end of the CREATE TABLE statement.
This means that the parameter marker would end up in that CREATE TABLE statement, which would result in the parameter value not being available when the statement is interpreted later.
You have to insert the default value directly into the SQL command.
My query returns false when some values are null, but my table allows Null values.
What did I do wrong?
cmd.CommandText ="Insert into BusinessTbl(BName,BAddress,BEmail,BMobile,BPhone,Cat_Id)" +
"values(#bname,#baddress,#bemail,#bmobile,#bphone,#catid)";
cmd.Parameters.AddWithValue("#bname", b.BusinessName);
cmd.Parameters.AddWithValue("#name", b.BusinessAddress);
cmd.Parameters.AddWithValue("#bemail", b.BusinessEmail);
cmd.Parameters.AddWithValue("#bmobile", b.BusinessMobile);
cmd.Parameters.AddWithValue("#bphone", b.BusinessPhone);
cmd.Parameters.AddWithValue("#catid", b.ddlbcategory);
con.ExecuteNonQuery(cmd);
My Table
This is a vexing feature of ADO.NET parameters; basically:
cmd.Parameters.AddWithValue("#bname", ((object)b.BusinessName) ?? DBNull.Value);
cmd.Parameters.AddWithValue("#name", ((object)b.BusinessAddress) ?? DBNull.Value);
// etc
should fix you. If the .Value is null, the parameter isn't sent - it needs to be DBNull.Value. Alternatively, a tool like "Dapper" helps avoid this pain:
con.Execute(#"Insert into BusinessTbl(BName,BAddress,BEmail,BMobile,BPhone,Cat_Id)
values(#bname,#baddress,#bemail,#bmobile,#bphone,#catid)",
new { bname = b.BusinessName, ... , catid = b.ddlbcategory });
(which will parameterize correctly, including the nulls)
How to set Default Value as Value of SqlCommand SqlParameter?
SqlCommand is the class contained in System.Data.SqlClient
My Schema does not accept DBNull.Value as value
SqlCommand command = new SqlCommand();
command.Parameters.Add(new SqlParameter("column_1", SqlDbType.VarChar, 1) { Value = DBNull.Value });
As lboshuizen points out, if your "schema" isn't taking null, or the parameter of the stored procedure or query cannot be null, trying to give it a null value will likely fail. In this case, you need to see why you are trying to set it to null if you know it doesn't accept it. I would surmise an empty string as opposed to null would work, or something else that is sensible.
The SqlParameterCollection property Parameters has an AddWithValue method:
https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlparametercollection.addwithvalue(v=vs.110).aspx
You can simply insert null and that will be handled for you:
command.Parameters.AddWithValue("#parameter", null);
If you cannot provide a null, you can provide something like an empty string:
command.Parameters.AddWithvalue("#parameter", "");
You also very rarely need to specify the data type using this mechanism.
If the schema doesn't accept null it indicates that the column is mandatory and requires a sensible value.
Using a default value for a column is a property of the schema.
So either alter the schema to provide a default.
ALTER TABLE {TABLENAME}
ADD {COLUMNNAME} {TYPE} {NULL|NOT NULL}
CONSTRAINT {CONSTRAINT_NAME} DEFAULT {DEFAULT_VALUE}
Choose a valid (not null) default value in your application code and use it as a value in the parameter.
const string default = "unknown";
...
SqlCommand command = new SqlCommand();
command.Parameters.Add(new SqlParameter("column_1", SqlDbType.VarChar, 1)
{ Value = default });
Note: Changing the schema to accept NULL is considered cheating :-)
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).
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.
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).
these are the variables i am passing to some method where i need to write some sql query like
string cmd = #"select *
from students_tbl
where
course_id=#courseId and branch_id=in(+" branchId "+)
and passout_year>=#passoutYear
and current_backlog>=#currentBacklog
and gender=#gender
and eGap<=#eGap
and first_year_percent>=#firstyearPercent
and second_year_percent>=#seconYearPercent
and third_year_percent>=#thirdyearPercent";
and so on but problem is that few of these parameters are optional means for those variable
there value is null so i don't want to include those parameter in query
so how should i eliminate those null variable i am not getting how should i write query to solve this issue
those parameter are random nothing fix when they will be null because hey are optional
so how should i write query by using only not null parameter
Just add an is null check before your comparison, which will short-circuit if the input parameter value is null, e.g.:
where (#currentBacklog is null or current_backlog >= #currentBacklog)
You can test for a null value in the condition, and use the value from the table instead. Example:
... where course_id = isnull(#courseId, course_id) ...
Instead of having
cmd = "one long string with many clauses, some of which are optional"
try
cmd = "first clause, required"
if second param is not null then
cmd = cmd & "second clause, optional"