SQL Server - ② : 테이블(TABLE) 생성하기
DataGridView를 이용한 간단한 윈폼을 통해 생성할 테이블의 열(Column)에 대한 속성을 전달받고,
최종적으로 SqlCommand 클래스를 통해 테이블 생성 쿼리문(CREATE TABLE ~ )을 전달해보겠습니다.
테이블을 생성하기 위한 윈폼은 아래와 같습니다.
Textbox 및 Button, DataGridView을 활용한 간단한 윈폼이기도하고,
본 글은 윈폼보단 테이블을 생성하는 쿼리문을 전달하는 과정에 초점을 맞추어서 설명을 할 예정입니다.
따라서 윈폼에대한 구체적인 설명은 생략하겠습니다. 😀
(INSERT 버튼은 오늘 만든 테이블에 행을 INSERT 하기 위한 폼으로 이동하는 버튼입니다.
따라서 오늘은 신경안쓰셔도 됩니다!!)
1. WinForm의 DataGridView에서 Column 관련 정보 추출하기
① DataGridView의 자동 행추가 차단
dataGridView1.AllowUserToAddRows = false;
AllowUserToAddRows의 속성이 True이면 자동으로 마지막 행이 추가가 됩니다.
저는 추가 및 삭제 버튼을 통해 행의 갯수를 제어할예정이기 때문에 관련 설정을 False해 주었습니다.
② DataGridView의 콤보박스 Default 값을 특정한 Item으로 설정
콤보박스 형태인 "데이터 형식"열의 Item 목록은 아래와 같습니다.
아무 설정을 안하면 콤보박스는 Default값이 공백(NULL)으로 지정되는데,
많이 사용하는 형식인 "VARCHAR"로 DEFAULT값을 지정하기 위해 아래와 같은 코드를 추가하였습니다.
dataGridView1.Columns[1].DefaultCellStyle.NullValue =
((System.Windows.Forms.DataGridViewComboBoxColumn)dataGridView1.Columns[1]).Items[1];
System.Windows.Forms.DataGridViewComboBoxColumn으로 형변환을 해서 NullValue에 넣었습니다.
(다른방식은 이상하게 오류가 발생하거나 제대로 DEFAULT값으로 들어가지 않더라구요.. 아시는분은 코멘트 부탁드립니다...😥)
③ PK를 선택하는 CheckBox가 반드시 1개이고, 생성된 행만큼 열이름이 모두 입력되었는지 확인하는 부분
if문을 거쳐서 테이블을 생성하기 위한 조건이 충족되었는지 확인합니다.
CheckBox의 경우의 수는 총 3가지 입니다.
첫번째, Default값 / 이는 True도 False도 아닌 null값이 들어가게 됩니다.
두번째, True / CheckBox가 선택되어 있다면 True를 반환합니다.
세번째, False / CheckBox를 선택했다 해제하면 Flase를 반환합니다.
따라서 is 키워드를사용해서 null 값인지 아닌지를 판단하였습니다.
(a is null : a가 null값이면 true를 null이 아니면 false를 반환합니다.)
// 테이블을 생성하기 위한 조건 2가지
// 1. PK 확인여부 CheckBox가 한개의 행에 체크되어있으면 넘어갑니다.
// 0개 혹은 2개이상이면 오류 문구 발생. (반드시 1개만 체크해야하도록)
// 2. 생성된 행의 갯수와 입력된 열이름을 비교해서 같지 않다면 확인 필요.
// 즉 열이름이 비어있는 행이 추가되어 있으면 안됨.
int RowNum = dataGridView1.Rows.Count;
int PKCount = 0;
int ColNameCount = 0;
for (int i = 0; i < RowNum; i++) {
object a = dataGridView1.Rows[i].Cells[3].Value; // PK 확인
if (a is null) { }
else if (a.ToString() == "True") PKCount++;
object b = dataGridView1.Rows[i].Cells[0].Value; // 열이름 확인
if (b.ToString() != "") ColNameCount++;
}
if (ColNameCount != RowNum) {
MessageBox.Show("열이름을 입력해주세요.");
return;
}
if (PKCount == 0) {
MessageBox.Show("PK를 지정해주세요.");
return;
}
else if (PKCount > 1) {
MessageBox.Show("PK를 1개만 지정해주세요.");
return;
}
④ DataGridView의 각 셀의 값을 변수로 저장해서 쿼리문 생성
for (int j = 0; j < RowNum; j++)
{
colName = dataGridView1.Rows[j].Cells[0].Value.ToString();
DataGridViewComboBoxCell dataTypeCombo;
dataTypeCombo = (DataGridViewComboBoxCell)dataGridView1.Rows[j].Cells[1]; // 콤보박스에 해당하는 셀을 형변환후 Items 값 추출
dataType = dataTypeCombo.Value == null ? dataTypeCombo.Items[1].ToString() : dataTypeCombo.Value.ToString();
nullCheck = dataGridView1.Rows[j].Cells[2].ToString();
pkCheck = dataGridView1.Rows[j].Cells[3].ToString();
if (nullCheck == "True" || pkCheck == "True")
query += colName + " " + dataType + " PRIMARY KEY,";
else if (nullCheck == "True" || pkCheck == "False")
query += colName + " " + dataType + ",";
else if (nullCheck == "False" || pkCheck == "True")
query += colName + " " + dataType + " NOT NULL PRIMARY KEY,";
else query += colName + " " + dataType + " NOT NULL,";
}
생성된 행만큼 for문을 통해 데이터를 추출하는 과정을 반복하게 됩니다.
dataType의경우 이항연산을 통해 null값이면 DEFAULT값인" VARCHAR"를
NULL값이 아니라면 선택된 콤보박스의 VALUE를 String 타입 변수에 저장합니다.
각 열의 데이터를 조합해서 string 타입의 변수(query)에 최종적으로 저장해서 쿼리문을 작성해줍니다.
2. SqlCommand 클래스를 통해 Query문을 DB에서 실행하기
SqlCommand를 사용하는 방법은 여러가지가 있지만(SqlCommand는 총 5가지 형태로 생성자를 생성할 수 있다.)
저는 먼저 인자가 없는 형태로 생성자를 생성하였습니다.(public Sqlcomand())
생성자 생성 후
✅ 쿼리문(string query)을 SqlCommand.CommandText 변수에 저장하고,
✅ DB 접속 문자열(SqlConnection)을 SqlCommand.Connection 변수에 저장 하였습니다.
그리고 SqlCommand.ExecuteNonQuery() 매서드를 통해 해당 쿼리문을 DB로 전달하였습니다.
해당메서드의 리턴값은 int형태로 영향을 받은 행의 갯수를 반환하게 됩니다.
따라서, 반환값이 1개일경우 정상적으로 테이블이 생성했다고 메세지를 보내게 됩니다.
(제가 구현한 코드는 테이블을 1개씩만 생성하기 때문에 1 또는 0만을 반환하게 됩니다.)
private SqlCommand cmd = new SqlCommand();
if (conn.State != ConnectionState.Open) conn.Open();
cmd.Connection = conn;
// ........................... 중략 ...........................
cmd.CommandText = query;
if (cmd.ExecuteNonQuery() == 1)
MessageBox.Show("정상적으로 테이블이 생성되었습니다.");
코드 전문(파일)
다음에는 단순히 문자열 형태가 아닌 매개변수화 된 쿼리를 사용해서 생성한 테이블에 데이터를 집어넣는 INSERT를 구현해보겠습니다. 👍
추가로 명령줄인수라는 기능을 사용해서 파일 실행시 특정 문자열(App.Config의 DB Name)을 전달해서 조금더 사용자 친화적인 코드를 구현해보도록 하겠습니다 :)
댓글