zoukankan      html  css  js  c++  java
  • Java实现 Oracle decode函数 转换为 MySQL 可用的 case when

    • 具体实现思路

    首先要确认sql中没有包含decode的字符串或者字段 有的话可以自行替代后再做操作
    先获取 decode的位置 然后截取出 decode括号内的部分 通过计算左右括号的数量即可截取出来
    然后再将 decode括号内的部分分为4段 然后拼接回原来的SQL 重复循环执行即可

        private static String decodeTransformToCaseWhen(String sql) {
            /**
             * 将decode的各部分分分别存储  最后拼接
             */
            List<String> strings = new ArrayList<>();
            StringBuilder result = new StringBuilder(" ( case " + strings.get(0) + " when ");
            int start = sql.indexOf("decode") + 6;
            int left = 0, right = 0, end = 0;
            /**
             * 获取当前第一个decode 出现的位置和结束的位置  start是decode之后左括号 ( 起始的位置  ende是 最右边括号 ) 的位置
             */
            for (int i = sql.indexOf("decode") + 6; i < sql.length(); i++) {
                if (sql.charAt(i) == '(') left++;
                if (sql.charAt(i) == ')') right++;
                if (right != 0 && left == right) {
                    end = i;
                    break;
                }
            }
            /**
             *  截取出decode括号内的部分
             */
            String subStr = sql.substring(sql.indexOf("decode") + 7, end);
            left = 0;
            right = 0;
            int end2 = 0;//每一个,切割位置记录   为下一次切割的起始位置
            for (int i = 0; i < subStr.length(); i++) {
                if (subStr.charAt(i) == '(') left++;
                if (subStr.charAt(i) == ')') right++;
                /**
                 * i == subStr.length() - 1时 直接截取到最后即可
                 */
                if ((subStr.charAt(i) == ',' && left == right) || i == subStr.length() - 1) {
                    left = 0;
                    right = 0;
                    if (i == subStr.length() - 1)
                        strings.add(subStr.substring(end2));
                    else
                        strings.add(subStr.substring(end2, i));
                    end2 = i + 1;
                }
            }
            result.append(" ( case ").append(strings.get(0)).append(" when ");
            for (int i = 1; i < strings.size() - 1; i++) {
                if (i % 2 == 1)
                    result.append(strings.get(i)).append(" ");
                else if (i == strings.size() - 2) {
                    result.append(" then ").append(strings.get(i)).append(" else ");
                } else {
                    result.append(" then ").append(strings.get(i)).append(" when ");
                }
            }
            result.append(strings.get(strings.size() - 1)).append(" end ) ");
            return sql.substring(0, start - 6) + result + sql.substring(end + 1);
        }
    
    • 调用函数及测试用例
        //测试用例
        public static void main(String[] args) {
            String sql = "select decode(substr(TIME_, 5, 6), 2, 777,\n" +
                    "              decode(substr(nvl(B103B,0), 1, 3), 14, 23, (nvl(B103B, 0) - substr(TIME_, 0, 3)) / substr(TIME_, 4, 6))) k,\n" +
                    "       B103B\n" +
                    "from user_info\n" +
                    "where TIME_ = '202004'";
            decodeToCaseWhen(sql);
        }
        //循环执行  把全部decode函数都替换
        public static String decodeToCaseWhen(String sql) {
            String ss = sql.replaceAll("nvl", "isnull")
                    .replaceAll("NVL", "isnull")
                    .replaceAll("DECODE", "decode");
            int s = ss.split("decode").length - 1;
            for (int i = 0; i < s; i++) {
                ss = decodeTransformToCaseWhen(ss);
            }
            return ss;
        }
    
  • 相关阅读:
    素因子分解
    【转载】一张表看懂LTE和5G NR的区别
    看国家宝藏,顺便学习一下国密算法
    LTE-Advanced(4G)主要技术学习:CA、CoMp、HetNet
    未来移动通信的需求与挑战
    傅里叶级数
    正余弦函数的复指数表示
    网络基础——相关面试考点
    操作系统——相关面试考点
    小米2015笔试编程题
  • 原文地址:https://www.cnblogs.com/qianyoo/p/14074214.html
Copyright © 2011-2022 走看看