简体   繁体   English

如何在SQLAlchemy中为Oracle更新查询移动CTE

[英]How to move CTE for oracle update query in sqlalchemy

I am facing the oracle error ORA-00928: missing SELECT keyword with a query, generated by sqlalchemy. 我面临着Oracle错误ORA-00928: missing SELECT keyword生成的查询ORA-00928: missing SELECT keyword The issue was already described and answered here . 该问题已在此处描述并得到解答。

My query looks like: 我的查询看起来像:

WITH table2 (id) AS (
    SELECT id
    FROM table3
)

UPDATE table SET id=1 
WHERE EXISTS (
    SELECT * 
    FROM table 
    WHERE id IN (SELECT id FROM table2)
)

and gets generated by this: 并由此生成:

table2 = session.query(table3.id).cte()
update(table).where(exists().where(table.id.in_(table2))).values(id=1)

Now I am wondering how to tell sqlachemy to put the CTEs inside the WHERE clause and not above the UPDATE . 现在,我想知道如何告诉sqlachemy将CTE放在WHERE子句中而不是UPDATE之上。

UPDATE table SET id=1 
WHERE EXISTS (
    WITH table2 (id) AS (
        SELECT id
        FROM table3
    )

    SELECT * 
    FROM table 
    WHERE id IN (SELECT id FROM table2)
)

CTE is a nice way to extract an inline view from the query and, by doing so, make your code easier to read and maintain. CTE是从查询中提取内联视图的一种好方法,这样做可以使您的代码更易于阅读和维护。

When the CTE wasn't invented yet, we used inline views. 尚未发明CTE时,我们使用了内联视图。 Here are a few examples (based on Scott's schema) to show what I mean. 这里有一些示例(基于Scott的模式)来说明我的意思。

First, a CTE: 首先,CTE:

SQL> with tab as
  2    (select deptno from dept
  3     where deptno > 10
  4    )
  5  select e.deptno, count(*)
  6  from emp e join tab t on t.deptno = e.deptno
  7  group by e.deptno;

    DEPTNO   COUNT(*)
---------- ----------
        30          6
        20          5

It can be moved into an inline view: 可以将其移入内联视图:

SQL> select e.deptno, count(*)
  2  from emp e join (select deptno from dept
  3                   where deptno > 10
  4                  ) t on t.deptno = e.deptno
  5  group by e.deptno;

    DEPTNO   COUNT(*)
---------- ----------
        30          6
        20          5

Or, using the old syntax, where tables (in the FROM clause) were separated by commas and joins were done within the WHERE clause (this might look familiar): 或者,使用语法,将表(在FROM子句中)用逗号分隔,并将联接在WHERE子句中完成(这看起来很熟悉):

SQL> select e.deptno, count(*)
  2  from emp e,
  3      (select deptno from dept
  4       where deptno > 10
  5      ) t
  6  where t.deptno = e.deptno
  7  group by e.deptno;

    DEPTNO   COUNT(*)
---------- ----------
        30          6
        20          5

It means that your query might look like this; 这意味着您的查询可能如下所示; note the comment which shows position of your CTE: 请注意显示您的CTE职位的评论:

update table set
  id = 1
  where exists (select *
                from table
                where id in (select id 
                             from 
                               (select id from table3)  --> this line is your CTE
                            )
               );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM