벌써 마지막 주차라니...!
12기 활동은 다른 일정이랑 너무 겹치다 보니 완주에 의의를 두게 되었다는 게 너무 아쉽다.
하지만 덕분에 포기하지 않고 책 한 권을 다 볼 수 있었고, 방학 동안의 불안을 정리할 수 있었다.
담주는 목요일에 첫 세미나가 있고, 토요일에 SQLD 시험이 있다.
12기분들 중에도 SQLD 시험에 응시하는 분이 많던데 모두 좋은 결과가 있으면 좋겠다!
함께한 족장님과 12기분들 너무 감사하고 고생 많으셨습니다! 기회가 된다면 13기로 다시 만나요~
(각 단원별 학습 내용 정리는 '혼공학습단 12기' 카테고리 안에 있습니다!)
기본 숙제
p. 363 market_db의 고객 테이블(member)에 입력된 회원의 정보가 변경될 때 변경한 사용자, 시간, 변경 전의 데이터 등을 기록하는 트리거 작성하고 인증하기
우선 연습용으로 회원 테이블에서 간단히 아이디, 이름, 인원, 주소 4개의 열을 복사한 singer 테이블을 만들자.
USE market_db;
CREATE TABLE singer (SELECT mem_id, mem_name, mem_number, addr FROM member);
singer 테이블에 INSERT 나 UPDATE 작업이 일어나는 경우, 변경되기 전의 데이터를 저장할 백업 테이블을 만들자.
그리고 백업 테이블에 기본미션에서 요구하는 변경한 사용자(modUser), 변경된 시간(modDate)을 추가하자.
DROP TABLE IF EXISTS backup_singer;
CREATE TABLE backup_singer
( mem_id CHAR(8) NOT NULL ,
mem_name VARCHAR(10) NOT NULL,
mem_number INT NOT NULL,
addr CHAR(2) NOT NULL,
modType CHAR(2), -- 변경된 타입. '수정' 또는 '삭제'
modDate DATE, -- 변경된 날짜
modUser VARCHAR(30) -- 변경한 사용자
);
이제 변경(UPDATE)과 삭제(DELETE)가 발생할 때 작동하는 트리거를 singer 테이블에 부착해 보자.
먼저 변경(UPDATE)이 발생했을 때 작동하는 singer_updateTrg 트리거를 만들어보자.
DROP TRIGGER IF EXISTS singer_updateTrg;
DELIMITER $$
CREATE TRIGGER singer_updateTrg -- 트리거 이름
AFTER UPDATE -- 변경 후에 작동하도록 지정
ON singer -- 트리거를 부착할 테이블
FOR EACH ROW
BEGIN
INSERT INTO backup_singer VALUES( OLD.mem_id, OLD.mem_name, OLD.mem_number,
OLD.addr, '수정', CURDATE(), CURRENT_USER() );
END $$
DELIMITER ;
OLD 테이블은 UPDATE나 DELETE가 수행될 때, 변경되기 전의 데이터가 잠깐 저장되는 임시 테이블이다. MySQL에서 내부적으로 제공되는 테이블이라고 하는데 사용자 입장에서 굉장히 편리한 테이블인 것 같다.
이번에는 삭제(DELETE)가 발생했을 때 작동하는 singer_deleteTrg 트리거를 생성해 보자.
DROP TRIGGER IF EXISTS singer_deleteTrg;
DELIMITER $$
CREATE TRIGGER singer_deleteTrg -- 트리거 이름
AFTER DELETE -- 삭제 후에 작동하도록 지정
ON singer -- 트리거를 부착할 테이블
FOR EACH ROW
BEGIN
INSERT INTO backup_singer VALUES( OLD.mem_id, OLD.mem_name, OLD.mem_number,
OLD.addr, '삭제', CURDATE(), CURRENT_USER() );
END $$
DELIMITER ;
이제 변경과 삭제 시에 작동하는 트리거는 모두 생성되었다.
이제 데이터를 변경하고 backup_singer을 확인해 보자.
UPDATE singer SET addr = '영국' WHERE mem_id = 'BLK';
DELETE FROM singer WHERE mem_number >= 7;
SELECT * FROM backup_singer;
backup_singer 테이블을 조회해 본 결과 1건의 수정과 4건의 삭제에 대한 변경 전의 데이터, 변경한 사용자, 시간, 등의 데이터가 잘 기록되어 있는 것을 확인할 수 있다.
선택 숙제
p. 402 GUI 응용 프로그램 만들고 인증하기
사용자가 Tkinter를 통해 입력한 데이터를 MySQL 데이터베이스에 저장하거나, 데이터베이스에서 데이터를 조회하여 표시하는 간단한 GUI를 만들어보는 과제였다.
전체코드
import pymysql
from tkinter import *
from tkinter import messagebox
## 데이터베이스에 데이터 삽입
def insertData():
con, cur = None, None
data1, data2, data3, data4 = "", "", "", ""
sql = ""
conn = pymysql.connect(host='127.0.0.1', user='root',
password='1234', db='soloDB', charset='utf8')
cur = conn.cursor()
data1 = edt1.get(); data2 = edt2.get()
data3 = edt3.get(); data4 = edt4.get()
sql = "INSERT INTO userTable VALUES('" + data1 + "','" + \
data2 + "','" + data3 + "','" + data4 + "')"
cur.execute(sql)
conn.commit()
conn.close()
messagebox.showinfo('성공', '데이터 입력 성공')
## 데이터베이스에서 데이터 조회
def selectData():
strData1, strData2, strData3, strData4 = [], [], [], []
conn = pymysql.connect(host='127.0.0.1', user='root',
password='1234', db='soloDB', charset='utf8')
cur = conn.cursor()
cur.execute("SELECT * FROM userTable")
strData1.append("사용자 ID"); strData2.append("사용자 이름")
strData3.append("사용자 이메일"); strData4.append("사용자 출생연도")
strData1.append("-----------"); strData2.append("-----------")
strData3.append("-----------"); strData4.append("-----------")
while (True):
row = cur.fetchone()
if row == None:
break
strData1.append(row[0]); strData2.append(row[1])
strData3.append(row[2]); strData4.append(row[3])
listData1.delete(0, listData1.size() - 1)
listData2.delete(0, listData2.size() - 1)
listData3.delete(0, listData3.size() - 1)
listData4.delete(0, listData4.size() - 1)
for item1, item2, item3, item4 in zip(strData1, strData2, strData3, strData4):
listData1.insert(END, item1)
listData2.insert(END, item2)
listData3.insert(END, item3)
listData4.insert(END, item4)
conn.close()
## 메인 GUI 코드
root = Tk()
root.geometry("600x300")
root.title("완전한 GUI 응용 프로그램")
edtFrame = Frame(root)
edtFrame.pack()
listFrame = Frame(root)
listFrame.pack(side=BOTTOM, fill=BOTH, expand=1)
edt1 = Entry(edtFrame, width=10); edt1.pack(side=LEFT, padx=10, pady=10)
edt2 = Entry(edtFrame, width=10); edt2.pack(side=LEFT, padx=10, pady=10)
edt3 = Entry(edtFrame, width=10); edt3.pack(side=LEFT, padx=10, pady=10)
edt4 = Entry(edtFrame, width=10); edt4.pack(side=LEFT, padx=10, pady=10)
btnInsert = Button(edtFrame, text="입력", command=insertData)
btnInsert.pack(side=LEFT, padx=10, pady=10)
btnSelect = Button(edtFrame, text="조회", command=selectData)
btnSelect.pack(side=LEFT, padx=10, pady=10)
listData1 = Listbox(listFrame, bg='yellow'); listData1.pack(side=LEFT, fill=BOTH, expand=1)
listData2 = Listbox(listFrame, bg='yellow'); listData2.pack(side=LEFT, fill=BOTH, expand=1)
listData3 = Listbox(listFrame, bg='yellow'); listData3.pack(side=LEFT, fill=BOTH, expand=1)
listData4 = Listbox(listFrame, bg='yellow'); listData4.pack(side=LEFT, fill=BOTH, expand=1)
root.mainloop()
1. 초기화면
2. 데이터 입력
3. 데이터 조회 (2 에서 입력한 test 데이터 확인)
12기도 너무 감사했습니다!!
오늘 하루도 쌓였다.
'혼공학습단 12기' 카테고리의 다른 글
[혼공S] 5주차를 마무리 하며 (0) | 2024.08.11 |
---|---|
[혼공S] 06 - 3 '인덱스의 실제 사용' 정리 (0) | 2024.08.11 |
[혼공S] 06 - 2 '인덱스의 내부 ' 정리 (0) | 2024.08.11 |
[혼공S] 06 - 1 '인덱스 개념을 파악하자' 정리 (0) | 2024.08.10 |
[혼공S] 4주차 마무리 (0) | 2024.07.28 |