19
19
package com .dtstack .flink .sql .sink .oracle ;
20
20
21
21
import com .dtstack .flink .sql .sink .rdb .dialect .JDBCDialect ;
22
+ import com .dtstack .flink .sql .table .TableInfo ;
22
23
import com .dtstack .flink .sql .util .DtStringUtil ;
23
24
import org .apache .commons .lang3 .StringUtils ;
24
25
34
35
*/
35
36
public class OracleDialect implements JDBCDialect {
36
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
+
37
46
@ Override
38
47
public boolean canHandle (String url ) {
39
48
return url .startsWith ("jdbc:oracle:" );
@@ -47,39 +56,50 @@ public Optional<String> defaultDriverName() {
47
56
@ Override
48
57
public Optional <String > getUpsertStatement (String schema , String tableName , String [] fieldNames , String [] uniqueKeyFields , boolean allReplace ) {
49
58
tableName = DtStringUtil .getTableFullPath (schema , tableName );
50
- StringBuilder sb = new StringBuilder ();
51
- sb .append ("MERGE INTO " + tableName + " T1 USING "
52
- + "(" + buildDualQueryStatement (fieldNames ) + ") T2 ON ("
53
- + 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 ) + ") " );
54
64
55
65
String updateSql = buildUpdateConnection (fieldNames , uniqueKeyFields , allReplace );
56
66
57
67
if (StringUtils .isNotEmpty (updateSql )) {
58
- sb .append (" WHEN MATCHED THEN UPDATE SET " );
59
- sb .append (updateSql );
68
+ mergeIntoSql .append (" WHEN MATCHED THEN UPDATE SET " );
69
+ mergeIntoSql .append (updateSql );
60
70
}
61
71
62
- sb .append (" WHEN NOT MATCHED THEN "
63
- + "INSERT (" + Arrays .stream (fieldNames ).map (this ::quoteIdentifier ).collect (Collectors .joining ("," )) + ") VALUES ("
64
- + 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 (")" );
65
78
66
- return Optional .of (sb .toString ());
79
+ return Optional .of (mergeIntoSql .toString ());
67
80
}
68
81
69
82
/**
70
- * 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")
71
84
* @param fieldNames
72
85
* @param uniqueKeyFields
73
86
* @param allReplace
74
87
* @return
75
88
*/
76
89
private String buildUpdateConnection (String [] fieldNames , String [] uniqueKeyFields , boolean allReplace ) {
77
90
List <String > uniqueKeyList = Arrays .asList (uniqueKeyFields );
78
- return Arrays .stream (fieldNames ).filter (col -> !uniqueKeyList .contains (col )).map (col -> {
79
- return allReplace ? quoteIdentifier ("T1" ) + "." + quoteIdentifier (col ) + " = " + quoteIdentifier ("T2" ) + "." + quoteIdentifier (col ) :
80
- quoteIdentifier ("T1" ) + "." + quoteIdentifier (col ) + " =nvl(" + quoteIdentifier ("T2" ) + "." + quoteIdentifier (col ) + ","
81
- + quoteIdentifier ("T1" ) + "." + quoteIdentifier (col ) + ")" ;
82
- }).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 ;
83
103
}
84
104
85
105
@@ -95,8 +115,43 @@ private String buildConnectionConditions(String[] uniqueKeyFields) {
95
115
*/
96
116
public String buildDualQueryStatement (String [] column ) {
97
117
StringBuilder sb = new StringBuilder ("SELECT " );
98
- 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 (", " ));
99
121
sb .append (collect ).append (" FROM DUAL" );
100
122
return sb .toString ();
101
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
+ }
102
157
}
0 commit comments