浮点数在插入时变为科学计数法

Posted

技术标签:

【中文标题】浮点数在插入时变为科学计数法【英文标题】:float changing to scientific notation on insert 【发布时间】:2013-11-08 21:26:38 【问题描述】:

当我插入浮点数时,我有一个包含 11 或 12 个数字的浮点数的 contactid 字段,该浮点数更改为科学记数法,导致重复键错误。如果我只是运行 Select 查询,我会得到我期望的结果。但是当我进行插入时,出现以下错误。我已经尝试了几乎所有的转换转换,但仍然以科学记数法结束?

Msg 2627, Level 14, State 1, Line 1 Violation of PRIMARY KEY constraint 'metavalues_primarykey'. Cannot insert duplicate key in object 'dbo.metavalues'. The duplicate key value is (4.56219e+014, 41070, 0). The statement has been terminated.

知道为什么吗?

我知道以这种方式设置数据库设计不是应有的方式,但这是我必须使用的方式。所以请不要告诉我我需要改变我的设计,因为我不能这样做,而不是我来改变设计。

 contactid       fieldgroup metatableid Subfields parent Metavalue
 456209564532953    1004    41140              0    0   NULL
 456209592021740    1004    41130              0    0   NULL
 456210014777935    1004    41097              0    0   NULL
 456211077079073    1004    41107              0    0   NULL




INSERT INTO contactease.dbo.metavalues
        (contactid,
         fieldgroup,
         metatableid,
         subfield,
         metaflags,
         metavalue)
SELECT DISTINCT m.contactid,
            1004,
            mt.metatableid,
            0,
            0,
            NULL
FROM  interact.dbo..[INT_LST_CUSTOM_ENUM] sic
   INNER JOIN interact.dbo.INT_AUX_LST_CUSTOM c
           ON c.LST_CUSTOM_ENUM_ID = sic.LST_CUSTOM_ENUM_ID
              AND c.DIRECTORY_ID <> -4
   INNER JOIN contactease.dbo.main m
           ON m.custnum1 = c.LISTING_ID
   INNER JOIN contactease.dbo.metatable mt
           ON mt.metaname = sic.LST_CUSTOM_ENUM_NM

【问题讨论】:

让我看看我能不能这样说,这样才有意义。如果您选择已经存在的键,它与您尝试以浮点数形式插入的键相比如何? 请记住,浮点数(和实数)是 SQL Server 中的近似值,我不确定如果将没有小数位的大量数字塞入浮点数会发生什么。 M.contactid 是浮点数据类型,列中的值位于示例的顶部,因此当我进行选择时,值返回为 456209564532953 但是当我根据选择进行插入时查询 456209564532953 正在尝试插入为 4.5621E+14 就像我将其导入 Excel 一样???希望自从 我怀疑你受到了舍入“错误”的影响。可悲的是,不知道你能做些什么。 我很确定科学记数法的存在只是为了显示错误消息。插入的值实际上是select 返回的值。否则会发生的唯一原因是源和目标字段具有(稍微)不同的数据类型,这将触发隐式类型转换/舍入。真正困扰我的是复合PK上发生的冲突。就算metatableid有冲突,那41070的值又是从哪里来的呢? 【参考方案1】:

Float 是一个approximate number data type,这意味着它不会总是显示确切的数字,您的主键列上可能拥有的最差数据类型,如果您的主键中有大量数字,您应该使用BIGINT这是Exact number data type。 由于 float 不代表确切的值,您可能有两个不同的值,但 float 可能认为它们几乎/appoxi 相同的值,您会收到重复的 PRIMARY KEY 约束错误。我的建议 更改列的数据类型或添加另一列用作主键。 最好使用 INT,如果表中有超过 2,147,483,647 条记录,则可以使用 BIGINT。老实说,如果你接近这个 INT 限制,你应该考虑表分区。

【讨论】:

同意你的观点,但只是一个小评论——如果你的主键值可以超过 2 147 483(他可以有一些不连续的数字),请使用 BIGINT 感谢您的建议,我希望情况已经如此。我们正在重新设计数据库,它一开始设计得很糟糕,但现在对我没有帮助。 @BogdanBogdanov 你忘记了几个数字。一个普通的int 可以上升到 (2,147,483,647。这是 20 亿和变化。你需要有很多行来证明bigint 的合理性。 正确,不是整套复制。【参考方案2】:

metavalues和main中contactid列的数据类型是什么,两列的数据类型一样吗?

我隐约记得几年前有一个类似的问题,这是由于两个不同服务器上的默认排序规则,我相信我通过将数值转换为 varchar 然后返回插入来解决了这个问题。我不确定这是否会对您有所帮助,但无论如何它可能会给您一些尝试。

我确实同意@Muhammed Ali,但如果您的表使用浮点数作为不好的主键 id 列。应该使用 int 或数字。

【讨论】:

以上是关于浮点数在插入时变为科学计数法的主要内容,如果未能解决你的问题,请参考以下文章

Python:将字符串(科学计数法)转换为浮点数

使用有限的类 C 库将科学计数法字符串中的数字转换为浮点数

将负科学记数法 1.3E-2 转换为浮点数?

PYTHON学习0009:浮点数及其精确度科学计数法----2019-6-7

在 Bigquery 中的 sum() 之后将科学记数法转换为浮点数

Pandas / 如何将存储为字符串的科学记数法转换为浮点数?