Skip to content

Commit 7bd42ed

Browse files
feat: MS SQL Server Merge Output clause
1 parent f919e00 commit 7bd42ed

File tree

4 files changed

+87
-6
lines changed

4 files changed

+87
-6
lines changed

src/main/java/net/sf/jsqlparser/statement/merge/Merge.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import net.sf.jsqlparser.expression.Expression;
1414
import net.sf.jsqlparser.expression.OracleHint;
1515
import net.sf.jsqlparser.schema.Table;
16+
import net.sf.jsqlparser.statement.OutputClause;
1617
import net.sf.jsqlparser.statement.Statement;
1718
import net.sf.jsqlparser.statement.StatementVisitor;
1819
import net.sf.jsqlparser.statement.select.FromItem;
@@ -37,6 +38,8 @@ public class Merge implements Statement {
3738
private MergeUpdate mergeUpdate;
3839
private boolean insertFirst = false;
3940

41+
private OutputClause outputClause;
42+
4043
public List<WithItem> getWithItemsList() {
4144
return withItemsList;
4245
}
@@ -155,6 +158,15 @@ public void setInsertFirst(boolean insertFirst) {
155158
this.insertFirst = insertFirst;
156159
}
157160

161+
public OutputClause getOutputClause() {
162+
return outputClause;
163+
}
164+
165+
public Merge setOutputClause(OutputClause outputClause) {
166+
this.outputClause = outputClause;
167+
return this;
168+
}
169+
158170
@Override
159171
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
160172
public String toString() {
@@ -190,6 +202,10 @@ public String toString() {
190202
b.append(mergeInsert);
191203
}
192204

205+
if (outputClause != null) {
206+
b.append(outputClause);
207+
}
208+
193209
return b.toString();
194210
}
195211

src/main/java/net/sf/jsqlparser/util/deparser/StatementDeParser.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,10 @@ public void visit(Merge merge) {
244244
if (!merge.isInsertFirst() && mergeInsert != null) {
245245
deparseMergeInsert(mergeInsert);
246246
}
247+
248+
if (merge.getOutputClause() != null) {
249+
merge.getOutputClause().appendTo(buffer);
250+
}
247251
}
248252

249253
private void deparseMergeInsert(MergeInsert mergeInsert) {

src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1647,6 +1647,7 @@ Statement Merge( List<WithItem> with ) : {
16471647
Expression condition;
16481648
MergeUpdate update;
16491649
MergeInsert insert;
1650+
OutputClause outputClause;
16501651
}
16511652
{
16521653
<K_MERGE> { merge.setOracleHint(getOracleHint()); } <K_INTO> table=TableWithAlias() { merge.setTable(table); }
@@ -1661,6 +1662,8 @@ Statement Merge( List<WithItem> with ) : {
16611662
)
16621663
]
16631664

1665+
[ outputClause = OutputClause() { merge.setOutputClause(outputClause); } ]
1666+
16641667
{ return merge.withWithItemsList(with); }
16651668
}
16661669

@@ -1847,7 +1850,9 @@ Table TableWithAliasAndMysqlIndexHint():
18471850
MySQLIndexHint indexHint = null;
18481851
}
18491852
{
1850-
table=Table() [alias=Alias() { table.setAlias(alias); }] [indexHint=MySQLIndexHint() {table.setHint(indexHint);}]
1853+
table=Table()
1854+
[ LOOKAHEAD(2) alias=Alias() { table.setAlias(alias); } ]
1855+
[ LOOKAHEAD(2) indexHint=MySQLIndexHint() { table.setHint(indexHint); } ]
18511856
{ return table; }
18521857
}
18531858

src/test/java/net/sf/jsqlparser/statement/merge/MergeTest.java

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -173,11 +173,67 @@ public void testInsertMergeWhere() throws JSQLParserException {
173173

174174
@Test
175175
public void testWith() throws JSQLParserException {
176-
String statement = "" + "WITH a\n" + " AS (SELECT 1 id_instrument_ref)\n" + " , b\n"
177-
+ " AS (SELECT 1 id_instrument_ref)\n" + "MERGE INTO cfe.instrument_ref b\n"
178-
+ "using a\n" + "ON ( b.id_instrument_ref = a.id_instrument_ref )\n"
179-
+ "WHEN matched THEN\n" + " UPDATE SET b.id_instrument = 'a' ";
180-
statement = "" + "WITH a\n" + " AS (SELECT 1 id_instrument_ref)\n" + "select * from a ";
176+
String statement = ""
177+
+ "WITH a\n"
178+
+ " AS (SELECT 1 id_instrument_ref)\n"
179+
+ "select * from a ";
181180
assertSqlCanBeParsedAndDeparsed(statement, true);
182181
}
182+
183+
@Test
184+
public void testOutputClause() throws JSQLParserException {
185+
String sqlStr = ""
186+
+ "WITH\n"
187+
+ " WMachine AS\n"
188+
+ " ( SELECT\n"
189+
+ " DISTINCT \n"
190+
+ " ProjCode,\n"
191+
+ " PlantCode,\n"
192+
+ " BuildingCode,\n"
193+
+ " FloorCode,\n"
194+
+ " Room\n"
195+
+ " FROM\n"
196+
+ " TAB_MachineLocation\n"
197+
+ " WHERE\n"
198+
+ " TRIM(Room) <> '' AND TRIM(Room) <> '-'\n"
199+
+ " ) \n"
200+
+ " MERGE INTO\n"
201+
+ " TAB_RoomLocation AS TRoom\n"
202+
+ " USING\n"
203+
+ " WMachine\n"
204+
+ " ON\n"
205+
+ " (\n"
206+
+ " TRoom.ProjCode = WMachine.ProjCode\n"
207+
+ " AND TRoom.PlantCode = WMachine.PlantCode\n"
208+
+ " AND TRoom.BuildingCode = WMachine.BuildingCode\n"
209+
+ " AND TRoom.FloorCode = WMachine.FloorCode\n"
210+
+ " AND TRoom.Room = WMachine.Room)\n"
211+
+ " WHEN NOT MATCHED /* BY TARGET */ THEN\n"
212+
+ " INSERT\n"
213+
+ " (\n"
214+
+ " ProjCode,\n"
215+
+ " PlantCode,\n"
216+
+ " BuildingCode,\n"
217+
+ " FloorCode,\n"
218+
+ " Room\n"
219+
+ " )\n"
220+
+ " VALUES\n"
221+
+ " (\n"
222+
+ " WMachine.ProjCode,\n"
223+
+ " WMachine.PlantCode,\n"
224+
+ " WMachine.BuildingCode,\n"
225+
+ " WMachine.FloorCode,\n"
226+
+ " WMachine.Room\n"
227+
+ " )\n"
228+
+ " OUTPUT GETDATE() AS TimeAction,\n"
229+
+ " $action as Action,\n"
230+
+ " INSERTED.ProjCode,\n"
231+
+ " INSERTED.PlantCode,\n"
232+
+ " INSERTED.BuildingCode,\n"
233+
+ " INSERTED.FloorCode,\n"
234+
+ " INSERTED.Room\n"
235+
+ " INTO\n"
236+
+ " TAB_MergeActions_RoomLocation";
237+
assertSqlCanBeParsedAndDeparsed(sqlStr, true);
238+
}
183239
}

0 commit comments

Comments
 (0)