oracle环境有关sql的注意事项

比较特殊的:

1. 原有 MySQL字段设置为 not null default ''

原因: ORACLE 数据库 不允许存空字符串, 认为它跟null是一样的 修改: 这种情况下, 在xml中, 我们暂时的处理办法是在xml中修改原先插入的空字符串变为固定格式的字符串, 格式为"NULL_大写的列名或者列名简称"

根据观察, 存为空的情况, 可能是指, 这些数据是 作为一种默认配置的设定 目前有修改的是 a. account_performance_info_daily表中的account_type字段 => 'NULL_TYPE' b. life_cycle_saas_attachment 表中的tenant字段 => 'NULL_TENANT'

具体业务逻辑碰到冲突的地方需要进行相应更改, 一般是在select以及不同的 type case 判断上

2. 有部分的sql 并没有写在xml中

这种情况可能是遇到了sql 语句 是: a. 存在了数据库表中 例: select TABLE_NAME as tableName, DELETE_SQL as deleteSql from custom_account_data_tables b. 代码里面动态拼出来的 customSql c. 根据model 上的注解, 通过反射, 动态拼出来的 例: DbSearchUtil

如果碰到不适配的语句时, 一般是在OracleUtil类中进行相关修改的

3. 同时删除2表的操作,进行了修改,变成了 2个删除语句.

例: accountMapper.deleteBenchMarkById(benchMarkIds); accountMapper.deleteBecnchMarkWeightById(benchMarkIds);

4. 不同的schema 在注入 DataSource的时候,进行一个设置.

hikariConfig.setConnectionInitSql("ALTER SESSION SET CURRENT_SCHEMA = " + schema);

有关语法的:

1. 在insert中有忽略 唯一索引检查的操作, 语法与mysql 不同

