sqlite读取小十进制值为0?

发布于 2025-02-03 01:05:18 字数 2142 浏览 2 评论 0原文

我在一列中有一个带有“非常小的值”的sqlite表。像0.00000363455000。 当我在“ sqlite的db浏览器”中运行查询时,这些值的显示正确:

SQLITE 1

在我的C#应用​​中,小值始终为0。

            using (SQLiteConnection connection = new SQLiteConnection(
                    "Data Source='" + dmaDataSource + "'"))
            {
                SQLiteCommand command = new SQLiteCommand(sqlQuery, connection);
                connection.Open();
                SQLiteDataReader reader = command.ExecuteReader();
                if (reader.HasRows)
                {
                    response = new DmaResponse();
                    
                    while (reader.Read())
                    {
                        Type t0 = reader.GetFieldType(0); // is decimal
                        Type t1 = reader.GetFieldType(1); // is decimal
                        string f0 = reader.GetName(0);
                        string f1 = reader.GetName(1);

                        response.price_per_ton = (decimal)reader[0];
                        string test = reader[1].ToString(); // "0"
                        response.price_per_mm3 = (decimal)reader[1]; // 0.00000363455000 becomes 0
                    }
                }
            }

“屏幕截图比较db

有什么想法吗?

在进行了更多测试之后:
这两个字段都是数字的类型:

在C#中是十进制的。

在创建此帖子之前,我尝试了GetDecimal方法。

response.price_per_ton = reader.GetDecimal(0);
string test = reader[1].ToString();
response.price_per_mm3 = reader.GetDecimal(1);

getDecimal(0)作品,getDecimal(1)抛出了一个例外: {“输入字符串不是正确的格式。”}

然后,我使用db浏览器更改“我的“行”形式中的小数分离器,为。

现在,reader.getDecimal(1)不再抛出异常,而是回馈0。

I have a sqlite table with "very small values" in one column. Like 0.00000363455000.
When I run a query in "DB Browser for SQlite" the values are shown correct:

Screenshot DB Browser for SQlite 1

Screenshot DB Browser for SQlite 1

In my c# application the small values are always 0.

            using (SQLiteConnection connection = new SQLiteConnection(
                    "Data Source='" + dmaDataSource + "'"))
            {
                SQLiteCommand command = new SQLiteCommand(sqlQuery, connection);
                connection.Open();
                SQLiteDataReader reader = command.ExecuteReader();
                if (reader.HasRows)
                {
                    response = new DmaResponse();
                    
                    while (reader.Read())
                    {
                        Type t0 = reader.GetFieldType(0); // is decimal
                        Type t1 = reader.GetFieldType(1); // is decimal
                        string f0 = reader.GetName(0);
                        string f1 = reader.GetName(1);

                        response.price_per_ton = (decimal)reader[0];
                        string test = reader[1].ToString(); // "0"
                        response.price_per_mm3 = (decimal)reader[1]; // 0.00000363455000 becomes 0
                    }
                }
            }

Screenshot Comparison DB Browser / VS Debug

Any Ideas?

After some more tests:
Both fields are type of NUMERIC:
enter image description here
which is decimal in c#.

I tried the GetDecimal method before I created this post.

response.price_per_ton = reader.GetDecimal(0);
string test = reader[1].ToString();
response.price_per_mm3 = reader.GetDecimal(1);

GetDecimal(0) works, GetDecimal(1) throwed an exception:
{"Input string was not in a correct format."}

Then I used DB Browser to change the decimal separator in "my" row form , to .
enter image description here

Now, reader.GetDecimal(1) doesn't throw an exception anymore, but gives back 0.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

白衬杉格子梦 2025-02-10 01:05:18

基于 sqlite的

  • 文档
  • 在您的情况下, 64位IEEE浮点数
  • 字符串
  • blob
  • null

,这将是64位IEEE浮点号。

The Microsoft.Data.Sqlite.Core library (note that I am assuming you are using this),

这意味着将字段检索为字符串,导致值从数字到文本的自动转换,然后将转换回带回到DECIMAL.PARSE的数字。这有很多方法可能会出错。

如果使用getDouble,则在驱动程序中使用本机方法sqlite_column_double,并且不会进行转换(因此我希望没有无效格式)。

双重比小数点不那么精确,因此您可能希望在对其进行计算之前将双重转换为十进制。

对于最小的错误余量,将小数作为字符串存储在数据库中,这样您就可以避免任何自动转换版(但会使用更多的字节来存储相同的数据)。

Based on the documentation of sqlite, the fundamental data types are:

  • 64-bit signed integer
  • 64-bit IEEE floating point number
  • string
  • BLOB
  • NULL

In your case, it would be a 64-bit IEEE floating point number.

The Microsoft.Data.Sqlite.Core library (note that I am assuming you are using this), uses decimal.Parse on the result of GetString if you use GetDecimal on the reader.

This means that the field is retrieved as a string, causing an auto-convert of the value from numeric to text, and then a conversion back to a number with decimal.Parse. This has lots of ways that it could go wrong.

If you use GetDouble, the native method sqlite_column_double is used in the driver, and there will be no conversions (and I expect therefore no invalid formats).

A double is less precise than a decimal, so you'd probably want to convert the double to decimal before doing calculations with it.

For the smallest possible margin of error, store the decimals as a string in the database, that way you avoid any auto-convert (but will use more bytes to store the same data).

z祗昰~ 2025-02-10 01:05:18

我越来越近:

ServerVersion = "3.37.0"  

列[1]system.decimal的类型,预期值是0.00000363455000
阅读器[1] .toString()返回“ 0”
(十进制)读取器[1]返回0
reader.getDecimal(1)抛出异常:

输入字符串的格式不正确。

reader.getString(1)返回“ 0,00000363455000”(德语小数分隔符)
我可以将其铸成十进制。

现在我有了我的预期价值,但我不知道为什么。

I'm getting closer to it:

ServerVersion = "3.37.0"  

Column[1] is type of System.Decimal and the expected value is 0.00000363455000.
reader[1].ToString() returns "0"
(decimal) reader[1] returns 0
reader.GetDecimal(1) throws an exception:

Input string was not in a correct format.

reader.GetString(1) returns "0,00000363455000" (German decimal separator)
which I can cast to decimal.

Now I have my expected value but I don't know why.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文