区别(转:)
1、if else分⽀
mysql:⽤elseif Oracle:⽤elsif
可以⽤select直接查看获取的值或者⼀个变量。
1 create procedure pd_testif2(in num int,out str varchar) 2 begin
3 if num=1 then 4 set str='⼀';
5 elseif num=2 then 6 set str='⼆'; 7 end if; 8 end; 9 --调⽤
10 call pd_testif2(1,@str);11 select @str;
执⾏结果:⼀ 2、循环
mysql:while 条件 do Oracle:while 条件 loop 语句块 语句块 end while; end loop;
1 create procedure pd_testwhile22(in num int,out sum int) 2 begin
3 --定义变量
4 declare i int default 1; 5 declare sum int default 0; 6 --循环条件
7 while i 14 call pd_testwhile22(100,@str);15 select @str; 执⾏结果:5050 补充:Oracle和MySQL的⼀点区别: 函数、⽇期、limit关键字区别(转 不同点: 1. mysql: IFNULL(a,b)oracle: NULLIF(a,b) 2. mysql: 可以⽤Date类型的⽇期进⾏⽐较时间⽐较 oracle:必须⽤to_date()函数和to_char()函数配合转换成统⼀格式的⽇期字符串,然后进⾏⽐较 3. mysql: 可以⽤YEAR(), MONTH(), NOW()等函数获取年/⽉/当前⽇期等oracle:必须⽤to_char(sysdate, 'yyyy'),to_char(sysdate, 'MM')获取4. mysql: 字符串识别\"\oracle:字符串只识别'' 5. mysql: 可以⽤limit关键字截取所需的数据⾏ oracle:必须⽤rownum关键字通过⼦查询来截取所需数据⾏ 表、列、索引、空字符串---转() 2.1 创建表(同)create table tableName(columnName1 int,columnName2 int) 2.2 删除表(异)MySQL: drop table if exists tableName Oracle: drop table tableName 注:Oracle没有if exists关键字,也没⽤类似if exists的SQL语法。 3 列 3.1 添加列(异)MySQL: A. alter table tableName add column columnName1 int; B. alter table tableName add column columnName1 int, add column columnName2 int;注:其中关键字column可有可⽆。 Oracle: A. alter table tableName add columnName1 int;B. alter table tableName add (columnName1 int); C. alter table tableName add (columnName1 int, columnName2 int); 注:对于A,只有添加单列的时候才可使⽤,对于添加多列时需要使⽤C,不能像MySQL那样重复使⽤add column关键字。3.2 删除列(异)MySQL: A. alter table tableName drop column columnName1 B. alter table tableName drop column columnName1, drop column columnName2注:其中关键字column可有可⽆。 Oracle: A. alter table tableName drop column columnName2B. alter table tableName drop (columnName1) C. alter table tableName drop (columnName1,columnName2) 注:对于A,只有删除单列的时候才可使⽤,对于删除多列时需要使⽤C,不能像MySQL那样重复使⽤drop column关键字。3.3 修改列名(异)MySQL: alter table tableName change column columnNameOld columnNameNew columnType; Oracle: alter table tableName rename column columnNameOld to columnNameNew;3.4 修改列类型(说明) Oracle中,在列有数据的时候,⽆法修改列类型;没有数据时可以。MySQL中,⽆论列是否有数据都可以修改列类型。 但是当有数据是,直接修改列类型都可能对数据造成丢失等,所以⼀般需要结合具体的业务来对列数据做处理后,再修改列类型类型。所以修改列的类型并⾮使⽤SQL语句进⾏⼀步到位的修改,⽽是通过以下流程:A. 添加临时列 B. 将需要更改的列的值经过类型转换的验证后,赋值给临时列C. 删除原有列 D. 将临时列的列名修改为原有列列名 4 索引 在整个数据库内,MySQL的索引可以同名,也就是说MySQL的索引是表级别的;但是Oracle索引不可以同名,也就是说Oracle的索引是数据库级别的。4.1 创建索引(同) create index indexName on tableName (columnName);4.2 删除索引(异)MySQL: alter table tableName drop index indexName Oracle: drop index indexName4.3 查询表的索引(异)MySQL: show index from tableName Oracle: select index_name, table_name, column_name from user_ind_columns where table_name=' tableName ' 5 空字符串问题 Oracle中空字符串''就是null(也就是说,只有null,没有空字符),⽽MySQL是区分null和''的。 对于使⽤语句:select * from table1 where user_name <> ''来查询列user_name不为空(不为null且不为空字符)时,Oracle会查不出任何结果,⽽MySQL可以正常运⾏。这⾥MySQL之所以可以得到正确结果,还因为⽐较符号<>会先将列为null的内容进⾏过滤,然后再⽐较内容 是否为空字符串。 这就要求⼀⽅⾯,以后在编写代码的时候,尽量保证不会往数据库插⼊空字符串''这样的值,要么保持有数据,要么保持为null。另外,对于MySQL中已经同时存在Null和''时,所有判断是否为null或者''的地⽅改为判断列的长度是否为0。 数据类型,基本语法,循环语句,存储过程&Function,⽤户权限,触发器 等 转() 数据类型编号ORACLE MYSQL 注释 DECIMAL就是NUMBER(10,2)这样的结构INT就是是NUMBER(10),表⽰整型; MYSQL有很多类int型,tinyint mediumint bigint等,不同的int宽度不⼀样 ⽇期字段的处理 MYSQL⽇期字段分DATE和TIME两种,ORACLE⽇期字段只有DATE,包含年⽉⽇时分秒信息,⽤当前数据库的系统时间为 SYSDATE, 精确到秒,或者⽤字符串转换成⽇期型函 数TO_DATE(‘2001-08-01’,’YYYY-MM-DD’)年-⽉-⽇ 24⼩时:分钟:秒的格式YYYY-MM-DD HH24:MI:SS TO_DATE()还有很多种⽇期格式, 可以参看ORACLE DOC.⽇期型字段转换成字符串函数TO_CHAR(‘2001-08-01’,’YYYY-MM-DD HH24:MI:SS’)⽇期字段的数学运算公式有很⼤的不同。MYSQL找到离当前时间7天 ⽤DATE_FIELD_NAME > SUBDATE(NOW(),INTERVAL7 DAY)ORACLE找到离当前时间7天⽤ DATE_FIELD_NAME >SYSDATE - 7; MYSQL中插⼊当前时间的⼏个函数是:NOW()函数以`'YYYY-MM-DD HH:MM:SS'返回当前的⽇期时间,可以直接存 到DATETIME字段中。CURDATE()以’YYYY-MM-DD’的格式返回今天的⽇期,可以直接存到DATE字段 中。CURTIME()以’HH:MM:SS’的格式返回当前的时间,可以直接存到TIME字段中。例:insert into tablename (fieldname)values (now()) ⽽oracle中当前时间是sysdate int / INTEGERMysql中INTEGER等价于intSQLEXCEPTION 详见<<2009001-eService-O2MG.doc>>中2.5 Mysql异常处理 从ORACLE迁移到MYSQL,所有CONSTANT常量只能定义成变 mysql中没有CONSTANT关键字 量光标 : mysql中有替代⽅案 详见<<2009001-eService-O2MG.doc>>中2.2 光标处理 1NUMBER2Varchar2(n) int / DECIMALvarchar(n) 3DateDATATIME 4INTEGER5EXCEPTION 6CONSTANT VARCHAR2(1)7 TYPE g_grp_cur IS REFCURSOR; 数组: mysql中借助临时表处理 TYPE unpacklist_type IS TABLE 或者直接写逻辑到相应的代码中, 8OF VARCHAR2(2000) INDEX BY详见<<2009001-eService-O2MG.doc>>中2.4 数组处理 直接对集合中每个值进⾏相应的处 BINARY_INTEGER; 理 MYSQL有⾃动增长的数据类型,插⼊记录时不⽤操作此字段,会⾃动获得数据值。ORACLE没有⾃动增长的数据类型,需要建⽴ 9⾃动增长的序列⾃动增长的数据类型 ⼀个⾃动增长的序列号,插⼊记录时要把序列号的下⼀个值赋于此字段。空字符的处理 MYSQL的⾮空字段也有空的内容,ORACLE⾥定义了⾮空字段就不容许有空的内容。按MYSQL的NOT NULL来定 10NULLNULL 义ORACLE表结构, 导数据的时候会产⽣错误。因此导数据时要对空字符进⾏判断,如果为NULL或空字符,需要把它改成⼀个空格的字符串。 基本语法 编号类别ORACLEMYSQL 1 变量的声明⽅ li_index NUMBER := 0 式不同 2 变量的赋值⽅ lv_inputstr := iv_inputstr 式不同 EXIT; 3 跳出(退出)while 条件 loop语句不同exit; end loop; 4 5 6 TYPE g_grp_cur IS REF 定义游标CURSOR; TYPE unpacklist_type IS 可以使⽤临时表代替oracle数 TABLE OF VARCHAR2(2000) 定义数组组, 也可以循环拆分字符来替 INDEX BY 代oracle数组. BINARY_INTEGER; \"-- message\" 或 \"/** …. \"-- message\" 或 \"/* …. 注释⽅式不同 */\" 或\"/* …. */\"*/\" 或 \"#\" 注释 1. mysql 使⽤DECLARE定义局部变量. 定义变量语法为: DECLARE var_name[,...] type DECLARE li_index INTEGER[DEFAULT value] 要给变量提供⼀个默认值,需要包DEFAULT 0含⼀个DEFAULT⼦句。值可以被指定为⼀个表达式, 不需要为⼀个常数。如果没有DEFAULT⼦句,初始值为NULL。 1. oracle变量赋值使⽤:= SET lv_inputstr = iv_inputstr mysql 使⽤赋值使⽤set关键字. 将⼀个值赋给⼀个变 量时使⽤\"=\". LEAVE procedure name;1. oracle: 如果exit语句在循环中就退出当前循环.如果 exit语句不再循环中,就退出当前过程或⽅法. label_name:while 条件 do Mysql: 如果leave语句后⾯跟的是存储过程名,则退出 leave label_name;当前存储过程. 如果leave语句后⾯跟的是lable名. 则退end while label_name;出当前lable. DECLARE cursor_nameoracle可以先定义游标,然后给游标赋值. CURSORmysql定义游标时就需要给游标赋值. Mysql定义游标出FOR SELECT_statement;⾃ Mysql 5.1 参考⼿册20.2.11.1.声明光标. ⽬前可以使⽤临时表来代替oracle数组. 详见<<2009002-OTMPPS-Difficult Questions-0001.doc>>中2.4 Mysql数组处理部分 7 8 mysql注释来⾃ MySQL 5.1参考⼿册 9.5. 注释语法, 建议同oracle⼀样, 单⾏⽤--, 多⾏/* */ 1. MYSQL⽇期字段分DATE和TIME两种. ORACLE⽇期字段只有DATE,包含年⽉⽇时分秒信 ⾃带⽇期时间Oracle时间格式:yyyy-MM-ddMysql时间格式:%Y-%m-%d息. 函数格式不同hh:mi:ss%H:%i:%s2. mysql中取当前系统时间为now()函数,精确到秒. oracle中取当前数据库的系统时间为SYSDATE, 精确到秒. ⽇期相加: date_add(now(),INTERVAL 180 DAY) 当前时间加N天: sysdate+N ⽇期加减⽇期相减: date_sub('1998-01- 当前时间减N天: sysdate-N 01 00:00:00', interval '1 1:1:1'day_second) 1. oracle使⽤||连接字符串,也可以使⽤concat函数. 但Oracle的concat函数只能连接两个字符串. Mysql使⽤concat⽅法连接字符串. MySQL的concat函数可以连接⼀个或者多个字符串,如 mysql> select concat('10'); 结果为: 10. mysql> select concat('11','22','33','aa'); 结果为:112233aa 2. \"||\"在Mysql是与运算 9 字符串连接符 result := v_int1||v_int2; 不同 set result =concat(v_int1,v_int2); 10 CURSOR l_bk_cur ISDECLARE l_bk_cur CURSOR SELECT FOR SELECTB.BK_HDR_INT_KEY,B.BK_HDR_INT_KEY,B.BK_NUMB.BK_NUM FROM ES_SR_DTL_VRB A, FROM ES_SR_DTL_VRB A,ES_BK_HDR BES_BK_HDR B WHERE WHERE详见<<2009002-OTMPPS-Difficult Questions-定义游标不同 A.BK_HDR_INT_KEY =A.BK_HDR_INT_KEY =0001.doc>>中2.2 Mysql游标处理部分B.BK_HDR_INT_KEYB.BK_HDR_INT_KEY AND b.BK_STATUS != AND b.BK_STATUS !=ES_BK_PKG.g_status_canES_BK_PKG.g_status_can AND ANDA.SR_HDR_INT_KEY =A.SR_HDR_INT_KEY =ii_sr_hdr_int_key;ii_sr_hdr_int_key;事务回滚GOTO语句 ROLLBACK;GOTO check_date; ROLLBACK;GOTO check_date; oracle和mysql中使⽤⽅法相同oracle和mysql中使⽤⽅法相同 1112 函数编 号类别ORACLE1 round(1.23456,4) 2abs(-1)3ceil(-1.001))数字函数4 floor(-1.001)5Max(expr)/Min(expr)6ascii(str)7CHAR(N,...)8REPLACE(str,from_str,to_str)9INSTR('sdsq','s',2)字符串函10数SUBSTR('abcd',2,2) 11instr(‘abcdefg’,’ab’)MYSQL round(1.23456,4) abs(-1) ceiling(-1.001) floor(-1.001) Max(expr)/Min(expr) ascii(str) CHAR(N,...) REPLACE(str,from_str,to_str) INSTR('sdsq','s') substring('abcd',2,2) locate(‘ab’,’abcdefg’) 注释⼀样: ORACLE:select round(1.23456,4) value fromdual MYSQL:select round(1.23456,4) value功能: 将当前数据取绝对值⽤法: oracle和mysql⽤法⼀样mysql: select abs(-1) value oracle: select abs(-1) value from dual功能: 返回不⼩于 X 的最⼩整数⽤法: mysqls: select ceiling(-1.001) value oracle: select ceil(-1.001) value from dual功能: 返回不⼤于 X 的最⼤整数值⽤法: mysql: select floor(-1.001) value oracle: select floor(-1.001) value from dual功能:返回 expr 的最⼩或最⼤ 值。MIN() 和 MAX() 可以接受⼀个字符串参数;在这 种情况下,它们将返回最⼩或最⼤的字符串传下。⽤法: ROACLE: select max(user_int_key) fromsd_usr; MYSQL: select max(user_int_key) from sd_usr;功能:返回字符串 str 最左边的那个字符的 ASCII 码值。如果 str 是⼀个空字符串, 那么返回值为 0。如果 str 是⼀个 NULL,返回值也是 NULL.⽤法: mysql:select ascii('a') value oracle:select ascii('a') value from dual 功能:CHAR() 以整数类型解释参数,返回这个整数所代表的 ASCII 码值给出的字符组成的字符串。NULL 值将被忽略.⽤法: mysql:select char(97) value oracle:select chr(97) value from dual 功能: 在字符串 str 中所有出现的字符 串 from_str 均被 to_str 替换,然后返回这个字符串.⽤法: mysql: SELECT REPLACE('abcdef', 'bcd','ijklmn') value oracle: SELECT Replace('abcdef', 'bcd', 'ijklmn')value from dual 参数个数不同 ORACLE: select INSTR('sdsq','s',2) value fromdual(要求从位置2开始) MYSQL: select INSTR('sdsq','s') value(从默认的位置1开始)函数名称不同: ORACLE: select substr('abcd',2,2) value fromdual MYSQL: select substring('abcd',2,2) value函数名称不同: instr -> locate(注意:locate的⼦串和总串的位置要互换) ORACLE: SELECT instr('abcdefg', 'ab') VALUEFROM DUAL MYSQL: SELECT locate('ab', 'abcdefg') VALUE函数名称不同: 12length(str)char_length() 13REPLACE('abcdef', 'bcd', 'ijklmn')REPLACE('abcdef', 'bcd', 'ijklmn') 14LPAD('abcd',14, '0')LPAD('abcd',14, '0') 15UPPER(iv_user_id)UPPER(iv_user_id) 16LOWER(iv_user_id)LOWER(iv_user_id) IFNULL(u.email_address, 10)17nvl(u.email_address, 10) 或 ISNULL(u.email_address) 控制流函数 18 DECODE(iv_sr_status,g_sr_status_com,⽆,请⽤IF或CASE语句代替.ld_sys_date, NULL)IF语句格式:(expr1,expr2,expr3) 19TO_CHAR(SQLCODE)date_format/ time_format 20to_date(str,format)STR_TO_DATE(str,format) ORACEL: SELECT length('AAAASDF') VALUE FROM DUAL MYSQL: SELECT char_length('AAAASDF')VALUE⼀样: ORACLE: SELECT REPLACE('abcdef', 'bcd','ijklmn') value from dual MYSQL: SELECT REPLACE('abcdef', 'bcd','ijklmn') value⼀样: ORACLE: select LPAD('abcd',14, '0') value fromdual MYSQL: select LPAD('abcd',14, '0') value fromdual⼀样: ORACLE: select UPPER(user_id) from sd_usr;MYSQL: select UPPER(user_id) from sd_usr;⼀样: ORACLE: select LOWER(user_id) from sd_usr;MYSQL: select LOWER(user_id) from sd_usr;函数名称不同(根据不同的作⽤进⾏选择):ORACLE: select u.email_address, nvl(u.email_address, 10) value from sd_usr u(如果u.email_address=NULl,就在DB中⽤10替换其值) MYSQL: select u.email_address, IFNULL(u.email_address, 10)value from sd_usr u(如 果u.email_address=NULl,显⽰结果中是10,⽽不是在DB中⽤10替换其值)select u.email_address, ISNULL(u.email_address)value from sd_usr u(如 果u.email_address是NULL, 就显⽰1 1. decode(条件,值1,翻译值1,值2,翻译值2,...值n,翻译值n,缺省值)该函数的含义如下:IF 条件=值1 THEN RETURN(翻译值1)ELSIF 条件=值2 THEN RETURN(翻译值2) ...... ELSIF 条件=值n THEN RETURN(翻译值n)ELSE RETURN(缺省值)END IF 2. mysql If语法说明 功能: 如果 expr1 是TRUE (expr1 <> 0 and expr1<> NULL),则IF()的返回值为expr2; 否则返回值则为 expr3。IF() 的返回值为数字值或字符串值,具体情况视其所在语境⽽定。⽤法: mysql: SELECT IF(1>2,2,3);函数名称不同 SQL> select to_char(sysdate,'yyyy-mm-dd') fromdual; SQL> select to_char(sysdate,'hh24-mi-ss') fromdual; mysql> select date_format(now(),'%Y-%m-%d');mysql> select time_format(now(),'%H-%i-%S');函数名称不同: ORACLE:SELECT to_date('2009-3-6','yyyy-mm-dd') VAULE FROM DUAL MYSQL: SELECT STR_TO_DATE('2004-03-01', '%Y-%m-%d') VAULE函数名称不同: TRUNC函数为指定元素⽽截去的⽇期值。 ORACLE: select trunc(-1.002) value from dualMYSQL:select cast(-1.002 as SIGNED) valueMYSQL: 字符集转换 : CONVERT(xxx USING gb2312)类型转换和SQL Server⼀样,就是类型参数有点点不同 : CAST(xxx AS 类型) , CONVERT(xxx,类型),类型必须⽤下列的类型: 可⽤的类型 ⼆进制,同带binary前缀的效果 : BINARY 字符型,可带参数 : CHAR() ⽇期 : DATE 时间: TIME ⽇期时间型 : DATETIME 浮点数 : DECIMAL 整数 : SIGNED ⽆符号整数 : UNSIGNED 类型转换函数21 trunc(-1.002) cast(-1.002 as SIGNED) 22 23 24 ⽇期函数25 26 27 28 29 SQL函数 函数名称不同 ORACLE:SELECT TO_NUMBER('123') ASVALUE FROM DUAL; TO_NUMBER(str)CAST(\"123\" AS SIGNED INTEGER) MYSQL: SELECT CAST(\"123\" AS SIGNEDINTEGER) as value; SIGNED INTEGER:带符号的整形写法不同: ORACLE:select SYSDATE value from dual SYSDATEnow() / SYSDATE() MYSQL:select now() valueselect sysdate() value函数名称不同: ORACLE: SELECT Next_day(sysdate,7) valueFROM DUAL ⾃定义⼀个函MYSQL: SELECT Next_day(sysdate,7) 数:F_COMMON_NEXT_DAY(date,int)F_COMMON_NEXT_DAY(SYSDATE(), 3) value from DUAL; (3:指星期的索引值)返回的指定的紧接着下⼀个星期的⽇期函数名称不同: ORACLE: SELECT ADD_MONTHS(sysdate, 2) DATE_ADD(sysdate(), interval 2 ADD_MONTHS(sysdate, 2)as value from DUAL; month) MYSQL: SELECT DATE_ADD(sysdate(),interval 2 month) as value from DUAL;功能: 返回两个⽇期之间的天数。⽤法: mysql: SELECT DATEDIFF('2008-12-30','2008-2个⽇期相减(D1-D2)DATEDIFF(date1,date2) 12-29') AS DiffDate oracle: 直接⽤两个⽇期相减(⽐如d1-d2=12.3) Oracle内置函数SQLCODE和SQLERRM是特别 MYSQL中没有对应的函数,但JAVA⽤在OTHERS处理器中,分别⽤来返回Oracle的 SQLCODE中SQLException。getErrorCode()函错误代码和错误消息。 数可以获取错误号MYSQL: 可以从JAVA中得到错误代码,错误状 态和错误消息 Oracle内置函数SQLCODE和SQLERRM是特别 MYSQL中没有对应的函数,但JAVA⽤在OTHERS处理器中,分别⽤来返回Oracle的 SQLERRM中SQLException。getMessage()函数错误代码和错误消息。 可以获取错误消息MYSQL: 可以从JAVA中得到错误代码,错误状 态和错误消息 在MYSQL中是⾃动增长列. 如下⽅法获取最新ID: START TRANSACTION; INSERT INTO user(username,password) SEQ_BK_DTL_OPT_INT_KEY.NEXTVAL⾃动增长列 VALUES (username,MD5(password)); SELECT LAST_INSERT_ID() INTO id; COMMIT;⼀样: 30SUM(enable_flag)SUM(enable_flag) 31 在MYSQL中⽆相应的⽅法,其作⽤是 dbms_output.put_line每⾏只能显⽰255个字符, DBMS_OUTPUT.PUT_LINE(SQLCODE)在控制台中打印,⽤于测试,对迁移 超过了就会报错 ⽆影响。 ORCALE: SELECT SUM(enable_flag) FROMSD_USR; MYSQL: SELECT SUM(enable_flag) FROMSD_USR; 循环语句编号类别 ORACLE MYSQL 注释 1. mysql和oracle除了关键字有⼀个字差别外(ELSEIF/ELSIF),if语句使⽤起来完全相同. 2. mysql if语句语法: 摘⾃ MySQL 5.1 参考⼿册 20.2.12.1. IF语句 IF search_condition THEN statement_list [ELSEIF search_condition THEN statement_list] ... [ELSE statement_list]END IF IF实现了⼀个基本的条件构造。如果search_condition求值为真,相应的SQL语句列表被执⾏。如果没有 search_condition匹配,在ELSE⼦句⾥的语句列表被执⾏。statement_list可以包括⼀个或多个语句。 1 IF iv_weekly_day = IF iv_weekly_day ='MON'THEN'MON'THEN set ii_weekly_day = ii_weekly_day := 'MON';'MON'; IF语句使⽤不 ELSIF iv_weekly_day =ELSEIF iv_weekly_day = 同 'TUE' THEN'TUE' THEN ii_weekly_day := 'TUE'; set ii_weekly_day =END IF;'TUE'; END IF; 2 3 loopLable:LOOP IF i > (ii_role_cnt-1) THEN LEAVE looplable; FOR li_cnt IN 0.. ELSE (ii_role_cnt-1) LOOP SELECT COUNT(*) INTO SELECT COUNT(*) INTO li_role_ik_cnt FROM li_role_ik_cnt FROM SD_ROLE SD_ROLE WHERE ROLE_CD = WHERE ROLE_CD =1. oracle使⽤For语句实现循环. 'ADMIN_SUPER'; FOR语句不同lo_aas_role_upl(li_cnt); Mysql使⽤Loop语句实现循环. /*lo_aas_role_upl(li_cnt);*/ IF li_role_ik_cnt = 0 2. oracle 使⽤For…loop关键字. IF li_role_ik_cnt = 0 THEN Mysql使⽤loopLable:LOOP实现循环. THEN RETURN 'N'; RETURN 'N'; END IF; END IF; li_role_ik_cnt := -3; SET li_role_ik_cnt = -3; END LOOP; SET i = i+1; END IF; END LOOP loopLable; WHILE lv_inputstr IS NOTWHILE lv_inputstr IS NOT1. oracle 中使⽤while语句关键字为: while 表达式 loop… while语句不NULL LOOPNULL DOend loop;同...... mysql 中使⽤while语句关键字为: while 表达式 do… end END LOOP;END WHILE;while;存储过程&Function 编 类别号 ORACLEMYSQL注释 1.在创建存储过程时如果存在同名的存储过程,会删除⽼的存储过程. oracle使⽤create or replace. mysql使⽤先删除⽼的存储过程,然后再创建新的存储过程. 2. oracle 存储过程可以定义在package中,也可以定义在Procedures中. 如果定义在包中,⼀个包中可以包含多个存储过程和⽅法.如果定义在Procedures中,存储过程中不可以定义多个存储过程. Mysql 存储过程中不可以定义多个存储过程. 3. oracle中字符串类型可以使⽤varchar2. Mysql 需要使⽤varchar 4. Oracle中参数varchar长度不是必须的, create or replace procedureDROP PROCEDURE IF EXISTS 创建存储过程语句不P_ADD_FAC(`SD_USER_P_ADD_USR`;1同 id_fac_cd INcreate procedure P_ADD_FAC( ES_FAC_UNIT.FAC_CD%TYPE) is id_fac_cd varchar(100)) 2创建函数语句不同 Mysql中参数varchar长度是必须的, ⽐如varchar(100) 1.在创建函数时如果存在同名的函数,会删除⽼的函数. oracle使⽤create or replace. mysql使⽤先删除⽼的函数,然后再创建新 CREATE ORDROP FUNCTION IF EXISTS的函数.REPLACEFUNCTION`SD_ROLE_F_ROLE_FACS_GRP`;2. oracle 函数可以定义在package中,也可F_ROLE_FACS_GRP(CREATE FUNCTION以定义在Functions中. 如果定义在包中,⼀ ii_role_int_key IN`SD_ROLE_F_ROLE_FACS_GRP`(个包中可以包含多个存储过程和函数.如果SD_ROLE.ROLE_INT_KEY%TYPE ii_role_int_key INTEGER(10)定义在Functions中,每个函数只能定义⼀个 ) RETURN VARCHAR2) RETURNS varchar(1000) 函数. Mysql Functions不可以定义多个函数. 3. oracle返回值⽤return. Mysql返回值⽤returns. procedure P_ADD_FAC( create procedure P_ADD_FAC( id_fac_cd IN (in) id_fac_cd varchar(100)) ES_FAC_UNIT.FAC_CD%TYPE) 1. oracle存储过程参数可以定义为表的字段类型. Mysql存储过程不⽀持这种定义⽅法.需要定义变量的实际类型和长度. 2. oracle 参数类型in/out/inout写在参数名后⾯. Mysql 参数类型in/out/inout写在参数名前⾯. 3. oracle 参数类型in/out/inout 都必须写. Mysql 参数类型如果是in,则可以省略. 如果是out或inout则不能省略. 注意: mysql中指定参数为IN, OUT, 或INOUT 只对PROCEDURE是合法的。(FUNCTION参数总是被认为是IN参数)RETURNS字句只能对FUNCTION做指定,对函数⽽⾔这是强制的。它⽤来指定函数的返回类型,⽽且函数体必须包含⼀个RETURN value语句。 oracle可以创建包,包中可以包含多个存储过程和⽅法. mysql没有没有包这个概念,可以分别创建存储过程和⽅法. 每个存储过程或⽅法都需要放在⼀个⽂件中. 例1: ⽅法命名 oracle 中SD_FACILITY_PKG.F_SEARCH_FAC to mysql SD_FACILITY_F_SEARCH_FAC 例2: 过程命名oracle 中SD_FACILITY_PKG.P_ADD_FACto mysql SD_FACILITY_P_ADD_FAC oracle存储过程和⽅法都可以使⽤return退出当前过程和⽅法. Mysql存储过程中只能使⽤leave退出当前存储过程.不可以使⽤return. Mysql⽅法可以使⽤return退出当前⽅法. oracle : 内部异常不需要定义,在存储过程或函数末尾写上EXCEPTION后,后⾯的部分即为异常处理的部分. oracle可以定义⾃定义异常,⾃定义异常需要使⽤raise关键字抛出异常后,才可以在EXCEPTION中捕获.mysql: mysql内部异常也需要先定义,在定义的同时也需要实现异常的功能. ⽬前mysql不⽀持⾃定义异常. oracle中: 3传⼊参数写法不同 function func_name( gw_id in(out) varchar2 ) create function func_name( gw_id varchar(100)) 4包的声明⽅式 create or replace package/package 拆分成多个存储过程或函数 body package name 5 存储过程返回语句不 return; ⼀样LEAVE proc; (proc 代表最外层的begin end) DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK ; set ov_rtn_msg = concat(c_sp_name,'(', li_debug_pos,'):', TO_CHAR(SQLCODE),':',SUBSTR(SQLERRM,1,100)); END; 声明变量在begin...end体 内,begin之后其他任何内容之前 EXCEPTION WHEN OTHERS THEN ROLLBACK ; 存储过程异常处理不6 ov_rtn_msg := c_sp_name||'('||⼀样 li_debug_pos ||'):'|| TO_CHAR(SQLCODE)||':'||SUBSTR(SQLERRM,1,100);过程和函数的声明变 声明变量在begin…end体之前 量的位置不同 EXCEPTION WHEN NO_DATA_FOUND 7 THEN oi_rtn_cd := 1; NO_DATA_FOUND ov_rtn_msg :=使⽤FOUND_ROWS()代替8异常处理SD_COMMON.P_GET_MSG('DP-NO_DATA_FOUND. 详见注释. CBM-01100a-016', li_sub_rtn_cd, lv_sub_rtn_msg );9 在存储过程中调⽤存 Procedure_Name(参数); 储过程⽅式的不同 Call Procedure_Name(参数); NO_DATA_FOUND是游标的⼀个属性. 当select没有查到数据就会出现 no datafound 的异常,程序不会向下执⾏.Mysql: 没有NO_DATA_FOUND这个属性.但可是使⽤FOUND_ROWS()⽅法得到select语句查询出来的数据.如果FOUND_ROWS()得到的值为0,就进⼊异常处理逻辑. MYSQL存储过程调⽤存储过程,需要使⽤Call pro_name(参数). Oracle调⽤存储过程直接写存储过程名就可以了. 详见<<2009002-OTMPPS-Difficult Questions-0001.doc>>中2.5 Mysql异常处理部分 10抛异常的⽅式不同 触发器编号类别 RAISE Exception_Name;见备注 注释 1. Oracle使⽤create or replace trigger语法创建触发器. create or replace trigger Mysql使⽤ create trigger创建触发器.TG_ES_FAC_UNITcreate trigger2. Oracle可以在⼀个触发器触发 创建触发器语 before insert or update`hs_esbs`.`TG_INSERT_ES_FAC_UNIT` BEFOREinsert,delete,update事件. 1 句不同or delete onINSERT on `hs_esbs`.`es_fac_unit` Mysql每个触发器只⽀持⼀个事件. 也就 ES_FAC_UNITfor each row 是说,⽬前每个trigger需要拆分成3个mysql for each rowtrigger. 3. mysql trigger 不能在客户端显⽰或编辑.需要在服务器所在的机器上操作. 取得新数1. new和old记录⾏的引⽤: 触发器new和 据: :new.FAC_CD取得新数据: NEW.FAC_CD mysql是NEW.col1,OLD.col1来引⽤。 2old记录⾏的引 取得⽼数取得⽼数据: OLD.FAC_CD oracle是:NEW.col1, :OLD.col1来引⽤。 ⽤不同 据: :old.FAC_CD2. NEW 和OLD不区分⼤⼩写. ⽤户权限 ORACLEMYSQL 编号类别ORACLE 1创建⽤户 注释 1.oracle创建⽤户 Oracle 的默认⽤户有三个: sys / system / scott. 其中sys和system 是系统⽤户,拥有dba权限, scott⽤户是Oracle数据库的⼀个⽰范账户, 在数据库安装时创建, 不具备dba权限. 创建⽤户命令: Create user user_name identified by user_password [default tablespace tableSpace] [temporary tablespace tableSpace}; Create user user_name说明: CREATE USER user_name identified by user_password 每个⽤户都有⼀个默认表空间和⼀个临时表空间,如果没 IDENTIFIED BY default tablespace starSpace有指定,oracle就将system设置为默认表空间,将temp设为 user_password; temporary tablespace temp;临时表空间. 2.mysql创建⽤户 创建⽤户命令: mysql> CREATE USER yy IDENTIFIED BY '123'; yy表⽰你要建⽴的⽤户名,后⾯的123表⽰密码上⾯建⽴的⽤户可以在任何地⽅登陆。 如果要限制在固定地址登陆,⽐如localhost 登陆: mysql> CREATE USER yy@localhost IDENTIFIED BY'123';1. Oracle SQL>drop user ⽤户名; //⽤户没有建任何实体 SQL> drop user ⽤户名 CASCADE; // 将⽤户及其所建实体全部删除 注: 当前正连接的⽤户不得删除。 2. Mysql ⾃4.1.1以后,删除⼀个MYSQL帐户,可以使⽤drop MYSQL 2删除⽤户 Drop user user_namecascade; Drop user user_name; user 语句了。 不过在5.0.2之前的版本中,drop user语句只能删除没有任何权限的⽤户。 从5.0.2往后的版本中,drop user语句可以删除任何⽤户。(当然不能⾃⼰删⾃⼰)。⽰例:drop user \"garfield\"@\"localhost\"。别忘了加后⾯的@,不然会报错。 在4.1.1与5.0.2之间的版本中要删除⼀个MYSQL帐户,需要进⾏以下操作。 1) 使⽤show grants语句查看要删除的MYSQL帐户都有哪些权限,使⽤⽅法如show grants for\"garfield\"@\"localhost\"。 2) 使⽤revoke语句收回⽤户在show grants⾥拥有的权限。执⾏这个语句将删除除user表之外的其它所有权限表中的相关记录,并且收回在user表中该⽤户拥有的全局权限。 3) 使⽤drop user 语句把⽤户从user表中删除。1.mysql修改密码第⼀种⽅式: 1) 更改之前root没有密码的情况 c:\\mysql\\bin>mysqladmin -u root password\"your password\" 2) 更改之前root有密码的情况,假如为123456 c:\\mysql\\bin>mysqladmin -u root -p123456password \"your password\" 注意:更改的密码不能⽤单引号,可⽤双引号或不⽤引号 第⼆种⽅式: 1) c:\\mysql\\bin>mysql -uroot -p密码 以root⾝份登录 2) mysql>use mysql 选择数据库 3) mysql>update user set password=password('你的密码') where User='root'; 4) mysqlflush privileges; 重新加载权限表 3修改密码 alter user user_namemysqladmin -u root -pidentified by new_password123456 password \"your password\"; 5 Grant connect to star -- star⾓⾊允许⽤户连接数据库, 并创建数据库对象1. 详见< 设置⽤户权Grant resource to star -- starGRANT ALL ON picture.* TO限设置 4限⾓⾊允许⽤户使⽤数据库中的test IDENTIFIED BY \"test\";2. 详见< 存储空间. 设置Grant dba to star -- DBA权限 1. Oracle Revoke语句的基本格式如下: REVOKE 权限类型 [(字段列表)] [, 权限类型 [(字段列表)]…]ON {数据库名称.表名称}FROM ⽤户名@域名或IP地址 例如,管理员撤销⽤户admin@localhost对数据库xsxk所拥有的创建、创建数据库及表的权限,并撤销该⽤户可以把⾃⼰所拥有的权限授予其他⽤户的权限,可使⽤以下命令。 mysql>revoke create,drop on xsxk.* fromadmin@localhost; mysql>revoke grant option on xsxk.* fromadmin@localhost; revoke语句中的“⽤户名@域名或IP地址”部分必须匹配原来grant语句中的“⽤户名@域名或IP地址”部分,⽽“权限类型”部分可以是所授权的⼀部分权限。⽽且,revoke只 REVOKE privilegesRevoke select, update on能撤销权限,不能删除⽤户账户,在授权表user中仍保(columns) ON what FROM留该⽤户的记录;⽤户仍可以连接到数据库服务器。如回收权限product from user02; user果要完全删除⽤户,则使⽤前⾯提到的delete语句从user 表中删除该⽤户记录。 2. Mysql 要取消⼀个⽤户的权限,使⽤REVOKE语句。REVOKE的语法⾮常类似于GRANT语句,除了TO⽤FROM取代并且没有INDETIFED BY和WITH GRANT OPTION⼦句: REVOKE privileges (columns) ON what FROM user user部分必须匹配原来GRANT语句的你想撤权的⽤户的user部分。privileges部分不需匹配,你可以⽤GRANT语句授权,然后⽤REVOKE语句只撤销部分权限。 REVOKE语句只删除权限,⽽不删除⽤户。即使你撤销了所有权限,在user表中的⽤户记录依然保留,这意味着⽤户仍然可以连接服务器。要完全删除⼀个⽤户,你必须⽤⼀条Delete语句明确从user表中删除⽤户记录 其它编 类别号 ORACLE MYSQL 注释 1 1、 select a.*, b.*, c.*, d.* from a, b, c, d where a.id = b.id and a.name is not null and a.id = c.id(+) and a.id = d.id(+) \"(+)\"所在位置的另⼀侧为连接的⽅向, 内连接的更改所以上⾯的例⼦1是左连接。 以下的例⼦2既是右连接。 2、 select a.*, b.*, c.*, d.* from a, b, c, d where a.id = b.id and a.name is not null and a.id(+) = c.id ⽅法⼀ select a.*, c.*, d.* from a left join(c, d) on (a.id = c.id and a.id = d.id), b where a.id = b.id and a.name is not null⽅法⼆ select a.*, c.*, d.* from a left join c on a.id = c.id left join d on a.id = d.id, b where a.id = b.id and a.name is not null oracle sql语句和mysql sql语句有⼀定的区别. 1. oracle左连接,右连接可以使⽤(+)来实现. Mysql只能使⽤left join ,right join等关键字. 2 最后⼀句执⾏的sql statement所SQL%ROWCOUNT取得或 影响的条数 执⾏select语句后⽤: FOUND_ROWS()执⾏update delete insert语句后⽤: ROW_COUNT(). oracle中: sql 表⽰最后⼀句执⾏的 SQL Statement, rowcount表⽰該 SQL 所取得或影响的条数.Mysql中: 执⾏select语句后查询所影响的条数⽤:FOUND_ROWS() 执⾏update delete insert语句后查询所影响的条数⽤: ROW_COUNT() 3查询分页 4java null值 ⽅法:使⽤循环变量替换oracle中ROWNUM SELECT t1.* set @mycnt = 0; FROM SELECT (@mycnt := @mycnt + 1) as (SELECT MSG_INT_KEY, ROW_NUM,t1.* MSG_TY, FROM MSG_CD, (SELECT MSG_INT_KEY, ROWNUM ROW_NUM MSG_TY, MSG_CD, ROWNUM FROM SD_SYS_MSG ROW_NUM WHERE (ii_msg_int_key IS NULL FROM SD_SYS_MSG OR msg_int_key = ii_msg_int_key) WHERE (ii_msg_int_key IS NULL OR ORDER BY MSG_CD msg_int_key = ii_msg_int_key ) ) t1 ORDER BY MSG_CD WHERE (in_page_no IS NULL) ) t1 OR (t1.ROW_NUM > WHERE (in_page_no IS NULL) ((in_page_no -1)*li_per_page_amt) OR (t1.ROW_NUM> AND t1.ROW_NUM < ((in_page_no - 1) * li_per_page_amt) (in_page_no*li_per_page_amt + 1) AND t1.ROW_NUM < ); (in_page_no * li_per_page_amt + 1) ); 现在java代码需要修改: \"\"作为参数传⼊后,在oracle中将识别 \"\"作为参数据传mysql还是\"\"inPara.add(MSG_TY.equals(\"\") ? null : 为null MSG_TY); 1. oracle可以将动态sql放在游标中执 set @a = iv_cd_field_name;⾏. set @b = iv_table_name; mysql游标声明有⼀定的局限性: set @c = IFNULL(iv_where_cause,' 1=1mysql游标必须在声明处理程序之前被 lv_sql := 'SELECT ' ||' distinct ' ||');声明,并且变量和条件必须在声明光标iv_cd_field_name || ' FIELD1 '||或处理程序之前被声明。Mysql采⽤ 5执⾏动态sql ' FROM ' || iv_table_name || SET @s = concat('SELECT distinct ', @aPrepared Statements实现动态sql. 例⼦ ' WHERE ' || NVL(iv_where_cause,', ' FIELD1 FROM ' , @b ,如下:1=1 '); ' WHERE ' , IFNULL(@c,' 1=1 '));INT Emp_id_var = 56 PREPARE SQLSA OPEN l_sys_cur FOR lv_sql; PREPARE stmt3 FROM @s;FROM \"DELETE FROM employee EXECUTE stmt3;WHERE emp_id=?\" ; EXECUTE SQLSA USING DEALLOCATE PREPARE stmt3;:Emp_id_var ; 6 使⽤数组步骤: 1. 将传⼊的字符串通 过P_UNPACK_LIST⽅法转换为数组.(lo_holiday_jan_upl即为数组) P_UNPACK_LIST(iv_jan__str, mysql中数⽤数组步骤: lv_delimiter, lo_holiday_jan_upl); 1. 将需要处理的字符串交给执⾏业务逻辑 2. 传数组到另⼀个存储过程. 的存储过程处理. P_MOD_MONTH(iv_year, 1, CALL lo_holiday_jan_upl, iv_user_cd); SD_HOLIDAY_P_MOD_MONTH(iv_year, 3. P_MOD_MONTH中使⽤数组: (将数 1, iv_jan__str, iv_user_cd); 组中的各个元素取出来插⼊ 2. SD_HOLIDAY_P_MOD_MONTH中处 到SD_HOLIDAY表) 理字符串. (将字符串按⾃定格式分隔出 存储过程相互调⽤时传递数组解决⽅FOR li_cnt IN 0 .. 9 LOOP 来,在对每个⼩字符串进⾏业务逻辑处理.) 法: IF iv_daystr(li_cnt) IS NOT NULL SET lv_inputstr = iv_inputstr; oracle中传⼊12个字符串到存储过程,THEN loopLable:LOOP 然后将这12个字符串转换为12个数组, INSERT INTO SD_HOLIDAY IF li_cnt > 9 THEN 再调⽤其他存储过程并将这12个数组分 (HOLIDAY_INT_KEY, LEAVE looplable; 别传给存储过程,便利每个数组进⾏业务 YEAR, ELSE 存储过程相互 MONTH,逻辑处理. SET li_pos = INSTR(lv_inputstr, 调⽤时传递数 DAY, mysql解决⽅法: 将存储过程中的数组 iv_delimiter); 组去掉,两个存储过程调⽤时直接传递字符 ENABLE_FLAG, IF li_pos = 0 THEN 串,然后再需要处理业务逻辑的地⽅将字 CREATE_BY, leave looplable; 符串分解,进⾏业务逻辑处理. CREATE_DATE, ELSE LAST_UPD_BY, set temp_str = SUBSTR(lv_inputstr, 可以参考<<2009002-OTMPPS- LAST_UPD_DATE) 1, li_pos - 1); Difficult Questions-0001.doc>> 中 VALUES /*插⼊temp_str到SD_HOLIDAY表*/ 2.4.2 逐层分解字符串 INSERT INTO SD_HOLIDAY(...) (SEQ_HOLIDAY_INT_KEY.NEXTVAL, SET lv_inputstr = iv_year, SUBSTRING(lv_inputstr, li_pos + iv_month, LENGTH(iv_delimiter)); iv_daystr(li_cnt), END IF; 1, SET li_cnt = li_cnt+1; iv_user_cd, END IF; ld_sys_date, END LOOP loopLable; iv_user_cd, ld_sys_date); END IF; END LOOP; select fac_unit_key FILED1在mysql中要 Java⽆法以 select fac_unit_key FILED1在oracle可改 String来接取CAST(intvalue A 以select CAST(fac_unit_key AS CHAR) int FILED1 7 因篇幅问题不能全部显示,请点此查看更多更全内容