例: <insert id="insertPermissions" parameterType="java.util.List"> insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(acl_entry(user, object_id, data_id)) */ into acl_entry("USER", object_id, data_id) <foreach collection="list" item="element" index="index" separator="union all"> ( select #{element.user, jdbcType = VARCHAR}, #{element.objectId, jdbcType = INTEGER}, #{element.dataId, jdbcType = VARCHAR} from dual) </foreach> </insert>

关于jdbcType根据现有的数据库设定来看, 与java类型的设定建议统一如下:

与数字相关的数据库一般使用NUMBER类型, jdbcType统一使用 NUMERIC

Java Type jdbcType
String VARCHAR
Boolean NUMERIC
Integer NUMERIC
Long NUMERIC
Double NUMERIC
Date DATE
DateTime TIMESTAMP
   

更多设置可以参考 http://www.mybatis.org/mybatis-3/apidocs/reference/org/apache/ibatis/type/JdbcType.html

2. SELECT * FROM ACCOUNT WHERE ID IN (1,2,3)

上述in的参数个数, Oracle 上限是1000个, 目前的处理办法是在OracleUtil中分批查询然后合并结果

3. Oracle 是大小写不敏感的, 如果不使用别名, 默认返回的列名会是全部大写

4. 列名显式引用 需要使用双引号

常量VARCHAR使用单引号, 使用 0 或者 1 查询, 映射到Boolean字段上, 使用 as 别名的时候, 在表名后面一定 不要 使用, 在列名后面 可以 使用, 在where条件中, 使用原始列名 查询 如果列名是关键词,那么需要使用双引号 显式使用 例: select "LEVEL" as "level" from life_cycle_saas_event_type a where a."LEVEL" = '母基金'

5. 根据条件进行删除的语句, delete 加上 join条件

例: <delete id="deleteRequirement"> delete from PRE_REQUIREMENT where rowid in ( select a.rowid from PRE_REQUIREMENT a left join pre_requirement_trace b on a.channel = b.channel where a.id = #{id} ) </delete>

6. 插入与更新操作中, 如果值可能为null, 需要显式指定jdbcType, 不然会报错. 例子见下一条.

7. 与mysql的replace into 语法相对应的写法如下

<insert id="moveInternalAccountsToDel" parameterType="com.datayes.mom.instance.attribution.AccountDel"> <!-- replace into account_del(ACCOUNT_ID, ACCOUNT_DATA, EXTERNAL_SOURCE) values <foreach collection="list" item="record" separator=","> (#{record.accountID}, \#{record.accountData}, \#{record.externalSource}) </foreach> Attention: Columns referenced in the ON Clause cannot be updated FOR ORACLE --> MERGE INTO account_del A USING ( <foreach collection="list" item="record" separator=" union all " index="index"> select #{record.accountID, jdbcType=VARCHAR} as accountID, #{record.accountData, jdbcType=VARCHAR} as accountData, #{record.externalSource, jdbcType=VARCHAR} as externalSource from dual </foreach> ) B ON (A.ACCOUNT_ID=B.accountID) WHEN MATCHED THEN UPDATE set A.ACCOUNT_DATA=B.accountData, A.EXTERNAL_SOURCE=B.externalSource WHEN NOT MATCHED THEN INSERT (ACCOUNT_ID, ACCOUNT_DATA, EXTERNAL_SOURCE) VALUES(B.accountID,B.accountData,B.externalSource)

</insert>

8. Oracle中的 分页查询参考下面的例子, 查询第2到11条数据

SELECT * FROM ACCOUNT OFFSET 1 ROWS FETCH NEXT 10 ROWS ONLY

9. 虽然在客户端中可以使用分号';'作为结尾, 但是在xml中使用分号将导致 sql 执行报错

10. 一些不同的函数

a. 获取今天的日期

SELECT TRUNC(sysdate, 'DD') FROM dual

b. 连接多个字符串

result.userName like '%' || #{keyword} || '%'
c. 映射到boolean的例子

 select case when count(*) > 0 then 1 else 0 end from duty_report dr left join duty_report_user_rel drur on drur.report_id = dr.id where drur.party_id = #{partyId} and dr.tenant = #{tenant} and drur.is_del = 0 and drur.submit_time is not null 

d. regexp 正则匹配,对应 REGEXP_LIKE

REGEXP_LIKE(查询的字段,正则表达式)

11.插入时返回主键id

原语法


<insert id="insert" useGeneratedKeys="true" keyColumn="ID" keyProperty="id">
  INSERT INTO xt_account_rule_info
  (ACCOUNT_ID, ACCOUNT_CODE, ACCOUNT_NAME, ACCOUNT_SET_ID, ACCOUNT_SHEET_NAME, ACCOUNT_CELL, DATE_START_CELL,
  UNIT_VALUE_START_CELL, ADJUST_VALUE_START_CELL, ACCUMULATE_VALUE_START_CELL)
  VALUES
  (#{accountId}, #{accountCode}, #{accountName}, #{accountSetId}, #{accountSheetName}, #{accountCell}, #{dateStartCell},
  #{unitValueStartCell}, #{adjustValueStartCell}, #{accumulateValueStartCell})
</insert>

由于Oracle是不支持自动生成主键的,不像Sql或者Mysql能自动生成。所以 需要将 useGeneratedKeys 设置为false,并添加selectKey标签,查询对应的自增序列id并返回,如下:

<insert id="insert" useGeneratedKeys="false" keyColumn="ID" keyProperty="id">
      <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long">
          SELECT
          get_seq_curr(sequence_name)
          FROM
          user_tab_identity_cols
          WHERE
          table_name = UPPER('xt_account_rule_info')
      </selectKey>
      INSERT INTO xt_account_rule_info
      (ACCOUNT_ID, ACCOUNT_CODE, ACCOUNT_NAME, ACCOUNT_SET_ID, ACCOUNT_SHEET_NAME, ACCOUNT_CELL, DATE_START_CELL,
      UNIT_VALUE_START_CELL, ADJUST_VALUE_START_CELL, ACCUMULATE_VALUE_START_CELL)
      VALUES
      (#{accountId,jdbcType=VARCHAR}, #{accountCode,jdbcType=VARCHAR}, #{accountName,jdbcType=VARCHAR}, #{accountSetId}, #{accountSheetName,jdbcType=VARCHAR}, #{accountCell,jdbcType=VARCHAR}, #{dateStartCell,jdbcType=VARCHAR},
      #{unitValueStartCell,jdbcType=VARCHAR}, #{adjustValueStartCell,jdbcType=VARCHAR}, #{accumulateValueStartCell,jdbcType=VARCHAR})
  </insert>  

12 不支持left 与 right函数

可以通过substr函数来进行替代

substr(字符串,截取开始位置,截取长度)

截取开始位置 = 负数时,表示截取的开始位置为字符串右端向左数第 截取长度 个字符

例如:

substr(str,0,2),等价于 left(str,2)

substr(str,-2,2),等价于 right(str,2)

替换公式如下:

right(str,len) -> substr(str,-len,len)

left(str,len) -> substr(str,0,len)

特别的,对于日期类型的截取,在mysql中可以直接使用left或者right函数进行操作,在oracle中,需要将对应的日期字段转换为标准的字符串内容后,再进行截取,比如:

在mysql中:

select left(curdate(),7) 可以得到:2022-02

在oracle中要使用substr替换

select substr(to_char(sysdate,'yyyy-MM-dd'),0,7) from dual;

13 char

对于char类型的字段,如果字段值实际长度小于字段设定长度,虽然肉眼看上去是没有空格的,但是实际上会在尾部补充空格,所以查询的时候,需要将字段trim之后或者将查询条件补充空格后进行查询。

不过一般来说,字段之所以定义为char类型,就是因为对应字段实际值会是定长的,所以一般也不需要额外的修改。对于一些特别的情况,可以按照上述方案,将查询字段添加trim函数后进行比较:TRIM(字段)=查询值

14 位运算

Oracle中只有位余运算:BITAND,表示返回两个数值型数值在按位进行 AND 运算后的结果。

语法:BITAND(nExpression1, nExpression2) BITAND将 nExpression1 的每一位同 nExpression2 的相应位进行比较。如果 nExpression1 和 nExpression2 的位都是 1,相应的结果位就是 1;否则相应的结果位是 0。

与:bitand,例如: bitand(7,1) 等价于 7 & 1

15 datediff函数

在oracle中没有datediff()函数 可以用以下方法在oracle中实现该函数的功能:

天:
ROUND(TO_NUMBER(END_DATE - START_DATE))
小时:
ROUND(TO_NUMBER(END_DATE - START_DATE) * 24)
分钟:
ROUND(TO_NUMBER(END_DATE - START_DATE) * 24 * 60)
秒:
ROUND(TO_NUMBER(END_DATE - START_DATE) * 24 * 60 * 60)
毫秒:
ROUND(TO_NUMBER(END_DATE - START_DATE) * 24 * 60 * 60 * 60)
getFundClose

16 CONCAT 函数

在mysql中 CONCAT函数可以拼接任意数量的参数

在oracle中,CONCAT函数仅接收两个参数的拼接,可用 || 替换

例如:

在mysql中,使用concat(1,2,3,4,5)

在oracle中,可替换为 1 || 2 || 3 || 4 || 5

17 oracle字段拼接过程中以0开头的小数,开头的0消失

为何小数点前0会省略,是因为oracle数据库中存在一个隐形类型转换,在拼接的过程中小数自动转成字符类型,相当于调用了to_char函数,所以丢失小数点前面的0

这里操作就是把数值类型转换为字符型,即加上to_char(字段,’fm9999999999999990.00’)

其中9代表如果存在数字则显示数字,不存在则显示空格; 0代表如果存在数字则显示数字,不存在则显示0,即占位符; fm代表删除如果是因9带来的空格,则删除。

18 时间差函数:timestampdiff

语法:timestampdiff(interval, datetime1,datetime2)

结果:返回(时间2-时间1)的时间差,结果单位由interval参数给出。

单位 MySQL(UNIT) oracle
毫秒   ROUND(TO_NUMBER(END_DATE - START_DATE) * 24 * 60 * 60 * 60)
second ROUND(TO_NUMBER(END_DATE - START_DATE) * 24 * 60 * 60)
分钟 minute ROUND(TO_NUMBER(END_DATE - START_DATE) * 24 * 60)
小时 hour ROUND(TO_NUMBER(END_DATE - START_DATE) * 24)
day ROUND(TO_NUMBER(END_DATE - START_DATE))
week  
month trunc(months_between(END_DATE,START_DATE))
quarter  
year trunc(months_between(END_DATE,START_DATE)/12)

19 中文排序问题

mysql 可以用过转换编码,达到使用中文拼音首字母排序的功能

order by convert ( 字段名 using gbk ) asc

在oracle中 可以使用

order by nlssort(字段名,'NLS_SORT=SCHINESE_PINYIN_M') asc

20 QUARTER() 函数,获取日期对应的季度

在mysql 中,QUARTER(日期字段) 函数返回给定日期值(从1到4的数字)的一年的四分之一。

  • 1月至3月返回1

  • 4月至6月返回2

  • 7月至9月返回3

  • 10月至12月返回4

在oracle中,可使用 to_char(日期字段,'Q') 替换

21 字符集不匹配问题

原因可能是字段类型不一致的原因,比如,两个字段一个是VARCHAR2,一个是NVARCHAR2

或者

是在union时,所联接的两块数据,对应的字段类型不一致,一边是VARCHAR2,一边是NVARCHAR2。

需要先对应到具体哪个字段不一致,然后其中一个进行转换。

目前遇到的情况,一般是查询中,有字段是写死的值, 用来做union或者与其他字段比较,而对应的字段是另一个数据类型。比如:

   select nianyue,'全部' as VALUE_NAME_CN,count(1) shu
                    from (
                              SELECT distinct a.FUND_ID
                                            ,year(a.ESTABLISH_DATE)nianyue
                              from fund_class a
                                      INNER JOIN fund_issue b on a.SECURITY_ID = b.SECURITY_ID and b.RAISE_METHOD = '1'
                          )a group by nianyue
            select distinct a.FUND_ID
                                            ,year(b.ESTABLISH_DATE)nianyue
                                            ,d.VALUE_NAME_CN
                              from fund_class a
                                      INNER JOIN fund_issue b on a.SECURITY_ID = b.SECURITY_ID and b.RAISE_METHOD = '1' and b.ESTABLISH_DATE is not null
                                      join fund_type c on a.SECURITY_ID = c.SECURITY_ID and c.CODE_TYPE_ID = '40123'
                                      join sys_code d on d.CODE_TYPE_ID = c.CODE_TYPE_ID and left(c.VALUE_NUM_CD,8) = d.VALUE_NUM_CD

以上两段sql中,VALUE_NAME_CN字段,上面的对应写死的值,下面的对应的实际字段,而实际字段的类型是NVARCHAR2,这个时候就会有字符集不一致的问题。

修改方案就是,将写死的值的类型转换一下就好了,Translate('全部' USING NCHAR_CS) as VALUE_NAME_CN

22 ORA-01799: 列不能外部联接到子查询

原因:Oracle 不支持 在 join中存在子查询,效率太低。

解决方案:先查询出关联表的关联列,条件列,以及其它需要的列,查询结果集作为一个表,再让其它表来关联这个结果集

例子:

修改前

SELECT DISTINCT a.PERSON_ID personId, g.manager_type investmentType
      FROM (SELECT PERSON_ID, max(POSITION) POSITION
      FROM fund_manager_new
      WHERE POSITION = 'FM'
      and PERSON_ID in <foreach collection="personIds" item="personId" open="(" close=")" separator=",">#{personId}</foreach>
      GROUP BY PERSON_ID) a
      LEFT JOIN fund_manager_rating_dy g ON a.PERSON_ID = g.PERSON_ID
      AND g.END_DATE = (SELECT max(END_DATE) FROM fund_manager_rating_dy)
 

修改后

        SELECT DISTINCT a.PERSON_ID personId, g.manager_type investmentType
      FROM (SELECT PERSON_ID, max(POSITION) POSITION
      FROM fund_manager_new
      WHERE POSITION = 'FM'
      and PERSON_ID in <foreach collection="personIds" item="personId" open="(" close=")" separator=",">#{personId}</foreach>
      GROUP BY PERSON_ID) a
      LEFT JOIN ( select PERSON_ID,manager_type from fund_manager_rating_dy
      where END_DATE = (SELECT max(END_DATE) FROM fund_manager_rating_dy)) g
          on a.PERSON_ID = g.PERSON_ID order by a.PERSON_ID

23 date_sub 函数

对应替换方式如下:

  oracle oracle
增减一小时 date_sub(createDate, interval -1 hour) date_sub(createDate, interval 1 hour) createDate+1/24 createDate-1/24
增减一天 date_sub(createDate, interval -1 day) date_sub(createDate, interval 1 day) createDate+1 createDate-1
增减一月 date_sub(createDate, interval -1 month) date_sub(createDate, interval 1 month) add_months(createDate, 1) add_months(createDate, -1)
增减一季度 date_sub(createDate, interval -3 month) date_sub(createDate, interval 3 month) add_months(createDate, 3) add_months(createDate, -3)
增减一年 date_sub(createDate, interval -1 year) date_sub(createDate, interval 1 year) add_months(createDate, 12) add_months(createDate, -12)
  listagg(c.SEC_SHORT_NAME, ',') within
      GROUP (order by rownum) as SEC_SHORT_NAME,

24 field 函数 自定义排序

ORACLE可以借助DECODE函数,自定义顺序排序:

DECODE(value,if 条件1,then 值1,if 条件2,then 值2,...,else 其他值)

例子:

mysql中自定义排序如下

ORDER BY FIELD(b.TYPE_NAME, '普通股票型', '偏股混合型', '短期纯债型', '中长期纯债型', '可转债型', '偏债混合型', '混合债券型(一级)', '混合债券型(二级)',
                      '平衡混合型', '灵活配置混合型', '被动指数股票型', '增强指数股票型', '被动指数债券型', 'QDII股票型', 'QDII债券型', 'QDII混合型', 'QDII其他',
                      '传统货币型', '短期理财型', '浮动净值型', 'FOF', 'REITs', '保本型', '传统封闭式', '商品型', '其他型')

等价于在oracle中的

ORDER BY DECODE(b.TYPE_NAME, '普通股票型', 1, '偏股混合型', 2, '短期纯债型', 3, '中长期纯债型', 4, '可转债型', 5,
                      '偏债混合型', 6, '混合债券型(一级)', 7, '混合债券型(二级)', 8,
                      '平衡混合型', 9, '灵活配置混合型', 10, '被动指数股票型', 11, '增强指数股票型', 12,
                      '被动指数债券型', 13, 'QDII股票型', 14, 'QDII债券型', 15, 'QDII混合型', 16, 'QDII其他', 17,
                      '传统货币型', 18, '短期理财型', 19, '浮动净值型', 20, 'FOF', 21, 'REITs', 22, '保本型', 23, '传统封闭式', 24, '商品型',25,
                      '其他型', 99)

25 date函数,截取日期

想将1997/1/8 10:30:27变为1997/1/8,在mysql中使用 date(时间字段)

在oracle中,使用 trunc(时间字段)

26 ORA-00907: 缺失右括号,子查询中不能有order by

oracle子查询中使用order by 会报错:ORA-00907: 缺失右括号

from 子句后面的内联视图是可以使用order by子句进行排序的。

所以,可以将对应的oder by 子查询语句再嵌套一层。

改造前

        SELECT CLOSE_INDEX FROM
      (( SELECT CLOSE_INDEX,TRADE_DATE FROM mkt_idxd
      WHERE INDEX_ID = 1782 AND TRADE_DATE &lt; #{date} ORDER BY TRADE_DATE DESC LIMIT 1)
      UNION
      (SELECT CLOSE_INDEX,TRADE_DATE FROM mkt_idxd
      WHERE INDEX_ID = 1782 AND TRADE_DATE >= #{date} ORDER BY TRADE_DATE)) t
      ORDER BY TRADE_DATE

改造后:

        SELECT CLOSE_INDEX FROM
      (( SELECT * from ( SELECT CLOSE_INDEX,TRADE_DATE FROM mkt_idxd
      WHERE INDEX_ID = 1782 AND TRADE_DATE &lt; #{date} and rownum=1 ORDER BY TRADE_DATE DESC ) a1 )
      UNION
        ( SELECT * from (SELECT CLOSE_INDEX,TRADE_DATE FROM mkt_idxd
      WHERE INDEX_ID = 1782 AND TRADE_DATE >= #{date} ORDER BY TRADE_DATE) a2) ) t
      ORDER BY TRADE_DATE

改动点就是将原order by 子句,再嵌套一层,select * from table order by create_time 改为 select * from (原子句)

27 ORA-01791:不是SELECTed表达式

SQL 语句是先执行 distinct 去重后,再使用 order by 进行排序的。所以如果在 order by 需要排序的字段,没有在 distinct 后的字段中,就会抛错。

解决方案:

在 distinct 后加入需要排序的字段即可。

28 limit 问题

oracle 中没有limit,可以使用rownum替换

但是在语句中存在order by 排序时,单纯的将limit替换为rownum是不对的,因为rownum是在order by排序执行之前设置的值,针对带有order by的语句,需要使用 fetch first关键字进行替换

例如:

select SECURITY_ID from MD_SECURITY  order by SECURITY_ID limit 1

转换为oracle

select SECURITY_ID from MD_SECURITY  order by SECURITY_ID  fetch first 1 rows only

即: 将 limit 替换为 fetch first {需要数据行数} rows only

详细内容可参考:https://www.cnblogs.com/CandiceW/p/10030936.html

to_date(sysdate)

29 CURDATE()函数

CURDATE()函数值为不包括时分秒的值,所以替换的时候,要替换为to_date(sysdate)

30 @自定义变量问题

lag与lead函数是跟偏移量相关的两个分析函数,通过这两个函数可以在一次查询中取出同一字段的前N行的数据(lag)和后N行的数据(lead)作为独立的列,从而更方便地进行进行数据过滤。这种操作可以代替表的自联接,并且LAG和LEAD有更高的效率。

over()表示 lag()与lead()操作的数据都在over()的范围内,他里面可以使用partition by 语句(用于分组) order by 语句(用于排序)。partition by a order by b表示以a字段进行分组,再 以b字段进行排序,对数据进行查询。

  例如:lead(field, num, defaultvalue) field需要查找的字段,num往后查找的num行的数据,defaultvalue没有符合条件的默认值。

窗口分析函数:

sum() over ()

下面列一下开窗函数与分析函数搭配使用的情况:

1.有partition by有order by : 在partition by分组下,按照不同的order by 字段 实现递增汇总

2.有partition by无order by: 实现分组内所有数据的汇总

3.无partition by有order by : 直接按order by 字段实现递增汇总

4.无partition by无order by: 所有数据相加

当然,除了使用sum() over(),还有

count() over(partition by ... order by ...):求分组后的总数。 max() over(partition by ... order by ...):求分组后的最大值。 min() over(partition by ... order by ...):求分组后的最小值。 avg() over(partition by ... order by ...):求分组后的平均值。 lag() over(partition by ... order by ...):取出前n行数据。  

lead() over(partition by ... order by ...):取出后n行数据。

原sql:

(SELECT z1.*,IF(z1.SECURITY_ID=@SECURITY_ID,cast(@shu as DECIMAL(20,4)),null) AS HOLD_VOLUME_z1,
      @SECURITY_ID:=SECURITY_ID,@shu:= HOLD_VOLUME_z
      from
      (SELECT REPORT_DATE,SECURITY_ID,TICKER_SYMBOL,SEC_SHORT_NAME,TYPE_NAME,sum(HOLD_FUND) HOLD_FUND_z,sum(HOLD_INST) HOLD_INST_z,sum(MARKET_VALUE) MARKET_VALUE_z,sum(RATIO_IN_FLOAT_A) RATIO_IN_FLOAT_A_z,sum(HOLD_VOLUME) HOLD_VOLUME_z
      from fund_mt_holdkey_type
      where CATEGORY in <foreach collection="strategyCodes" item="code" open="(" close=")" separator=",">#{code}</foreach>
      group by REPORT_DATE,SECURITY_ID,TICKER_SYMBOL,SEC_SHORT_NAME,TYPE_NAME
      order by SECURITY_ID,REPORT_DATE) z1,(SELECT @SECURITY_ID:=NULL,@shu:= null)r)

改造后sql:

(SELECT
      case when z1_pre = SECURITY_ID then HOLD_VOLUME_z1_1 end as HOLD_VOLUME_z1,
      z1_1.*
      from (SELECT lag(z1.SECURITY_ID, 1, null) over (order by SECURITY_ID,REPORT_DATE) as z1_pre,
      lag(cast(z1.HOLD_VOLUME_z as DECIMAL(20,4)), 1, null) over (order by SECURITY_ID,REPORT_DATE) AS HOLD_VOLUME_z1_1,
      z1.*
      from
      (SELECT REPORT_DATE,SECURITY_ID,TICKER_SYMBOL,SEC_SHORT_NAME,TYPE_NAME,sum(HOLD_FUND) HOLD_FUND_z,sum(HOLD_INST) HOLD_INST_z,sum(MARKET_VALUE) MARKET_VALUE_z,sum(RATIO_IN_FLOAT_A) RATIO_IN_FLOAT_A_z,sum(HOLD_VOLUME) HOLD_VOLUME_z
      from fund_mt_holdkey_type
      where CATEGORY in <foreach collection="strategyCodes" item="code" open="(" close=")" separator=",">#{code}</foreach>
      group by REPORT_DATE,SECURITY_ID,TICKER_SYMBOL,SEC_SHORT_NAME,TYPE_NAME
      order by SECURITY_ID,REPORT_DATE) z1) z1_1)

31 substring 函数

直接替换为substr函数即可

32 year 函数获取日期的年份

year ( 日期字段 )

转换为oracle函数为:

extract(year from 日期字段)

33 force index 强制使用索引

SELECT /*+index(t pk_emp)*/* FROM EMP T   

--强制索引,/*.....*/第一个星星后不能有空格,里边内容结构为:加号index(表名 空格 索引名)。
--如果表用了别名,注释里的表也要使用别名。

34 join时没有on或者where条件

使用join或时inner joinon条件是可选的。这与ANSI标准不同,并且与几乎所有其他数据库不同。效果是cross join

MySQL和Oracle里面SQL转换的更多相关文章

  1. 基于TreeSoft实现mysql、oracle、sql server的数据同步

    一.为了解决数据同步汇聚,数据分发,数据转换,数据维护需求,TreeSoft推出了数据同步,数据处理等丰富功能 . TreeSoft作为中间传输载体负责连接各种数据源,为各种异构数据库之间架起沟通的桥 ...

  2. MySQL、Oracle和SQL Server的分页查询语句

    假设当前是第PageNo页,每页有PageSize条记录,现在分别用Mysql.Oracle和SQL Server分页查询student表. 1.Mysql的分页查询: SELECT * FROM s ...

  3. MySql和Oracle的日期转换到底有哪些不同?我们来比较一下

    1.MySql和Oracle的日期转换 mysql中有2种日期格式DATE和TIME,oracle只有一种日期格式DATE. oracle> select to_char(sysdate,'yy ...

  4. JDBC连接MySQL、Oracle和SQL server的配置

    什么是JDBC 我们可以将JDBC看作是一组用于用JAVA操作数据库的API,通过这个API接口,可以连接到数据库,并且使用结构化查询语言(SQL)完成对数据库的查找,更新等操作. JDBC连接的流程 ...

  5. Java分别与MySQL、Oracle、SQL Server数据库建立连接

    1.与MySQL连接 jar包下载地址: Class.forName("com.mysql.jdbc.Driver");//加载数据库驱动(MySQL的jar包) String u ...

  6. Spring连接MySQL、Oracle和SQL Server的数据库运动连接属性

    在配置文件applicationContext.xml设置如下:<?xml version="1.0" encoding="UTF-8"?>< ...

  7. Spring连接MySQL、Oracle和SQL Server

    其中applicationContext.xml的配置如下: <?xml version="1.0" encoding="UTF-8"?> < ...

  8. mysql、oracle和SQL server数据库的区别

    1.总体对比. SQL,在这里我理解成SQL Server.三者是目前市场占有率最高(依安装量而非收入)的关系数据库,而且很有代表性.排行第四的DB2(属IBM公司),与Oracle的定位和架构非常相 ...

  9. 加载MySQL、Oracle、SQL Server 2000、SQL Server 2005及以上版本 的加载数据库驱动程序

    2018-11-04  20:00:59 开始 //getConnection(String url, String user, String password) //url:连接数据库的URL 3 ...

  10. MySQL和ORACLE、SQL Server、PostgreSQL相比

随机推荐

  1. SpringBoot学习-图文并茂写Hello World

    一. 生成SpringBoot新项目demo 在 https://start.spring.io/ 生成一个新的项目 1. 步骤: 1)Project 选择 Maven Project 2)Sprin ...

  2. Lucene介绍与使用

    Lucene介绍与使用 原文链接:https://blog.csdn.net/weixin_42633131/article/details/82873731 不选择使用Lucene的6大原因? 原文 ...

  3. protobuf简单示例

    user.proto syntax = "proto3"; package demo; option go_package = "./pb"; //指定go_o ...

  4. 记一个 Duplicate class kotlin-stblib vs kotlin-stdlib-jdk7/8 编译问题引发的案例

    某天将项目 kotlin 版本升级到了 1.8.0 ,然后编译报错了, Duplicate class kotlin-stblib vs kotlin-stdlib-jdk7/8 然后开始寻求解决方案 ...

  5. 1-Django框架简介以及基本操作

    安装 注意:安装的磁盘目录,以及后续通过Django创建目录的时候,不要出现中文,否则会出现预料之外的错误 建议:禁止套娃,即不要在A项目中创建B项目 # 如果不指定版本号,默认最新版 pip ins ...

  6. 名校 AI 课程|斯坦福 CS25:Transformers United 专题讲座

    自 2017 年提出后,Transformer 名声大噪,不仅颠覆了自然语言处理(NLP)领域,而且在计算机视觉(CV).强化学习(RL).生成对抗网络(GANs).语音甚至是生物学等领域也大显锋芒, ...

  7. 【Azure App Service】通过Visual Studio部署Azure App Service 遇见 401 'Unauthorized'错误

    问题描述 最近通过Visual Studio 2022部署Azure App Service的时候,突然遇见了部署失败, 401 Unauthorized错误. 错误消息: Build started ...

  8. 【Azure Redis 缓存】Lettuce 连接到Azure Redis服务,出现15分钟Timeout问题

    问题描述 在Java应用中,使用 Lettuce 作为客户端SDK与Azure Redis 服务连接,当遇见连接断开后,长达15分钟才会重连.导致应用在长达15分的时间,持续报错Timeout 问题解 ...

  9. 【Azure 环境】自动化账号生成的时候怎么生成连接与证书

    问题描述 自动化账号生成的时候怎么生成连接与证书? 什么是自动化? Azure 自动化提供基于云的自动化和配置服务,用于支持 Azure 环境和非 Azure 环境之间的一致管理. Azure 自动化 ...

  10. C++ //类模板中成员函数创建时机 //类模板中成员函数和普通类中成员函数创建时机是有区别的: //1.普通类中的成员函数一开始就可以创建 //2.类模板中的成员函数在调用时才创建

    1 //类模板中成员函数创建时机 2 //类模板中成员函数和普通类中成员函数创建时机是有区别的: 3 //1.普通类中的成员函数一开始就可以创建 4 //2.类模板中的成员函数在调用时才创建 5 6 ...