관리 메뉴

새로운 시작, GuyV's lIfe sTyle.

닷넷 게시판 만들기 Part 24 - 닷넷에서 DB랑 놀아보기 본문

ⓟrogramming/asp.net 게시판

닷넷 게시판 만들기 Part 24 - 닷넷에서 DB랑 놀아보기

가이브 2011. 3. 2. 16:50

2011/02/16 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 20
2011/02/18 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 21
2011/02/18 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 22
2011/02/28 - [ⓟrogramming/asp.net 게시판] - 닷넷 게시판 만들기 Part 23

1. 닷넷 개발환경 준비, 테스트
2. 닷넷 알아보기 [7/7]
3. asp.net 컨트롤 [10/10]
4. 데이터베이스(DB) [5/..]


이전시간에 이어 계속 진행하고 있는 DB연동은 매우 중요한 부분입니다. 앞서 말했지만 웹프로그래밍에서 웹 상에서 사용자의 정보를 저장(쇼핑몰, 회원가입 등)하는 곳은 DBMS입니다. 웬만한 프로그래밍에서는 DB연동 기술이 적용됩니다.

이번시간부터는 실제 DB서버에 연결하여 네 종류의 쿼리문을 실행하고, SELECT 같이 결과가 있다면 그 결과를 받기도 할 것입니다. 이 강의에서 전반적으로 빼먹을 것은 없지만(^^;) DB연동은 꽤 자주 사용하기 때문에 숙지하셔야 될 것입니다. 외우지는 마세요! 찾아쓰면 됩니다.



지난 시간의 기억을 되살려서.. SqlConnection 으로 연결을 Open() 하거나 Close() 할 수 있다고 하였다. 이번 시간에는 연결(Open)후 쿼리문을 DB서버로 보내는 작업을 해보도록 하자. 당연하겠지만 DB에 쿼리문을 날리는(명령을 내리는) 과정은 이 Open() 과 Close() 사이에 있어야 될 것이다.

이전 예제에 이어서 소스파일을 계속 사용하자.(파일명은 db2.aspx로 변경추천)
이전 시간에 본인의 컴퓨터 DB서버에 연결이 성공하셨다면 문제가 없으나, 오류가 발생(실패)하였다면 다시 한번 Part 23 을 보셔야 할 것이다. 혹시 4장에서 Part 20~22를 건너뛰셨다면 DB서버 설치, aspnet 데이터베이스 생성, 그리고 aspnet에 테이블 생성을 하셔야 한다. (지면상 재탕은 생략하겠다)

db2.aspx


<%@ Page Language="C#" runat="server" %>
<%@ Import Namespace = "System.Data" %>
<%@ Import Namespace = "System.Data.SqlClient" %>

<script language="C#" runat="server">

 void Page_Load()
 {
  string str_conn = "server=notebook-PC\\STUDY;user id=sa;password=1121;database=aspnet;";
  SqlConnection conn = new SqlConnection(str_conn);
  conn.Open();

  
  // DB연동작업 시작






  // DB연동작업 끝
  conn.Close();
 }


</script>



꺼진 불도 다시보라는 말이 있듯이, DB연결이 잘 되는 것을 확인하기 위해 소스를 실행해보자. 당연히 백지만 나오고 오류가 발생하지 않아야 한다.

이제 결과값이 없는 INSERT, DELETE, UPDATE 쿼리를 수행하는 작업을 해보자. 이 쿼리문은 실제 값의 리턴이 없다. (정확하게는 몇 행(row)이 쿼리문에 의해 적용이 되었는지 리턴이 되긴 한다만) SELECT 는 조회하는 쿼리문이므로 어떤 값이든 되돌려주는 리턴 값이 있을 것이다.

쿼리문을 담당하는 클래스는 따로 존재한다.
바로 SqlCommand 라는 클래스이다. 이 클래스는 SqlConnection 클래스를 이용하여 쿼리문을 실행하게 된다.

db2.aspx 에서 연결하는 aspnet 이름의 DB에는 테이블이 존재한다. member_table 을 기억할 것이다. 예전에는 DB관리툴을 이용해 INSERT 문을 실행해보았다. 이번 시간에는 asp.net 에서 INSERT 문을 실행하는 것이 목적이다.

SqlCommand 를 이용해서 쿼리문을 실행하는 것은 어떻게 할까?
당연히 MSDN에 모두 나와있을 것이다. (System.Data.SqlClient.)SqlCommand 클래스를 찾아보자. (아직도 클래스를 MSDN에서 못 찾으신다면..?!)

