当我在SQL INSERT INTO

时间:2017-03-28 05:31:47

标签: sql excel-vba data-formats vba excel

我在一个工作簿(工作簿A)中使用Excel(2013)表,我使用SQL INSERT INTO将工作簿A中的整行数据转移到工作簿B中的相同Excel表。工作簿B通常是在此操作期间关闭,因此使用数据库连接(读取和写入)和SQL是最佳途径。我在Excel中使用Native SQL引擎,而不是外部数据库引擎。

工作簿A中的Excel表有73个字段,这些字段包含文本,数字和日期(DMYHMS)的混合,尽管该表主要是针对常规格式设置的。工作簿B是连接到它的工作簿A集合的中央数据库。目前,我只测试从工作簿A到工作簿B的一个连接。

在工作簿A中,当我执行SQL INSERT INTO时出现错误:

  

“条件表达式中的数据类型不匹配。”(Err = -2147217913)

经过仔细的消除过程后,我现在可以得出结论,工作簿A中有一个字段(第71个字段)导致问题,这是“LASTMOD_BY”,这是一个用户ID,即'12345678',但是由于某些未知原因,工作簿B预计是一个约会。这特别奇怪,因为我有一个SUB_BY字段(Submitted By),它也是一个用户ID'12345678',这被接受为文本字符串。为什么Excel Table认为LASTMOD_BY的相同数据应该是日期?!

在这里阅读很多帖子,大多数用户似乎都希望字符串成为日期:我希望字符串保留为字符串!

对于我的生活,我已经研究并尝试了一切来解决这个问题,但我没有想法!

为了记录,我尝试了以下内容,但没有成功:

  1. 确保将工作簿A和工作簿B LASTMOD_BY字段设置为 一般
  2. 确保将工作簿A和工作簿B LASTMOD_BY字段设置为 文本
  3. 在工作簿中的LASTMOD_BY字段中生成数字和数字 然后,一个文本字段(作为一个数字,LASTMOD_BY抛出一个 “溢出”错误,因为用户标识太大而无法成为日期值)
  4. 将另一个表字段(可接受为文本字段)复制到 LASTMOD_BY列并将其重命名为LASTMOD_BY,并删除 旧的LASTMOD_BY专栏。
  5. 在工作簿A和工作簿B中插入另一个名为的字段 在LASTMOD_BY之前的列中提供LASTMODBY并提供LASTMODBY 用户标识并从SQL语句中省略LASTMOD_BY(Excel 仍然期望LASTMODBY成为约会!)
  6. 测试表格单元格中的所有值以确保正确的数据 检测到类型,然后确保它正确反映在 SQL语法(即如果日期然后格式化为'日期';如果是文本格式 作为'文本';如果数字格式为数字(没有单引号))
  7. 从INSERT INTO语句中丢失LASTMOD_BY(哪个DID work)然后添加一个单独的UPDATE语句来设置 LASTMOD_BY字段(不起作用)。
  8. 如何让工作簿B中的Excel表格接受用户ID('LASTMOD_BY')作为文本而不是日期?

    这让我感到疯狂,我开始得出结论,Excel Tables与嵌入式SQL引擎一起使用时会出现错误。

    对于那些需要查看SQL的人来说,这里是:

    INSERT INTO [CQDB$] (ProductQ, Version, QID_1, QID_2, QID_3, QID_4, QID_5, QID_6, QID_7, QID_8, QID_9, QID_10, QID_11, QID_12, QID_13, QID_14, QID_15, QID_16, QID_17, QID_18, QID_19, QID_20, QID_21, QID_22, QID_23, QID_24, QID_25, QID_26, QID_27, QID_28, QID_29, QID_30, QID_31, QID_32, QID_33, QID_34, QID_35, QID_36, QID_37, QID_38, QID_39, QID_40, QID_41, QID_42, QID_43, QID_44, QID_45, QID_46, QID_47, QID_48, QID_49, QID_50, QID_51, QID_52, QID_53, QID_54, QID_55, QID_56, QID_57, QID_58, QID_59, QID_60,  QID_61, QID_62, QID_63, QID_64, QID_65, SUB_DMYHM, SUB_BY, LASTMOD_DMYHM, LASTMOD_BY, RECSTATUS, SubMonth)
    VALUES('NonBank', 6, 98765432, ‘Mr Smith',12348765,’My Insurance plan','0',’My Local Branch','0','0','29-Sep-16','30-Dec-09’, '0', '0', 'No', '0', '0', '0', '0', '0', '0', '0', 'No', 'Yes', '0', '0', '0', '0', '0', '0', 'N/A', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 12345678, ‘28-Sep-16 11:09:00', '0', '0', ‘28-Sep-16 11:09:29', 12345678, ‘28-Sep-16 11:09:29', 12345678, 'FAIL: To Follow-up',’01-Sep-16')
    

    仅供参考,SQL是使用VBA构建的。您在上面看到的是我的手工编辑版本(删除任何真实数据)。如果你应该发现一个丢失/额外的逗号等,它可能来自我的手动编辑,而不是生成的SQL!

    如果有人能为我解决这个问题,我真的很感激!

    干杯

2 个答案:

答案 0 :(得分:1)

乍一看;您的数据中的分隔符在您的文本字段周围似乎不一致...我还没有进一步查看,但您可以在手动编辑之前确认它们在SQL中是否一致吗?感谢

答案 1 :(得分:0)

我没有找到一个令人满意的答案来解决这个问题,我的意思是没有检测到故障然后纠正。但是,我能够解决这个问题。

我的结论已经确定了一个Excel表格功能,其中Excel表格中的每个字段都可以确定"通过Excel成为基于该表中找到的大多数值的数据类型。

本文解释了这一点: ExcelTable determines data types based on first 8 values entered in field

我尝试删除表中的所有行并重新插入数据,但似乎theExcel Table有一个"内存"之前有什么,并将添加的新数据转换为日期格式。

但是,我不认为这篇文章充分解释了我遇到的问题。考虑到一个" bug"在Excel中,单元格按Excel格式化为日期。看到这篇文章: Excel formats cells as Date bug

我没有将整个工作簿格式化为日期,但是在我的一些SQL更新中发生了这种情况。基本上,我没有做任何事情可以让Excel忘记"忘记"它为Workbook B中的表自动选择的上一个日期格式。

解决方案

  1. 在工作簿B的表格中插入一个全新的列。将其命名为第1列和第39列。第1列格式为General。
  2. 我重新运行了我的SQL而不是将用户ID写入LASTMOD_BY我改变了SQL以将其放入'第1列'。有效!用户ID出现在第1列'作为用户ID而不是日期。
  3. 现在,将LASTMOD_BY重命名为'第2列'并重命名第1列'到LASTMOD_BY。更改SQL以便'第1列'现在称为LASTMOD_BY并重新运行。它工作正常,现在用户标识在LASTMOD_BY中显示为用户ID而不是日期。
  4. 最后,删除多余的第2列'
  5. 此外,我然后将表格式化为Text。我尝试了ADO IMEX = 1标志,但这不起作用所以我保持在IMEX = 0。

    我的所有SQL查询现在都有效。我已经在表格上应用条件格式来整理条目的显示(不确定它们是否在每种情况下都有所不同,但是带和括号!)。

    当我继续报告时,我可能需要使用高级过滤器并将文本转换为值/日期等,但这比SQL的黑盒子更容易处理。

    不是一个非常令人满意的答案,但我从我的工作簿中删除了这种腐败/异常。