为什么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
中的值,并且根据您的精度,应该只有一行。
答案 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 |
+--------+--------------------+