본문 바로가기

카테고리 없음

ORACLE & MariaDB SQL Comparison No.1 v1.0

ORACLE & MariaDB Data Manipulation Statements Comparison No.1 v1.0

 

Date

Ver

Etc.

 13.06.12

1.0 

 

 

 

 

 

 

 

 

 

1.    SQL Comparison Overview

 

 

 

ORACLE

MariaDB

SQL

UNION ALL, UNION

지원

지원

ROLLUP

GROUP BY ROLLUP()

GROUP BY WITH ROLL UP

부분범위처리 (페이징)

ROWNUM

LIMIT

출력저장

SPOOL

INTO

DELETE

ERROR 에 대한 처리

비지원

IGNORE

INSERT

DEFAULT 값 없는 NOT NULL 컬럼의 INSERT VALUE 누락

허용하지 않음

허용 (strict mode 가 아닐 때)

values column 사용

허용하지 않음

허용

HINT

조인순서를 강제함

ordered, leading

straight_join

INDEX

index, no_index

use index (index_list)

BIND VARIABLE

 

지원 ( :variable_name )

지원 ( @variable_name )

 

2.    Comparison List

l  SELECT syntax

l  Join Syntax

l  Delete syntax

l  Insert syntax

l  Replace syntax

l  UPDATE syntax

l  Declaring Variables

 

여기서는 위 대상에 대해 진행하였다.

 

3.    SELECT syntax

SELECT 구문은 ORACLE 과 동일하다.

다만 구문과 같이 사용되는 옵션이 다르다.

 

ALL | DISTINCT | DISTINCTROW

 

위 옵션들은 중복되는 값에 대한 처리를 컨트롤한다.

ALL default 옵션으로 중복되는 값을 전부 리턴한다.

 

DISTINCT ORACLE 과 마찬가지 기능을 한다.

DISTINCTROW DISTINCT SYNONYM 이다.

 

HIGH_PRIORITY

 

SELECT HIGH_PRIORITY

 

SELECT UPDATE 보다 더 높은 권한을 부여한다. 테이블에 대해 UPDATE 를 위해 대기중인 UPDATE

데이터를 읽기 위한 SELECT HIGH_PRIORITY 가 있을 때 SELECT 가 우선 수행된다.

이 옵션은 테이블 레벨 락킹에만 적용된다. (영향받는 스토리지엔진 : MyISAM, MEMORY, MERGE)

 

STRAIGHT_JOIN

 

FROM 절에 나열된 테이블을 순차적으로 엑세스 하도록 강제한다.

ORACLE HINT ORDERED 와 동일한 기능을 한다.

 

SQL_CACHE | SQL_NO_CACHE | SQL_CALC_FOUND_ROWS

 

SQL_CACHE SQL_NO_CACHE SQL 수행 결과를 캐싱 할 지 컨트롤한다.

 

이 값은 query_cache_type variable 에 영향을 받으며 default 값은 1이다.

이 경우 SELECT SQL_NO_CACHE 를 제외하고 캐싱 할 수 있는 모든 값을 캐싱한다.

 

SQL_CALC_FOUND_ROWS MariaDB 에서 지원하나?

 

WITH ROLLUP

 

ORACLE ROLLUP 과 동일하다.

 

MariaDB

 

MariaDB [test]> select id2, sum(id1) from test3 group by id2 with rollup;

+------+----------+

| id2  | sum(id1) |

+------+----------+

|    2 |        2 |

|    3 |        1 |

| NULL |        3 |

+------+----------+

3 rows in set (0.00 sec)

 

 

ORACLE

 

18:53:50 TEST2@TEST2>select id2, sum(id1) from test3 group by rollup(id2);

 

       ID2   SUM(ID1)

---------- ----------

         2          2

         3          1

                    3

 

Elapsed: 00:00:00.00

 

 

LIMIT

 

결과를 제한한다.

페이징할 때 주로 사용된다.

오라클의 ROWNUM 역할을 하지만 사용은 더 간단하다.

 

SELECT FROM WHERE GROUP ORDER HAVING LIMIT 순서로 오며,

LIMIT {[offset,] row_count | row_count OFFSET offset}] 로 사용된다.

 

보통 LIMIT rowcount, LIMIT offset row_count 형태로 많이 사용하며,

