使用Oracle MERGE INTO将两个表中的数据合并为第三个表

时间:2018-06-11 12:55:56

标签: oracle merge duplicates

我是一名来自MySQL背景的PHP开发人员,第一次与Oracle合作。我正在尝试将两个表中的数据插入到第三个表中,其功能目标是跟踪用户权限以访问我平台上的某些产品,同时避免UNIQUE CONSTRAINT错误(即添加重复记录)。我有三张桌子:

position: relative

我想要做的是添加一行包含来自USERS的ID,来自PERMISSIONS的ID以及当前用户的ID(所以我们知道谁添加了记录)。这是我的尝试:

USERS
PERMISSIONS
USER_PERMISSIONS

但是我遇到了INVALID IDENTIFIER错误。我知道查询的USING(SELECT)部分告诉查询我将使用哪些表,但我不确定如何正确识别它们以便查询起作用。这是错误的方法吗?任何意见,将不胜感激。非常感谢!

编辑:我收到的确切错误消息是:

MERGE INTO USER_PERMISSIONS up 
    USING (
        SELECT 
            USERS.ID, 
            PERMISSIONS.ID 
        FROM 
            USERS, 
            PERMISSIONS 
        WHERE 
            PERMISSIONS.NAME = 'productalpha'
        AND 
            USERS.SHORTNAME = 'username'
    ) ON (
        USERS.ID = up.USER_ID 
        AND 
        PERMISSIONS.ID = up.PERMISSION_ID
    ) WHEN NOT MATCHED THEN 
    INSERT (
        USER_ID, 
        PERMISSION_ID, 
        LAST_UPDATED_BY_USER_ID
    ) VALUES (
        USERS.ID, 
        PERMISSIONS.ID, 
        '1'  
    );

2 个答案:

答案 0 :(得分:0)

USING子句中的查询是内嵌视图,因此别名USERSPERMISSIONS在其外部无效。试试这个:

MERGE INTO USER_PERMISSIONS up 
    USING (
        SELECT 
            USERS.ID, 
            PERMISSIONS.ID 
        FROM 
            USERS, 
            PERMISSIONS 
        WHERE 
            PERMISSIONS.NAME = 'productalpha'
        AND 
            USERS.SHORTNAME = 'username'
    ) source ON (
        source.ID = up.USER_ID 
        AND 
        source.ID = up.PERMISSION_ID
    ) WHEN NOT MATCHED THEN 
    INSERT (
        USER_ID, 
        PERMISSION_ID, 
        LAST_UPDATED_BY_USER_ID
    ) VALUES (
        source.ID, 
        source.ID, 
        '1'  
    );

答案 1 :(得分:0)

问题出在您的ON子句中。连接条件必须引用USING子句,但您引用的是基础表名。解决方案非常简单:别名USING子句并使用别名标记ON子句。像这样::

MERGE INTO USER_PERMISSIONS up 
    USING (
        SELECT 
            USERS.ID as user_id, 
            PERMISSIONS.ID as permission_id
        FROM 
            USERS, 
            PERMISSIONS 
        WHERE 
            PERMISSIONS.NAME = 'productalpha'
        AND 
            USERS.SHORTNAME = 'username'
    ) q ON (
        q.user_id = up.USER_ID 
        AND 
        q.permission_id = up.PERMISSION_ID
    ) WHEN NOT MATCHED THEN 
    INSERT (
        USER_ID, 
        PERMISSION_ID, 
        LAST_UPDATED_BY_USER_ID
    ) VALUES (
        q.user_id, 
        q.permission_id, 
        '1'  
    );

请注意,您还需要对USING子句中的两个ID列进行别名,以避免ORA-00918列模糊定义错误。