【问题标题】:SQL "Insert" in VBA codeVBA 代码中的 SQL“插入”
【发布时间】:2017-01-29 21:11:47
【问题描述】:

以下代码行中存在问题(类型不匹配错误): 行动 = ....

我尝试使用 Sql INSERT INTO 从 Excel 复制数组并将其粘贴到 PostgreSQl 数据库中。

Sub UploadToDatamart2()

'Defining connection objects
Dim cnn As New ADODB.Connection
Dim rst As New ADODB.Recordset
Dim LastRow As Long

Sheets("AVON DICTIONARY").Activate

'Opening the ODBC connection
cnn.Open "Driver={PostgreSQL Unicode(x64)};DSN=postgres;Server=XXX;Port=5432;UID=YYY;PWD=ZZZ;Database=hurtownia;READONLY=0;PROTOCOL=6.4;FAKEOIDINDEX=0;SHOWOIDCOLUMN=0;ROWVERSIONING=0;SHOWSYSTEMTABLES=1"

'Find the last row
With ActiveSheet
    LRow = .Cells(.Rows.Count, "A").End(xlUp).Row
'Picking up cell values
    Category = .Range("A3:A" & LRow).Value
    segment = .Range("B3:B" & LRow).Value
    brand = .Range("C3:C" & LRow).Value
End With

'Defining and executing SQL insert
Action = "INSERT INTO temp.avon_dictionary_test" & " VALUES ('{" & Category & "}','{" & segment & "}','{" & brand & "}')"
Result = cnn.Execute(Action)

cnn.Close
End Sub

如果有人能帮忙,我会很高兴

【问题讨论】:

  • 在模块顶部添加Option Explicit。它将有助于调试此类问题。您需要添加Dim Action As String 并将您的执行行更改为cnn.Execute(Action)。这不会返回记录集。
  • 我添加了:Option Explicit - 在顶部,还有:Dim Category As Variant Dim Segment As Variant,Dim brand As Variant。修改此:Dim LRow As Long 并将 Result = cnn.Execute(Action) 替换为 cnn.Execute (Action)。还是一样的错误
  • Dim Action As String - 我也添加了这个,但仍然遇到问题
  • Action = 行之前添加这个 - Debug.Print TypeName(Category), TypeName(segment), TypeName(brand) 立即窗格中的输出是什么?
  • 这是即时窗口显示的内容:Variant() Variant() Variant()

标签: sql excel vba postgresql insert


【解决方案1】:

您将范围分配给Categorysegmentbrand 变量。将范围分配给变量后,它将变量从变量转换为数组(除非该变量特别声明)。现在变量是数组,您必须引用该项目(即Category(0))。尝试在您的 Action = 声明中引用该项目

【讨论】:

    【解决方案2】:

    Category、Segment 和 Brand 是二维数组,您不能将它们连接成这样的字符串。您首先需要将它们转置为 1D-Array,然后使用 Join 从它们构建一个字符串:

    先替换

    Category = .Range("A3:A" & LRow).Value
    segment = .Range("B3:B" & LRow).Value
    brand = .Range("C3:C" & LRow).Value
    

    Category = Application.Transpose(.Range("A3:A" & LRow).Value)
    segment = Application.Transpose(.Range("B3:B" & LRow).Value)
    brand = Application.Transpose(.Range("C3:C" & LRow).Value)
    

    然后替换

    Action = "INSERT INTO temp.avon_dictionary_test" & " VALUES ('{" & Category & "}','{" & segment & "}','{" & brand & "}')"
    

    Action = "INSERT INTO temp.avon_dictionary_test" & " VALUES ('{" & Join(Category, ",") & "}','{" & Join(segment, ",") & "}','{" & Join(brand, ",") & "}')"
    

    Transpose 会将 (1 to LRow, 1 to 1) 数组更改为普通 (1 to LRow) 数组。

    Join 会将数组中的值连接成一个由分隔符(此处为“,”)分隔的字符串。

    【讨论】:

    • 谢谢文森特。现在我在 Action =... 行中收到“无效的过程调用或参数”错误。在我的测试文件 LRow = 4000 中,这个过程是否太多?
    • 由于您的数据是在行中,我认为您需要在使用 Join 之前转置您的数组。
    • 嗯,所以我想知道使用 COPY 而不是 INSERT INTO [link] (postgresql.org/docs/9.2/static/sql-copy.html) 是个好主意吗?我觉得sql很弱所以我在问
    • 仍然无法像我编辑的答案那样使用 Transpose?
    • 如果我转置数据,我将得到 4000 列。如果我的数据达到 10 万怎么办?
    猜你喜欢
    • 2014-03-12
    • 2018-03-25
    • 1970-01-01
    • 2017-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-09
    • 1970-01-01
    相关资源
    最近更新 更多