访问链接表从 SQL 服务器截断我的十进制值

Posted

技术标签:

【中文标题】访问链接表从 SQL 服务器截断我的十进制值【英文标题】:Access linked tables truncating my Decimal values from the SQL server 【发布时间】:2015-10-19 09:37:23 【问题描述】:

自从将 Access 数据迁移到 SQL 服务器后,我在十进制值方面遇到了多个问题。在我的 SQL 2012 服务器上的 SQL 表中,我将 Decimal 数据类型用于多个字段。过了一会儿,我首先尝试将十进制值设置为 18,2,但 Access 通过截断所有值(55,55 变成 50 等等)对此采取了奇怪的做法。

因此,在多次更改之后,Access 似乎接受了 SQL 服务器中的30,2 decimal 设置(现在这些值在链接的 Access 表中链接正确)。

几天前我偶然发现了这个问题,因为用户在编辑访问表单中的数字时遇到了问题。所以我检查了链接表的数据类型,似乎 Access 将decimal 30,2 值转换为Short Text data type,这显然是错误的。所以我做了一些研究,发现Access无法处理30,2 decimal,因此它被ODBC驱动程序转换为文本。 (见我之前的帖子:Access 2013 form field value gets cut off on changing the number before the point)

因此,为了修复后一个错误,我再次尝试(忘记我已经搞砸了)将十进制值更改为 17,2 / 18,2 和其他一些十进制值,但是在所有这些更改上,我又回到了截断问题...

我发现了一些关于它的帖子,但没有关于如何解决它的具体或答案。

一些附加信息:

使用 SQL 2012 服务器 使用 Access 2013 安装了 SQL Server Native Client 10 和 11。 查看注册码发现我使用的是ODBC驱动02.50版 SQL 本地客户端 11 具有/使用 DriverODBC 版本 03.80,而本地客户端 10 使用 DriverODBC 版本 10.00(但不确定这是否相关)。

用图片更新

在访问表单中,我有多行将链接表(sql 表)作为记录源。这些行使用 SQL 服务器中的数据填充。 您可以在下面看到一个带有特定示例的行,即 eenh。 prijs 是从链接的 (SQL) 表中加载的。

现在,当我更改点前面的 5(因此将其设为 2555,00 而不是 5555,00)时,值会被截断:

======>>>

所以我对其进行了研究,并了解到我的 SQL 十进制 30,2 不被 Access 接受。所以我查看了我的访问链接表,看看该字段是什么类型的数据:

因此,特定列 (CorStukPrijs) 在 SQL 服务器中是十进制的 30,2,但这里是一个短文本(对不起荷兰语单词)。 顺便说一句,其他数字(可以)只是普通整数。

在我的访问链接表 - 数据表视图中,值如下所示:

我还在链接表中添加了一个十进制值:

在我的 SQL 服务器中,(相同的)数据如下所示:

尽管如此,由于点之前的数字变化问题(回到表格 - 第一张图像),我将服务器中 30,2 的十进制类型更改为 18,2。 这是相同 5555 值的链接表中的结果:

它给出#Errors 和错误消息:

十进制值的缩放导致值被截断

(翻译过来可能和英文不太一样)

前面的 0,71 值结果为小数点 18,2:

希望现在更清楚一点! 附言我现在只是将一个十进制字段更改为 18,2。

【问题讨论】:

这很有趣。不久前,我正在为 C++ odbc-lib 进行单元测试,我试图让测试针对访问运行。对于我放弃的数字类型 - 说明 Access 根本无法使用数字(十进制)值。因此,您唯一的选择是让驱动程序将其转换为文本,并在写入时让驱动程序将文本转换回数值。如果'.'后面总是有两位数如果您在 Access 中将该列的类型设置为“Money”,您可以尝试访问是否可以“更好”工作。根据我的研究,这“类似于小数,但有 2 位数字”。 您能否举一个具体的例子来说明您遇到问题的值,以及问题究竟是什么?例如,如果您在 Access 前端使用没有千位分隔符的数字格式,是否一切正常? 您在示例中写道:值(55,55 变为 50,依此类推)。 您使用什么进行小数分隔?像这样的逗号 - 50,55 - 或像这样的点 - 50.55 - ?例如,在德国使用逗号,而在英语中则需要一个点。你考虑过吗? 如果您启动 Access,在数据表视图中打开链接表,然后在那里编辑 Decimal(18,2) 列,会发生什么情况?小数点分隔符是否显示为逗号或句点?如果在编辑现有值时使用相同的分隔符,该值会被截断吗? (我刚刚尝试将我的机器设置为“法语(加拿大)”并且2,34 被接受为有效的十进制值并且未被截断。) @GordThompson 好的,所以在数据表视图中,我现在有 2 个字段的 18,2 十进制。在 SQL 服务器中,当我现在查看我的访问权限时,我的值是 0.71 ,当我在链接表中用逗号 (0,71) 更改它时,它会更改为 71。所以它似乎只是除了 2 个小数位。机器语言为荷兰语,机器小数点为 2,分隔符为逗号。 【参考方案1】:

最近我找到了解决这个问题的方法!毕竟这一切都与语言设置有关..(以及在 Access 2013 中不被接受为小数的小数 30,2)。

我将 Native 客户端从 10 更改为 11,并在我的连接字符串中添加了一个重要值:regional=no。这解决了问题!

