MySQL(或C#)不匹配双精度或小数

时间:2015-09-02 15:29:53

标签: c# mysql string double decimal

为什么MySQL或C#我不知道哪一个,不喜欢匹配双变量或十进制变量?它会匹配字符串,但我需要一个double或一个十进制,因为我需要匹配大于或小于小数位。它与decimal或double完全匹配,并且没有错误。这是我的代码:

double lat5 = -26.00033;
string Lati = "-26.00033";
decimal lat6 = decimal.Parse(Lati, CultureInfo.InvariantCulture);

//this
CommandString = "SELECT * FROM lapdetails2 WHERE Latitude = -26.00033";
//and this work
CommandString = "SELECT * FROM lapdetails2 WHERE Latitude = '" + Lati + "'";
//but this
CommandString = "SELECT * FROM lapdetails2 WHERE Latitude = '" + lat5 + "'";
//and this do not work
CommandString = "SELECT * FROM lapdetails2 WHERE Latitude = '" + lat6 + "'";

MySQL DB中的数据是DOUBLE(10,5)。

编辑:这是我试过的参数化查询:

CommandString = "SELECT * FROM lapdetails2 WHERE Latitude = @Latitude";
MySqlCommand cmd = new MySqlCommand(CommandString);
cmd.Connection = DB.ConnectSQL;
cmd.Parameters.AddWithValue("@Latitude", lat6);
cmd.Connection.Open();
MySqlDataReader reader = cmd.ExecuteReader();

我还根据Rick James的建议将数据库数据更改为DECIMAL(8,5),但它仍然不起作用。

编辑2:我用存储过程修复了这个问题(效率不高但是有效)。

CREATE DEFINER=```localhost` PROCEDURE `coord_pro`(IN Longi1 double(8,5), IN Longi2 double(8,5), IN lat double(8,5))
BEGIN

create table tmp engine=memory select * 
from lapdetails2 where Latitude = lat AND Longitude >= Longi2 AND Longitude <= Longi1;

END

,其中 Longi1 = actualLong * 1.00001;Longi2 = actualLong * 0.99991;

然后只需读取tmp中的值,并且根据您的精度,应该只有一行。

2 个答案:

答案 0 :(得分:3)

转换为字符串时,您似乎必须使用InvariantCulture

// this should be OK
CommandString = "SELECT * FROM lapdetails2 WHERE Latitude = '" + lat5.ToString(CultureInfo.InvariantCulture) + "'";

使用CultureInfo.InvariantCulture可确保.将用作小数点分隔符。更好的方法是消除撇号',让DMBS比较数字,而不是字符串

CommandString = "SELECT * FROM lapdetails2 WHERE Latitude = " + lat5.ToString(CultureInfo.InvariantCulture);

答案 1 :(得分:0)

首先,请勿在{{1​​}}或(M,N)上使用FLOAT,否则会导致额外的舍入。

如果您的lat / lng数字总是有5个小数位,请使用DOUBLE。十进制将与-26.00033完全比较,有或没有引号。

一般来说,比较本质上为“浮点”的等号是不明智的,例如纬度/经度。

在C#中工作时,请确保舍入到5个小数位并向MySQL显示一个字符串,而不是DECIMAL(8,5)FLOAT以保持一致性。 (也许格式DOUBLE适用于C#,如C?)

<强>附加物

给出一个包含%.5f的表格:

d DECIMAL(18,4)

当客户端(在您的情况下为C#)构建值时,它必须转换为字符串并可选择引用它。请注意mysql> SELECT d, d<1.2346, d<'1.2346', d=1.2346, d='1.2346', d>1.2346, d>'1.2346' FROM `dec184` WHERE d = 1.2346; +--------+----------+------------+----------+------------+----------+------------+ | d | d<1.2346 | d<'1.2346' | d=1.2346 | d='1.2346' | d>1.2346 | d>'1.2346' | +--------+----------+------------+----------+------------+----------+------------+ | 1.2346 | 0 | 0 | 1 | 1 | 0 | 0 | +--------+----------+------------+----------+------------+----------+------------+ 在所有情况下如何正常工作。

现在,让我们改变一切。 1.2346被声明为dx

FLOAT

注意mysql> SELECT d, dx, dx<1.2346, dx<'1.2346', dx=1.2346, dx='1.2346', dx>1.2346, dx>'1.2346' FROM `dec184` WHERE d = 1.2346; +--------+--------+-----------+-------------+-----------+-------------+-----------+-------------+ | d | dx | dx<1.2346 | dx<'1.2346' | dx=1.2346 | dx='1.2346' | dx>1.2346 | dx>'1.2346' | +--------+--------+-----------+-------------+-----------+-------------+-----------+-------------+ | 1.2346 | 1.2346 | 1 | 1 | 0 | 0 | 0 | 0 | +--------+--------+-----------+-------------+-----------+-------------+-----------+-------------+ 恰好低于常数。为了验证,让我们通过MySQL来提供更精确的值。 (注意:dx只有大约7位有效数字,存储在24个中。)

FLOAT

或者...

mysql> SELECT dx, dx+0 FROM `dec184` WHERE d = 1.2346;
+--------+--------------------+
| dx     | dx+0               |
+--------+--------------------+
| 1.2346 | 1.2345999479293823 |
+--------+--------------------+