如何使用 SqlDataReader 获取双倍值
How to get double value with SqlDataReader
我正在尝试从 sql 数据库中读取数据。当我 运行 代码时,它在读取数据的位置时出错。
"System.InvalidCastException: Specified cast is not valid."
我收到一个错误。我研究了我的错误,但找不到适合我的解决方案。虽然我编写的查询文本在 ssms 中有效,但在代码中不起作用。
private void pbx_frame_MouseUp(object sender, MouseEventArgs e) //
{
//take cropped image to picture box of crooped images
try
{
string[] resim = lbx_raw_image.SelectedItem.ToString().Replace(':','.').Split('.');
string sorgu_sql = "Data Source=DESKTOP-OON7EET\SQLEXPRESS;Initial Catalog=Target;Integrated Security=True;"; //sql bağlantısı kuruldu
//string query = "SELECT * FROM MP_Data$ WHERE time= '19.53.06'"; //'" + lbx_raw_image.SelectedItem.ToString() + "'"; //time=19.53.06 tek bir veriyi çağrır. muhtemelen yorum haline getirilen kısım olacaktı.
string query = "SELECT * FROM MP_DATA_15_mayıs_2019$ WHERE time='" + lbx_raw_image.SelectedItem.ToString() + "'"; //12.50.23
DB_islem db = new DB_islem(sorgu_sql, query); //
pic_info_from_MP = db.Raw_Image(pic_info_from_MP);
public Target Raw_Image(Target pic_info)
{
sql.Open();
sql_read = sql_command.ExecuteReader();
//while (sql_read.Read())
if (sql_read.Read())
{
pic_info.lat = sql_read.GetDouble(0);
pic_info.lon = sql_read.GetDouble(1);
pic_info.alt = sql_read.GetDouble(2);
pic_info.yaw = sql_read.GetDouble(3);
}
sql.Close();
return pic_info;
}
解决方案:
ALTER TABLE table1(name of table) ALTER COLUMN clmn1(name of column) float(datatype);
我使用上述查询确定了每一列的数据类型。帮我调用了需要的数据。
首先,您应该仅使用参数执行查询。
其次,我们不知道您的 table 架构 - 请出示它。
但很可能您存储此值的方式存在问题。 GetDouble 不进行任何转换,因此您的数据应该已经保存为 double。
此外,全球化可能会出现问题。你应该做的是:
using System.Globalization;
//...
double result = double.NaN;
if(!sql_read.IsDbNull(0))
{
string s = sql_read.GetString(0);
result = Convert.ToDouble(s, CultureInfo.InvariantCulture);
}
我要求 table 定义的原因是因为数据库端有特定的列类型映射到 C# 端的特定数据类型。发布的屏幕截图不足以实际确定列类型。纬度和经度不是 real
,否则它们会被截断,但除此之外我们真的不能说
广义地说:
- 如果您使用了
real
列类型,请调用 GetFloat(..)
- 如果您使用了
float
列类型,请调用 GetDouble(..)
- 如果您使用了
decimal
(或 numeric
)列类型,请调用 GetDecimal(..)
GetXxx 不会为您转换,因为它会进行拆箱转换。如果您的 reader 在第 0 列中有一个 decimal
,您只能对其调用 GetDecimal
。您不能调用 GetDouble
并期望您将真正的小数转换为双精度数,原因与这不起作用相同:
object o = 0.1m; //decimal boxed inside object
double d = (double)o;
拆箱转换和转换转换是不同的事情。如果您希望将对象中的小数作为双精度数,则必须进行两次转换,一次用于拆箱,一次用于转换:
object o = 0.1m; //decimalboxed inside object
double d = (double)(decimal)o;
同样,如果您在 reader 列 0 中的内容是 decimal
,而您想要 double
,则必须将其作为小数,因为它确实是小数,然后转换它:
var dbl = (double)reader.GetDecimal(0);
简单规则:
- 按照原来的样子拉出来,然后转换
至于你有什么,我们不知道;您的 yaw
可能是 real
而不能 GetDouble
(必须是 GetFloat
)。您的 alt
可能是小数(您真的需要高度为 picometer/pico-ft 的十分之一吗?)并且不能 GetDouble
'd(必须 GetDecimal
'd) .. 但你有自己解决这个问题的所有必要信息。
如果所有其他方法都失败了,并且上面的内容完全超出了您的理解范围,请尝试将不起作用的行的 GetDouble 更改为 GetDecimal。如果这不起作用,请尝试将其更改为 GetFloat。如果那不起作用,请提供 table 定义,我们会告诉您它应该是什么
更新:您已经指出它们都是 varchar。就我个人而言,我会将它们转换为浮点数或真实数 - 打开 SSMS,设计 table,将列类型更改为例如浮点数并保存 table。然后他们可以GetDouble'd
我正在尝试从 sql 数据库中读取数据。当我 运行 代码时,它在读取数据的位置时出错。
"System.InvalidCastException: Specified cast is not valid."
我收到一个错误。我研究了我的错误,但找不到适合我的解决方案。虽然我编写的查询文本在 ssms 中有效,但在代码中不起作用。
private void pbx_frame_MouseUp(object sender, MouseEventArgs e) //
{
//take cropped image to picture box of crooped images
try
{
string[] resim = lbx_raw_image.SelectedItem.ToString().Replace(':','.').Split('.');
string sorgu_sql = "Data Source=DESKTOP-OON7EET\SQLEXPRESS;Initial Catalog=Target;Integrated Security=True;"; //sql bağlantısı kuruldu
//string query = "SELECT * FROM MP_Data$ WHERE time= '19.53.06'"; //'" + lbx_raw_image.SelectedItem.ToString() + "'"; //time=19.53.06 tek bir veriyi çağrır. muhtemelen yorum haline getirilen kısım olacaktı.
string query = "SELECT * FROM MP_DATA_15_mayıs_2019$ WHERE time='" + lbx_raw_image.SelectedItem.ToString() + "'"; //12.50.23
DB_islem db = new DB_islem(sorgu_sql, query); //
pic_info_from_MP = db.Raw_Image(pic_info_from_MP);
public Target Raw_Image(Target pic_info)
{
sql.Open();
sql_read = sql_command.ExecuteReader();
//while (sql_read.Read())
if (sql_read.Read())
{
pic_info.lat = sql_read.GetDouble(0);
pic_info.lon = sql_read.GetDouble(1);
pic_info.alt = sql_read.GetDouble(2);
pic_info.yaw = sql_read.GetDouble(3);
}
sql.Close();
return pic_info;
}
解决方案:
ALTER TABLE table1(name of table) ALTER COLUMN clmn1(name of column) float(datatype);
我使用上述查询确定了每一列的数据类型。帮我调用了需要的数据。
首先,您应该仅使用参数执行查询。 其次,我们不知道您的 table 架构 - 请出示它。
但很可能您存储此值的方式存在问题。 GetDouble 不进行任何转换,因此您的数据应该已经保存为 double。
此外,全球化可能会出现问题。你应该做的是:
using System.Globalization;
//...
double result = double.NaN;
if(!sql_read.IsDbNull(0))
{
string s = sql_read.GetString(0);
result = Convert.ToDouble(s, CultureInfo.InvariantCulture);
}
我要求 table 定义的原因是因为数据库端有特定的列类型映射到 C# 端的特定数据类型。发布的屏幕截图不足以实际确定列类型。纬度和经度不是 real
,否则它们会被截断,但除此之外我们真的不能说
广义地说:
- 如果您使用了
real
列类型,请调用GetFloat(..)
- 如果您使用了
float
列类型,请调用GetDouble(..)
- 如果您使用了
decimal
(或numeric
)列类型,请调用GetDecimal(..)
GetXxx 不会为您转换,因为它会进行拆箱转换。如果您的 reader 在第 0 列中有一个 decimal
,您只能对其调用 GetDecimal
。您不能调用 GetDouble
并期望您将真正的小数转换为双精度数,原因与这不起作用相同:
object o = 0.1m; //decimal boxed inside object
double d = (double)o;
拆箱转换和转换转换是不同的事情。如果您希望将对象中的小数作为双精度数,则必须进行两次转换,一次用于拆箱,一次用于转换:
object o = 0.1m; //decimalboxed inside object
double d = (double)(decimal)o;
同样,如果您在 reader 列 0 中的内容是 decimal
,而您想要 double
,则必须将其作为小数,因为它确实是小数,然后转换它:
var dbl = (double)reader.GetDecimal(0);
简单规则:
- 按照原来的样子拉出来,然后转换
至于你有什么,我们不知道;您的 yaw
可能是 real
而不能 GetDouble
(必须是 GetFloat
)。您的 alt
可能是小数(您真的需要高度为 picometer/pico-ft 的十分之一吗?)并且不能 GetDouble
'd(必须 GetDecimal
'd) .. 但你有自己解决这个问题的所有必要信息。
如果所有其他方法都失败了,并且上面的内容完全超出了您的理解范围,请尝试将不起作用的行的 GetDouble 更改为 GetDecimal。如果这不起作用,请尝试将其更改为 GetFloat。如果那不起作用,请提供 table 定义,我们会告诉您它应该是什么
更新:您已经指出它们都是 varchar。就我个人而言,我会将它们转换为浮点数或真实数 - 打开 SSMS,设计 table,将列类型更改为例如浮点数并保存 table。然后他们可以GetDouble'd