【问题标题】:Oracle to MS-Access SQL:Oracle 到 MS-Access SQL:
【发布时间】:2016-06-02 11:24:47
【问题描述】:

我正在尝试将 SQL 代码从 Oracle 复制到我的 Access 以自动创建一些报告。到目前为止,我已经成功了,但我遇到了麻烦:

这是 Oracle SQL:

SELECT DISTINCT o587265.PROJECT_NUMBER AS E587273,
    o587265.PROJECT_NAME AS E587274,
    o587265.PROJECT_STATUS_CODE AS E587275,
    o587265.PROJECT_MANAGER AS E587276
FROM (
    SELECT p.segment1 project_number,
        p.NAME project_name,
        p.project_status_code,
        (
            SELECT a.FULL_NAME
            FROM apps.per_all_people_f a,
                apps.pa_project_players_v pm
            WHERE a.person_id = pm.person_id
                AND pm.project_ID = p.project_ID
                AND pm.ROLE = 'Project Manager'
                AND a.current_employee_flag = 'Y'
                AND a.person_type_id = 1
                AND SYSDATE BETWEEN a.effective_start_date
                    AND a.effective_end_date
                AND SYSDATE BETWEEN pm.start_date_active(+)
                    AND NVL(pm.end_date_active, SYSDATE)
            ) project_manager
    FROM apps.pa_projects_all p
    WHERE p.project_status_code != 'CLOSED'
        AND p.template_flag = 'N'
        AND p.org_ID = 5003
    ) o587265
    ORDER BY o587265.PROJECT_NUMBER ASC,
    o587265.PROJECT_NAME ASC,
    o587265.PROJECT_MANAGER ASC;

这是我当前的 MS-Access 版本:

SELECT DISTINCT o587265.PROJECT_NUMBER AS E587273,
    o587265.PROJECT_NAME AS E587274,
    o587265.PROJECT_STATUS_CODE AS E587275,
    o587265.PROJECT_MANAGER AS E587276
FROM (
    SELECT p.segment1 AS project_number,
        p.NAME AS project_name,
        p.project_status_code,
        (
            SELECT a.FULL_NAME
            FROM ((apps_per_all_people_f AS a INNER JOIN apps_pa_project_players_v AS pm ON a.person_id = pm.person_id
                ) INNER JOIN apps_pa_projects_all AS p ON pm.project_ID = p.project_ID
            )
            WHERE pm.ROLE = 'Project Manager'
                AND a.current_employee_flag = 'Y'
                AND a.person_type_id = 1
                AND DATE () BETWEEN a.effective_start_date
                AND a.effective_end_date
                AND DATE () BETWEEN pm.start_date_active
                AND IIf(IsNull(pm.end_date_active), DATE (), pm.end_date_active)
            ) AS PROJECT_MANAGER
    FROM apps_pa_projects_all AS p
    WHERE p.project_status_code <> 'CLOSED'
        AND p.template_flag = 'N'
        AND p.org_ID = 5003
    ) AS o587265
ORDER BY o587265.PROJECT_NUMBER ASC,
    o587265.PROJECT_NAME ASC,
    o587265.PROJECT_MANAGER ASC;

第一个直接在 Oracle 11g (SQL Developer) 上运行并且可以工作。 MS-Access 似乎在子查询中返回不止一行。我用尽了我的知识,但我似乎无法复制它。

我做错了什么?

另外,Oracle SQL 代码中的这个 (+) 运算符是什么?

我知道这个运算符是 OUTER (LEFT/RIGHT) JOIN,但我从来没有见过它被这样使用,这绝对不是 JOIN。

有人可以帮我吗?

【问题讨论】:

  • 我很确定 (+) 确实是一个左外连接运算符,即使在这种情况下也是如此。但它看起来并不奏效,因为它没有得到一致的应用。我认为你可以从 Oracle 查询中删除它,它不会改变任何东西。
  • 您应该尝试重写 Oracle 查询以使用显式连接。至少,您将了解查询实际在做什么。
  • sstan: (+) 我也是这样,但在这种情况下不是。此查询是从 Oracle Discovery 界面中提取的,它按原样用于生成报告,因此它确实有效。我确实删除了它,它没有改变任何东西。
  • tim:已经在 Oracle 中工作过。我认为我在 MS-ACCESS 中使用了错误的东西。

标签: sql oracle ms-access


【解决方案1】:

可能在将 Oracle 的隐式连接转换为 MS Access 显式连接时,您在派生表的子查询中为 PROJECT_MANAGER 列添加了一个额外的 INNER JOIN 引用 apps_pa_projects_all 表,替换别名 p。但是,此子查询与外部 FROM 子句的派生表相关,apps_pa_projects_all 具有原始别名 p

考虑删除第二个INNER JOIN 并返回相关的WHERE 子句条件:

原创

...
    (
        SELECT a.FULL_NAME
        FROM ((apps_per_all_people_f AS a 
        INNER JOIN apps_pa_project_players_v AS pm 
                ON a.person_id = pm.person_id) 
        INNER JOIN apps_pa_projects_all AS p 
                ON pm.project_ID = p.project_ID)
        WHERE pm.ROLE = 'Project Manager'
         AND a.current_employee_flag = 'Y'
         ...

改变

...
    (
        SELECT a.FULL_NAME
        FROM apps_per_all_people_f AS a 
        INNER JOIN apps_pa_project_players_v AS pm 
                ON a.person_id = pm.person_id
        WHERE pm.project_ID = p.project_ID
         AND pm.ROLE = 'Project Manager'
         AND a.current_employee_flag = 'Y'
         ...

【讨论】:

  • 不幸的是,它仍然没有工作。 ODBC 返回“精确提取返回的行数超过了请求的行数”。但是,Oracle SQL(使用 SQL Developer)返回准确的 1648 条记录。我的理解是,由于某种原因,MS-ACCESS 正在返回更多具有相同查询的记录。也许 Access 不理解 where 子句中的某些内容?
  • 将子查询的SELECT 替换为SELECT TOP 1。另外,尝试根据特定的project_ID 单独运行子查询,看看是否有多个条目返回。
  • 是的,这行得通。非常感谢冻糕。使用该策略帮助我跟踪问题。似乎 Oracle 有一个被描述为十进制 (15) 的 Project_Number 字段,但其中包含字符串名称(它是一个视图,但即便如此,我还是无法理解 Oracle 如何无法强制执行此类约束)。在我消除它之后,你的建议奏效了。
  • 太棒了!乐意效劳。请接受答案以确认解决方案。顺便说一句,请注意 MS Access 具有传递查询,允许您从后端 RDMS 保留准确的 SQL 语法(并且不符合 Access 的方言)。但是,此类查询无法连接到本地 Access 表,除非您使用 make-table/append 操作查询对其进行转换。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多