270 likes | 438 Views
서버 연결 (Connection). 연결형 방식의 주요 클래스 Connection, Reader, Adapter 클래스 연결 객체 연결은 뒤에 ~Connection 이라는 이름이 붙은 클래스로 관리 SQL 서버의 경우 SqlConnection 클래스가 연결을 담당 SqlConnection 클래스의 생성자 연결 문자열을 지정하는 방법 통상적으로 생성자에서 연결 문자열을 지정 디폴트 생성자로 일단 생성한 후 프로퍼티로 연결 문자열을 따로 지정할 수도 있음.
E N D
서버 연결(Connection) • 연결형 방식의 주요 클래스 • Connection, Reader, Adapter 클래스 • 연결 객체 • 연결은 뒤에 ~Connection 이라는 이름이 붙은 클래스로 관리 • SQL 서버의 경우 SqlConnection클래스가 연결을 담당 • SqlConnection클래스의 생성자 • 연결 문자열을 지정하는 방법 • 통상적으로 생성자에서 연결 문자열을 지정 • 디폴트 생성자로 일단 생성한 후 프로퍼티로 연결 문자열을 따로 지정할 수도 있음. public SqlConnection( ) public SqlConnection( string connectionString)
연결과 관련된 정보와 여러 가지 옵션들이 프로퍼티로 제공됨.
제한 시간, 연결할 서버명 등에 대한 정보는 모두 연결 문자열을 통해 초기화되며 실행 중에 변경하려면 별도의 메서드를 호출해야 함. • 메서드 목록 • 런타임이 해제를 자동으로 수행하지 않으므로 연결 해제는 직접 해야하며 절대로 생략해서는 안됨.
연결 문자열 • DB서버에는 서버가 요구하는 인증을 통과해야 하는데 일반적으로 ID와 비밀번호를 인증 수단으로 사용함. • 연결 문자열 • 연결에 필요한 정보를 가장 일반적인 포맷인 문자열 형태로정의한 것. • 연결 문자열은 “키=값” 형태의 대입문을 세미콜론으로 구분하여 여러 개 모아 놓은 것이며 접속에 필요한 여러 가지 정보를제공 • 키의 종류는 공급자마다 다르며 접속하고자 하는 서버가 요구하는키를 문법에 맞게 잘 작성해야 함.
연결 문자열의 각 키에 적당히 값을 대입하고 Open 메서드를 호출하면 연결됨. • (예) 로컬 서버의 ADOTest DB 에 연결하는 간략한 예 Con = new SqlConnection(); Con.ConnectionString = "Server=(local);database=ADOTest;" + "Integrated Security=true"; try { Con.Open(); } catch (Exception ex) { MessageBox.Show(ex.Message); } …….. Con.Close() ;
연결뿐만 아니라 명령 실행 중에도 예외는 언제든지 발생할 수 있으며 예외가 발생할 만한 코드는 항상 try 블록으로 감싸는 것이원칙 • Open 호출이 성공했으면 서버와 연결된 것이므로 이후 이 연결을통해 서버에게 명령을 보낼 수 있음. • 연결은 가비지 컬렉션 대상이 아니므로 사용이 끝난 후에는 반드시 Close 나 Dispose 를호출하여 명시적으로 닫아야 함. • SQL 서버의 연결 문자열은 최소한 서버명, DB명, 인증 모드 세가지의 정보가 필요함. • 윗 코드에서는 윈도우즈 통합 인증 모드를 사용하여 현재 로그인한 사용자의 ID 로 인증을 받았는데 로컬 서버에서는 이 방법이가장 간편함. • SQL 서버의 인증 모드가 윈도우즈 인증 모드가 아니라면 사용자의 계정과 ID를 지정하여 접속해야 함. Con.ConnectionString = "Server=(local);database=ADOTest; User ID=sa;Pwd=“;
암호를 연결 문자열에 넣어 버리면 시스템 상황에 따라 실행 여부가결정되는 문제가 있고 중요한 암호가 노출될 수 있으므로 바람직하지 않으며 권장되지도 않음. • 가급적이면 윈도우의 통합 보안을 사용하는 것이 안전함.
SQL 문 실행 • 서버에 연결했으면 다음은 서버에게 명령을 보내거나 프로시저를호출하여 데이터를 달라고 요청해야 함. • 실행 명령은 SqlCommand클래스로 표현함. public SqlCommand(string cmdText, SqlConnectionconection) public SqlCommand( ) • SqlCommand클래스로 실행하는 방법 • 윗 예문과 같이 생성자로SQL 명령 문자열과 연결 객체에 대한 참조를 전달하는것이 가장 일반적 • 명령문과 명령을 실행할 서버를 생성 시점에 미리 밝히는 것 • 하나의 명령만 실행할 때는 이 방법이 간편함. • 기본 생성자나 연결 객체의 다음 메서드로 빈 명령 객체를생성 public SqlCommandCreateCommand( )
빈객체를 생성한 후 프로퍼티를 통해 연결이나 실행할 명령을대입하면 됨. • 명령 객체 하나로 여러 개의 명령을 번갈아 가며 실행할 때는 이방법이 더 편리함. • 명령 객체의 프로퍼티(property) • 생성자로 전달하는 연결 객체와 명령문이 프로퍼티로도 정의되며 그 외 시간 설정이나 명령의 유형, 파라미터 등의 정보들도 지정할 수 있음.
명령 객체가 준비되었으면 실행 메서드를 호출함. • 실행할 명령의 종류에 따라 호출하는 메서드들이 따로 준비되어있는데 각 메서드는 리턴값의 형태가 다름.
private void btnSum_Click(object sender, EventArgs e) { string Sql = "SELECT SUM(Age) FROM tblPeople"; SqlCommandCom = new SqlCommand(Sql, Con); int Sum = (int)Com.ExecuteScalar(); MessageBox.Show("나이의 총 합은 " + Sum + "입니다."); } • SUM, AVG, COUNT 같은 집계 함수들은 결과셋을리턴하는 것이아니라 하나의 단일값을리턴하므로ExecuteScalar메서드로 실행
Reader객체는 SELECT문의 결과셋을 가지는 읽기 전용, 전진 전용의 객체 • Reader 객체는 오로지 결과셋을 읽기만 할 뿐이며 삽입, 삭제,수정 등의 동작은 할 수 없음. • 명령 실행의 결과로만 생성되므로 별도의 생성자는 정의되어있지않으며 따로 생성할 필요도 없음. • 결과셋의 정보들은 Reader 객체의 다음 프로퍼티를 통해 조사
Reader로부터 결과셋을 읽을 때는 별도로 제공되는 메서드를 쓸 수도 있지만 통상은 인덱서를 사용함. • 읽고자 하는 열의 이름이나 순서 값을 인덱서의 인수로 전달함. • 주요 메서드 • Read메서드는결과셋의 레코드를 순서대로 읽음. • 리더 객체가 생성된 후에는 결과셋의 첫 레코드 이전을 가리키고 있으므로 Read 메서드를 먼저 호출해야 첫번째 레코드를읽을 수 있음. • NextResult메서드는 여러 개의 결과셋을 한꺼번에 읽을 때 다음 결과 셋으로 이동함. • 다 읽은 후에는 Close메서드로결과셋을 반드시 닫아야 함. public override bool Read( ) public override boolNextResult( )
파라미터 사용 사용법 1 • SQL 쿼리문은 단순한 문자열 포맷이지만 이 문자열 안에는 검색조건이나 삭제 대상, 수정할 값 등을 전달받기 위한 인수들이 포함됨. • UPDATE 문은 수정할 대상과 수정할 값을 입력 받아야 하고 DELETE문은 삭제할 레코드의 키를 입력 받아야 함. • 새로운 레코드를 삽입하는 INSERT문의 경우 새 레코드의 정보를전달받기위한 인수가 반드시 필요함. • 실행 중에 사용자의 입력을 받아들이려면 텍스트 박스나 체크 박스같은 컨트롤을 배치하고 이 컨트롤의 값을 읽어 사용자가 입력한 값을 SQL 쿼리문에 포함시키는 방법을 사용. private void btnInsert1_Click(object sender, EventArgs e) { string Sql=string.Format("INSERT INTO tblPeople VALUES ('{0}',{1},{2})", textName.Text, textAge.Text, checkMale.Checked ? 1 : 0); SqlCommandCom = new SqlCommand(Sql, Con); Com.ExecuteNonQuery(); PrintTable(); }
INSERT INTO 쿼리문을 작성하되 VALUES절로 전달되는 필드의 값을컨트롤로 부터입력받음. • 문자열인 경우 작은따옴표로 적어야 함. • 사용자가 어떤 값을 입력하는 가에 따라 쿼리문의 내용이 달라지며 실제로 삽입되는 레코드도 달라짐.
사용법 2 • ADO.NET은 쿼리문을 생성할 때 사용법 1과 같은 문자열 조립 방법대신 좀 더 효율적인 파라미터라는 문법을 제공 • 마치 메서드에게 인수를 전달하는 것처럼 SQL문에게 파라미터를전달하여 실행할 명령의 정보를 제공 • 실행 중에 결정되는 값에 @으로 시작되는 파라미터 이름만 적어놓고 실제 값은 쿼리문을 실행하기 전에 제공하는 방법. • 파라미터를 쓰는 쿼리문은 한번만 컴파일되며 이후부터는 파라미터만 바꿔 가며 실행할 수 있으므로 매번 문자열을 조립하는 것보다실행 속도가 훨씬 더 빠름. • 파라미터 자체는 SqlParameter클래스로 표현하며 SqlCommand의 Parameters 프로퍼티로파라미터의 컬렉션을 관리함. • 명령 하나로 여러 개의 값이 포함될 수 있으므로 파라미터도컬렉션을 구성함.
파라미터의생성자 public SqlParameter(string parameterName, SqlDbTypedbType, int size, string sourceColumn) • 파라미터의 이름, 타입, 크기, 연결된 컬럼 등을 인수로 받아들임. • 이 값들은 프로퍼티로도 제공되므로 객체 생성 후에 언제든지변경 가능.
파라미터가 있는 명령문을 실행하려면 파라미터 개수 만큼 SqlParameter객체를 생성하여 Parameters 컬렉션에 넣어두어야 함. • (방법 1) • 파라미터 객체를 미리 생성한 후 컬렉션의 Add 메서드로추가 • (방법 2) • 컬렉션의 Add 메서드로파라미터의 주요 프로퍼티를전달하여 생성과 동시에 추가 public SqlParameter Add(SqlParameter value) public SqlParameter Add(string parameterName, SqlDbTypesqlDbType, [ int size, string sourceColumn ] ) • 파라미터의 실제 값은 Value 프로퍼티를 통해 제공됨. • 쿼리 실행문은파라미터의 실제 값으로 쿼리문을재작성하여실행함. Com.Parameters["@Name"].Value = textName.Text;
프로시저 실행 • 저장 프로시저는 서버에 미리 정의해 놓은 함수 • 업무 로직을 서버가 관리하기 위해 일련의 명령들을 모아 놓고 이름을 붙여 놓은 것. • 클라이언트는 상세한 규칙을 몰라도 명령 객체를 통해 프로시저를호출하여 서버의 서비스를 받음. • (실습)SQL 서버의 쿼리 창에서 다음 명령으로 프로시저를 하나생성하자!!! CREATE PROCEDURE IncAllAge AS UPDATE tblPeople Set Age = Age + 1 • 모든 고객이 대상이며 증감 값이 고정되어 있으므로 인수도없고 리턴값도 없음.
클라이언트에서 명령 객체를 사용하여 위의 저장 프로시저를 호출하는코드 private void btnIncAllAge_Click(object sender, EventArgs e) { SqlCommand Com = new SqlCommand("IncAllAge", Con); Com.CommandType = CommandType.StoredProcedure; intnRow; nRow = Com.ExecuteNonQuery(); PrintTable(); MessageBox.Show("영향받은 행수 = " + nRow); }
인수가 있는 저장 프로시저 CREATE PROCEDURE IncSomeAge @Name NVARCHAR(10), @Age INT OUTPUT AS UPDATE tblPeople SET Age = Age + 1 WHERE Name=@Name ; SELECT @Age= Age FROM tblPeople WHERE Name=@Name ; • 인수로 전달받은 고객의 나이만 1 증가시키고 증가된 나이를리턴함.
인수가 있는 저장 프로시저를 호출하는 코드 private void btnIncSomeAge_Click(object sender, EventArgs e) { // 명령 객체 생성 SqlCommand Com = new SqlCommand("IncSomeAge", Con); Com.CommandType = CommandType.StoredProcedure; // 파라미터 설정 Com.Parameters.Add("@Name", SqlDbType.NVarChar, 10); Com.Parameters.Add("@Age", SqlDbType.Int); Com.Parameters["@Age"].Direction = ParameterDirection.Output; // 호출 Com.Parameters["@Name"].Value = "김태희"; Com.ExecuteNonQuery(); // 결과 출력 PrintTable(); int Age = (int)Com.Parameters["@Age"].Value; MessageBox.Show("프로시저 호출 후 나이 = " + Age); }
트랜잭션(transaction) 처리 • 트랜잭션은 작업을일관되게 처리할 수 있는 서버측의 장치 • 트랜잭션을 사용하면작업 중에 치명적인 에러가 발생하더라도모든 작업을 안전하게 취소할 수 있어 무결성을 유지할 수 있음. • 트랜잭션은 연결(Connection) 수준에서 관리됨. • Connection 객체의BeginTransaction메서드를 호출하면 트랜잭션이 시작되며 이후의 모든 명령은 즉시 실행되지 않고 트랜잭션 내에 모았다가 한꺼번에 수행 또는 취소됨. public SqlTransactionBeginTransaction( [IsolationLeveliso, string transactionName] ) • BeginTransaction메서드의 인수로 격리 수준과 트랜잭션의 이름을지정 • 생략시에는 서버의 기본 격리 수준을 따르며 트랜잭션의이름은 없음.
트랜잭션이 시작되면 SqlTransaction객체가 생성되어 리턴되는데 이 객체는 트랜잭션 끝에서 트랜잭션의 처리 여부를 결정함. • 작업 후 SqlTransaction객체의 다음 두 메서드를 호출하여 트랜잭션 전체를 실행하거나 또는 전체를 취소함. • 롤백할 때는 미리 지정한 트랜잭션의 이름을 인수로 전달 가능 public override void Commit( ) public void Rollback( [string transactionName] ) • 다음두 SQL 명령은 트랜잭션의 가장 흔한 예인 계좌 이체를흉내 낸 것. UPDATE tblPeopleSET Age = Age + 1 WHERE Name = '정우성’ ; UPDATE tblPeopleSET Age = Age - 1 WHERE Name = '배용준’ ;