FormatSqlOracle.java 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package jnpf.database.sql.param;
  2. import cn.hutool.core.util.HexUtil;
  3. import jnpf.constant.TableFieldsNameConst;
  4. import jnpf.database.constant.DbFieldConst;
  5. import jnpf.database.model.dbfield.DbFieldModel;
  6. import jnpf.database.model.dbfield.JdbcColumnModel;
  7. import jnpf.database.model.dbtable.DbTableFieldModel;
  8. import jnpf.database.model.dto.PrepSqlDTO;
  9. import jnpf.database.model.entity.DbLinkEntity;
  10. import jnpf.database.source.DbBase;
  11. import jnpf.database.sql.enums.SqlOracleEnum;
  12. import jnpf.database.sql.model.SqlPrintHandler;
  13. import jnpf.database.sql.util.SqlFrameUtil;
  14. import jnpf.database.util.DbTypeUtil;
  15. import jnpf.database.util.JdbcUtil;
  16. import jnpf.database.util.NotTenantPluginHolder;
  17. import jnpf.util.context.SpringContext;
  18. import io.swagger.v3.oas.annotations.media.Schema;
  19. import lombok.Data;
  20. import oracle.sql.TIMESTAMP;
  21. import java.sql.SQLException;
  22. import java.util.Arrays;
  23. import java.util.List;
  24. import java.util.Map;
  25. import java.util.function.Function;
  26. /**
  27. * Oracle一些语句的特殊处理
  28. *
  29. * @author JNPF开发平台组 YanYu
  30. * @version v3.4.5
  31. * @copyrignt 引迈信息技术有限公司
  32. * @date 2022-12-06
  33. */
  34. @Data
  35. public class FormatSqlOracle {
  36. private static SqlPrintHandler sqlPrintHandler = SpringContext.getBean(SqlPrintHandler.class);
  37. /**
  38. * 时间格式化
  39. * "TO_DATE('2022-12-12 00:00:00','YYYY-MM-DD HH24:MI:SS')"
  40. * to_date('2022-12-12 00:00:00', 'yyyy-mm-dd hh24:mi:ss')
  41. */
  42. public static String dateTime(String dbEncode, String dateTime){
  43. if(DbBase.ORACLE.equals(dbEncode)){
  44. return "to_date(" + dateTime + ", 'yyyy-mm-dd hh24:mi:ss')";
  45. }else {
  46. return dateTime;
  47. }
  48. }
  49. /**
  50. * 格式Oracle时间戳类型
  51. */
  52. public static Object timestamp(Object value){
  53. if(value instanceof TIMESTAMP){
  54. try {
  55. return ((TIMESTAMP)value).dateValue();
  56. } catch (SQLException e) {
  57. e.printStackTrace();
  58. }
  59. }
  60. return value;
  61. }
  62. /**
  63. * 非空时空串报错,因Oracle空串存储为NULL,用一个空格代替空串
  64. */
  65. public static void nullValue(String dbEncode, JdbcColumnModel model, Map<String, Object> map){
  66. if(DbBase.ORACLE.equals(dbEncode) || DbBase.DM.equals(dbEncode)){
  67. // 字符串类型 && 字符串不为空 && 空串
  68. if(model.getValue() instanceof String && model.getNullSign().equals(DbFieldConst.NOT_NULL)
  69. && model.getValue().toString().equals("")){
  70. map.put(model.getField(), " ");
  71. }
  72. }
  73. }
  74. /**
  75. * 获取主键值
  76. */
  77. public static Function<Map<String, Object>,Map.Entry<String, Object>> getPrimaryVal = (fieldMap)->{
  78. for (Map.Entry<String, Object> field : fieldMap.entrySet()) {
  79. String primaryKey = field.getKey();
  80. if (primaryKey.equalsIgnoreCase(TableFieldsNameConst.F_ID) || primaryKey.equalsIgnoreCase(TableFieldsNameConst.ID) || primaryKey.equalsIgnoreCase("ID_")) {
  81. return field;
  82. }
  83. }
  84. return null;
  85. };
  86. public static Object clobExecute(String dbEncode, Object context, String table, String column, Map<String, Object> dataMap, StringBuilder sqlBuilder){
  87. if(DbBase.ORACLE.equals(dbEncode) && context instanceof String){
  88. Map.Entry<String, Object> field = FormatSqlOracle.getPrimaryVal.apply(dataMap);
  89. if(field != null){
  90. String clobUpdateSql = FormatSqlOracle.clobUpdate(context.toString(), table, column, field.getKey(), field.getValue().toString());
  91. if(clobUpdateSql != null){
  92. sqlPrintHandler.updateClob(clobUpdateSql);
  93. // 连续的匿名存储过程块,结尾都必须跟上 ; / 隔离
  94. sqlBuilder.append(clobUpdateSql).append(";\n/\n");
  95. return "context";
  96. }
  97. }
  98. }
  99. return context;
  100. }
  101. public static Object blobExecute(String dbEncode, Object context, String table, String column, Map<String, Object> dataMap, StringBuilder sqlBuilder){
  102. if(DbBase.ORACLE.equals(dbEncode) && (context instanceof byte[])){
  103. Map.Entry<String, Object> field = FormatSqlOracle.getPrimaryVal.apply(dataMap);
  104. if(field != null){
  105. String clobUpdateSql = FormatSqlOracle.blobUpdate(HexUtil.encodeHexStr((byte[]) context), table, column, field.getKey(), field.getValue().toString());
  106. if(clobUpdateSql != null){
  107. sqlPrintHandler.updateClob(clobUpdateSql);
  108. // 连续的匿名存储过程块,结尾都必须跟上 ; / 隔离
  109. sqlBuilder.append(clobUpdateSql).append(";\n/\n");
  110. // 字符串0 HEX 30
  111. return "30";
  112. }
  113. }
  114. }
  115. return context;
  116. }
  117. /**
  118. * Oracle处理超2000字符
  119. */
  120. public static String clobUpdate(String context, String table, String column, String primaryColumn, String primaryValue){
  121. if(context.length() > 1500){
  122. context = context.replace("'", "''");
  123. List<String> splitStrList = SqlFrameUtil.splitStrRepeat(context, 1500);
  124. StringBuilder contextInfo = new StringBuilder();
  125. for (String contextFragment : splitStrList) {
  126. contextInfo.append("\t").append(SqlOracleEnum.CLOB_APPEND.getSqlFrame().replace("{context}", contextFragment)).append(";\n");
  127. }
  128. return SqlOracleEnum.CLOB_UPDATE.getFastSql(Arrays.asList(table, column, contextInfo.toString(), primaryColumn, primaryValue));
  129. } else {
  130. return null;
  131. }
  132. }
  133. /**
  134. * Oracle处理Blob
  135. */
  136. public static String blobUpdate(String context, String table, String column, String primaryColumn, String primaryValue){
  137. context = context.replace("'", "''");
  138. List<String> splitStrList = SqlFrameUtil.splitStrRepeat(context, 1500);
  139. StringBuilder contextInfo = new StringBuilder();
  140. for (String contextFragment : splitStrList) {
  141. contextInfo.append("\t").append(SqlOracleEnum.BLOB_APPEND.getSqlFrame().replace("{context}", contextFragment)).append(";\n");
  142. }
  143. return SqlOracleEnum.BLOB_UPDATE.getFastSql(Arrays.asList(table, column, contextInfo.toString(), primaryColumn, primaryValue));
  144. }
  145. public static void autoIncrement(DbLinkEntity dbLinkEntity, DbTableFieldModel dbTableFieldModel) throws Exception {
  146. if (DbTypeUtil.checkOracle(dbLinkEntity)) {
  147. String table = dbTableFieldModel.getTable();
  148. boolean autoInc = false;
  149. String autoIncField = "";
  150. for (DbFieldModel dbFieldModel : dbTableFieldModel.getDbFieldModelList()) {
  151. if(dbFieldModel.getIsAutoIncrement() != null && dbFieldModel.getIsAutoIncrement()){
  152. autoInc = true;
  153. autoIncField = dbFieldModel.getField();
  154. }
  155. }
  156. if (autoInc) {
  157. NotTenantPluginHolder.setNotSwitchFlag();
  158. String autoIncrement = SqlOracleEnum.CREATE_AUTO_INCREMENT.getSqlFrame().replace("{table}", table);
  159. String autoIncrementTrigger = SqlOracleEnum.CREATE_AUTO_INCREMENT_TRIGGER.getSqlFrame().replace("{table}", table).replace("{autoInc_field}", autoIncField);
  160. if(!sqlPrintHandler.oracleAutoIncrement(autoIncrement)){
  161. JdbcUtil.creUpDe(new PrepSqlDTO(autoIncrement).withConn(dbLinkEntity));
  162. NotTenantPluginHolder.setNotSwitchFlag();
  163. JdbcUtil.update(new PrepSqlDTO(autoIncrementTrigger).withConn(dbLinkEntity));
  164. }
  165. }
  166. }
  167. }
  168. }