I'm wondering how to set an nchar column to null with an update statement. I found this: NULL value for int in Update statement
which says you have to cast to set non-int fields to NULL.
So I tried the following:
commandText =
#"UPDATE Brukere
SET Engangskode = CAST(NULL AS NCHAR)
WHERE Navn = #navn AND Mobilnr = #mobilnr";
However, when I execute this it still won't update the column to NULL. Am I casting wrong, or is it something else? Any help would be appreciated :)
Longer code snip if needed: http://pastebin.com/8auKuk6Q
The problem is that you are setting the local variable commandText to the update statement instead of the command.CommandText. Change it to the following
command.CommandText = "UPDATE Brukere SET Engangskode=NULL WHERE Navn=#navn AND Mobilnr=#mobilnr";
And I think it will work with or without the casting.
I would recommend NOT to "re-use" the SqlCommand in your example - create a new, specific command for the UPDATE statement, something like this:
using (SqlConnection con = new SqlConnection(connectionString))
{
con.Open();
string bruker = Request.Cookies["Navn"].Value;
string mobilnr = Request.Cookies["Mobilnr"].Value;
string commandText = "SELECT Engangskode FROM Brukere WHERE Navn=#navn AND Mobilnr=#mobilnr";
bool correctCode = false;
try
{
using (SqlCommand command = new SqlCommand(commandText, con))
{
.....
if (correctCode)
{
// DO NOT "reuse" the previous SqlCommand - create a new, specific one!
string updateQuery = "UPDATE Brukere SET Engangskode = NULL WHERE Navn = #navn AND Mobilnr = #mobilnr;";
using (SqlCommand updateCmd = new SqlCommand(updateQuery, con)
{
updateCmd.Parameters.Add("#navn", SqlDbType.NVarChar, 20).Value = bruker;
updateCmd.Parameters.Add("#mobilnr", SqlDbType.NChar, 10).Value = mobilnr;
updateCmd.ExecuteNonQuery();
Response.Redirect("Kvittering.aspx", false);
}
}
}
}
catch( .... )
{
.......
}
}
No need to cast. Juse set column = null. NO quotes, tho!
Related
I'm trying to create a generic function, using SqlClient in C#, which will accept a value for any column name and return the valid objects. My approach is to create a stored procedure which accepts values for every column, and where a value has not been provided it will be assume that any value is accepted. My code is as below (code is a little unfinished with regards the final requirement):
public async Task<List<OrganisationInstance>> GetOrganisationInstances(string name, int id)
{
List<OrganisationInstance> responses = new List<OrganisationInstance>();
using (SqlConnection connection = new SqlConnection(connectionString))
{
try
{
await connection.OpenAsync();
using (SqlCommand command = new SqlCommand(OrganisationInstancesSP.READ_ORGANISATION, connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("Id", SqlDbType.BigInt).Value = 2;
command.Parameters.Add("CreationDate", SqlDbType.DateTime).Value = "2021-12-14 23:59:25.837";
command.Parameters.Add("CompanyName", SqlDbType.VarChar).Value = "xxxxxxxxxx";
command.Parameters.Add("Postcode", SqlDbType.VarChar).Value = "xxxxxxxxxxx";
command.Parameters.Add("FormationDate", SqlDbType.DateTime).Value = "2021-12-14 23:59:25.837";
command.Parameters.Add("NodeId", SqlDbType.Int).Value = id;
SqlDataReader reader = await command.ExecuteReaderAsync();
while (reader.Read())
responses.Add(new OrganisationInstance { CompanyName = reader["CompanyName"].ToString(), Id = Convert.ToInt32(reader["Id"]) });
}
}
catch (DbException ex)
{
return null;
}
finally
{
connection.Close();
}
}
return responses;
}
The query returns the expected object, when all values are set to the values of an instance/row in the database. However, I cannot find a way to set the column to allow any value.
In SQL, it would be possible to say WHERE CreationDate = CreationDate , which would translate to:
command.Parameters.Add("CreationDate", SqlDbType.DateTime).Value = "CreationDate";
However, this doesn't work in SqlClient. Can anyone suggest how I might achieve this?
I am having c# code like this:
using (MySqlConnection con = new MySqlConnection(AR.ConnectionString))
{
con.Open();
using (MySqlCommand cmd = new MySqlCommand(#"SELECT PORUDZBINAID, USERID, BRDOKKOM, DATUM,
STATUS, MAGACINID, PPID, INTERNIKOMENTAR, REFERENT_OBRADE, NACIN_PLACANJA, TAG FROM
PORUDZBINA WHERE TAG LIKE '%#MOB%'", con))
{
cmd.Parameters.AddWithValue("#MOB", Mobilni);
MySqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
list.Add(new Porudzbina()
{
PorudzbinaID = Convert.ToInt32(dr[0]),
UserID = Convert.ToInt32(dr[1]),
BrDokKom = Convert.ToInt32(dr[2]),
Datum = Convert.ToDateTime(dr[3]),
Status = (PorudzbinaStatus)Convert.ToInt32(dr[4]),
MagacinID = Convert.ToInt32(dr[5]),
PPID = (dr[6] is DBNull) ? (int?)null : Convert.ToInt32(dr[6]),
InterniKomentar = (dr[7] is DBNull) ? null : dr[7].ToString(),
ReferentObrade = (dr[8] is DBNull) ? (int?)null : Convert.ToInt32(dr[8]),
NacinUplate = (PorudzbinaNacinUplate)Convert.ToInt32(dr[9]),
Tag = JsonConvert.DeserializeObject<Properties>(dr["TAG"].ToString())
});
}
}
I put breakpoint and it passes good paramter to query but doesn't enter while() loop (so i is not reading) and it returns no rows.
When i enter same query in my mysql and replace #MOB with parameter passed there, it does return me one row.
I guess problem is something with passing LIKE through c# but not sure why it does that.
You need to change how you are adding parameters slightly:
In your SQL, no quotes and no % symbols.
using (MySqlCommand cmd = new MySqlCommand(#"SELECT PORUDZBINAID, USERID, BRDOKKOM, DATUM,
STATUS, MAGACINID, PPID, INTERNIKOMENTAR, REFERENT_OBRADE, NACIN_PLACANJA, TAG FROM
PORUDZBINA WHERE TAG LIKE #MOB", con))
{
Then the parameter like this, without quotes.
cmd.Parameters.AddWithValue("#MOB", "%" + Mobilni + "%");
BTW: Ideally you should not use AddWithValue, but rather Add(). See this blog:
https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/
And this SO post:
MySqlCommand Command.Parameters.Add is obsolete
Instead, it should be like this:
cmd.Parameters.Add("#MOB", SqlDbType.Varchar).Value = "%" + Mobilni + "%";
//you must update to use the correct DBType for your data
Since #MOB is inside single quotes, it's interpreted as a string literal, which isn't what you meant. You can fix this by concatenating the placeholder to the % characters:
using (MySqlCommand cmd = new MySqlCommand(
#"SELECT PORUDZBINAID, USERID, BRDOKKOM, DATUM, STATUS, MAGACINID, PPID, INTERNIKOMENTAR, REFERENT_OBRADE, NACIN_PLACANJA, TAG
FROM PORUDZBINA
WHERE TAG LIKE CONCAT('%', #MOB, '%')", con))
I am trying to update a databse entry under a specific id in my table when the users enter their ID number in a textBox.
At the moment it updates but updates all entries in my table except the entry containing the users ID number.
This is the code I am currently using:
private void Button1_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(#"Data Source=DEVELOPMENT\ACCESSCONTROL;Initial Catalog=ACCESSCONTROL;User ID=sa;Password=P#55w0rd123");
SqlCommand check_User_Name = new SqlCommand("SELECT Id FROM NewVisitor WHERE (IDNumber = #IDNumber)", con);
check_User_Name.Parameters.AddWithValue("#IDNumber", idNumber_TxtBox.Text);
con.Open();
int UserExist = (int)check_User_Name.ExecuteScalar();
if (UserExist > 0)
{
var connetionString = #"Data Source=DEVELOPMENT\ACCESSCONTROL;Initial Catalog=ACCESSCONTROL;User ID=sa;Password=P#55w0rd123";
var sql = "UPDATE NewVisitor SET PersonVisit = #PersonVisit, PurposeVisit = #PurposeVisit, Duration = #Duration, Disclaimer = #Disclaimer";
try
{
using (var connection = new SqlConnection(connetionString))
{
using (var command = new SqlCommand(sql, connection))
{
command.Parameters.Add("#PersonVisit", SqlDbType.NVarChar).Value = personVisiting_TxtBox.Text;
command.Parameters.Add("#PurposeVisit", SqlDbType.NVarChar).Value = purposeOfVisit_CMBox.SelectedItem;
command.Parameters.Add("#Duration", SqlDbType.Date).Value = duration_dateTimePicker1.Value.Date;
command.Parameters.Add("#Disclaimer", SqlDbType.NVarChar).Value = disclaimer_CHKBox.Checked;
connection.Open();
command.ExecuteNonQuery();
}
}
}
The whole table has many more fields but would like to just update the above fields within that specific ID.
Thanks
You forgot the WHERE clause on the UPDATE statement, telling it specifically which records to update. It sounds like you just want to add the exact same WHERE clause that you have on your SELECT:
var sql = "UPDATE NewVisitor SET PersonVisit = #PersonVisit, PurposeVisit = #PurposeVisit, Duration = #Duration, Disclaimer = #Disclaimer WHERE (IDNumber = #IDNumber)";
And don't forget to add the paramter for it:
command.Parameters.Add("#IDNumber", SqlDbType.Int).Value = idNumber_TxtBox.Text;
You may need to convert the input value to an integer first, I'm not 100% certain (it's been a while since I've had to use ADO.NET directly). Something like this:
if (!int.TryParse(idNumber_TxtBox.Text, out var idNumber))
{
// input wasn't an integer, handle the error
}
command.Parameters.Add("#IDNumber", SqlDbType.Int).Value = idNumber;
im writing a library database program. It can insert books, but I have a problem in making a reference between book and a person which rents it. I can't get a last inserted id from a rents table to put it to the compilation table to assign book to a person who rents it. I've tried SCOPE_IDENTITY() but it doesn't works for me. Here's the code:
private void addRentButton_Click(object sender, EventArgs e) {
elibrary f1 = new elibrary();
string query = "INSERT INTO rents VALUES (#renterName, #rentStartDate, #rentEndDate)";
using(f1.Connection = new SqlConnection(f1.connectionString))
using(SqlCommand command = new SqlCommand(query, f1.Connection)) {
f1.Connection.Open();
command.Parameters.AddWithValue("#renterName", rentNameBox.Text);
command.Parameters.AddWithValue("#rentStartDate", DateTime.Now);
command.Parameters.AddWithValue("#rentEndDate", rentEndDatePicker.Value);
command.ExecuteScalar();
}
rentEndDatePicker.Value = DateTime.Now;
string Compilationquery =" INSERT INTO compilation VALUES (#bookId, SELECT SCOPE_IDENTITY())";
using(f1.Connection = new SqlConnection(f1.connectionString))
using(SqlCommand command = new SqlCommand(Compilationquery, f1.Connection)) {
f1.Connection.Open();
command.Parameters.AddWithValue("#bookId", f1.listBook.SelectedValue);
command.ExecuteScalar();
Actually, you are not retrieving the last inserted ID value from the first query, since the SCOPE_IDENTITY() is wrongly placed and you are not assigning the ExecuteScalar() return value anywhere:
String query = "INSERT INTO rents VALUES (#renterName, #rentStartDate, #rentEndDate); SELECT CONVERT(INT, SCOPE_IDENTITY())"; // "SELECT CAST(SCOPE_IDENTITY() AS INT)" can also be an option
Int32 lastId = 0;
using (f1.Connection = new SqlConnection(f1.connectionString))
using (SqlCommand command = new SqlCommand(query, f1.Connection))
{
f1.Connection.Open();
command.Parameters.AddWithValue("#renterName", rentNameBox.Text);
command.Parameters.AddWithValue("#rentStartDate", DateTime.Now);
command.Parameters.AddWithValue("#rentEndDate", rentEndDatePicker.Value);
lastId = (Int32)command.ExecuteScalar();
}
Once this is done, you can proceed with the second query as follows:
String compilationQuery = "INSERT INTO compilation VALUES (#bookId, #rentId)";
using (f1.Connection = new SqlConnection(f1.connectionString))
using (SqlCommand command = new SqlCommand(compilationQuery, f1.Connection))
{
f1.Connection.Open();
command.Parameters.AddWithValue("#bookId", f1.listBook.SelectedValue);
command.Parameters.AddWithValue("#rentId", lastId);
// ...
You have disposed the command so SCOPE_IDENTITY() is gone. There is no reason to dispose of the commmand twice.
using(SqlCommand command = new SqlCommand(query, f1.Connection))
{
f1.Connection.Open();
command.Parameters.AddWithValue("#renterName", rentNameBox.Text);
command.Parameters.AddWithValue("#rentStartDate", DateTime.Now);
command.Parameters.AddWithValue("#rentEndDate", rentEndDatePicker.Value);
command.ExecuteScalar();
int id = (Int32)command.ExecuteScalar();
command.Parameters.Clear();
Compilationquery = "INSERT INTO compilation VALUES (#bookId, #id)";
command.CommandText = Compilationquery;
command.Parameters.AddWithValue("#bookId", f1.listBook.SelectedValue);
command.Parameters.AddWithValue("#id", id);
command.ExecuteScalar();
}
How do I properly declair a parameter in the code below. Im getting underlines on "SelectCommand" Im not sure what im doing wrong.
public int GetTotalNumberOfAprovedPictureIds(string SexType)
{
string strConectionString = ConfigurationManager.AppSettings["DataBaseConnection"];
SqlConnection conn = new SqlConnection(strConectionString);
conn.Open();
SqlCommand oCommand = new SqlCommand("SELECT COUNT(1) AS Expr1 FROM MEMBERS INNER JOIN Picture ON MEMBERS.MemberID = Picture.MemberID WHERE (Picture.PicAproval = 1) AND (Picture.PicArchive = 0) AND (MEMBERS.MemberSex = #dSexType)", conn);
object oValue = oCommand.ExecuteScalar();
oCommand.SelectCommand.Parameters.Add("#dSexType", SqlDbType.Text);
oCommand.SelectCommand.Parameters["#dSexType"].Value = SexType;
conn.Close();
if (oValue == DBNull.Value)
{
return 0;
}
else
{
return Convert.ToInt32(oValue);
}
}
You are doing a couple of things wrong;
1) You are adding the parameter AFTER you execute the query
2) You are using the SelectCommand property when you don't need to. In fact, you are probably confusing this with a DataAdapter object, which does have a SelectCommand property.
Instead, try:
public int GetTotalNumberOfAprovedPictureIds(string SexType)
{
string strConectionString = ConfigurationManager.AppSettings["DataBaseConnection"];
using (SqlConnection conn = new SqlConnection(strConectionString))
{
conn.Open();
using (SqlCommand oCommand = new SqlCommand("SELECT COUNT(*) FROM MEMBERS INNER JOIN Picture ON MEMBERS.MemberID = Picture.MemberID WHERE (Picture.PicAproval = 1) AND (Picture.PicArchive = 0) AND (MEMBERS.MemberSex = #dSexType)", conn))
{
oCommand.CommandType = CommandType.Text;
SqlParameter myParam = oCommand.Parameters.Add("#dSexType", SqlDbType.Text);
myParam.Value = SexType;
object oValue = oCommand.ExecuteScalar();
if (oValue == DBNull.Value)
{
return 0;
}
else
{
return Convert.ToInt32(oValue);
}
}
}
}
I'd strongly urge you to use a "USING" statement when dealing with SqlConnection, SqlCommand and similar objects. It will ensure your connection is closed and disposed as soon as it leaves the scope, including after an exception.
To my knowledge SqlCommand does not have a property or field called SelectCommand. Just get rid of it:
oCommand.Parameters.Add("#dSexType", SqlDbType.Text);
oCommand.Parameters["#dSexType"].Value = SexType;
oCommand.Parameters.Add("#dSexType", SqlDbType.Text);
oCommand.Parameters["#dSexType"].Value = SexType;
SelectCommand has no such properties. Use directly like the above.