2016-01-13 59 views
0

我有以下声明,我想根据它的一些列条目来更新表。我使用Firebird 2.1,文档显示更新可以与CTE一起使用,但是我的flamerobin固执地坚持认为update语句不被识别。你能对此有所了解吗?更新声明与CTE(火鸟2.1)

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 

回答

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 

即只select是允许的main-query。我想你该语句

当用括号括起来困惑,CTE结构可作为在SELECT语句子查询,而且在更新,合并等

在doc以后。据我了解,这意味着你可以使用类似的语句

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

注意,CTE必须选择在这种情况下一个singelton。

+0

好的,我完全迷惑于你所表明的那种陈述。如果CTE的返回值是数据集(这是我的情况)而不是单例,那么问题就出现了,任何解决方法,我不限于CTE表达式,任何满足更新任务的其他选项都是很好的。 –

+0

我想你可以使用MERGE语句,参见http://www.firebirdsql.org/file/documentation/reference_manuals/reference_material/html/langrefupd21-merge.html或者也许只是将逻辑包装到一个存储过程中,您可以使用各种使逻辑更容易理解的构造。 – ain

+0

我也尝试用合并语句更新问题中显示的代码。我认为它不接受CTE作为子查询语句。请注意,我使用发生器,所以这可能是造成差异的原因。 –