【问题标题】:TeraData query in VBA with volatile table带有易失表的 VBA 中的 TeraData 查询
【发布时间】:2014-09-17 16:00:18
【问题描述】:

我正在尝试自动执行一系列查询。一个查询,比如 Q1,是有问题的,因为它在 select 语句之前创建了一个易失的表。在 TeraData 中,Q1 运行良好,但是通过 VBA 将 Q1 传递给 TeraData 时出现错误:

只有在 DDL 语句之后的 ET 或空语句是合法的。

Q1 的形式为:

    create multiset volatile table volatileTable,
    no fallback,
    no before journal,
    no after journal,
    (
        a1,
        a2,
        a3,
        a4,
        a5
    ) as 
    (sel
        b1,
        b2,
        b3,
        min(b4) as a1,
        min(b5) as a2
    from
        db.table
    where
        b6 = 'condition'
    group by
        b1,
        b2,
        b3
    )
    with data
    on commit preserve rows;

    sel
        c1,
        c2,
        c3
    from 
        db.table
    group by
        1,
        2

    union

    sel
        d1,
        d2,
        d3
    from 
        (sel
            e.f1,
            e.f2,
            e.f3,
            e.a1,
            s.a1,
            e.a2,
            s.a2,
            e.a3,
            s.a3,
            e.a4,
            s.a4,
            e.a5,
            s.a5
        from 
            db.table) as e
            left outer join volatileTable as s
            on
                e.a1 = s.a1
                e.a2 = s.a2
                e.a3 = s.a3
                e.a4 >= s.a4
                e.a5 <= s.a5    
    group by
        1,
        2

    union

    sel
        g1,
        g2,
        g3
    from 
        db.table
    group by
        1,
        2

    union

    ...

问题在于在 VBA ADODB.Command.Execute() 语句中创建易失性表。关于如何解决这个问题的任何想法?

【问题讨论】:

    标签: sql vba teradata volatile recordset


    【解决方案1】:

    您已在 BT/ET 模式下连接。执行完Q1查询后,执行“ET”命令结束交易。

    或者您可以在 Teradata 默认模式下连接以自动提交查询。

    【讨论】:

    • 我尝试将 Q1 包装在 BT 和 ET 中。我还尝试在 BT 和 ET 中仅包装 create volatile 语句。两者都给了我原始帖子中描述的相同错误。
    • 如何选择通过 VBA 连接到 Teradata 的模式?我当前的 VBA 连接显示为 connection.Open "Data Source = environment; Database = db; Persist Security Info = True; User ID= UID; Password= PW; Session Mode=ANSI;"
    • 对,我是这么认为的。但是问题仍然存在:为什么我会收到 no-DML-after-DDL 错误?
    【解决方案2】:

    您必须在两个单独的请求中发送 Create 和 Select。

    在 ANSI 会话中,您必须将 COMMIT; 添加到 Create after on commit 保留行;

    要从 ANSI 切换到 Teradata 会话,您需要更改为 Session Mode=Teradata;

    如果您处于 Teradata 模式会话中,则不需要 BT/ET,因为每个请求都是隐式事务。

    【讨论】:

    • 如何在一个 Teradata 会话中发送两个单独的请求?现在,我有一个执行行读取recordSet = cmdSQL.Execute()。原谅我,我只是在学习如何通过 VBA 进入 Teradata。
    • 在上面的评论中:cmdSQL.CommandText = queryFromFile queryFromFile 作为字符串和cmdSQL.commandType = adCmdText
    • 您必须有两个单独的执行请求,一个用于create as...,一个用于select
    【解决方案3】:
    1. 将连接参数设置为:

      connection.Open "数据源 = 环境;数据库 = db;持久安全信息 = True;用户 ID = UID;密码 = PW;会话模式 = Teradata;"

    2. 将创建易失性表和从易失性表中选择为两个单独的查询/命令文本。您还需要两个不同的记录集(在我的例子中是 adoDbRs1、adoDbRs2)。

    一个。创建查询(ON COMMIT PRESERVE ROWS; 之后不需要 COMMITT;):

    selectCmd.CommandText = SqlQuery1 'SqlQuery has the Create Volatile Table (A) Query'
    Set adoDbRs1 = selectCmd.Execute(, , adCmdText)
    

    b.选择查询:

    SqlQuery2 = "SELECT * FROM A"
    selectCmd.CommandText = SqlQuery2
    Set adoDbRs2 = selectCmd.Execute(, , adCmdText)
    

    c。粘贴记录集:

    Worksheets("Mysheet").Cells(1, 1).CopyFromRecordset adoDbRs2
    

    【讨论】:

      猜你喜欢
      • 2016-01-18
      • 1970-01-01
      • 2017-01-10
      • 2019-10-08
      • 2016-02-15
      • 1970-01-01
      • 1970-01-01
      • 2016-04-25
      • 1970-01-01
      相关资源
      最近更新 更多