인자가 하나만 쓰인 겨우 몇 개를 리턴할 것인가의 의미이며,

인자가 두개 쓰인 경우는 ‘offset’ 번째의 결과에서 ‘row_count’ 개수만큼 결과를 리턴하란 의미이다.

 

LIMIT 3,2 4번째 결과부터 2건을 출력하란 의미가 된다.

offset position 0부터 시작으로 0은 첫번째 값을 의미한다.

 

 

MariaDB [test]> select * from test1;

+-----+

| id1 |

+-----+

|   1 |

|   2 |

|   3 |

|   4 |

|   5 |

+-----+

5 rows in set (0.00 sec)

 

MariaDB [test]> select * from test1 limit 2,2;

+-----+

| id1 |

+-----+

|   3 |

|   4 |

+-----+

2 rows in set (0.00 sec)

 

 

PROCEDURE

 

SELECT FROM WHERE GROUP ORDER HAVING LIMIT PROCEDURE procedure_name

SELECT ~ LIMIT 에서 얻어진 결과셋을 재처리하기 위해 PROCEDURE 를 호출한다.

 

INTO

 

SELECT FROM WHERE GROUP ORDER HAVING LIMIT INTO {var_list | OUTFILE | DUMPFILE}

SELECT INTO {var_list | OUTFILE | DUMPFILE} FROM WHERE GROUP ORDER HAVING LIMIT

 

 

위와 같은 형태로 쓰인다.

INTO 는 결과셋을 어떻게 로컬 파일시스템에 처리(저장) 할 지에 대한 절이며 개략적인 정보는 다음과 같다.

 

l  var_list : variable 에 저장

l  OUTFILE : OUTFILE file_name’ 형태로 쓰며 결과를 파일 시스템에 저장한다.

더불어 사용자가 컬럼 구분자와 row terminator 를 지정할 수 있다.

가장 많이 사용하는 기능이다.

l  DUMPFILE : 파일에 아무 포맷팅 없이 하나의 ROW 를 저장한다.

 

INTO 는 기본적으로 로컬 파일 시스템에 대해 사용가능하며 원격지에 결과를 내려야 하는 경우는 mysql client 가 있는 상황에서

mysql e SELECT … “ > file_name

방법으로 저장할 수 있다.

 

INTO OUTFILE [CHARACTER SET charset_name] 형태로도 사용가능하다.

이는 저장할 파일의 캐릭터셋을 지정하며, 생략시 binary character set 으로 지정된다.

 

n  outfile1.txt 쿼리원문

 

select id1, id2

into outfile /oracle/log/maria/outfile1.txt

from test3;

 

n  outfile2.txt 쿼리원문

select id1, id2

into outfile /oracle/log/maria/outfile2.txt

fields terminated by /

optionally enclosed by ‘”’

lines terminated by \n

from test3;

 

devaspdb@/oracle/log/maria>cat outfile1.txt

1       2

1       3

1       2

devaspdb@/oracle/log/maria>cat outfile2.txt

1/2

1/3

1/2

 

 

FOR UPDATE | LOCK IN SHARE MODE

 

SELECT FROM WHERE GROUP ORDER HAVING LIMIT FOR UPDATE | LOCK IN SHARE MODE

 

Page row locks 을 사용하는 storage engine FOR UPDATE 를 사용하면, 쿼리에 의해 처리되는 rows

write locked Transaction 의 종료까지 획득한다.

 

LOCK IN SHARE MODE 는 쿼리에 의해 처리된 rows 에 대해 shared lock 을 획득하고 다른 트랜잭션이

읽을 수는 있지만 UPDATE DELETE 하지 못한다.

 

4.    Join Syntax

 

table_references:

    escaped_table_reference [, escaped_table_reference] ...

 

escaped_table_reference:

    table_reference

  | { OJ table_reference }

 

table_reference:

    table_factor

  | join_table

 

table_factor:

    tbl_name [[AS] alias] [index_hint_list]

  | table_subquery [AS] alias

  | ( table_references )

 

join_table:

    table_reference [INNER | CROSS] JOIN table_factor [join_condition]

  | table_reference STRAIGHT_JOIN table_factor

  | table_reference STRAIGHT_JOIN table_factor ON conditional_expr

  | table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_condition

  | table_reference NATURAL [{LEFT|RIGHT} [OUTER]] JOIN table_factor

 