SqlCommand 클래스의 설명을 읽어보자. [SqlCommand는 다음 메서드를 제공하여 SQL Server 데이터베이스에서 명령을 실행합니다.] 라고 설명이 되어 있다. 테이블을 보면 여러가지 메서드들이 있는데,


우리가 필요한 것은 이렇게 3개의 메서드이다. 테이블 우측의 용어가 조금 난해할 것이다.
필자가 조금 정리를 하자면 이 3개의 메서드는 우리가 알고 있는 쿼리문의 형식에 따라 결과물이 없는 쿼리문을 실행하는 것, 결과물이 있는 쿼리문을 실행하는 것 이렇게 두 가지에 대한 메서드이다. SqlCommand는 DB서버에 연결(Open)된 상태에서만 수행이 가능하다. 그러니까 SqlCommand의 메서드들은 모두 DB가 연결되었을 때만 사용가능한 것이다.

1. 결과가 없는 쿼리문을 실행할 때 : ExecuteNonQuery 메서드 사용
2. 결과가 있는 쿼리문을 실행할 때 : ExecuteScalar, ExecuteReader 메서드 사용

1번은 이해될 것이다. 말 그대로 결과가 없는 INSERT, DELETE, DELETE 쿼리문일 때 사용하면 될 것 같다.

2번은 결과값이 있을 때인데, ExecuteScalar 메서드는 "단일 값"이라고 했다. 이에 반해 ExecuteReader 메서드는 여러개의 값일 것이다.
일단 이렇게만 알고 있자.

DB관리툴(SQL Server Management Studio) 을 열고, 여러분들이 만든 DB(필자는 aspnet)를 열어서 테이블에 들어있는 자료를 확인해보자. 

다음처럼 수행하면 될 것이다.



관리툴 중간에 자동으로 쿼리문이 만들어져서 실행될 것이다.
하단에 여러분들이 넣어둔 자료가 보여질 것이다.


필자의 member_table 은 위 그림과 같다.

SqlCommand 클래스에서 결과를 리턴하는 메서드인 ExecuteScalar 는 위의 자료에서 각각의 칼럼 딱 하나인 값이 될 것이다. test_id, 김병만, 1234 이렇게 오직 1개의 값을 읽어올 수 있다. 퀴리문은 여러분들이 직접 작성한다. test_id 회원의 정보를 모두 가져올지, 회원가입일자만 가져올지는 만드는 사람 마음이다. 그러므로 그에 따라서 사용하는 메서드도 달라야 할 것이다.
쿼리의 리턴이 2개 이상의 자료를 다 가져올 때는 ExecuteReader 를 사용한다. 레코드(Row)가 1개인 값이라도 컬럼이 2개라면 ExecuteScalar 로 모두 리턴시킬 수 없다. 오직 한 개이기 때문이다. 그 이상(개)의 값이라면 ExecuteReader 메서드를 이용해야 한다.

실습을 해보자. DB관리툴은 확인을 위해 내려놓기만 하자. 소스로 돌아와서 INSERT 문으로 member_table 테이블에 새 자료를 넣어보자. 실행할 쿼리문은 다음과 같다.

INSERT INTO member_table VALUES('aspnet', '1234', '닷넷초보', getdate())

이것은 테이블명 우측에 컬럼명이 빠졌으므로 차례대로 모든 컬럼에 값을 넣는 INSERT 쿼리문이다. 이전에 관리툴에서 별 문제 없이 잘 들어간 것을 확인했었다.
asp.net 으로 SqlCommand 을 이용해서 넣어보자.

(..생략)

string QUERY =
      "INSERT INTO member_table VALUES('aspnet', '1234', '닷넷초보', getdate())";
SqlCommand cmd = new SqlCommand(QUERY, conn);
cmd.ExecuteNonQuery();

(..후략)

db2.aspx 파일에서 DB연동작업 중간에 넣자.
이 aspx 파일을 한 번만 실행하고 DB관리툴에서 F5를 눌러 다시 member_table 자료를 조회해보자. 자료가 하나 잘 들어갔는가? (들어가야 정상이니 소스를 확인해보자)

이 소스는 SqlCommand 클래스의 생성자에서 쿼리문과 연결(SqlConnection)을 함께 주었다. 생성자가 아닌 프로피터로 줄 수도 있다. 여러가지 방법이니, MSDN을 찾아보면 사용하는 방법을 나름대로 찾으실 수 있을 것이다. 물론 어떤 방법으로 하든 상관 없다.

