【问题标题】:Is there any way to create multiple insert statements in a ms-access query?有没有办法在 ms-access 查询中创建多个插入语句?
【发布时间】:2010-09-08 21:59:38
【问题描述】:

我正在使用 MS Access 2003。我想在 MS Access 中所谓的“查询”中运行大量插入 SQL 语句。有什么简单的(或确实有任何方法)可以做到吗?

【问题讨论】:

    标签: ms-access


    【解决方案1】:

    是和不是。

    你不能这样做:

    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”确保您不会重复超过一行的表格

    但话又说回来,只执行三个单独的插入语句可能会更容易, 特别是如果您已经在循环中构建内容(当然,除非进行插入的成本大于您编写代码的时间成本)。

    【讨论】:

    • 非常有趣和描述性的答案。它肯定会帮助我做我正在做的事情
    • 就是这样!只有一个提示:如果您有超过 50 个嵌套的 SELECT 语句,您必须以 50 个或更少的组执行它们。我有 1080 行要插入,我将它们分成 48 组。否则 Access(我使用 v. 2010)会警告您“查询过于复杂”错误。
    • 有没有人可以使用 oledb 插入 dbf 文件?
    【解决方案2】:

    就个人而言,我会创建一个 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
    

    【讨论】:

    • 很好的解决方案。我总是忘记 Access 中内置了一门完整的编程语言,您可以使用它来自动管理数据库
    【解决方案3】:

    我认为,如果您还没有明确代码将在其中运行的上下文,那么建议一个特定的数据接口是不可取的,就像 Jonathan 所做的那样。

    如果数据存储是 Jet 数据库,那么使用任何形式的 ADO 都毫无意义,除非您从首选的脚本平台运行代码。如果你在 Access 中,肯定不是这种情况,DAO 是首选接口。

    【讨论】:

      【解决方案4】:

      MS Access 不允许从同一个 sql 窗口进行多次插入。如果您想插入,请说表格中的 10 行,请说 movie (mid, mname, mdirector,....) ,你需要 打开sql窗口,

      1. 键入第一条语句,执行第一条语句,删除第一条语句
      2. 输入第二条语句,执行第二条语句,删除第二条语句
      3. 键入第三条语句,执行第三条语句,删除第三条语句......

      很无聊。 相反,您可以通过执行以下操作从 excel 导入行:

      1. 右键单击您已经创建的表名
      2. 从 Excel 导入(打开导入对话框)
      3. 浏览到包含要导入表中的记录的 excel 文件
      4. 点击“将记录的副本附加到表中:”
      5. 选择所需的表格(在本示例电影中)
      6. 点击“确定”
      7. 选择包含电子表格中数据的工作表
      8. 点击完成

      excel中的整个数据集已经加载到“MOVIE”表中

      【讨论】:

        【解决方案5】:

        否 - Access 中的查询是单个 SQL 语句。无法在一个查询对象中创建一批多条语句。 您可以创建多个查询对象并从宏/模块运行它们。

        【讨论】:

          【解决方案6】:

          @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 在 DAO 上推广 ADO 时,MS 故意将某些功能排除在 DAO 之外。我希望 Access 现在拥有自己的 Jet 私有版本,DAO 将得到更新以支持 Jet 本身支持的所有内容。
          • 我也希望你是正确的。但在他们这样做之前,仍然需要 ADO 来填补 DAO 中的漏洞:检查约束、WITH COMPRESSION、行级锁定等。如果发布者没有“澄清上下文”,那么答案肯定可以在 ADO 或 DAO 中,一个仅仅是生活方式的选择,不是吗? :)
          • 升级到 SQL Server 后 DAO 的功能如何?
          【解决方案7】:

          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
          

          【讨论】:

            【解决方案8】:

            基于@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
            

            【讨论】:

              猜你喜欢
              • 2020-07-05
              • 1970-01-01
              • 2019-02-11
              • 2017-01-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多