所以现在我的连接字符串是: szSQLConnectionString = "DRIVER=SQL Server Native Client 11.0;SERVER=" & szSQLServer & ";DATABASE=" & szSQLDatabase & ";UID=" & szSQLUsername & ";PWD=" & szSQLPassword & ";regional=no;Application Name=OPS-FE;MARS_Connection=yes;"

【讨论】:

【参考方案2】:

一些事情:

没有真正好的理由尝试 30 位的十进制值?

Access 仅支持 28 位压缩十进制列。因此,转到 30 将强制 Access 将该值视为字符串。

如果您将总位数保持在 28 以下,那么您应该没问题。

您还遗漏了您正在使用的驱动程序。 (旧版,或本机 10 或本机 11)。但是,所有 3 都应该没有小数的问题。

正如这里提到的,在对 sql 表进行任何更改后,您必须刷新链接表,否则此类更改将不会显示。

每次启动时都不需要重新链接代码。并且不清楚您的重新链接代码是如何工作的。如果重新链接代码复制了 tabledef 对象,然后重新设置了相同的 tabledef,那么对后端的更改很可能不会显示出来。

我建议在测试期间不要使用重新链接例程,只需右键单击给定的链接表并选择链接表管理器。然后点击一张表,ok刷新一下。

此外,在此测试期间,在 Access 中,转储(删除)您在用于测试的表设置(格式设置)中的任何格式。

我建议你重新开始,把原来的表格重新放大。

Access 应该并且可以轻松处理小数类型,但不清楚您的原始设置是什么。如果这些值从不要求小数点后超过 4 个有效数字,那么我会考虑使用货币,但小数点也应该可以。

【讨论】:

哇,积极的反馈不是你的强项,是吗。不过感谢您的反馈。 30 位的十进制值并不是突然出现的,如果你阅读了整篇文章,你会发现我为什么选择那个。就像我在我的帖子中所说的那样,为什么 Access 不接受它只是因为你说的原因(提供的链接。你对客户端问题的权利,我使用的是 Native Client 10。重新链接机制首先删除所有 TableDefs(比如我也提到过)。但我可以尝试用不同的方式进行测试。我也会像你建议的那样从头开始。 @Albert:“Access 应该并且可以轻松处理十进制类型”。恕我直言,这是不正确的。 Access 无法真正处理数值,它无法在内部工作,例如 SQL_C_NUMERIC_STRUCT。如果 Access 链接表使用 ODBC 连接到数据库,它将始终要求数据库驱动程序将任何数字列读取为 SQL_C_WCHAR。因此驱动程序将转换为/从文本并将其映射到数据库数字类型的表示。 现在您说的是 ODBC 而不是 Access?简单的事情是十进制类型可以很好地映射到 Access 并在与 Access 一起使用时保留它们的数据类型以及它们的值。对于 Access 无法处理的任何数据类型,数据类型将作为字符串返回。在这种情况下,数据不会保留为字符串,因此谁在乎数据是否在磁盘上是二进制的,然后去非洲并被一些猴子读取?在一天结束时,Access 有一个十进制类型的数据的 LOGCAL 视图。所以你的观点是不相关的,除非数据在 Access 中保留为字符串并且它没有。 当然,您确实指出了为什么使用 30 - 我指出这确实是一个猜测,而不是一个好主意。没什么大不了的,我只是想通过建议更好的解决问题的方法来为您节省未来的痛苦。一个简单的重新上传数据,重新链接,你应该没问题。您不需要在这里做任何其他事情 - 祝您好运! @erg - 抱歉,您在两个方面错了:(1)“货币”数据类型具有固定的 Scale(小数位数)为 4,而不是 2。(2)“小数”值作为数字而非文本存储在 Access 数据库中。您的其他评论是正确的,Access ODBC 确实将 Decimal 数字检索为 SQL_C_WCHAR,但 Access 本身将 Decimal 值存储为 96 位缩放数值。例如,Decimal(18,5) 值 3.14159 在 Access 数据库中存储为 ... 2F CB 04 ...,0x04CB2F 为 314159。【参考方案3】:

我今天遇到了这个问题,一位同事帮助了我。我们花了一个多小时才弄清楚这一点。在表的 SQL 数据库设计视图中更改数据类型并保存后,我们打开 ACCESS 并打开链接表的设计视图。收到一条消息说“无法修改链接表设计。仍然打开吗?”是的。然后我们调查并看到我们更改的数据类型,但我们必须在 Format 属性中输入 #.00 格式,在 Decimal Places 属性中输入 Auto,它最终在我们的 ACCESS 表单中正确显示小数。好郁闷!!!

【讨论】:

嗨。这是一个解决方案还是只是一个评论? 我看不出这如何回答本页顶部的问题,但它应该。请edit根据How to Answer或删除答案。否则,它可能会被标记为“不是答案”并被删除。

以上是关于访问链接表从 SQL 服务器截断我的十进制值的主要内容,如果未能解决你的问题,请参考以下文章

MVC3 十进制在编辑时被截断为 2 位小数

sql问题:将截断字符串或二进制数据。

不使用 SetRoundingMode() 截断浮点值

将截断字符串或二进制数据。语句已终止。

sql server,将截断字符串或二进制数据,如何知道出错在哪个字段?

sql2008企业管理器中修改字段值报:将截断字符串或二进制数据。说字段长度不够的请绕开。