소스에서 진하게 표시한 QUERY 는 무엇일까? asp.net 과 DB는 아~무 관련이 없다는 말을 기억하시리라 생각한다. asp.net 에서

string QUERY = ".." 

이 문장은 string 형식의 문자열 상수값이 할당되었을 뿐
이다.
단지 그 쿼리문이 실제 DB에서 수행될 쿼리문이다.

왜 필자가 이것을 강조하냐면 지금은 상수로 모두 구성된 쿼리문이지만 게시판 등 사용자의 입력을 변수로 쿼리문을 만들 때 여러분들이 헷갈릴 수 있기 때문이다. 중요한 내용이기에 반복한다. 쿼리문은 string 문자열 형식이다. 상수는 DB에서 해석될 쿼리문이다. 꼭 생각해놓길 바란다.

cmd.ExecuteNonQuery();

항목이 실제 쿼리를 날리는 명령이 되겠다. 리턴은 int 형이다. 그러나 일단 무시하기로 하자.

이처럼, 리턴이 없는 INSERT, DELETE, UPDATE 쿼리문의 실행 방법은 모두 동일하게 이렇게 사용하면 된다. 사용자의 입력값은 Request[""] 등으로 받아서 string QUERY 를 알맞게 문자열 결합으로 바꿔주기만 하면 될 것이다. 당연한 말 아닌가?

프로그래밍이라고 해서 특별한건 없다. 사용하는 방법을 알게 되었으면 활용하면 된다.
여러분들은 이제 DB를 연동해서 게시판을 만드는 방법에서 게시물을 쓰거나 수정, 삭제하는 구문을 작성할 수 있다. 단, 안해봤을 뿐이고 완벽한 프로그램을 만들기 위해서 막막할 뿐이다.

DB의 자료를 삭제하는 DELETE, 수정하는 UPDATE는 실습하지 않고 넘어가도록 하겠다. 여러분들은 한번 해보시기 바란다. 쿼리문 연습은 DB관리툴에서 실행하고, 쿼리문이 어느정도 이해되셨으면 asp.net 에서 코드로 넣어보자. 이렇듯 DB연동이라고 하면 asp.net(웹) 또는 윈도우 어플리케이션에서 쿼리문을 만들어서 DB서버로 날리는 것을 말한다.

이제 자료를 받아보자. 단 1개의 자료를 받는 ExecuteScalar 메서드를 이용하자.
이 메서드의 리턴은 object 형이다. object 형은 어떤 특정 클래스형이다. 그러나 어떤 자료인지는 알 수 없다. object 형은 닷넷의 모든 자료형을 말한다. 

자료를 리턴하는 형은 왜 object 형일까?? 이해를 위해 문제를 내겠다.

Q. 닷넷은 DB서버에 날린 SELECT 쿼리의 결과를 예상할 수 있을까?
A. "없다."

닷넷 입장에서는 쿼리문은 문자열일 뿐이다. 쿼리문이 잘 실행될지, 안될지는 알 수 없다.
게다가 닷넷은 DB가 어떤 컬럼의 자료형인지는 받아보기 전에는 알 수 없다. 
1개의 값을 리턴하는 쿼리문의 결과가 정수(int)인지, 문자열(string)인지, 날짜형(DateTime)인지 결코 알 수 없다. 그래서 object 형이다. 당연하겠지만 닷넷 입장에서는 어떤 자료형의 녀석이 넘어올지 모르기 때문이다. 쿼리문은 개발자가 그때그때 짜기 때문이다. 그러므로 ExecuteScalar 메서드는 개발자가 받아서 따로 자료를 실제 DB의 컬럼에 해당하는 자료형으로 바꾸어 주어야 한다.

SELECT count(*) FROM member_table

이 쿼리를 DB관리툴에서 실행해보자. count(컬럼명) 함수는 SQL Server에 내장된 함수이다. member_table 테이블의 레코드(Row) 수를 정수형(int)으로 조회하는 쿼리문이다. 이 쿼리문의 결과는 1개의 레코드에 1개의 컬럼이다. 그 컬럼의 값은 0 이상이 될 것이다. 자료가 없다면 0, 있다면 1이상이 나오게 될 것이다. 이 시점에서, 필자의 결과는 3이다.

