在 Access 2010 中使用一个插入语句插入多行

Posted

技术标签:

【中文标题】在 Access 2010 中使用一个插入语句插入多行【英文标题】:Insert multiple rows using one insert statement in Access 2010 【发布时间】:2011-05-28 16:44:33 【问题描述】:

我想在 Access 2010 表中插入多个值,但我似乎找不到方法。 mysql 有一个不错的方法:

INSERT INTO Production.UnitMeasure
VALUES 
    (N'FT2', N'Square Feet ', '20080923'),
    (N'Y', N'Yards', '20080923'),
    (N'Y3', N'Cubic Yards', '20080923');

这样的事情也可以在 SQL Server 中完成吗?

【问题讨论】:

它是什么? Access 2010 还是 SQL Server? Access 2010 语法有区别吗? 是的,语法和功能都不同。请参阅下面的答案。 回复:MS Access - 是和否 - ***.com/questions/62504/… 【参考方案1】:

正如 marc_s 所指出的,对于 SQL Server 2008 及更高版本,您可以只使用表值构造函数。对于以前的版本,您可以使用insertselect...union all,例如:

INSERT INTO Production.UnitMeasure
SELECT N'FT2',N'Square Feet ','20080923' union all
SELECT N'Y',  N'Yards',       '20080923' union all
SELECT N'Y3', N'Cubic Yards', '20080923'

(关于 SQL Server 中 Table Value Constructors 的特定文档。我找不到有关行值构造函数的特定单独文档,但它们就是这样)

【讨论】:

【参考方案2】:

使用此确认工作查询:

INSERT INTO Product (Code,Name,IsActive,CreatedById,CreatedDate )

SELECT * FROM 
(    
  SELECT '10001000' AS Code,
         'Blackburn sunglasses' AS Name,
         1 AS IsActive,
         1 AS CreatedById,
         '2/20/2015 12:23:00 AM' AS CreatedDate 
   FROM Product    
   UNION 
   SELECT '10005200' AS Code,
          '30 panel football' AS Name,
          1 AS IsActive,
          1 AS CreatedById,
          '2/20/2015 12:23:09 AM' AS CreatedDate 
    FROM Product

) ;

【讨论】:

如果插入的列已经与表的内部顺序匹配,则不需要列名和别名。这可以显着简化/缩短长语句。这可能违背 SQL 引擎可以以随机顺序返回列和行的原则,但它在 Access 中有效。但即使 INTO 子句保留列名,也只有 UNION 中的第一个 SELECT 语句需要列别名,因为所有后续联合都将采用相同的名称。这仍然有助于缩短包含许多行的非常长的插入。 结合@user3177671 和@C Perkins 的想法。我发现我必须在开头和第一个选择中有列名。为了帮助缩短语句,我创建了一个具有相同结构的新空表,并在我的别名中使用了它。这里 TT 是一个空表,其字段与 TABLE_T 相同。 INSERT INTO TABLE_T (FIELD1, FIELD2, FIELD3) SELECT * FROM ( SELECT "EE" AS FIELD1, 0 AS FIELD2, 100 AS FIELD3 from TT union SELECT "RR" , 0, 200 from TT union SELECT "FF" , 0, 200 from TT union SELECT "GG" , 0, 200 from TT)【参考方案3】:

对于 SQL-Server:是的,它完全可以像你写的那样。只需确保列值的顺序与它们在表中出现的顺序相同。另外:您必须为每个现有列提供一个值。

对于 Access 2010:不。至少不是通过 sql 中的硬编码值,而只能通过从表中选择多条记录(在同一个或另一个数据库中)。另请参阅 Khepri 答案中的链接。

【讨论】:

是 - 从 SQL Server 2008 开始 - 这在 2008 版本之前无效 这个答案并不完全正确。 我只需要知道,这可以在 Access 中完成吗?这个答案说不。对我来说已经足够了! 对于 MS-Access 更多的是肯定和否定,请参阅此答案:***.com/questions/62504/…【参考方案4】:

SQL Server 绝对允许这样做:编辑: [截至 SQL Server 2008,谢谢 Marc_s]

INSERT INTO [Table]
([COL1], [COL2])
VALUES
('1@1.com', 1),
('2@2.com', 2)

