简体   繁体   English

错误查询Sql Server插入,不正确的值格式C#

[英]Error query Sql Server insert, not correct value format C#

I have a problem with inserting data into a sql server 2012 . 我在将数据插入sql server 2012遇到问题。
My problem is that when I save Quantita and Prezzo the values are changed! 我的问题是,当我保存QuantitaPrezzo ,价值会发生变化! 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. QuantitaPrezzo as Money值取自datagridview我给你留下一个例子,其中包含用于插入的datagridview图像和插入数据库的结果。

VALUE WITHIN DATAGRIDVIEW: DATAGRIDVIEW中的价值:

在此输入图像描述

AFTER INSERT INTO SQL-SERVER: 插入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();

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. 编辑:如果值是预期的,请检查sql数据类型。

I would also suggest adding sql parameters, otherwise your code is vulnerable to sql injections: 我还建议添加sql参数,否则你的代码很容易被sql注入:

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 insert string values with ',' separator into money data type, and this is a problem. 您将带有','分隔符的字符串值插入money数据类型,这是一个问题。

First of all, in SQL Server the decimal separator is ALWAYS '.', not the ','. 首先,在SQL Server中,小数分隔符始终是'。',而不是','。

Second, you should not pass numbers as strings 其次,你不应该将numbers作为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. Money数据类型接受带有','分隔符的输入,但它不将其视为小数分隔符而是千分隔符。

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

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. 但是这个查询参数是重要的部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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