Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 更新联接的权限不足_Oracle_Join_Permissions_Sql Update - Fatal编程技术网

Oracle 更新联接的权限不足

Oracle 更新联接的权限不足,oracle,join,permissions,sql-update,Oracle,Join,Permissions,Sql Update,场景:我们为经理批准的请求生成记录。在挂起期间,经理会发生变化(通过人力资源提要在夜间更新)。我们需要更新请求以指明新经理 下面是查询的缩写版本,可以实现这一点: update (select grw.approver_user_id, gup.supervisor_id from gs3.user_role gur join gsu.user_profile gup on gur.user_id = gup.user_id

场景:我们为经理批准的请求生成记录。在挂起期间,经理会发生变化(通过人力资源提要在夜间更新)。我们需要更新请求以指明新经理

下面是查询的缩写版本,可以实现这一点:

update (select grw.approver_user_id, gup.supervisor_id
        from   gs3.user_role gur
          join gsu.user_profile gup
            on gur.user_id = gup.user_id
          join gs3.request_workflow grw
            on gur.user_role_id = grw.user_role_id
           and gup.supervisor_id != grw.approver_user_id  -- records with new mgr
        where  grw.auth_status_cd = 'SUBMITTED')  -- reapprovals currently open
set    grw.approver_id = gup.supervisor_id;

问题:执行此查询的帐户仅在
gsu.user\u profile
上具有读取权限

内部select工作正常,返回我需要更新的所有行。。。但是,尽管我没有更新
gup.supervisor\u id
,但似乎我需要对该表具有写访问权限。如果我以对
gsu.user\u profile
具有写入权限的用户身份执行此更新,则更新成功

这有逻辑上的原因吗?我宁愿不向不需要的帐户授予权限

谢谢


更新

接受托马斯的回答。。。虽然它并没有真正回答我的问题,为什么执行更新联接的帐户需要对未更新的表具有更新权限,但我可以看到这样的逻辑:“不要使用更新联接,它们不是ISO标准”

很遗憾,因为我的建议和托马斯的建议的不同之处在于,我的建议中没有任何嵌套选择。如果有人知道没有嵌套选择的ISO标准查询方法,我很想知道


谢谢你,托马斯

尝试使用ISO认可的更新声明格式,看看是否有效。ISO没有规定在Update语句中直接使用联接。相反,您只能通过子查询使用联接

此外,如果用于设置
approver\u id
的子查询返回多行,这可能会说明原始Update语句中的一些问题,这显然会导致异常,并且您需要确定如何找到应为每行设置的一个且仅一个主管id

Update gs3.request_workflow
Set approver_id =   (
                    Select gup.supervisor_id
                    From gs3.user_role As gur
                        Join gsu.user_profile As gup
                            On gur.user_id = gup.user_id
                    Where gup.user_role_id = gs3.request_workflow.user_role_id
                        And gup.supervisor_id != grw.approver_user_id
                    )
Where auth_status_cd = 'SUBMITTED'                          
    And Exists  (
                Select 1
                From gs3.user_role As gur
                    Join gsu.user_profile As gup
                        On gur.user_id = gup.user_id
                Where gup.user_role_id = gs3.request_workflow.user_role_id
                    And gup.supervisor_id != grw.approver_user_id
                )

因此,对select进行更新的能力是特定于Oracle的?@James B-将连接烘焙到update语句中的能力是特定于供应商的,尽管供应商之间存在一些相似之处。例如,Microsoft允许使用From子句来放置联接。MySQL将连接直接放在Update子句中,我认为Oracle也会这样做。它们都有各自的细微差别。但是,所有的供应商都支持ISO格式,这就是我建议使用ISO格式的原因,它可以更清楚地说明哪里可能存在问题。我还想问,为什么您说用于设置approver_id的子查询会返回多行并导致异常?如果我在另一个帐户下运行我编写的查询,并且正确地更新了290行,那么它将很好地执行。我遗漏了什么吗?@James B-在您最初的查询中,如果联接最终生成多个
gs3.request\u workflow
行,您可能会得到意外的结果,因为相同的行将被更新多次,这就是为什么ISO没有在Update语句中直接提供联接。在我的解决方案中,如果用于设置
approver\u id
的子查询为
gs3.request\u workflow
中的给定行返回了多行,它将抛出异常。我将返回多个
gs3.request\u workflow
记录,但我正在更新
gs3.request\u workflow
记录本身;据我所知,我只更新每个
请求\u工作流
记录一次。。。但也许我遗漏了什么。您是对的,查询不是设计用于处理多行的,因为我将与同一个主管一起更新所有
请求\u工作流
记录,但我不知道如何获得异常。。。只是需要清理一下:但是对于我正在处理的数据,只返回一行,所以我不担心:)