无法更改MS Access 2007中的数据类型

4

我有一个庞大的数据库(800MB),其中包含一个名为“Date Last Modified”的字段。目前,该字段输入为文本数据类型,但需要更改为日期/时间字段以执行一些查询。

我还有另一个完全相同的数据库,但只有35MB的数据,当我更改数据类型时,它可以正常工作。但是,当我尝试在大型数据库上更改数据类型时,它会给出一个错误:

Micorosoft Office Access can't change the data type.

There isn't enough disk space or memory

经过一些调查,有些网站提到了更改注册表文件(MaxLocksPerFile),我也尝试了,但没有运气 :-(

请问有人可以帮忙吗?


你尝试过创建一个新表,除了“Date Last Modified”是日期时间类型外,其他字段都相同吗?这个新表不应该有任何索引。使用追加查询将数据附加到新表中。 - Fionnuala
抱歉,我不太确定您所说的索引是什么意思 :s数据存储在CSV文件中,我使用它来导入Access,但是它也没有让我设置数据类型,在导入过程中遇到了相同的问题。 - Khalid Fazeli
如果你不知道什么是索引,那么你可能没有一个 :) 请发布两到三个日期以显示格式,谢谢。 - Fionnuala
7个回答

3
根据John W. Vinson在此处的说法,你遇到的问题是Access希望在进行更改时保留表的副本,这导致它超出了Access文件的最大允许大小。压缩和修复可能有助于将文件大小限制在范围内,但对我没有用。
如果像我一样,在旧表上有许多复杂的关系和报告,您不想重新做,请尝试使用@user292452的解决方案的变体。
  1. 复制表格(即'YourTable'),然后只将结构粘贴回数据库中,使用不同的名称(即'YourTable_new')。
  2. 再次复制YourTable,并将数据附加到YourTable_new。 (要进行粘贴附加操作,请先进行粘贴操作,然后选择附加数据到现有表。)
  3. 此时您可能需要复制一份Access数据库,以防下一部分出现问题。
  4. 使用删除查询删除YourTable中的所有数据---选择所有字段,使用星号,然后使用默认设置运行。
  5. 现在您可以根据需要更改YourTable中的字段并保存。
  6. YourTable_new中的数据附加到YourTable中,并检查是否存在类型转换、长度等错误。
  7. 删除YourTable_new

1
在第五步,您编辑原始表格,对吗? - Andre

1

一个相对繁琐(但直截了当)的解决方案是将大型数据库分成较小的数据库,对较小的数据库进行转换,然后重新组合它们。

这样做的另一个好处是,如果某个块中的文本由于某种机会是无效日期,那么很容易找到它(因为块大小较小)。

假设您在表上有某种整数键,范围从1到(比如)10000000,您可以执行查询,例如

SELECT *
INTO newTable1
FROM yourtable
WHERE yourkey >= 0 AND yourkey < 1000000

SELECT *
INTO newTable2
FROM yourtable
WHERE yourkey >= 1000000 AND yourkey < 2000000

等等,确保单独输入和运行这些查询,因为如果您尝试一次运行多个查询,Access似乎会给出语法错误。

如果您的键是其他内容,则可以执行相同类型的操作,但您必须对WHERE子句进行更加巧妙的处理。

当然,最后要考虑的一件事情是,如果您能够承受,就迁移到具有更强大功能的不同数据库。我猜您有理由认为这并不容易,但是随着您继续使用Access,您可能也会遇到其他问题,特别是在处理大量数据时。

编辑

既然您仍然遇到了一些麻烦,请查看以下详细信息,希望您能看到我之前没有描述清楚的地方:

在此,您可以看到我创建了类似于您描述的“OutputIDrive”表。我有一个ID标签,尽管我只有三个条目。 alt text

在这里,我创建了一个查询,进入了SQL模式,并输入了适当的SQL语句。在我的情况下,因为我的查询只抓取值>= 0和<2,我们只会得到一行...ID = 1的那一行。

alt text

当我点击运行按钮时,弹出窗口告诉/警告我将要发生的事情...它将把一行数据放入新表中。这很好...这就是我们要找的。我点击“确定”。

alt text

现在我们的新表已经被创建,当我点击它时,我们可以看到我们的一行数据(ID = 1)已经复制到了这个新表中。
alt text

现在,您应该能够仅修改SQL查询中的表名和数字值,然后再次运行它。

希望这可以帮助您解决任何问题。

编辑2:

啊哈!这就是诀窍。您必须逐个输入并运行Access中的SQL语句。如果您尝试放入多个语句并运行它们,您将会得到错误。因此,请先运行第一个语句,然后擦除它并运行第二个语句,以此类推,您应该没问题。我认为这样就可以了!我已经编辑了上面的内容,使其更清晰明了。


