35
35
*/
36
36
public class OracleDialect implements JDBCDialect {
37
37
38
+ private final String SQL_DEFAULT_PLACEHOLDER = " ? " ;
39
+ private final String DEAL_CHAR_KEY = "char" ;
40
+ private String RPAD_FORMAT = " rpad(?, %d, ' ') " ;
41
+
42
+ private List <String > fieldList ;
43
+ private List <String > fieldTypeList ;
44
+ private List <TableInfo .FieldExtraInfo > fieldExtraInfoList ;
45
+
38
46
@ Override
39
47
public boolean canHandle (String url ) {
40
48
return url .startsWith ("jdbc:oracle:" );
@@ -48,39 +56,50 @@ public Optional<String> defaultDriverName() {
48
56
@ Override
49
57
public Optional <String > getUpsertStatement (String schema , String tableName , String [] fieldNames , String [] uniqueKeyFields , boolean allReplace ) {
50
58
tableName = DtStringUtil .getTableFullPath (schema , tableName );
51
- StringBuilder sb = new StringBuilder ();
52
- sb .append ("MERGE INTO " + tableName + " T1 USING "
53
- + "(" + buildDualQueryStatement (fieldNames ) + ") T2 ON ("
54
- + buildConnectionConditions (uniqueKeyFields ) + ") " );
59
+ StringBuilder mergeIntoSql = new StringBuilder ();
60
+ mergeIntoSql .append ("MERGE INTO " + tableName + " T1 USING (" )
61
+ .append (buildDualQueryStatement (fieldNames ))
62
+ .append (") T2 ON (" )
63
+ .append (buildConnectionConditions (uniqueKeyFields ) + ") " );
55
64
56
65
String updateSql = buildUpdateConnection (fieldNames , uniqueKeyFields , allReplace );
57
66
58
67
if (StringUtils .isNotEmpty (updateSql )) {
59
- sb .append (" WHEN MATCHED THEN UPDATE SET " );
60
- sb .append (updateSql );
68
+ mergeIntoSql .append (" WHEN MATCHED THEN UPDATE SET " );
69
+ mergeIntoSql .append (updateSql );
61
70
}
62
71
63
- sb .append (" WHEN NOT MATCHED THEN "
64
- + "INSERT (" + Arrays .stream (fieldNames ).map (this ::quoteIdentifier ).collect (Collectors .joining ("," )) + ") VALUES ("
65
- + Arrays .stream (fieldNames ).map (col -> "T2." + quoteIdentifier (col )).collect (Collectors .joining ("," )) + ")" );
72
+ mergeIntoSql .append (" WHEN NOT MATCHED THEN " )
73
+ .append ("INSERT (" )
74
+ .append (Arrays .stream (fieldNames ).map (this ::quoteIdentifier ).collect (Collectors .joining ("," )))
75
+ .append (") VALUES (" )
76
+ .append (Arrays .stream (fieldNames ).map (col -> "T2." + quoteIdentifier (col )).collect (Collectors .joining ("," )))
77
+ .append (")" );
66
78
67
- return Optional .of (sb .toString ());
79
+ return Optional .of (mergeIntoSql .toString ());
68
80
}
69
81
70
82
/**
71
- * build T1."A"=T2."A" or T1."A"=nvl(T2."A",T1."A")
83
+ * build T1."A"=T2."A" or T1."A"=nvl(T2."A",T1."A")
72
84
* @param fieldNames
73
85
* @param uniqueKeyFields
74
86
* @param allReplace
75
87
* @return
76
88
*/
77
89
private String buildUpdateConnection (String [] fieldNames , String [] uniqueKeyFields , boolean allReplace ) {
78
90
List <String > uniqueKeyList = Arrays .asList (uniqueKeyFields );
79
- return Arrays .stream (fieldNames ).filter (col -> !uniqueKeyList .contains (col )).map (col -> {
80
- return allReplace ? quoteIdentifier ("T1" ) + "." + quoteIdentifier (col ) + " = " + quoteIdentifier ("T2" ) + "." + quoteIdentifier (col ) :
81
- quoteIdentifier ("T1" ) + "." + quoteIdentifier (col ) + " =nvl(" + quoteIdentifier ("T2" ) + "." + quoteIdentifier (col ) + ","
82
- + quoteIdentifier ("T1" ) + "." + quoteIdentifier (col ) + ")" ;
83
- }).collect (Collectors .joining ("," ));
91
+ String updateConnectionSql = Arrays .stream (fieldNames ).
92
+ filter (col -> !uniqueKeyList .contains (col ))
93
+ .map (col -> buildConnectionByAllReplace (allReplace , col ))
94
+ .collect (Collectors .joining ("," ));
95
+ return updateConnectionSql ;
96
+ }
97
+
98
+ private String buildConnectionByAllReplace (boolean allReplace , String col ) {
99
+ String conncetionSql = allReplace ? quoteIdentifier ("T1" ) + "." + quoteIdentifier (col ) + " = " + quoteIdentifier ("T2" ) + "." + quoteIdentifier (col ) :
100
+ quoteIdentifier ("T1" ) + "." + quoteIdentifier (col ) + " =nvl(" + quoteIdentifier ("T2" ) + "." + quoteIdentifier (col ) + ","
101
+ + quoteIdentifier ("T1" ) + "." + quoteIdentifier (col ) + ")" ;
102
+ return conncetionSql ;
84
103
}
85
104
86
105
@@ -96,8 +115,43 @@ private String buildConnectionConditions(String[] uniqueKeyFields) {
96
115
*/
97
116
public String buildDualQueryStatement (String [] column ) {
98
117
StringBuilder sb = new StringBuilder ("SELECT " );
99
- String collect = Arrays .stream (column ).map (col -> " ? " + quoteIdentifier (col )).collect (Collectors .joining (", " ));
118
+ String collect = Arrays .stream (column )
119
+ .map (col -> wrapperPlaceholder (col ) + quoteIdentifier (col ))
120
+ .collect (Collectors .joining (", " ));
100
121
sb .append (collect ).append (" FROM DUAL" );
101
122
return sb .toString ();
102
123
}
124
+
125
+
126
+ /**
127
+ * char type is wrapped with rpad
128
+ * @param fieldName
129
+ * @return
130
+ */
131
+ public String wrapperPlaceholder (String fieldName ) {
132
+ int pos = fieldList .indexOf (fieldName );
133
+ String type = fieldTypeList .get (pos );
134
+
135
+ if (StringUtils .contains (type .toLowerCase (), DEAL_CHAR_KEY )) {
136
+ TableInfo .FieldExtraInfo fieldExtraInfo = fieldExtraInfoList .get (pos );
137
+ int charLength = fieldExtraInfo == null ? 0 : fieldExtraInfo .getLength ();
138
+ if (charLength > 0 ) {
139
+ return String .format (RPAD_FORMAT , charLength );
140
+ }
141
+ }
142
+ return SQL_DEFAULT_PLACEHOLDER ;
143
+ }
144
+
145
+
146
+ public void setFieldList (List <String > fieldList ) {
147
+ this .fieldList = fieldList ;
148
+ }
149
+
150
+ public void setFieldTypeList (List <String > fieldTypeList ) {
151
+ this .fieldTypeList = fieldTypeList ;
152
+ }
153
+
154
+ public void setFieldExtraInfoList (List <TableInfo .FieldExtraInfo > fieldExtraInfoList ) {
155
+ this .fieldExtraInfoList = fieldExtraInfoList ;
156
+ }
103
157
}
0 commit comments