join_condition:

    ON conditional_expr

  | USING (column_list)

 

index_hint_list:

    index_hint [, index_hint] ...

 

index_hint:

    USE {INDEX|KEY}

      [FOR {JOIN|ORDER BY|GROUP BY}] ([index_list])

  | IGNORE {INDEX|KEY}

      [FOR {JOIN|ORDER BY|GROUP BY}] (index_list)

  | FORCE {INDEX|KEY}

      [FOR {JOIN|ORDER BY|GROUP BY}] (index_list)

 

index_list:

    index_name [, index_name] ...

 

Ref.B 에서 발췌

 

l  index_hint_list

 

FROM (table_name) (table_alias) USE | IGNORE | FORCE {INDEX | KEY} (index_list) 형태로 사용한다.

 

USE 는 해당 인덱스를 사용하라는 정도이며, FORCE 는 사용을 강제한다.

possible keys 에 한해서 강제할 수 있다.

IGNORE 는 해당 키를 사용하지 말라는 뜻인나 강제하는지는 알 수 없다.  /*+ 테스트로 확인 */

 

MariaDB [test]> explain

    -> select t1.id1, t3.id2

    -> from test1 t1 straight_join test3 t3

    -> on t1.id1 = t3.id1;

+------+-------------+-------+-------+---------------+---------+---------+------+------+-------------------------------------------------+

| id   | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra                                           |

+------+-------------+-------+-------+---------------+---------+---------+------+------+-------------------------------------------------+

|    1 | SIMPLE      | t1    | index | PRIMARY       | PRIMARY | 4       | NULL |    5 | Using index                                     |

|    1 | SIMPLE      | t3    | ALL   | test3_ix2     | NULL    | NULL    | NULL |    3 | Using where; Using join buffer (flat, BNL join) |

+------+-------------+-------+-------+---------------+---------+---------+------+------+-------------------------------------------------+

2 rows in set (0.00 sec)

 

MariaDB [test]> explain

    -> select t1.id1, t3.id2

    -> from test1 t1 straight_join test3 t3 force index (test3_ix2)

    -> on t1.id1 = t3.id1;

+------+-------------+-------+-------+---------------+-----------+---------+-------------+------+-------------+

| id   | select_type | table | type  | possible_keys | key       | key_len | ref         | rows | Extra       |

+------+-------------+-------+-------+---------------+-----------+---------+-------------+------+-------------+

|    1 | SIMPLE      | t1    | index | PRIMARY       | PRIMARY   | 4       | NULL        |    5 | Using index |

|    1 | SIMPLE      | t3    | ref   | test3_ix2     | test3_ix2 | 5       | test.t1.id1 |    1 |             |

+------+-------------+-------+-------+---------------+-----------+---------+-------------+------+-------------+

2 rows in set (0.00 sec)

 

l  INNER | CROSS JOIN

MySQL 에서 INNER JOIN, CROSS JOIN, JOIN 모두 같다.

 

l  STRAIGHT_JOIN

Join 의 테이블의 엑세스 순서를 고정한다. (A) STRAIGHT_JOIN (B) 와 같이 기술하면,

(A)  를 먼저 엑세스 한 다음 (B) 를 엑세스 한다.

위와 같이 FROM 절에 기술하는 방법이 있고, SELECT STRAIGHT_JOIN … 으로 기술하는 방법이 있다.

FROM 절에 기술한 경우는 STRAIGHT_JOIN 의 대상이 되는 두 테이블에 한정적이지만,

SELECT 다음에 사용한 경우 FROM 절에 순서대로 엑세스 한다.

 

l  {LEFT |RIGHT } [OUTER] JOIN

일반적으로 알고 있는 ANSI LEFT OUTER JOIN, RIGHT OUTER JOIN 이다.

 

l  NATURAL [{LEFT|RIGHT} [OUTER]] JOIN

equi-join (Inner join, join) 의 특수한 케이스이다.

NATURAL JOIN 을 쓰는 경우 ON, USING 을 사용하지 못한다.

 

NATURAL JOIN 의 두 대상 테이블에 대해 공통의 컬럼을 조인컬럼으로 사용하게 된다.

공통 컬럼이 없는 경우 카티션 곱이 일어난다.

 

