[#7491] Emulate ON CONFLICT .. DO UPDATE .. WHERE <p> on SQL Server using WHEN MATCHED AND <p>
This commit is contained in:
parent
c16aafcac5
commit
701ab65dfc
@ -40,6 +40,7 @@ package org.jooq;
|
||||
import static org.jooq.SQLDialect.CUBRID;
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.POSTGRES_9_5;
|
||||
// ...
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
|
||||
@ -39,6 +39,7 @@ package org.jooq;
|
||||
|
||||
import static org.jooq.SQLDialect.CUBRID;
|
||||
// ...
|
||||
// ...
|
||||
|
||||
/**
|
||||
* This type is used for the {@link Merge}'s DSL API.
|
||||
@ -83,13 +84,17 @@ public interface MergeMatchedWhereStep<R extends Record> extends MergeNotMatched
|
||||
* Add an additional <code>WHERE</code> clause to the preceding
|
||||
* <code>WHEN MATCHED THEN UPDATE</code> clause.
|
||||
* <p>
|
||||
* <b>Note:</b> This syntax is only available for the
|
||||
* {@link SQLDialect#CUBRID} and {@link SQLDialect#ORACLE} databases!
|
||||
* <h3>In Oracle, this will produce:</h3>
|
||||
* <p>
|
||||
* See <a href=
|
||||
* "http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_9016.htm"
|
||||
* >http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_9016.
|
||||
* htm</a> for a full definition of the Oracle <code>MERGE</code> statement
|
||||
* <code><pre>
|
||||
* WHEN MATCHED THEN UPDATE SET .. WHERE [ condition ]
|
||||
* </pre></code>
|
||||
* <p>
|
||||
* <h3>In SQL Server, this will produce:</h3>
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* WHEN MATCHED AND [ condition ] THEN UPDATE SET ..
|
||||
* </pre><code>
|
||||
*/
|
||||
@Support({ CUBRID })
|
||||
MergeMatchedDeleteStep<R> where(Condition condition);
|
||||
@ -98,13 +103,17 @@ public interface MergeMatchedWhereStep<R extends Record> extends MergeNotMatched
|
||||
* Add an additional <code>WHERE</code> clause to the preceding
|
||||
* <code>WHEN MATCHED THEN UPDATE</code> clause.
|
||||
* <p>
|
||||
* <b>Note:</b> This syntax is only available for the
|
||||
* {@link SQLDialect#CUBRID} and {@link SQLDialect#ORACLE} databases!
|
||||
* <h3>In Oracle, this will produce:</h3>
|
||||
* <p>
|
||||
* See <a href=
|
||||
* "http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_9016.htm"
|
||||
* >http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_9016.
|
||||
* htm</a> for a full definition of the Oracle <code>MERGE</code> statement
|
||||
* <code><pre>
|
||||
* WHEN MATCHED THEN UPDATE SET .. WHERE [ condition ]
|
||||
* </pre></code>
|
||||
* <p>
|
||||
* <h3>In SQL Server, this will produce:</h3>
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* WHEN MATCHED AND [ condition ] THEN UPDATE SET ..
|
||||
* </pre><code>
|
||||
*/
|
||||
@Support({ CUBRID })
|
||||
MergeMatchedDeleteStep<R> where(Field<Boolean> condition);
|
||||
@ -113,13 +122,17 @@ public interface MergeMatchedWhereStep<R extends Record> extends MergeNotMatched
|
||||
* Add an additional <code>WHERE</code> clause to the preceding
|
||||
* <code>WHEN MATCHED THEN UPDATE</code> clause.
|
||||
* <p>
|
||||
* <b>Note:</b> This syntax is only available for the
|
||||
* {@link SQLDialect#CUBRID} and {@link SQLDialect#ORACLE} databases!
|
||||
* <h3>In Oracle, this will produce:</h3>
|
||||
* <p>
|
||||
* See <a href=
|
||||
* "http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_9016.htm"
|
||||
* >http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_9016.
|
||||
* htm</a> for a full definition of the Oracle <code>MERGE</code> statement
|
||||
* <code><pre>
|
||||
* WHEN MATCHED THEN UPDATE SET .. WHERE [ condition ]
|
||||
* </pre></code>
|
||||
* <p>
|
||||
* <h3>In SQL Server, this will produce:</h3>
|
||||
* <p>
|
||||
* <code><pre>
|
||||
* WHEN MATCHED AND [ condition ] THEN UPDATE SET ..
|
||||
* </pre><code>
|
||||
*
|
||||
* @deprecated - 3.8.0 - [#4763] - Use {@link #where(Condition)} or
|
||||
* {@link #where(Field)} instead. Due to ambiguity between
|
||||
|
||||
@ -175,6 +175,7 @@ final class Keywords {
|
||||
static final Keyword K_LIMIT = keyword("limit");
|
||||
static final Keyword K_LOCK_IN_SHARE_MODE = keyword("lock in share mode");
|
||||
static final Keyword K_LOOP = keyword("loop");
|
||||
static final Keyword K_MATCHED = keyword("matched");
|
||||
static final Keyword K_MERGE_INTO = keyword("merge into");
|
||||
static final Keyword K_MINUS = keyword("minus");
|
||||
static final Keyword K_MODIFY = keyword("modify");
|
||||
@ -289,8 +290,6 @@ final class Keywords {
|
||||
static final Keyword K_VERSIONS_BETWEEN = keyword("versions between");
|
||||
static final Keyword K_VIEW = keyword("view");
|
||||
static final Keyword K_WHEN = keyword("when");
|
||||
static final Keyword K_WHEN_MATCHED_THEN_UPDATE_SET = keyword("when matched then update set");
|
||||
static final Keyword K_WHEN_NOT_MATCHED_THEN_INSERT = keyword("when not matched then insert");
|
||||
static final Keyword K_WHERE = keyword("where");
|
||||
static final Keyword K_WINDOW = keyword("window");
|
||||
static final Keyword K_WITH = keyword("with");
|
||||
|
||||
@ -49,21 +49,28 @@ import static org.jooq.Clause.MERGE_WHEN_MATCHED_THEN_UPDATE;
|
||||
import static org.jooq.Clause.MERGE_WHEN_NOT_MATCHED_THEN_INSERT;
|
||||
import static org.jooq.Clause.MERGE_WHERE;
|
||||
// ...
|
||||
// ...
|
||||
import static org.jooq.impl.DSL.condition;
|
||||
import static org.jooq.impl.DSL.exists;
|
||||
import static org.jooq.impl.DSL.insertInto;
|
||||
import static org.jooq.impl.DSL.notExists;
|
||||
import static org.jooq.impl.DSL.nullSafe;
|
||||
import static org.jooq.impl.Keywords.K_AND;
|
||||
import static org.jooq.impl.Keywords.K_AS;
|
||||
import static org.jooq.impl.Keywords.K_DELETE_WHERE;
|
||||
import static org.jooq.impl.Keywords.K_INSERT;
|
||||
import static org.jooq.impl.Keywords.K_KEY;
|
||||
import static org.jooq.impl.Keywords.K_MATCHED;
|
||||
import static org.jooq.impl.Keywords.K_MERGE_INTO;
|
||||
import static org.jooq.impl.Keywords.K_NOT;
|
||||
import static org.jooq.impl.Keywords.K_ON;
|
||||
import static org.jooq.impl.Keywords.K_SET;
|
||||
import static org.jooq.impl.Keywords.K_THEN;
|
||||
import static org.jooq.impl.Keywords.K_UPDATE;
|
||||
import static org.jooq.impl.Keywords.K_UPSERT;
|
||||
import static org.jooq.impl.Keywords.K_USING;
|
||||
import static org.jooq.impl.Keywords.K_VALUES;
|
||||
import static org.jooq.impl.Keywords.K_WHEN_MATCHED_THEN_UPDATE_SET;
|
||||
import static org.jooq.impl.Keywords.K_WHEN_NOT_MATCHED_THEN_INSERT;
|
||||
import static org.jooq.impl.Keywords.K_WHEN;
|
||||
import static org.jooq.impl.Keywords.K_WHERE;
|
||||
import static org.jooq.impl.Keywords.K_WITH_PRIMARY_KEY;
|
||||
import static org.jooq.impl.Tools.EMPTY_FIELD;
|
||||
@ -73,6 +80,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@ -143,6 +151,7 @@ import org.jooq.Record;
|
||||
import org.jooq.Record1;
|
||||
import org.jooq.Row;
|
||||
import org.jooq.SQL;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.Select;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.TableLike;
|
||||
@ -226,31 +235,35 @@ implements
|
||||
/**
|
||||
* Generated UID
|
||||
*/
|
||||
private static final long serialVersionUID = -8835479296876774391L;
|
||||
private static final Clause[] CLAUSES = { MERGE };
|
||||
private static final long serialVersionUID = -8835479296876774391L;
|
||||
private static final Clause[] CLAUSES = { MERGE };
|
||||
|
||||
private final WithImpl with;
|
||||
private final Table<R> table;
|
||||
private final ConditionProviderImpl on;
|
||||
private TableLike<?> using;
|
||||
|
||||
|
||||
|
||||
|
||||
private final WithImpl with;
|
||||
private final Table<R> table;
|
||||
private final ConditionProviderImpl on;
|
||||
private TableLike<?> using;
|
||||
|
||||
// [#998] Oracle extensions to the MERGE statement
|
||||
private Condition matchedWhere;
|
||||
private Condition matchedDeleteWhere;
|
||||
private Condition notMatchedWhere;
|
||||
private Condition matchedWhere;
|
||||
private Condition matchedDeleteWhere;
|
||||
private Condition notMatchedWhere;
|
||||
|
||||
// Flags to keep track of DSL object creation state
|
||||
private boolean matchedClause;
|
||||
private FieldMapForUpdate matchedUpdate;
|
||||
private boolean notMatchedClause;
|
||||
private FieldMapsForInsert notMatchedInsert;
|
||||
private boolean matchedClause;
|
||||
private FieldMapForUpdate matchedUpdate;
|
||||
private boolean notMatchedClause;
|
||||
private FieldMapsForInsert notMatchedInsert;
|
||||
|
||||
// Objects for the UPSERT syntax (including H2 MERGE, HANA UPSERT, etc.)
|
||||
private boolean upsertStyle;
|
||||
private QueryPartList<Field<?>> upsertFields;
|
||||
private QueryPartList<Field<?>> upsertKeys;
|
||||
private QueryPartList<Field<?>> upsertValues;
|
||||
private Select<?> upsertSelect;
|
||||
private boolean upsertStyle;
|
||||
private QueryPartList<Field<?>> upsertFields;
|
||||
private QueryPartList<Field<?>> upsertKeys;
|
||||
private QueryPartList<Field<?>> upsertValues;
|
||||
private Select<?> upsertSelect;
|
||||
|
||||
MergeImpl(Configuration configuration, WithImpl with, Table<R> table) {
|
||||
this(configuration, with, table, null);
|
||||
@ -1503,7 +1516,14 @@ implements
|
||||
// [#999] WHEN MATCHED clause is optional
|
||||
if (matchedUpdate != null) {
|
||||
ctx.formatSeparator()
|
||||
.visit(K_WHEN_MATCHED_THEN_UPDATE_SET)
|
||||
.visit(K_WHEN).sql(' ').visit(K_MATCHED);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ctx.sql(' ').visit(K_THEN).sql(' ').visit(K_UPDATE).sql(' ').visit(K_SET)
|
||||
.formatIndentStart()
|
||||
.formatSeparator()
|
||||
.visit(matchedUpdate)
|
||||
@ -1514,21 +1534,22 @@ implements
|
||||
.start(MERGE_WHERE);
|
||||
|
||||
// [#998] Oracle MERGE extension: WHEN MATCHED THEN UPDATE .. WHERE
|
||||
if (matchedWhere != null) {
|
||||
if (matchedWhere != null)
|
||||
|
||||
|
||||
|
||||
ctx.formatSeparator()
|
||||
.visit(K_WHERE).sql(' ')
|
||||
.visit(matchedWhere);
|
||||
}
|
||||
|
||||
ctx.end(MERGE_WHERE)
|
||||
.start(MERGE_DELETE_WHERE);
|
||||
|
||||
// [#998] Oracle MERGE extension: WHEN MATCHED THEN UPDATE .. DELETE WHERE
|
||||
if (matchedDeleteWhere != null) {
|
||||
if (matchedDeleteWhere != null)
|
||||
ctx.formatSeparator()
|
||||
.visit(K_DELETE_WHERE).sql(' ')
|
||||
.visit(matchedDeleteWhere);
|
||||
}
|
||||
|
||||
ctx.end(MERGE_DELETE_WHERE)
|
||||
.end(MERGE_WHEN_MATCHED_THEN_UPDATE)
|
||||
@ -1537,7 +1558,11 @@ implements
|
||||
// [#999] WHEN NOT MATCHED clause is optional
|
||||
if (notMatchedInsert != null) {
|
||||
ctx.formatSeparator()
|
||||
.visit(K_WHEN_NOT_MATCHED_THEN_INSERT);
|
||||
.visit(K_WHEN).sql(' ')
|
||||
.visit(K_NOT).sql(' ')
|
||||
.visit(K_MATCHED).sql(' ')
|
||||
.visit(K_THEN).sql(' ')
|
||||
.visit(K_INSERT);
|
||||
notMatchedInsert.toSQLReferenceKeys(ctx);
|
||||
ctx.formatSeparator()
|
||||
.start(MERGE_VALUES)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user