DML은 비절차적 언어로써 무슨 데이터를 원하는지만 명세한다
호스트 프로그램속 삽입되어 사용되는 DML명령어들을 데이터부속어라고 한다.
PK생성
ALTER TABLE PRODUCT ADD CONSTRAINT PRODUCT_PK PRIMARY KEY (컬럼);
혹은
CONSTRAINT PRODUCT_PK PRIMAY KEY (컬럼);
문제에서는 ON과 같은 쓸모없는 문장이 있다.
ADD CONSTRAINT 만 적으면 ALTER가 없어서 안된다. >> CONSTRAINT를 작성해야한다.
SQL SERVER에서는 여러개 컬럼의 동시수정이 되질 않는다.
그렇기에 세미콜론으로 두번 작성해야한다.
ALTER TABLE A ATLER COLUMN A-A ( 타입+용량 ) ( 제약조건 );
ALTER TABLE A ALTER COLUMN A-B ( 타입+용량 ) (제약조건 );
키
유니크 : 고유값 ( null 허용 )
PK : 주키 1개만 생성가능
FK : 외래키 여러개 생성 가능
NOT NULL : 명시적으로 NULL입력방지
PK는 주키로 1개만 생성가능하다.
여러개의 속성을 묶어서 PK로 만들수는 있다.
이 경우에도 PK는 1개이다.
테이블 생성
CREATE TABLE NULL값 입력 예제
DATEA DATE NULL
DATEA DATE
둘다 가능하다.
FK의 특징
NULL값을 가질 수 있다.
테이블 생성 시 설정할 수 있다.
한 테이블에 여러개가 존재할 수 있다.
참조무결성제약을 받을 수 있다.
당연한것들이다.
컬럼을 삭제하는 구문
ALTER TABLE (TBLNM ) DROP COLUMN ( COLNM );
테이블이름 변경
RENAME (BEFTBLNM) TO (NEWTBLNM );
리네임 테이블네임 투 뉴테이블네임
fk 참조동작
삭제 : CASECADE / SET NULL / SET DEFAULT / RESTRICT / NO ACTION
삽입 : AUTOMATIC / SET NULL / SET DEFAULT / DEPENDENT / NO ACTION
FK데이터 생성 시 부모테이블에 PK가 없을 경우 자식 테이블 데이터 입력을 허용하지 않는 참조동작은 DEPENDENT다 의존적이니까.
문제 잘읽어보기
varchar2 에서
insert 시 길이만 맞으면 '' 생략가능하다.
ex)varchar2(10) == pk
values ( 1 , ect )
update _ set pk = 1 where ... )
A테이블의 PK를 B테이블의 FK로 설정할 경우
A테이블에 자료를 삽입하는건 문제가 되지 않는다.
B테이블으 자료를 삭제하는건 문제가 되 않는다.
A테이블에 없는 FK정보를 B테이블에 입지력할 수 없다.
B테이블에 연결되어 있는 정보를 A 테이블에서 삭제할 수 없다 ( 제약조건 확인 )
DROP TRUNCATE DELETE
TRUNCATE : 테이블의 구조를 유지하면서 모든 값을 삭제 ( 로그도 삭제 )
DELETE : 테이블 구조를 유지하면서 모든 값을 삭제 ( 로그는 유지 )
DROP : 테이블구조와 값 모두 삭제 ( 로그도 삭제 )
truncate : T유지L삭제
delete : T유지 L유지
drop : T삭제 L삭제
트랜잭션 격리성 문제점
Dirty read : 커밋되지 않은 데이터를 읽는 것 지저분하게;
Non-Repeatable Read : 한 트랜잭션 내에서 같은 쿼리를 두번 수행했는데 그 사이에 다른 트랜잭션이 값을 수정 또는 삭제하는 바람에 두 쿼리 결과가 다르게 나타나는 현상
Phantom read : 한 트랜잭션내에서 같은 쿼리를 두번 수행했는데 첫 쿼리에 없던 유령 레코드가 두번재 쿼리에서 나타나는 현상
Non-repeatable, dirty, phantom
BEGIN TRANSACTION으로 트랜잭션을 시작하고 COMMIT / ROLLBACK 으로 트랜잭션을 종료한다. ROLLBACK구문을 만나면 커밋 이전의 BEGIN TRANSACTION 시점까지 모두 ROLLBACK이 된다.
TO_DATE와 문자열 TO_CHAR
TO_CHAR로 DATE를 설정하고 201501 이런식으로 작성 시
201501로 시작하는 모든 값을 찾기때문에 20150101~20150131까지 검색된다. 하지만 TO_DATE('201501', 'YYYYMM') 으로 작성 시 20150101가 값이 된다.
'201501' = TO_CHAR(SVC_END_DATE, 'YYYYMM');
== 20150101~20150131의 모든 값
TO_DATE('201501', 'YYYYMM') = SVC_DEN_DATE
위의 구문은 20150101의 값을 반환한다.
내장함수
단일행/다중행 함수 모두 단일 값만을 반환한다.
1:m 관계의 두 테이블을 조인할 경우 다중/단일행 함수 모두 사용가능하다.
NULL 관련 문제들
17-1. SELECT COL2 FROM TAB WHERE COL1 = 'b'
ㄴ COL1의 b의 값은 '' 이다. SQLserver의 경우 ''와 null이 다르기때문에 출력이 된다.
17-2. SELECT COUNT(COL1) FROM TABL1 WHERE COL2 = NULL
ㄴ col2 = null의 경우 올바르지 않은 쿼리문. SQL서버/ORACLE 마찬가지
17-3. SELECT COUNT(COL2) FROM TAB1 WHERE COL1 IN ('b','c')
ㄴ b는 '' 공백문자이고 c는 3이라는 값이 있다 위와 같은 경우
오라클에서는 1이 출력되는것이 옳으나
SQL서버의 경우 '' 공백문자일 경우 2가 출력된다.
select isnull('col2','X') from tab1 wehre col1='a';
col1의 a는 null이다. 그러므로 x를 반환하는것은 옳은 답이다.
테이블 문제가 나왔을 때 공백문자와 NULL이 존재하면 위 테이블은 SQL SERVER이다.
오라클은 NULL과 공백문자를 구분하지않고 모두 NULL로 처리하기때문이다.
NULL 관련 문제들
NVL (A, B) A가 널이면 B를 반환한다.
ISNULL(A, B) A가 널이면 B를 반환한다.
NULLIF(A, B) A와 B가 같으면 NULL을 다르면 A를 반환한다.
COALESCE(A,B,C, ... ) 임의의 갯수 표현식에서 NULL이아닌 최초의 표현식을 나타내고 모든 표현식이 NULL이면 NULL을 반환한다.
NVL/ISNULL ★ NULLIF ★COALESCE
ORDER BY 문장에 대해서
sql 실행 순서에 의해 select 절 이후에 order by가 수행되기때문에 select절에 기술되지않은 컬럼으로 조회는 불가능하나 오라클은 가능하다. 하지만 서브쿼리시에는 불가능하다.
Group by를 사용할 경우 group by표현식이 아닌 값은 기술할 수 없다.
alias도 사용가능하고 컬럼순서 정수도 가능하고 두개를 혼용해서 사용도 가능하다.
서브쿼리시 기술되지않은 컬럼 불가.
group by시 그룹바이,셀렉트에 속해있지 않은 값은 불가.
alias + 컬럼순서 정수 혼용 가능.
FWGHSO
from > where > groupby > having > select > order
ties?
sql server의 top N 의 질문에서 N에 해당하는 값이 동일한 경우 함께 출력되도록 하는 with ties 옵션을 order by 절과 함께 사용해야 한다.
WITH TIES ( 동일한 값이 있을 경우 함께 출력하기 위한 구문
join
대부분 Non EQUI Join을 수행할 수 있지만, 때로는 설계상의 이유로 수행이 불가능한 경우도 있다.
두 테이블 간에 적절한 조인 조건이 없는 경우
범위나 조건이 모호하게 정의되어 있어 Non EQUI Join으로 원하는 결과를 얻을 수 없는 경우
특정 DBMS에서 최적화 이슈나 성능 문제로 인해 Non EQUI Join을 피해야 하는 경우