l  USING (column_list)

조인에 사용할 컬럼이 모든 테이블에 존재해야 하며, ON 과 함께 사용하지 못한다.

 

사용은 다음과 같이 하며 모두 같은 결과를 반환한다.

n  select test1.id1 from test1 join test2 on test1.id1 = test2.id1;

n  select test1.id1 from test1 join test2 using (id1);

 

5.    DELETE Syntax

DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name

    [WHERE where_condition]

    [ORDER BY ...]

    [LIMIT row_count]

Multiple-table syntax:

 

DELETE [LOW_PRIORITY] [QUICK] [IGNORE]

    tbl_name[.*] [, tbl_name[.*]] ...

    FROM table_references

    [WHERE where_condition]

Or:

 

DELETE [LOW_PRIORITY] [QUICK] [IGNORE]

    FROM tbl_name[.*] [, tbl_name[.*]] ...

    USING table_references

    [WHERE where_condition]

 

ORACLE 과 대비되는 DELETE Syntax LOW_PRIORITY, QUICK, IGNORE 이다.

 

n  LOW_PRIORITY : TABLE-LOCKING 을 쓰는 Storage Engine 에서 적용된다.

 이 옵션을 사용하는 경우 타겟이 되는 테이블을 읽으려는 세션이 없을 때까지 수행이 미뤄진다.

n  QUICK : MyISM 에서만 사용가능한 옵션으로 DELETE 와중에 INDEX LEAVES MERGE 하지 않는다.

이 옵션을 사용하여 delete 수행을 빠르게 할 수도 있다.

n  IGNORE : Deleting rows 과정중에 발생하는 모든 에러를 무시한다. (파싱단계에 발생하는 에러도 무시 됨)

IGNORE 옵션의 사용으로 무시되는 error warning 으로 반환된다.

 

위 옵션을 제외하고 기본적으로 ORACLE 과 동일하게 사용되지만, 예외적인 부분으로

DELETE 의 타겟이 되는 테이블의 서브쿼리에 타겟 테이블을 또 지정하게 되면 DELETE 는 실패한다.

 

다시 말하면 DELETE FROM A WHERE A.B = (SELECT B FROM A ) 는 실패한다.

간단한 테스트로 보면 다음과 같다.

 

MariaDB [test]> delete from test1 where id1 = (select max(id1) from test1);

ERROR 1093 (HY000): You can't specify target table 'test1' for update in FROM clause

 

17:22:43 TEST2@TEST2>delete from test1 where id1 = (select max(id1) from test1);

 

1 row deleted.

 

DELETE FROM LIMIT row_count 의 사용은 Replication Master-Slave 간에 동기화가 깨질 위험,

혹은 데이터가 달라질 위험성이 있어 사용이 권장되지 않는다. 흔히 ORDER BY 와 같이 사용하는 케이스가

있다.

 

6.    INSERT Syntax

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]

    [INTO] tbl_name [(col_name,...)]

    {VALUES | VALUE} ({expr | DEFAULT},...),(...),...

    [ ON DUPLICATE KEY UPDATE

      col_name=expr

        [, col_name=expr] ... ]

Or:

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]

    [INTO] tbl_name

    SET col_name={expr | DEFAULT}, ...

    [ ON DUPLICATE KEY UPDATE

      col_name=expr

        [, col_name=expr] ... ]

Or:

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]

    [INTO] tbl_name [(col_name,...)]

    SELECT ...

    [ ON DUPLICATE KEY UPDATE

      col_name=expr

        [, col_name=expr] ... ]

 

ORACLE 과 차이나는 MariaDB INSERT 동작은 다음과 같다.

 

Strict SQL mode 에서 수행하지 않는 경우 컬럼에 대해 주어지지 않은 값은 그 컬럼의 default 값을

가져간다.

 

MariaDB [test]> insert into test6(id1) values(4);

Query OK, 1 row affected, 1 warning (0.01 sec)

 

MariaDB [test]> show warnings;

+---------+------+------------------------------------------+

| Level   | Code | Message                                  |

+---------+------+------------------------------------------+

| Warning | 1364 | Field 'id2' doesn't have a default value |

+---------+------+------------------------------------------+

1 row in set (0.00 sec)

 

MariaDB [test]> select * from test6;

+------+-----+

| id1  | id2 |

+------+-----+

|    4 |   0 |

+------+-----+

1 row in set (0.00 sec)

 

위 결과를 보면 id2 에 대해 not null 제약조건이 있고 insert 시 이 컬럼에 대한 값을 넣지 않았다.

그럼에도 불구하고 insert 를 성공했다. 다만 이 과정에서 Warning 이 발생했고 id2 에 대해 default value 가 없다는

이야기를 하고 있다.

 

test6 를 조회해 본 결과 사용자가 의도하지 않은 id2=0 이란 값이 들어가 있다.

int data type 에 대해 MariaDB 가 할당하는 default value 0 이라는 걸 알 수 있다.

 

sql_mode strict 로 변경하고 위 INSERT Operation 을 다시 수행하면 다음과 같이 에러를 얻는다.

 

MariaDB [test]> show variables like '%sql_mode%';

+---------------+-------------------+

| Variable_name | Value             |

+---------------+-------------------+

| sql_mode      | STRICT_ALL_TABLES |

+---------------+-------------------+

1 row in set (0.00 sec)

 

MariaDB [test]> insert into test6(id1) values(4);

ERROR 1364 (HY000): Field 'id2' doesn't have a default value

 

참고로 sql_mode defulat 값은 ‘ ‘  이며, 이는 default 값이 없는 not null 제약 조건 컬럼에 대해

INSERT 시 누락되더라도 해당 오퍼레이션을 성공한다.

 

MariaDB 에서는 insert value 항목에 column 을 사용할 수 있다.

오라클은 지원하지 않는다.

 

MariaDB [test]> insert into test3 values (3, id1*2);

Query OK, 1 row affected (0.00 sec)

 

MariaDB [test]> select * from test3;

+------+------+

| id1  | id2  |

+------+------+

|    1 |    2 |

|    1 |    3 |

|    1 |    2 |

|    2 |    3 |

|    3 |    6 |

+------+------+

5 rows in set (0.00 sec)

 

MariaDB [test]> insert into test3 values (id2*3, 3);

Query OK, 1 row affected (0.00 sec)

 

MariaDB [test]> select * from test3;

+------+------+

| id1  | id2  |

+------+------+

|    1 |    2 |

|    1 |    3 |

|    1 |    2 |

|    2 |    3 |

|    3 |    6 |

| NULL |    3 |

+------+------+

 

위 결과의 두 번째 INSERT 구문을 보면 values (id2 * 3, 3) 과 같이 사용했다.

첫 번째와 달리 컬럼이 앞선 케이스고 Ref.D 에서는

But the following is not legal, because the value for col1 refers to col2, which is assigned after col1

이라는 이야기를 하고 있다.

첫 번째 컬럼에 대해 컬럼을 사용했는데 해당하는 컬럼에 대해 참조할 수 있는 값이 없다, 순서가 잘못되었다란

이야기를 하고 있다.

 

/*+ MySQL 에서는 위 상황에 어떤 동작을 하는지 추가 확인해야겠지만 */ MariaDB 에서는

에러없이 수행되며 참조될 컬럼의 값이 미확정 된 시점이기에 NULL 값을 얻었다.

 

또 다음과 같이 INSERT 할 수 있다.

 

insert into test1 values(6),(7),(8);

 

또 다른 특징으로 데이터 길이를 넘는 경우 넘치는 만큼 데이터를 잘라 INSERT 한다.

 

MariaDB [test]> create table test7(id1 tinyint(3), id2 char(3));

Query OK, 0 rows affected (0.00 sec)

 

MariaDB [test]> insert into test7 values (1234,'abcd');

Query OK, 1 row affected, 2 warnings (0.00 sec)

 

MariaDB [test]> show warnings;

+---------+------+----------------------------------------------+

| Level   | Code | Message                                      |

+---------+------+----------------------------------------------+

| Warning | 1264 | Out of range value for column 'id1' at row 1 |

| Warning | 1265 | Data truncated for column 'id2' at row 1     |

+---------+------+----------------------------------------------+

2 rows in set (0.00 sec)

 

MariaDB [test]> select * from test7;

+------+------+

| id1  | id2  |

+------+------+

|  127 | abc  |

+------+------+

1 row in set (0.00 sec)

 

tinyint 의 경우 최대값이 127 이기에 해당 값이 insert 되었고,

char(3) 에 대해서는 길이를 넘는 부분이 잘려나갔다.

 

위 오퍼레이션은 strict sql_mode 에서는 실패한다.

 

INSERT 는 다음의 옵션을 지원한다.

n  LOW_PRIORITY

n  DELAYED

n  HIGH_PRIORITY

n  IGNORE

 

LOW_PRIORITY HIGH_PRIORITY TABLE LOCKING 을 사용하는 Stroage Engine 에 해당하는 이야기다.

 

LOW_PRIORITY INSERT 의 수행이 테이블을 읽는 다른 클라이언트가 없을 때 까지 연기된다.

DELAYED 의 경우 입력이 시작되면 완료까지 수행하지만 LOW_PRIORITY 는 수행을 일시중지한다.

때문에 사용이 활발한 TABLE 에 대한 INSERT LOW_PRIORITY 는 굉장히 오랜시간동안 수행될 수 있다.

 

HIGH_PRIORITY 를 사용하는 경우 이는 –low-priority-updates 기능을 오버라이드하며

이 옵션과 함께 server 를 시작했다면, concurrent insert 사용이 불가능해진다.

 

DELAYED 를 사용하면 입력되어야 할 데이터는 버퍼에 입력되고, Client 는 다른 동작을 할 수 있다.

서버는 타겟 테이블이 사용중이면 입력을 대기하고, 아니라면 insert 를 시작한다.

입력 대기는 정기적인 확인을 통해 이루어지며, 사용중이라면 테이블 사용이 자유로워질 때까지

일시중지한다.

 

IGNORE 를 사용하면 ERROR Warning 으로 취급된다.

Key 에 대해 Duplicate 된 대상을 이후 다시 조회해 보면 아무 변경이 없음을 알 수 있다.

 

MariaDB [test]> create table test8 (id1 int primary key, id2 int);

Query OK, 0 rows affected (0.00 sec)

 

MariaDB [test]> insert into test8 values (1,3);

Query OK, 1 row affected (0.00 sec)

 

MariaDB [test]> insert ignore into test8 values (1,4);

Query OK, 0 rows affected, 1 warning (0.00 sec)

 

MariaDB [test]> show warnings;

+---------+------+---------------------------------------+

| Level   | Code | Message                               |

+---------+------+---------------------------------------+

| Warning | 1062 | Duplicate entry '1' for key 'PRIMARY' |

+---------+------+---------------------------------------+

1 row in set (0.00 sec)

 

MariaDB [test]> select * from test8;

+-----+------+

| id1 | id2  |

+-----+------+

|   1 |    3 |

+-----+------+

1 row in set (0.00 sec)

 

IGNORE 의 활용은 적합한 파티션이 없는 partitioned-table 에 대해서도 활용할 수 있다.

적합한 파티션이 없는 경우 일반적으로 에러와 함께 abort 되겠지만, IGNORE 를 사용하면 문제되는

rows 에 대해서만 조용히 Warning 처리되고 다른 rows 는 정상처리 된다.

 

ON DUPLICATE KEY UPDATE 는 중첩되는 키가 있는 경우 에러없이 처리하기 위한 방법이다.

중첩되는 키가 문제가 되는 케이스이기에 키를 업데이트 하게 된다.

 

다만 중첩되는 키가 발견되어 업데이트 한 결과물이 또 다른 키와 중첩되는 연쇄적인 상황에 대해서는

에러가 발생한다.

 

MariaDB [test]> select * from test8;

+-----+------+

| id1 | id2  |

+-----+------+

|   1 |    4 |

|   2 |    3 |

+-----+------+

2 rows in set (0.00 sec)

 

MariaDB [test]> insert into test8 values(1,4) on duplicate key update id1= id1 + 1;

ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'

MariaDB [test]> insert into test8 values(2,5) on duplicate key update id1= id1 + 1;

Query OK, 2 rows affected (0.00 sec)

 

MariaDB [test]> select * from test8;

+-----+------+

| id1 | id2  |

+-----+------+

|   1 |    4 |

|   3 |    3 |

+-----+------+

2 rows in set (0.00 sec)

 

MariaDB [test]> insert into test8 values(2,5) on duplicate key update id1= id1 + 1;

Query OK, 1 row affected (0.00 sec)

 

