

-- select 구문은 트랜잭션과 아무런 연관성이 없음 -- 데이터의 변화와 상관이 없기 때문이다. select * from DEPT; -- DEPT 테이블에 데이터를 하나 삽입해보자. -- dept 테이블에 데이터 1개 삽입, 이전 트랜잭션이 없어서 트랜잭션 생성 insert into DEPT (deptno, dname, loc) values (50, "Computing", "SEOUL"); select * from DEPT; -- 철회: savepoint를 입력하지 않으면 트랜잭션 시작 전으로 복구 ROLLBACK; -- 내가 insert 한 것이 없어졌어! -- 트랜잭션 전으로 돌아가버렸다. select * from DEPT;insert 명령을 수행한 데이터가 없어졌다. COMMIT을 안했기 때문이다.
-- 다시 데이터를 넣어보자. -- 트랜잭션이 다시 하나 생성된다. insert into DEPT (deptno, dname, loc) values (50, "Computing", "SEOUL"); -- 이제 create 구문을 하나 써볼까? -- DEPT 복제 테이블 하나 생성하기 create table DEPT_COPY as select * from DEPT; -- 다시 ROLLBACK하기 ROLLBACK; -- 이번에는 50이 나온다. -- ROLLBACK을 했는데 왜 나왔지? -- DDL(create, drop, alter, truncate, rename)이나 -- DCL(grant, revoke)를 수행하면 AUTO COMMIT이다. -- why? : 관리자 영역의 명령어들이라 나중에 적용되면 안되기 때문이다. -- 트랜잭션은 변경 내역을 반영하고 종료를 한다. -- 물론 create한 테이블도 잘 보인다. select * from DEPT; select * from DEPT_COPY;
-- 트랜잭션 생성 insert into DEPT (deptno, dname, loc) values (60, "Computing1", "SEOUL1"); savepoint sv1; insert into DEPT (deptno, dname, loc) values (70, "Computing2", "SEOUL2"); savepoint sv2; insert into DEPT (deptno, dname, loc) values (80, "Computing3", "SEOUL3"); select * from DEPT; -- sv1을 생성한 지점으로 이동 ROLLBACK TO sv1; -- sv1으로 오게 된다면 sv2는 없는 것을 생각하자. select * from DEPT; -- 이대로 냅두면 lock이 걸린다. -- 왜냐면 내가 rollback이나 commit, ddel, dcl 한 적이 없음 -- 에러는 아니고 데드락에 걸려요 이걸 connect timeout을 걸어야 함 -- commit 수행 : 트랜잭션 종료 COMMIT;
SELECT * from ? ; 이 명령은 보조기억장치에 두고 실행한다. 이 명령을 실행하면 메모리에 올려서 cpu에서 작업하는것이다.select ~ from (select 구문) 이름slsect * from EMP, DEPT where EMP.DEPTNO=DEPT.DEPTNO and JOB='CLERK';select * from (select * from EMP where JOB='CLERK') TEMP, DEPT where TEMP.DEPTNO=DEPT.DEPTNO;
create [or replace] view 뷰이름 as select 구문 [with check option] [with read only]MySQL은 버전에 따라서 OR REPLACE를 사용하지 못하는 경우가 있다.
WITH CHECK OPTIONWITH READ ONLYNOT NULL 컬럼을 제외하고 만든 경우에는 DML 작업이 안됩니다.READ ONLY 옵션을 추가해야 합니다.ALTER를 사용할 수 없습니다.DROP VIEW 뷰이름;-- emp 테이블에서 empno, ename, sal, comm만으로 구성된 뷰를 생성 create view KIM as select EMPNO, ENAME, SAL, COMM from EMP; -- 사용은 테이블과 똑같다. select * from KIM; -- VIEW에 DML(삽입 삭제, 갱신) 작업은 가능한 경우도 있고 -- 가능하지 않는 경우도 존재 DESC EMP; -- view에 데이터 삽입 insert into KIM(EMPNO, ENAME, SAL, COMM) VALUES(999, 'MINO', 10000, 9000); SELECT * FROM KIM; -- 확인해 보면 EMP 테이블에 들어가있음 SELECT * FROM EMP; -- VIEW 구조 확인 DESC KIM; -- VIEW 삭제 DROP VIEW KIM;
create temporary table 테이블이름(내용);-- 임시 테이블 create temporary table temp( name char(20) ); select * from temp;해당 세션을 종료하고 새 세션을 킨다면 사용 못하는 임시 테이블이다.
WITH 테이블이름(컬럼이름 나열) AS (SELECT 구문)SELECT 구문이 복잡한 경우, 동일한 SELECT 구문 여러 번 입력해야 하는 경우가 있는데, 이 때 CTE를 사용하면 편리하다.
2개 이상의 CTE를 사용하고자 하는 경우에는 콤마(,)로 구분
-- CTE : SQL 수행 중에만 일시적으로 -- 메모리 공간을 할당받아서 사용하는 테이블 -- FROM 절에 쓰는 것 : INLINE VIEW -- SUB QUERY는WHERE 뒤에 있는거 SELECT * FROM (SELECT NAME, SALARY, SCORE) FROM tStaff WHERE DEPART='영업부' AND GENDER='남') TEMP WHERE SALARY>=(SELECT AVG(SALARY) FROM TEMP); -- 이러면 WEHRE에 있는 TEMP가 뭔지 모른다. -- 이와 유사한 작업을 INLINE VIEW에서 가능할거라 보이지만, -- INLINE VIEW는 SUB QUERY보다 늦게 수행되기 때문에 -- INLINEEVESMS SUB QUERY에서 못쓴다. WITH TEMP AS (SELECT NAME, SALARY, SCORE FROM tStaff WHERE DEPART='영업부'AND GENDER='남') SELECT * FROM TEMP WHERE SALARY>=(SELECT AVG(SALARY)FROM TEMP);
DELIMITER 기호기호 CREATE [OR REPLACE] 프로시저 이름() BEGIN SQL 작성 END 기호기호 DELIMITER
CALL 프로시저이름(매개변수 나열)-- 프로시저 생성 -- delimiter는 프로시저 종료를 알리기 위한 기호설정 -- 왜냐하면 안에 이미 세미콜론이 있기 때문에 모르기 때문이다. -- 두개로 쓰는 이유는 하나로 만들면 데이터로 사용되는 것과 -- 혼동이 올 수 있기 때문이다. -- dbeaver에서 수행할 때는 sql script 실행으로 실행해야 한다. delimiter // create procedure myproc(vuserid char(15), vname varchar(20), vbirthyear int(11), vaddr char(100), vmobile char(11), vmdate date) begin insert into usertbl values(vuserid, vname, vbirthyear,vaddr, vmobile, vmdate); end// delimiter ; -- 지우기는 drop 입니다. drop procedure myproc; -- 실행하기 call myproc('mino', '이민호', 1998,'서울' , '01012341234', '1998-09-25'); select * from usertbl;
~~~ 하기 전에 ~~한다 는 유효성 검사~~~하고 나서는 ~~한다는 로깅을 하는 것이다.create trigger 이름 timing [before|after] event [insert|update|delete] on 테이블 이름 [for each row] -- 행단위? 아니면 한번만(한번만이면 생략가능) [where 조건] begin 수행할 내용 end권한 문제로 트리거 생성이 안되면 관리자 계정으로 접속해서 명령을 수행하거나, 관리자 계정에서
set global log_bin_trust_function_creators=on;명령어를 입력해주자.

-- 트리거를 수행하기 위한 샘플 테이블 생성 create table emp01( empno int primary key, ename varchar(30) not null, job varchar(100) ); create table sal01( salno int primary key auto_increment, sal float(7,2), empno int references emp01(empno) on delete cascade ); -- emp01 테이블에 데이터 추가시, sal01테이블에 데이터가 자동으로 추가되는 트리거 set global log_bin_trust_function_creators=on; delimiter // create trigger trg_01 after insert on emp01 for each row BEGIN insert into sal01(sal,empno) values(100,NEW.empno); END// delimiter ; insert into emp01 values(1,'mino','데이터분석가'); select * from emp01; select * from sal01;
NEW.컬럼이름을 사용하면 되고, 수정되기 전의 값이나 삭제되는 값을 사용하고자 하는 경우는 OLD.컬럼이름을 사용하면 됩니다.
- SQL Mapper
- 소스코드와 SQL을 분리시켜서 수행하는 방식
- MyBatis가 대표적인 Framework(우리나라 SI 업계에서 주로 이용, 쉽기는 하지만 효율이 떨어짐)
pip install pyMySQL변수 = pymysql.connect(host=?,port=?,user=?,passwd=?,db=?,charset=?)
성공하면 메시지 x 실패하면 에러 메시지와 함께 예외 발생함
변수.close() : 접속 종료
# 파이썬 MySQL 드라이버 패키지 다운로드 pip install pyMySQL import pymysql try: con=pymysql.connect(host='localhost',port=3306,db='mino', user='root', passwd='12alsgh12!', charset='utf8') print(con) except: print("예외 발생!", sys.exc_info()) finally: if con!=None: con.close()
<과정>
SQL 실행 객체.excute(SQL[,parameter 값 나열])con.commit()을 호출하면 원본에 반영됩니다.작업할 테이블 확인 : DBeaver 에서 확인
파이썬에서 SQL 작성
import pymysql import sys try: #db 연결객체 생성 con=pymysql.connect(host='localhost',port=3306,db='mino', user='--', passwd='--', charset='utf8') print(con) #sql 실행 객체 생성 cursor=con.cursor() #sql 실행 - 값을 직접 sql에작성 cursor.execute("insert into DEPT values(11,'비서','서울')") #sql 실행 - sql에 서식을 설정하고, 파라미터를 대입하는 코드 작성 : 권장 cursor.execute("insert into DEPT values(%s,%s,%s)", (12,'기획','제주')) ### 이렇게 하고 dbeaver에서 select * from DEPT 보면 데이터 없음 # 여기의 DEPT와 DBeaver의 DEPT와는 다른 것이다. (세션이 다르다.) # Commit을 해주자. con.commit() except: print("예외 발생!", sys.exc_info()) finally: if con!=None: con.close()DB 연결객체 생성 시, user 와 pwd는 기존 db와 맞아야 한다.
똑같이 쓰는 부분들이 존재한다. 이는 프레임워크가 채워줄 것이다.
fetchone 메서드를 호출하면 하나의 튜플로 데이터를 리턴합니다.fetchall 메서드를 호출하면, tuple의 tuple로 모든 데이터를 리턴합니다.fetchone 호출 경우fetchall을 호출함import pymysql import sys try: #db 연결객체 생성 con=pymysql.connect(host='localhost',port=3306, db='mino', user='-', passwd='-', charset='utf8') #sql 실행 객체 생성 cursor=con.cursor() cursor.execute("select * from DEPT where DEPTNO=%s",(12)) #검색 결과 중 하나의 데이터를 읽어오는 것 record=cursor.fetchone() #검색된 결과가 없다면 None, 존재하면 Tuple #print(record) if record==None: print("검색된 데이터가 없음") else: for attr in record: print(attr) except: print("예외 발생!", sys.exc_info()) finally: if con!=None: con.close()
데이터베이스에 파일을 저장하는 방법
- 파일을 파일 서버(AWS의 S3 또는 Google Firebase의 File Storage 서비스) 에 별도로 젖아하고 그 경로를 저장하는 방법
- 파일의 이름과 내용을 모두 데이터베이스에 저장하는 방식
파일을 파일 서버에 별도로 저장하면 DB에 저장하는 것 보다 비용이 저렴하지만 파일을 사용하려고 할 때 마다 다운로드를 받아야 합니다.
- select 구문 만으로는 파일을 사용할 수 없습니다.
최근에는 대부분 파일을 데이터베이스에 저장하지는 않습니다.
파일의 내용을 데이터베이스에 저장하고자 하면, 데이터 타입을 blob or longblob로 설정해야 합니다.
- 파일의 내용을 저장할 때, 형식을 알아야 하기 때문에 파일 이름을 같이 저장
파이썬에서는 BLOB는 bytes와 매핑됩니다.
DB에 파일을 저장할 수 있는 테이블을 생성해야 한다.
create table blobtable( filename varchar(100), filecontent longblob ); desc blobtable;
import pymysql import sys try: #db 연결객체 생성 con=pymysql.connect(host='localhost',port=3306, db='mino', user='-', passwd='-', charset='utf8') #sql 실행 객체 생성 cursor=con.cursor() #삽입할 이미지 파일 내용 읽기 f=open('galoo7.jpg','rb') galoo=f.read() f.close() # 데이터 삽입 cursor.execute("insert into blobtable values(%s, %s)", ("galoo7.jpg",galoo)) con.commit() except: print("예외 발생!", sys.exc_info()) finally: if con!=None: con.close()
import pymysql import sys try: #db 연결객체 생성 con=pymysql.connect(host='localhost',port=3306, db='mino', user='--', passwd='--', charset='utf8') #sql 실행 객체 생성 cursor=con.cursor() #데이터 읽어오기 cursor.execute("select * from blobtable") data=cursor.fetchone() #두 번쨰 데이터가 blob 이므로 두번째 데이터를 파일로 변경 print(data[0]) f=open(data[0],'wb') f.write(data[1]) f.close() #select는 transaction이랑 상관 없어서 commit 할 필요가 없음 #con.commit() except: print("예외 발생!", sys.exc_info()) finally: if con!=None: con.close()몇 번째가 이름이고 몇 번째가 사진인지 데이터 인덱스 잘 생각하기
docker run --name 컨테이너이름 -d -p 포트번호(1521):1521 jaspeen/oracle-xe-11g 이러면 관리자는 sys, system 이고, sid 는 xe가 되고 관리자는 system이고 비번은 oracledocker run --name 컨테이너이름 -d -p 포트번호(1521):1521 -e ORACLE_PASSWORD=관리자비밀번호 gvenzl/oracle-xe sid는 xe가 되고 관리자는 sys, system이며 비번은 설정한 값
소중한 정보 감사드립니다!