【发布时间】:2010-09-08 21:59:38
【问题描述】:
我正在使用 MS Access 2003。我想在 MS Access 中所谓的“查询”中运行大量插入 SQL 语句。有什么简单的(或确实有任何方法)可以做到吗?
【问题讨论】:
标签: ms-access
我正在使用 MS Access 2003。我想在 MS Access 中所谓的“查询”中运行大量插入 SQL 语句。有什么简单的(或确实有任何方法)可以做到吗?
【问题讨论】:
标签: ms-access
是和不是。
你不能这样做:
insert into foo (c1, c2, c3)
values ("v1a", "v2a", "v3a"),
("v1b", "v2b", "v3b"),
("v1c", "v2c", "v3c")
但你可以做到
insert into foo (c1, c2, c3)
select (v1, v2, v3) from bar
如果您还没有表格中的数据,这会给您带来什么?好吧,您可以制作一个由许多带有硬编码结果的 Select 联合组成的 Select 语句。
INSERT INTO foo (f1, f2, f3)
SELECT *
FROM (select top 1 "b1a" AS f1, "b2a" AS f2, "b3a" AS f3 from onerow
union all
select top 1 "b1b" AS f1, "b2b" AS f2, "b3b" AS f3 from onerow
union all
select top 1 "b1c" AS f1, "b2c" AS f2, "b3c" AS f3 from onerow)
注意:我还必须包含某种形式的虚拟表(例如,onerow)以欺骗访问以允许联合(其中必须至少有一行),并且您需要“前 1”确保您不会重复超过一行的表格
但话又说回来,只执行三个单独的插入语句可能会更容易, 特别是如果您已经在循环中构建内容(当然,除非进行插入的成本大于您编写代码的时间成本)。
【讨论】:
SELECT 语句,您必须以 50 个或更少的组执行它们。我有 1080 行要插入,我将它们分成 48 组。否则 Access(我使用 v. 2010)会警告您“查询过于复杂”错误。
就个人而言,我会创建一个 VBA 子例程来执行此操作,并使用某种形式的 sql 连接来连接到数据库。
在我的脑海中,执行此操作的代码应该类似于:
Sub InsertLots ()
Dim SqlConn as Connection
SqlConn.Connect("your connection string")
SqlConn.Execute("INSERT <tablename> (column1, column2) VALUES (1, 2)")
SqlConn.Execute("INSERT <tablename> (column1, column2) VALUES (2, 3)")
SqlConn.Close()
End Sub
【讨论】:
我认为,如果您还没有明确代码将在其中运行的上下文,那么建议一个特定的数据接口是不可取的,就像 Jonathan 所做的那样。
如果数据存储是 Jet 数据库,那么使用任何形式的 ADO 都毫无意义,除非您从首选的脚本平台运行代码。如果你在 Access 中,肯定不是这种情况,DAO 是首选接口。
【讨论】:
MS Access 不允许从同一个 sql 窗口进行多次插入。如果您想插入,请说表格中的 10 行,请说 movie (mid, mname, mdirector,....) ,你需要 打开sql窗口,
很无聊。 相反,您可以通过执行以下操作从 excel 导入行:
excel中的整个数据集已经加载到“MOVIE”表中
【讨论】:
否 - Access 中的查询是单个 SQL 语句。无法在一个查询对象中创建一批多条语句。 您可以创建多个查询对象并从宏/模块运行它们。
【讨论】:
@Rik Garner:不知道你所说的“批处理”是什么意思,但
INSERT INTO foo (f1, f2, f3)
SELECT *
FROM (select top 1 "b1a" AS f1, "b2a" AS f2, "b3a" AS f3 from onerow
union all
select top 1 "b1b" AS f1, "b2b" AS f2, "b3b" AS f3 from onerow
union all
select top 1 "b1c" AS f1, "b2c" AS f2, "b3c" AS f3 from onerow)
construct,虽然是单个 SQL 语句,但实际上会一次插入每一行(而不是一次插入),但在同一个事务中:您可以通过添加相关约束来测试这一点例如
ALTER TABLE foo ADD
CONSTRAINT max_two_foo_rows
CHECK (2 >= (SELECT COUNT(*) FROM foo AS T2));
假设表是空的,上面的INSERT INTO..SELECT.. 应该可以工作:事实上它不是因为在插入第一行之后检查约束而不是在插入所有三个之后(违反 ANSI SQL- 92 但那是你的 MS Access );表仍然为空的事实表明内部事务已回滚。
@David W. Fenton:您可能对 DAO 有强烈的个人偏好,但请不要对某人选择替代数据访问技术(在本例中为 ADO)太苛刻,尤其是对于普通的 INSERT 和何时他们将他们的 cmets 限定为“在我的脑海中,执行此操作的代码应该看起来像……”毕竟,您不能使用 DAO 来创建 CHECK 约束:)
【讨论】:
MS Access 还可以将数据从简单的文本文件附加到表中。 CSV 值(我只是使用全部替换框删除除逗号之外的所有内容)并在外部数据下选择文本文件。
From this:
INSERT INTO CLASS VALUES('10012','ACCT-211','1','MWF 8:00-8:50 a.m.','BUS311','105');
INSERT INTO CLASS VALUES('10013','ACCT-211','2','MWF 9:00-9:50 a.m.','BUS200','105');
INSERT INTO CLASS VALUES('10014','ACCT-211','3','TTh 2:30-3:45 p.m.','BUS252','342');
To this:
10012,ACCT-211,1,MWF 8:00-8:50 a.m.,BUS311,105
10013,ACCT-211,2,MWF 9:00-9:50 a.m.,BUS200,105
10014,ACCT-211,3,TTh 2:30-3:45 p.m.,BUS252,342
【讨论】:
基于@Jonathan 的 VBA 解决方法,并在当前 Access 数据库中执行:
Public Sub InsertMinimalData()
CurrentDb.Execute "INSERT INTO FinancialYear (FinancialYearID) VALUES ('FY2019/2020');"
CurrentDb.Execute "INSERT INTO FinancialYear (FinancialYearID) VALUES ('FY2020/2021');"
End Sub
【讨论】: