I have a problem with inserting data into a sql server 2012.
My problem is that when I save Quantitaand Prezzothe values are changed! what can it be?. Quantita and Prezzo as Money values are taken from a datagridview I leave you under an example with the image of the datagridview used for insertion and the result of insertion into the database.
VALUE WITHIN DATAGRIDVIEW:
AFTER INSERT INTO SQL-SERVER:
SqlConnection conn = db.apriconnessione();
SqlTransaction sqlTran = conn.BeginTransaction();
try
{
//avvio la transazione
SqlCommand command = conn.CreateCommand();
command.Transaction = sqlTran;
//InserimentoBolla
DateTime dataconvertita = Convert.ToDateTime(labelDATADDTMOD.Text);
command.CommandText = "SET IDENTITY_INSERT Bolla ON";
command.ExecuteNonQuery();
command.CommandText = "INSERT INTO Bolla(NumeroDDT,IdCantiere,DataDDT,Agente,RagioneSociale,CodiceCliente,RiferimentiInterni,Importo,Destinazione,Filiale,Magazzino,Preparato,Vettore,TipoTrasporto) VALUES('" + labelNUMDDTMOD.Text+"','"+IdCantiere+"',convert(datetime,'"+dataconvertita+"', 103),'" + labelAgenteMOD.Text+"','"+labelRagioneSocialeMOD.Text+"','"+int.Parse(labelCodiceClienteMOD.Text)+"','"+labelRIFInternoMOD.Text+"','"+float.Parse(labelImportoMOD.Text)+"','"+labelDestMOd.Text+"','"+labelFilialeMOD.Text+"','"+labelMagazzinoMOD.Text+"','"+labelPreparatodaMOD.Text+"','"+labelvettoreMOD.Text+"','"+labelTipoTrasportoMOD.Text+"')";
command.ExecuteNonQuery();
command.CommandText = "SET IDENTITY_INSERT Bolla OFF";
command.ExecuteNonQuery();
//fine bolla
//inserimento articolo
for (int rows = 0; rows < dataGridViewArticoli.Rows.Count; rows++)
{
string Fornitore = dataGridViewArticoli.Rows[rows].Cells[0].Value.ToString();
string ModelloFornitore = dataGridViewArticoli.Rows[rows].Cells[1].Value.ToString();
string SiglaMetel = dataGridViewArticoli.Rows[rows].Cells[2].Value.ToString();
string CodiceMetel = dataGridViewArticoli.Rows[rows].Cells[3].Value.ToString();
string CodiceInterno = dataGridViewArticoli.Rows[rows].Cells[4].Value.ToString();
string Descrizione = dataGridViewArticoli.Rows[rows].Cells[5].Value.ToString();
float prezzo = float.Parse(dataGridViewArticoli.Rows[rows].Cells[6].Value.ToString());
// MessageBox.Show(" "+prezzo);
float quantita = float.Parse(dataGridViewArticoli.Rows[rows].Cells[8].Value.ToString());
// MessageBox.Show("Quantita: "+quantita);
command.CommandText = "INSERT INTO ArticoloCantiere(IdCantiere,IdUtente,CodArt,CodMarca,CodiceInterno,ModelloFornitore,Prezzo,Quantita,Fornitore,Importato) VALUES('" + IdCantiere + "','"+u.IdUtente+"','" + CodiceMetel + "','" + SiglaMetel + "','" + CodiceInterno + "','" + ModelloFornitore + "','" + prezzo + "','" + quantita + "','COMET','BOLLA')";
command.ExecuteNonQuery();
}
//fine inserimento articolo
//conferma delle transazioni con la commit
sqlTran.Commit();
}
catch (Exception ex)
{
sqlTran.Rollback();
MessageBox.Show("Errore nell'inserimento "+ex);
}
conn.Close();
this.DialogResult = DialogResult.OK;
this.Close();
You insert string values with ',' separator into money data type, and this is a problem.
First of all, in SQL Server the decimal separator is ALWAYS '.', not the ','.
Second, you should not pass numbers as strings
Here is the code to reproduce your problem:
declare #t table(col money)
insert into #t values
('1,44');
select *
from #t;
----------
-- 144,00
Money data type accepts input with ',' separator, but it treats it not as decimal separator but thousand separator.
So to resolve it, the best way is pass in numbers as numbers, the worst thing you can do is just replace ',' with '.' before insert:
declare #t table(col money)
insert into #t values
(replace ('1,44', ',', '.'));
select *
from #t;
-----
---1,44
I would suggest adding a breakpoint at:
command.ExecuteNonQuery();
and double check that both values are correct for:
prezzo and quantita
edit: if the values are as expected, please check sql data types.
I would also suggest adding sql parameters, otherwise your code is vulnerable to sql injections:
INSERT INTO
ArticoloCantiere
(field1, field2...)
VALUES
(#value1, #value2...)
then:
command.Parameters.Add(new SqlParameter("#value1", <somevalue>));
command.Parameters.Add(new SqlParameter("#value1", <somevalue>));
...
command.ExecuteNonQuery();
You need to use parameterized queries. This is a BIG DEAL in terms of security, to the point where if you're not doing this you're practically begging to get hacked.
But this isn't just about security. Parameterized queries will also likely fix your formatting issue, because they can also automatically account for things like date formats and text values with single quotes in the data. As a bonus, you'll also typically get a (very small, but measurable) performance boost.
Here's how it will look:
//putting this all in one sql string to execute in one DB call eliminates the need for C# to manage transactions.
// If you're nervous about it, you can add "BEGIN TRANSACTION" and "COMMIT" statements to the SQL.
string sql = "SET IDENTITY_INSERT Bolla ON;\n"
+ "INSERT INTO Bolla (NumeroDDT,IdCantiere,DataDDT,Agente,RagioneSociale,CodiceCliente,RiferimentiInterni,Importo,Destinazione,Filiale,Magazzino,Preparato,Vettore,TipoTrasporto)\n"
+ " VALUES(\n"
+ "#NumeroDDT, #IdCantiere, #DataDDT, #Agente, #RagioneSociale, #CodiceCliente, #RiferimentiInterni, #Importo, #Destinazione, #Filiale, #Magazzino, #Preparato, #Vettore, #TipoTrasporto);\n"
+ "SET IDENTITY_INSERT Bolla OFF;";
using (var conn = db.apriconnessione())
using (var cmd = new SqlCommand(sql, conn))
{
//I have to guess at column types and lengths. Update these parameters to match your DB columns
cmd.Paramerers.Add("#NumeroDDT", SqlDbType.NVarChar, 50).Value = labelNUMDDTMOD.Text;
cmd.Paramerers.Add("#IdCantiere", SqlDbType.Int).Value = IdCantiere;
cmd.Paramerers.Add("#DataDDT", SqlDbType.DateTime).Value = Convert.ToDateTime(labelDATADDTMOD.Text);
cmd.Paramerers.Add("#Agente", SqlDbType.NVarChar, 50).Value = labelAgenteMOD.Text;
cmd.Paramerers.Add("#RagioneSociale", SqlDbType.NVarChar, 50).Value = labelRagioneSocialeMOD.Text;
cmd.Paramerers.Add("#CodiceCliente", SqlDbType.Int).Value = int.Parse(labelCodiceClienteMOD.Text);
cmd.Paramerers.Add("#RiferimentiInterni", SqlDbType.NVarChar, 50).Value = labelRIFInternoMOD.Text;
cmd.Paramerers.Add("#Importo", SqlDbType.Float).Value = float.Parse(labelImportoMOD.Text); //probably should be double or decimal
cmd.Paramerers.Add("#Destinazione", SqlDbType.NVarChar, 50).Value = labelDestMOd.Text;
cmd.Paramerers.Add("#Filiale", SqlDbType.NVarChar, 50).Value = labelFilialeMOD.Text;
cmd.Paramerers.Add("#Magazzino", SqlDbType.NVarChar, 50).Value = labelMagazzinoMOD.Text;
cmd.Paramerers.Add("#Preparato", SqlDbType.NVarChar, 50).Value = labelPreparatodaMOD.Text;
cmd.Paramerers.Add("#Vettore", SqlDbType.NVarChar, 50).Value = labelvettoreMOD.Text;
cmd.Paramerers.Add("#TipoTrasporto", SqlDbType.NVarChar, 50).Value = labelTipoTrasportoMOD.Text;
conn.Open();
cmd.ExecuteNonQuery();
}
Note there are some other improvements in here, too. I didn't re-write the other parts of your code just for the fun of it. But this query parameters are the important part.
I have an application that get a datetime value from the database but it give me this error
Specified cast is not valid
here is the code
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["Golden_RoseConnectionString"].ConnectionString);
con.Open();
String sel3 = "select Booking_Date from booking where Booking_ID='" + Booking_Id + "'";
SqlCommand cmd3 = new SqlCommand(sel2, con);
SqlDataReader n3 = cmd3.ExecuteReader();
n3.Read();
DateTime Booking_Date = (DateTime)n3.GetSqlDateTime(0);
con.Close();
How can I solve this problem?
You should use:
var Date = Convert.ToDateTime(n3["YOUR_DATE_COLUMN"]);
an sql date is not a .Net DateTime object.
GetSqlDateTime does not do a convertion - see MSDN.
It must be converted - see the SO question as an example
I'm trying to update a table element of type timestamp called dtprint with the current time (the original value is NULL). The code that I am using is as follows:
MySqlConnection con = new MySqlConnection("Connection_String");
con.Open();
MySqlCommand _cmd = con.CreateCommand();
string dt = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
_cmd.CommandText = "UPDATE requests SET dtprint = " + dt + " WHERE idPerson = " + _personID[index];
_cmd.ExecuteNonQuery();
con.Close();
The exception I keep getting is: Additional information: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '14:03:23 WHERE idPerson = 45' at line 1.
The only thing I can think of is that the Database isn't recognizing the time as a timestamp, any help is greatly appreciated.
Since dt is a string and your dtprint is timestamp, you need to use single quotes when you try to insert it. Like;
"UPDATE requests SET dtprint = '" + dt + "' WHERE
But don't use this way.
You should always use parameterized queries. This kind of string concatenations are open for SQL Injection attacks.
Also use using statement to dispose your database connections and objects.
using(MySqlConnection con = new MySqlConnection(ConnectionString))
using(MySqlCommand _cmd = con.CreateCommand())
{
string dt = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
_cmd.CommandText = #"UPDATE requests SET dtprint = #dtprint
WHERE idPerson = #id";
_cmd.Parameters.Add("#dtprint", MySqlType.TimeStamp).Value = dt;
_cmd.Parameters.Add("#id", MySqlType.Int).Value = _personID[index];
con.Open();
_cmd.ExecuteNonQuery();
}
I'm new in programming and want you to help me.
I have field of type (date) and when I insert data to database from my website in visual studio 2010 with C#, it Shows me an error during execution.
Can anyone help me?
Thank you
Code behind
string InsMus = "Insert into StoreMus (MusNo,MusDate)" +
"Values (" + Convert.ToInt16(txtMusNo.Text) + ",'" + DateTime.Parse(txtMusDate.Text) + "')";
cmd = new SqlCommand(InsMus , con);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
Don't use string concanation to prevent sql injection. I'm sure that it will also fix this issue.
string InsMus = #"Insert into StoreMus (MusNo,MusDate)
Values (#MusNo, #MusDate);";
using(var con = new SqlConnection("Connection String..."))
using(var cmd = new SqlCommand(InsMus, con))
{
cmd.Parameters.Add("#MusNo", SqlDbType.SmallInt).Value = short.Parse(txtMusNo.Text);
cmd.Parameters.Add("#MusDate", SqlDbType.Date).Value = DateTime.Parse(txtMusDate.Text);
con.Open();
int inserted = cmd.ExecuteNonQuery();
}
Note that i've used the using-statement to ensure that the connection gets disposed/closed.
You could also use DateTime.TryParse instead of DateTime.Parse to prevent an exception that happens when the format of the date is invalid:
DateTime musDate;
if(!DateTime.TryParse(txtMusDate.Text, out musDate))
{
MessageBox.Show("Please enter a valid mus-date.");
return;
}
// here you can use musDate
This should hopefully be a simple one. When using a date time picker in a windows form, I want an SQL statement to be carried out, like so:
string sql = "SELECT * FROM Jobs WHERE JobDate = '" + dtpJobDate.Text + "'";
Unfortunately, this doesn't actually provide any results because the JobDate field is stored as a DateTime value. I'd like to be able to search for all records that are on this date, no matter what the time stored may be, any help?
New query:
SqlDataAdapter da2 = new SqlDataAdapter();
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "SELECT * FROM Jobs WHERE JobDate >= #p_StartDate AND JobDate < #p_EndDate";
cmd.Parameters.Add ("#p_StartDate", SqlDbType.DateTime).Value = dtpJobDate.Value.Date;
cmd.Parameters.Add ("#p_EndDate", SqlDbType.DateTime).Value = dtpJobDate.Value.Date.AddDays(1);
cmd.Connection = conn;
da2.SelectCommand = cmd;
da2.Fill(dt);
dgvJobDiary.DataSource = dt;
Huge thanks for all the help!
Just one answer: use parametrized queries.
This is for different reasons:
security (no risk of SQL
Injection
no longer those problems for which you're opening a topic
performance.
Thus, write your statement like this:
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "SELECT * FROM Jobs WHERE JobDate = #p_Date"
cmd.Parameters.Add ("#p_Date", SqlDbType.DateTime).Value = dtpJobDate.Value;
If you want to ignore the time, then I think the best bet is to do a range search, if the time is stored in the DB, that is.
Something like this (just the SQL query):
SELECT * FROM Jobs WHERE JobDate >= #p_StartDate AND JobDate < #p_EndDate
StartDate would then be dtpJobDate.Value.Date, and EndDate would be dtpJobDate.Value.Date.AddDays(1)
If the Time is not stored in the DB, then you can do this:
SELECT * FROM Jobs WHERE JobDate = #p_Date
where the search argument should be dtpJobDate.Value.Date
Try dtpJobDate.Value.
Other than the SQL injection stuff in other answers, you can use something like this:
dtpJobDate.Value.ToString("yyyyMMdd HH:mm:ss");
But probably you won't find anything with exact time match, so you can change your query for something like
string sql = "SELECT * FROM Jobs WHERE JobDate BETWEEN '" + dtpJobDateStart.Value.ToString("yyyyMMdd HH:mm:ss") + "' AND '" + + dtpJobDateEnd.Value.ToString("yyyyMMdd HH:mm:ss") + " + "'";
First of all - you have left a door open for SQL injection in your example.
Other than that - to answer your question, you'll have to drop the times off of the JobDate column to get the match done. Try something like this (SQL Injection code left in example for comparison)...
string sql = "SELECT * FROM Jobs WHERE CAST(CONVERT(CHAR(8), JobDate, 112) AS DATETIME) = '" + dtpJobDate.Text + "'";
If you were to parameterize your query - you could do it something like this...
using (var conn = new SqlConnection(myConnectionString))
using (var cmd = new SqlCommand("SELECT * FROM Jobs WHERE JobDate = #JobDate", conn))
{
cmd.Parameters.Add(new SqlParameter("#JobDate", dtpJobDate.Value));
conn.Open();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
// your code here to deal with the records...
}
}
}