【问题标题】:Update statement with CTE (Firebird 2.1)使用 CTE 更新语句 (Firebird 2.1)
【发布时间】:2022-02-05 09:11:24
【问题描述】:

我有以下语句,我想根据它的一些列条目来更新表。我使用 Firebird 2.1,文档显示更新可以与 CTE 一起使用,但我的 Flamerobin 顽固地坚持认为更新语句无法识别。你能对此有所了解吗?

with cte as (select gen_id(gen_new,1) as num , N.elm_prof, N.elm_mat From 
(select distinct elm_mat, elm_prof from elements ) N )
update elements E set E.PROP_TYPE = cte.num where cte.elm_prof = E.ELM_PROF and cte.elm_mat = E.ELM_MAT

Engine Message :
Dynamic SQL Error
SQL error code = -104
Token unknown - line 3, column 1
update


merge into elements E1
using (with CTE as (select distinct e2.ELM_MAT mat1, e2.ELM_PROF mat2 from elements e2)
select gen_id(gen_new,1) num, mat1, mat2 from cte)
on E1.elm_mat = mat1 and e1.elm_prof = mat2
when matched then update set e1.prop_type = num

【问题讨论】:

    标签: sql firebird flamerobin


    【解决方案1】:

    文档中的哪些地方显示更新可以与 CTE 一起使用?当我查看Common Table Expressions 时,它说

    <cte-construct>  ::=  <cte-defs>
                          <main-query>
    
    <main-query>     ::=  the main SELECT statement, which can refer to the
                          CTEs defined in the preamble
    

    即只允许selectmain-query。我认为您对声明感到困惑

    当用括号括起来时,CTE 构造可用作 SELECT 语句中的子查询,也可用于 UPDATE、MERGE 等。

    稍后在文档中。据我了解,这意味着您可以使用类似的语句

    UPDATE elements E
       SET E.PROP_TYPE = (CTE statement here) WHERE...
    

    请注意,在这种情况下,CTE 必须是单例选择。

    【讨论】:

    • 好吧,我对你所展示的那句话感到困惑。如果 CTE 的返回值是数据集(在我的情况下将是)而不是单例,则会出现问题,对此的任何解决方法,我不限于 CTE 表达式,任何其他满足更新任务的选项都是受欢迎的。
    • 我认为您可以使用 MERGE 语句,请参阅 firebirdsql.org/file/documentation/reference_manuals/… 或者只是将逻辑包装到存储过程中,您可以在其中使用各种结构,使逻辑更易于理解。
    • 我还尝试使用问题中显示的代码使用合并语句进行更新。但我认为它不接受 CTE 作为子查询语句。另请注意,我使用生成器,因此这可能是造成差异的原因。
    • 我不认为生成器是它失败的原因。我认为这是您尝试在子选择之外引用cte,AFAIK 这是无法完成的。错误消息应该说明它,不是吗?请始终包含错误消息!无论如何,我这里没有安装 Firebird,所以我无法自己测试,抱歉。
    • 我在 OP 的底部添加了错误消息,它指出了 CTE 表达式大括号末尾的语法错误。
    【解决方案2】:

    例如“CTE”,它并不完全是 CTE,但它会帮助任何需要它的人。

    merge into tribcfop t
    using(
        with prodncm as (
        select a.iditemproduto, a.idncm, b.codigoncm, a.idtribcfop, c.piscstsai, c.cofinscstsai
        from produtoestoque a
        join ncm b on b.idncm = a.idncm
        join tribcfop c on c.idtribcfop = a.idtribcfop
        where b.codigoncm like '0201%')
        select prodncm.idtribcfop, prodncm.piscstsai, prodncm.cofinscstsai from prodncm
        ) a
    on t.idtribcfop = a.idtribcfop
    when matched then update set piscstsai = '06', cofinscstsai = '06'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-01
      • 2016-06-20
      • 1970-01-01
      相关资源
      最近更新 更多