抱歉,我在SQL方面有点新手。我的表名为“OutputIDrive”,我的键名为“ID”,范围从0到1325210。我该如何将其放入SQL中?我尝试更改您上面的源代码,但出现了“查询表达式中的语法错误'ID >=0 AND ID < 662605'”。感谢您的帮助。 - Khalid Fazeli

1

这篇文章内容翻译自 MSDN 上Karl Donaubauer的回答

  • 切换至立即窗口(Ctl + G)
  • 执行以下语句:

    DBEngine.SetOption dbMaxLocksPerFile, 200000


微软有一篇知识库文章直接解决并描述了这个问题的原因:

事务所需的页面锁超过了MaxLocksPerFile值,该值默认为9500个锁。MaxLocksPerFile设置存储在Windows注册表中。

知识库文章称其适用于Access 2002和2003,但我在更改Access 2013中的.mdb字段时也有效。

0

在那么大的数据库中,完全有可能存在无法转换为有效日期/时间的文本数据。

我建议(也许你会讨厌我这样做),从“Big”导出所有潜在的日期值,并通过Excel等工具检查它们的格式是否符合预期。


有趣的是,我实际上已经做到了!:(数据库中的数据是自动生成的,全部都是日期类型。至于Excel,起初我尝试使用Excel打开它,但Excel有最大单元格数限制,我认为大约是120万个,而这个数据超过了这个限制 :( - Khalid Fazeli
我可以建议将你的数据从Access迁移到SQL Express或者其他的数据库吗?那么庞大的数据量,使用Access来处理可是相当冒险的。 - Phil.Wheeler
这是一个好主意,但是除了Access之外的任何数据库我都是个完全的新手,但如果有一个简单的步骤将这个数据库转换成SQL,那就太好了。 - Khalid Fazeli
1
Access有2GB的限制,800MB并不是太多的数据。我认为如果你熟悉Access的话,最好还是继续使用它,除非你,khalidfazeli,预计数据量会增加一倍以上。 - Fionnuala
不会再有数据量的变化,现在只需要几个查询,不应该添加超过200MB的数据。 - Khalid Fazeli

0

假设错误信息是准确的,您可能遇到了磁盘或内存限制。假设您的磁盘驱动器上有超过几个千兆字节的可用空间,我最好的猜测是重建表会使包括工作空间在内的数据库超过Access每个文件2千兆字节的限制。

如果是这种情况,您需要:

  1. 将数据卸载到某个方便的格式中,并将其加载回已经存在表定义的空数据库中。

  2. 将数据子集移动到较小的表中,更改较小表中的数据类型,压缩和修复数据库,并重复此过程,直到所有数据都转换完毕。

如果错误消息不正确(这是可能的),最有可能的原因是文本日期列中的日期错误或超出范围。


0
  1. 复制表格(即“YourTable”),然后仅将其结构粘贴回数据库并使用不同的名称(即“YourTable_new”)。

  2. 更改新表中的字段为所需内容并保存。

  3. 创建追加查询并将所有数据从旧表复制到新表中。

希望Access会自动将旧文本字段直接转换为新日期/时间字段的正确值。如果没有,您可能需要清除旧表并重新追加所有数据,并在追加时使用字符串转日期函数来转换该字段。

此外,如果旧表中有自动编号字段,则可能无法正常工作,因为无法确保旧自动编号值与分配的新自动编号值相对应。


当然可以保留相同的自动编号值。只需将旧的自动编号字段附加到新的自动编号字段即可。Jet/ACE自动编号数据类型只是具有特殊默认值(以及一些其他限制,例如在创建记录后无法编辑)的长整型字段,因此只要不违反现有数据的索引,就可以将任何值附加到新记录的字段中。 - David-W-Fenton

0

你已经尝试了很多种方法来解决磁盘空间错误信息的问题。

你是否尝试过在现有表中添加一个使用日期数据类型的新字段,然后使用现有字符串日期字段的值更新该字段?如果可以成功,那么你可以删除旧字段并将新字段重命名为旧名称。这样做可能比直接将字符串转换为日期在单个字段上占用更少的临时空间。

如果仍然无法解决问题,你可以使用第二个具有两列的表来完成,第一列是长整型(将其设置为主键),第二列是日期。然后将PK和字符串日期字段附加到此空表中。然后在现有表中添加一个新的日期字段,并使用连接将新字段更新为来自两列表的值。

这可能会遇到相同的问题。这取决于Jet/ACE数据库引擎内部的许多因素,我们无法真正控制。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接