2016-12-16 43 views
-1

我的应用程序,它与MySQL数据库操纵工作,但在这个表中插入值时,我有错误:C#Mysql的插入查询“数据被截断列费用”

private const string createItemTableQuery = "CREATE TABLE IF NOT EXISTS `virtualstartupdb`.`item` (" + 
           "`id` BIGINT(20) NOT NULL AUTO_INCREMENT," + 
           "`name` VARCHAR(1000) NOT NULL," + 
           "`title` VARCHAR(1000) NOT NULL," + 
           "`description` VARCHAR(1000) NOT NULL," + 
           "`language_id` VARCHAR(45) NOT NULL," + 
           "`price` DOUBLE(12,2) NOT NULL," + 
           "`costs` DOUBLE(12,2) NOT NULL," + 
           "`item_type_id` BIGINT(20) NOT NULL," + 
           "PRIMARY KEY(`id`)," + 
           "FOREIGN KEY(item_type_id) REFERENCES `virtualstartupdb`.`item_type` (id) ON DELETE NO ACTION ON UPDATE NO ACTION); "; 

我也有类于插入查询该表:

这些属性:

long _id; 
double _costs; 
string _name; 
string _title; 
string _description; 
string _language_id; 
double _price; 
long _item_type_id; 

这是插入查询我使用:

private string insertQuery = "INSERT INTO `virtualstartupdb`.`item` (`name`, `title`, `description`, `language_id`, `price`, `item_type_id`, `costs`) VALUES ('{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}');"; 

这是当我插入值像2650,551,0,属性成本和价格都可以,但是当我尝试插入41.67或193.33我得到控制台此错误:

Error in adding mysql row. Error: Data truncated for column 'costs' at row 1 

我也尝试与浮动,同样的错误。我做错了什么?

+0

的'193.33'值,不应产生这个错误。 – Rahul

+1

41.67和193.33听起来像是实际上可能插入了无限小数(如41.6666666666667或193.333333333)。你确定你的值真的只有2位小数?而且,考虑使用DECIMAL字段,而不是放松精度。 – jishi

+0

我不认为这是事实。我甚至在插入之前尝试了Math.round(成本,2),仍然是相同的错误。 – Teemo

回答

1

根据您的发布表定义costs DOUBLE(12,2) NOT NULL成本栏可以保存长达12位数的值,其中2位数可以在小数点后面,这就是DOUBLE(M,D)所指定的值。

由于这个值为193.33是完全正确的,应该不会造成任何问题。您必须通过放置一个断点来调试您的代码,并查看哪些特定值导致此错误/异常。

将代码包装在try .. catch块中。 同样,不是将整个CREATE语句放在一个字符串中;将其卸载到存储过程中,然后从您的代码中调用该过程。

0

将引号从INSERT中的数值中除去。

private string insertQuery = "INSERT INTO `virtualstartupdb`.`item` (`name`, `title`, `description`, `language_id`, `price`, `item_type_id`, `costs`) VALUES ('{0}', '{1}', '{2}', '{3}', {4}, {5}, {6});"; 

当您将引号留在原地时,您会让MySQL执行字符串到数字的转换。

更好的是,使用参数化查询。你可以阅读这些。

+0

嗯,但这种转换不会造成这种情况。会吗? – Rahul

+0

我试过,但现在我得到不同的错误:添加mysql行错误。错误:列计数与第1行的值计数不匹配 – Teemo

+0

我认为问题在于它以某种方式格式化了我的十进制数字,例如197,33而不是197.33 – Teemo

-5

谢谢大家的回答,但我发现不知何故,mySQL接受我的价值用逗号,而不是点(193.33是193,33等)。所以我改变我的查询到这:

private string insertQuery = "INSERT INTO `virtualstartupdb`.`item` (`name`, `title`, `description`, `language_id`, `price`, `item_type_id`, `costs`) VALUES ('{0}', '{1}', '{2}', '{3}', REPLACE('{4}', ',', '.'), {5}, REPLACE('{6}', ',', '.'));"; 

现在一切都像魅力!

+2

直到有人在说明字段中放入单引号。 –

1

请求您使用DECIMAL是正确的。在处理金钱时,你应该几乎总是使用DECIMAL而不是DOUBLE。但我认为这不是真正的问题。做出改变是很重要的,但是完成后我仍然会得到同样的错误。

相反,我怀疑问题与costsprice字段占位符周围的单引号有关。这使MySQL首先将您的值转换为字符串,然后必须将其重新转换为DOUBLE(12,2)以匹配列类型。在双倍转换的某处,您将失去精确度,并最终导致浮点舍入误差,从而使您获得的小数位数比您认为的要多。

或者,您的服务器运行的默认本地使用,而不是.作为小数点分隔符。

此外,这种技术很容易受到SQL injection攻击。您可以通过使用参数化查询解决所有三个问题(铸造,小数点分隔符,和大量的安全漏洞):

private string insertQuery = "INSERT INTO `virtualstartupdb`.`item` (`name`, `title`, `description`, `language_id`, `price`, `item_type_id`, `costs`) VALUES (@name, @title, @description, @language_id, @price, @item_type_id, @costs);"; 
private string connectionString = "Connection String here"; 

public void InsertRecord(MyInsertType newData) 
{ 
    using (var cn = new MySqlConnection(connectionString)) 
    using (var cmd = new MySqlCommand(insertQuery, cn)) 
    { 
     //Guessing at column types and lengths here 
     cmd.Parameters.Add("@name", MySqlDbType.VarChar, 20).Value = newData._name; 
     cmd.Parameters.Add("@title", MySqlDbType.VarChar, 20).Value = newData._title; 
     cmd.Parameters.Add("@description", MySqlDbType.VarString, 1000).Value = newData._description; 
     cmd.Parameters.Add("@language_id", MySqlDbType.VarChar, 5).Value = newData._language_id; 
     cmd.Parameters.Add("@price", MySqlDbType.Decimal).Value = newData._price; 
     cmd.Parameters.Add("@item_type_id", MySqlDbType.Int64).Value = newData._item_type_id; 
     cmd.Parameters.Add("@costs", MySqlDbType.Decimal).Value = newData._costs; 

     cn.Open(); 
     cmd.ExecuteNonQuery(); 
    } 
}