SELECT user_name FROM member_table

이 쿼리문 역시 member_table에 있는 user_name 하나의 컬럼만 가져올 것이다. 그러나 결과는 모든 레코드(Row)에 해당된다. 위에서 필자의 자료는 총 3개의 레코드가 있기 때문에, user_name 값은 3개의 레코드로 나올 것이다. 그러므로 일반적으로 ExecuteScalar 는 WHERE 절이 들어가는 경우가 많을 엇이다. 목적상 1개의 레코드에 1개의 컬럼을 가져오기 위한 메서드이기 때문이다.

SELECT user_name FROM member_table WHERE user_id='aspnet'

ExecuteScalar 메서드는 필자 생각에 아이디/비밀번호 찾기에서 많이 사용될 것 같다. 
이 쿼리의 결과를 가져와보자.

  // DB연동작업 시작
  string QUERY = "SELECT user_name FROM member_table WHERE user_id='aspnet'";
  SqlCommand cmd = new SqlCommand(QUERY, conn);
  object result = cmd.ExecuteScalar();
  Response.Write(result);

ExecuteScalar 메서드의 결과는 object 이므로 object 로 받으면 된다. 물론 내부적으로 값은 정해져 있다. member_table 을 만든 사람이 개발자에게 알려줬을 것이다. 지금은 우리가 만들어서 우리가 알고 있지만 말이다. SQL Server 에서 varchar() 는 문자열이라고 했다. 그러므로, 위의 소스에서 값을 받아오는(진하게 표시된) 코드는 다음처럼 변경될 수 있다.

string result = (string)cmd.ExecuteScalar();
Response.Write(result);
-또는-
Response.Write( "결과: " + cmd.ExecuteScalar() );
-또는-
Response.Write( cmd.ExecuteScalar() );
-또는-
Response.Write( "결과: " + cmd.ExecuteScalar() );
-....-

WHERE 절을 빼보고 실행하자.
DB관리툴에서 실제 결과를 눈으로 확인한 후 db2.aspx에 적용해보자. 오류가 발생하는가? 발생하지 않는다면 우리는 쉽게 생각할 수 있다. ExecuteScalar() 메서드의 기능은 쿼리의 결과에 관련없이 무조건 첫 레코드 첫 컬럼의 값만 object 로 리턴하고 있음을..

member_table의 user_regdate 컬럼은 SQL Server에서 datetime 형이다. 이것은 닷넷에서 DateTime 클래스로 사용할 수 있다.

string QUERY = "SELECT user_regdate FROM member_table WHERE user_id='aspnet'";
SqlCommand cmd = new SqlCommand(QUERY, conn);
object result = cmd.ExecuteScalar();
Response.Write(result);

이렇듯 그냥 출력하면 결과는..

2011-03-02 오후 3:53:02

닷넷 DateTime 을 출력한 것 처럼 나온다.

string QUERY = "SELECT user_regdate FROM member_table WHERE user_id='aspnet'";
SqlCommand cmd = new SqlCommand(QUERY, conn);
DateTime result = (DateTime)cmd.ExecuteScalar();
Response.Write( result.ToString("yyyy년 MM월 dd") );

그러므로 위처럼 마음대로 요리할 수 있다.



자, 이제 해볼거리가 많이 생기셨을 것 같다.
테이블을 또 아무거나 만들고, 자료를 넣고, 신나게 쿼리문을 날려보자. 자료의 결과도 받아보자. 더 나아가 ExecuteReader 메서드를 MSDN을 보며 실습해보자.




이 그림을 한번 슥~ 눈으로 봐주고.

다음 시간에는 2개 이상의 데이터, 즉 여러개의 데이터를 SELECT 문의 결과를 다루어보도록 하겠다. 게시판 리스트가 될 수 있고, 게시판 내용보기, 댓글 보기에 적용될 수 있을 것이다.

필자가 귀찮아서 예제를 생략한 것이 아니라고 말씀드리고 싶다.
여러분들이 잡는 고기가 더욱 더 맛있으리라 생각들며, 오랫동안 기억에 남기 때문이다.
결국 공부는 여러분들이 직접 하는 것이다. 자기도 모르게 프로그래밍 스킬이 레벨업 되어 있는 자신을 발견할 때의 희열을 맛보길 바란다.

결과는 나오게 되어있다. 결과를 얼마나 빨리 내느냐는 노력에 달린 것이다. =)


다음시간에..


반응형
Comments