MariaDB [test]> select * from test8;

+-----+------+

| id1 | id2  |

+-----+------+

|   1 |    4 |

|   2 |    5 |

|   3 |    3 |

+-----+------+

3 rows in set (0.00 sec)

 

7.    REPLACE Syntax

REPLACE [LOW_PRIORITY | DELAYED]

    [INTO] tbl_name [(col_name,...)]

    {VALUES | VALUE} ({expr | DEFAULT},...),(...),...

Or:

REPLACE [LOW_PRIORITY | DELAYED]

    [INTO] tbl_name

    SET col_name={expr | DEFAULT}, ...

Or:

REPLACE [LOW_PRIORITY | DELAYED]

    [INTO] tbl_name [(col_name,...)]

    SELECT ...

 

REPLACE 는 기본적으로 INSERT 와 동일한 기능을 한다.

차이는 INSERT IGNORE 의 경우 Duplicated row 에 대해 Warning 을 남기고 변경하지 않지만,

REPLACE 의 경우 Duplicated row non-key columns value update 하고,

중첩되지 않는 Key value insert 한다.

 

결과적으로 INSERT 와 다른 점은 키가 중첩된 row 에 대한 처리방법이 다르다.

 

MariaDB [test]> select * from test8;

+-----+------+

| id1 | id2  |

+-----+------+

|   1 |    4 |

|   2 |    5 |

|   3 |    3 |

+-----+------+

3 rows in set (0.00 sec)

 

MariaDB [test]>     

MariaDB [test]> replace into test8 values(3,6);

Query OK, 2 rows affected (0.00 sec)

 

MariaDB [test]> select * from test8;

+-----+------+

| id1 | id2  |

+-----+------+

|   1 |    4 |

|   2 |    5 |

|   3 |    6 |

+-----+------+

3 rows in set (0.00 sec)

 

8.    UPDATE syntax

UPDATE [LOW_PRIORITY] [IGNORE] table_reference

    SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...

    [WHERE where_condition]

    [ORDER BY ...]

    [LIMIT row_count]

Multiple-table syntax:

UPDATE [LOW_PRIORITY] [IGNORE] table_references

    SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...

    [WHERE where_condition]

 

ORACLE 과 다른 특이점은 없다.

LOW_PRIORITY, IGNORE INSERT, UPDATE 옵션과 동일하다.

IGNORE 의 경우 UPDATE 의 결과로 Duplicated key 상태가 되는 ros update 하지 않으며,

Update 로 인해 data conversion 이 일어나는 경우 가장 가까운 유효한 값으로 변환된다.

 

9.    Declaring variables on MariaDB & ORACLE

n  ORACLE

 

11:42:46 TEST2@TEST2>var tmp number

11:42:59 TEST2@TEST2>exec :tmp := 30;

 

PL/SQL procedure successfully completed.

 

Elapsed: 00:00:00.00

11:43:11 TEST2@TEST2>select :tmp from dual;

 

      :TMP

----------

        30

 

Elapsed: 00:00:00.01

 

n  MariaDB

 

MariaDB [test]> select 30 into @tmp from dual;

Query OK, 1 row affected (0.00 sec)

 

MariaDB [test]> select @tmp;

+------+

| @tmp |

+------+

|   30 |

+------+

1 row in set (0.00 sec)

 

MariaDB [test]> set @hello='hi';

Query OK, 0 rows affected (0.00 sec)

 

MariaDB [test]> select @hello from dual;

+--------+

| @hello |

+--------+

| hi     |

+--------+

1 row in set (0.00 sec)

 

10. References

A.     Data Manipulation Statements | http://dev.mysql.com/doc/refman/5.5/en/sql-syntax-data-manipulation.html

B.     13.2.9.2. JOIN Syntax | http://dev.mysql.com/doc/refman/5.5/en/join.html

C.     13.2.2. DELETE Syntax | http://dev.mysql.com/doc/refman/5.5/en/delete.html

D.     13.2.5. INSERT Syntax | http://dev.mysql.com/doc/refman/5.5/en/insert.html

E.     13.2.8. REPLACE Syntax | http://dev.mysql.com/doc/refman/5.5/en/replace.html

F.     13.2.11. UPDATE Syntax | http://dev.mysql.com/doc/refman/5.6/en/update.html