public virtual ISqlNode VisitMerge(SqlMergeNode n) { var target = Visit(n.Target); var source = Visit(n.Source); var cond = Visit(n.MergeCondition); var m = Visit(n.Matched); var nmt = Visit(n.NotMatchedByTarget); var nms = Visit(n.NotMatchedBySource); return(n.Update(target, source, cond, m, nmt, nms)); }
public ISqlNode VisitMerge(SqlMergeNode n) { Append("MERGE"); IncreaseIndent(); AppendLineAndIndent(); Visit(n.Target); AppendLineAndIndent(); Append("USING "); Visit(n.Source); AppendLineAndIndent(); Append("ON "); Visit(n.MergeCondition); if (n.Matched != null) { AppendLineAndIndent(); Append("WHEN MATCHED "); Append(" THEN"); IncreaseIndent(); AppendLineAndIndent(); Visit(n.Matched); DecreaseIndent(); } if (n.NotMatchedByTarget != null) { AppendLineAndIndent(); Append("WHEN NOT MATCHED BY TARGET"); Append(" THEN"); IncreaseIndent(); AppendLineAndIndent(); Visit(n.NotMatchedByTarget); DecreaseIndent(); } if (n.NotMatchedBySource != null) { AppendLineAndIndent(); Append("WHEN NOT MATCHED BY SOURCE"); Append(" THEN"); IncreaseIndent(); AppendLineAndIndent(); Visit(n.NotMatchedBySource); DecreaseIndent(); } DecreaseIndent(); return(n); }
public SqlMergeNode ParseMergeStatement(ITokenizer t) { var mergeToken = t.Expect(SqlTokenType.Keyword, "MERGE"); var mergeNode = new SqlMergeNode { Location = mergeToken.Location }; // TODO: "TOP" <maybeParenVariableOrNumericExpression> "PERCENT"? t.NextIs(SqlTokenType.Keyword, "INTO", true); mergeNode.Target = ParseMaybeAliasedTable(t, ParseObjectIdentifier); t.Expect(SqlTokenType.Keyword, "USING"); mergeNode.Source = ParseMaybeAliasedTable(t, ParseObjectIdentifier); t.Expect(SqlTokenType.Keyword, "ON"); mergeNode.MergeCondition = ParseBooleanExpression(t); while (true) { var whenClauseToken = t.MaybeGetKeywordSequence("WHEN", "NOT", "MATCHED", "BY", "SOURCE", "TARGET"); if (whenClauseToken == null) { break; } // TODO: "AND" <clauseSearchCondition> t.Expect(SqlTokenType.Keyword, "THEN"); if (whenClauseToken.Value == "WHEN MATCHED") { // TODO: Allow multiple mergeNode.Matched = ParseMergeMatched(t); } else if (whenClauseToken.Value == "WHEN NOT MATCHED" || whenClauseToken.Value == "WHEN NOT MATCHED BY TARGET") { mergeNode.NotMatchedByTarget = ParseMergeNotMatched(t); } else if (whenClauseToken.Value == "WHEN NOT MATCHED BY SOURCE") { // TODO: Allow multiple mergeNode.NotMatchedBySource = ParseMergeMatched(t); } } // TODO: Output clause // TODO: OPTION clause return(mergeNode); }
public override ISqlNode VisitMerge(SqlMergeNode n) { _result.AssertNotNull(n, nameof(n.Target), n.Target); _result.AssertNotNull(n, nameof(n.Source), n.Source); _result.AssertNotNull(n, nameof(n.MergeCondition), n.MergeCondition); if (n.Matched != null) { if (!(n.Matched is SqlUpdateNode || (n.Matched is SqlKeywordNode keyword && keyword.Keyword == "DELETE"))) { _result.AddError(n, nameof(n.Matched), "MATCHED clause must be valid UPDATE or DELETE"); } } if (n.NotMatchedBySource != null) { if (!(n.NotMatchedBySource is SqlUpdateNode || (n.NotMatchedBySource is SqlKeywordNode keyword && keyword.Keyword == "DELETE"))) { _result.AddError(n, nameof(n.NotMatchedBySource), "NOT MATCHED BY SOURCE clause must be valid UPDATE or DELETE"); } } return(base.VisitMerge(n)); }