至于访问要求,我不是访问专家,但我发现 this MSDN documentation 显示了如何一次执行多个插入。

INSERT INTO target [(field1[, field2[, …]])] [IN externaldatabase]
     SELECT [source.]field1[, field2[, …] FROM tableexpression

除此之外进行一些粗略的阅读,如果您的所有值都像您的示例中那样提前知道,您可以使用表中的“虚拟”。

【讨论】:

自 SQL Server 2008 起 - 是;在此之前,这是不可能的 使用虚拟表(它仍然必须存在)允许您只插入一条记录,因为不允许使用 Damien 提到的 UNION ALL 技巧。在这种情况下,您还必须使用 TOP 1 来限制结果。如果我错了,请告诉我。 @ngln 使用只有一行的虚拟表,例如 OneRow。【参考方案5】:

创建一个名为 OneRow 的表,其中包含一个整数列。插入一行。

然后:

INSERT INTO Production.UnitMeasure
SELECT 'FT2', 'Square Feet ', '20080923' FROM OneRow
UNION ALL SELECT 'Y', 'Yards', '20080923' FROM OneRow
UNION ALL SELECT 'Y3', 'Cubic Yards', '20080923' FROM OneRow

您的确切语法适用于 SQL Server 2008。对于早期使用我上面的查询,没有 FROM 子句和辅助表。

【讨论】:

【参考方案6】:

我知道现在回答太晚了,但是有一些方法在今天仍然有用(这里没有提到)。 一般有两种方法。


    使用带有“Docmd.RunSQL”语句的 VBA 脚本循环。 - 这通常很慢,尤其是随着行数的增加但很容易理解。

    将您的“数据数组”复制到 excel 工作表中,然后使用指向 excel 文件的数据库查询链接(我的首选方法) - 这样做的好处是它几乎与表已经在数据库中而不是在数据库中一样快与以前的方法一样,必然会因记录数量而减慢 - 但是,当您的记录数量较少时,会比上述方法稍慢


Docmd 方法:

Option Compare Database
Option Base 1

'------- method created by Syed Noshahi --------
'https://www.linkedin.com/in/syed-n-928b2490/


Sub DoCmdRoutine()

Dim arr() As Variant    ' create an unsized array ready for data

'--------------For the purposes of the Example, put some data in the array----------

ReDim arr(5, 5)
For i = LBound(arr) To UBound(arr)
    For j = LBound(arr) To UBound(arr)
        arr(i, j) = i * j
        If i = LBound(arr) Then arr(i, j) = "col_" & arr(i, j) 'Append "col_" before the column names
    Next
Next
    

'-------------Importing the data to a table in MS ACCESS----------------------------

sSQL = "INSERT INTO [#TableTemp] "  ' change table to actual table name

DoCmd.SetWarnings False             'turn warnings off - no popups!

For i = 2 To UBound(arr)            'start at 2 assuming that the first columns are headers
    vals = ""                       'go through each column and copy the data to SQL string format
                                    'replace any single quote with double quotes so it does not error importing into SQL
    For j = 1 To UBound(arr, 2)
        If IsDate(arr(i, j)) Then           'if a date, convert to a number and let access re-covert to date (best chance at success)
            vals = vals & " cdate('" & CDbl(arr(i, j)) & "'),"
        ElseIf IsNumeric(arr(i, j)) Then    'if a number put through as a number
            vals = vals & arr(i, j) & ","
        Else                                'otherwise treat as a text value
            vals = vals & Replace(arr(i, j), "'", "''", , , 1) & "',"
        End If
    Next
    
    vals = " VALUES(" & Left(vals, Len(vals) - 1) & ")"     'put in correct sql format
    DoCmd.RunSQL sSQL & vals        'Run the SQL statement and import into the database
Next

DoCmd.SetWarnings True             'turn warnings on

End Sub

Excel链接方法:

Option Compare Database
Option Base 1

'------- method created by Syed Noshahi --------
'https://www.linkedin.com/in/syed-n-928b2490/

Sub ExcelLinkRoutine()

Dim arr() As Variant    ' create an unsized array ready for data
Dim oExcel As Object    ' Excel instance - late binding
                        ' works with access 2007+, access 2003 has a different SQL syntax

'--------------For the purposes of the Example, put some data in the array----------

ReDim arr(5, 5)
For i = LBound(arr) To UBound(arr)
    For j = LBound(arr) To UBound(arr)
        arr(i, j) = i * j
        If i = LBound(arr) Then arr(i, j) = "col_" & arr(i, j) 'Append "col_" before the column names
    Next
Next

    
'----------------------------output the array to an excel file ---------------------

Set oExcel = CreateObject("Excel.Application")
oExcel.Workbooks.Add 1
Set wb = oExcel.ActiveWorkbook

'network file path & normal path examples below
'fileNameWithExtention = "\\networkpath\location\example999.xlsb"           ' note that xlsb file format must be used
                                                                            ' other formats can be used by changing 'xlExcel12'
                                                                            ' ONLY change the path not the FILE NAME
fileNameWithExtention = "C:\Users\public\documents\example999.xlsb"         ' same as above

checkFileExists = Dir(fileNameWithExtention)
If Len(checkFileExists) > 0 Then
    'only delete the file if its called example999!
    If checkFileExists = "example999.xlsb" Then
        Kill fileNameWithExtention
    End If
End If

With wb
    .Sheets(1).Cells(1, 1).Resize(UBound(arr), UBound(arr, 2)).Value2 = arr()
    .SaveAs fileNameWithExtention, 50                                       ' 50 means xlExcel12
    .Close False
End With

Set wb = Nothing
Set oExcel = Nothing

'------------ Importing the data to a table in MS ACCESS-----------------------------

    'NOTE1: The saved down excelfile MUST be named Sheet1
    'NOTE2: if the file path contains special characters such as ,-'
    '       you may need find the correct way to input (or remove the special chars)

sSQL = "SELECT T1.* INTO [#TableTemp] "  ' change table to actual table name
sSQL = sSQL & " FROM [Excel 12.0;HDR=YES;IMEX=2;ACCDB=YES;DATABASE=" & fileNameWithExtention & "].[Sheet1$] as T1;" ' linked table format


DoCmd.SetWarnings False             'turn warnings off - no popups!
DoCmd.RunSQL sSQL                   'Run the SQL statement and import into the database
DoCmd.SetWarnings True              'turn warnings on


End Sub 

输出:

Col_1 Col_2 Col_3 Col_4 Col_5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
5 10 15 20 25

【讨论】:

【参考方案7】:

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

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

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

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

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

【讨论】:

【参考方案8】:

我知道我玩游戏有点晚了,但我想做你们在示例中提到的完全相同的事情。我试图使用 Access 将默认行的新列表插入到表/列表中,因为我有很多 SQL 经验,我试图以同样的方式做,但是正如你的海报所指出的那样,这是不可能的做工会之类的。

但是我只是想在此处发布回复,因为在您手动输入值(在这种情况下为字符串默认值)的情况下,您只需在数据表视图中打开 Access,从 Excel 复制数据,然后将其粘贴到您的 Access 表(或在我的情况下,SharePoint 列表)中。您需要确保列排列准确,但如果您要手动输入“插入”sql 语句,只需将该信息放入 Excel 电子表格中应该没什么大不了的。

在我的例子中,我的表/列表只有一个列作为查找,所以我只是从 notepad++ 复制列并将其粘贴到数据表视图中。

祝大家好运!

【讨论】:

【参考方案9】:

检查以下,

INSERT INTO [Customer] ([Id],[FirstName],[LastName],[City],[Country],[Phone])VALUES(1,'Maria','Anders','Berlin','Germany','030-0074321')
INSERT INTO [Customer] ([Id],[FirstName],[LastName],[City],[Country],[Phone])VALUES(2,'Ana','Trujillo','México D.F.','Mexico','(5) 555-4729')

【讨论】:

以上是关于在 Access 2010 中使用一个插入语句插入多行的主要内容,如果未能解决你的问题,请参考以下文章

从文本框表单中将多行插入到单个表中 - Access 2010

在 ms access 2010 中将查询结果插入表中

SQL 语句末尾的字符--Access 数据库

在 INSERT INTO 语句中插入值时出现语法错误。 -VB 和 ACCESS 2013

从 SQL Server 插入 Access

网页设计,Access入门 2010,数学