Window Programming/VB

recordset - addnew, insert, update

목사 2021. 5. 8. 08:34
이번의 강좌는 레코드셋 객체를 통한 레코드의 조작방법에 대한 이야기입니다. 레코드 셋을 통해서 데이터를 Insert 하고, Update 하고, Delete 하는 방법을 알아보자는 것입니다. 기존에 우리는 테이블에 데이터를 넣기위해 주로 쿼리를 사용했습니다. 물론, 그 방법이 속도면에서는 빠르고, 데이터의 제어도 탁월한 편이지요. 하지만, 그 쿼리를 이용한 방법은 뭔가 직관적이지 못하다는 문제가 있었습니다.

에러메시지가 빠방!! 터지면 머리가 터질때까지 그 문자열에 작은 따옴표며, 문장 형식이며, 데이터들이 변수에는 잘 들어있는지 등등을...살펴야만 하지요.. 어떤 데이터가 들어갈 경우 에러가 나는 것인지도 모르고 무작정 찾아 헤매야만 합니다. 하나의 레코드에 약 100 개의 컬럼값을 넣는다고 생각해 보세요... 이 부분에서 에러가 나버리면 정말.. 술 생각 납니다.... 해서 그러한 경우는 속도가 조금은 느려진다고 하더라도 상당히 직관적인 방법인 RecordSet 객체의 Addnew 를 사용해서 데이터를 넣으면 편합니다.

테이블의 어떠한 데이터를 insert 를 하려 할 경우, 예를 들면 아마도 제 강좌나 책을 보고 공부하신 분은 예를 들자면 다음과 같이 하고 계실 것입니다.

<%
name = Request.Form("name")
Email = Request.Form("Email")
title = Request.Form("title")
memo = Request.Form("memo")

Set adoCon= Server.CreateObject("ADODB.Connection")
adoCon.Open("dsn = MySite;uid = ***;pwd = ***;")

Set Rs = Server.CreateObject("ADODB.RecordSet")

SQL = "INSERT INTO guest (name,Email,title,memo,writeday) VALUES "
SQL = SQL & "('" & name & "'"
SQL = SQL & ",'" & Email & "'"
SQL = SQL & ",'" & title & "'"
SQL = SQL & ",'" & memo & "'"
SQL = SQL & ",'" & date & "')"
adoCon.Execute SQL

adoCon.close
Set adoCon = Nothing
%>


이것은 RecordSet을 통해서 다음과 같은 방법으로도 가능합니다.

<!--METADATA TYPE= "typelib" NAME= "ADODB Type Library"
FILE="C:Program FilesCommon FilesSYSTEMADOmsado15.dll" -->
<%
name = Request.Form("name")
Email = Request.Form("Email")
title = Request.Form("title")
memo = Request.Form("memo")
Set adoCon= Server.CreateObject("ADODB.Connection")
adoCon.Open("dsn = MySite;uid=***;pwd=***;")

Set Rs = Server.CreateObject("ADODB.RecordSet")

rs.open "guest", adoCon, adOpenKeyset, adLockPessimistic, adCmdTable
rs.AddNew
rs.Fields("name") = name
rs.Fields("Email") = email
rs.Fields("title") = title
rs.Fields("memo") = memo
rs.Fields("writeday") = date
rs.Update
rs.Close

adoCon.close
Set Rs = Nothing
Set adoCon = Nothing





주의 해야할 것은.. 레코드셋 Open시 인자들의 세팅입니다.

첫번째 인자로는 여기서는 테이블 이름을 기입해 주었습니다. 이 첫번째 인자로는 테이블 명과, SQL쿼리등등의 사용이 가능한데,(많은 분들이 오로지 쿼리만이 가능한 것으로 아시는 분들이 많습니다.) 이것을 사용할 경우에는 다섯번째 인자로 어떤 것을 사용할 것인지 지정해 주는 것이 좋습니다. 다음 처럼 말입니다.

rs.open "guest", db, adOpenKeyset, adLockPessimistic, adCmdTable

여기서는 상수(adCmdTable)로 코딩을 했지만, AdoVBs.inc에 보시면. Const adCmdTable = &H0002 라고 추가되어져 있는 것을 보실 수가 있습니다. 사실상 adCmdTable 대신에 그 값인 2 라고 다음처럼 써주어도 됩니다만...

rs.open "guest", db, adOpenKeyset, adLockPessimistic, 2

숫자로 쓰면 여러분이 차후에 보기에 가독성이 떨어지기에 이렇게 상수로 지정해놓고 사용하시는 것이 여러모로 편합니다. Adovbs.inc를 타입 라이브러리로 바꾸시는 것이 좋은 것은 이미 알고 계시죠?

이제 우리는 Open시의 5개의 인자중 3개를 알았습니다. 첫번째는 오픈할 테이블, 두번째는 디비커넥션.. 다섯번째로 사용옵션!!(쿼리냐? 테이블이냐? 스토어드 프로시져나 등등) 이제는 3 번째 인자와 4번째 인자가 남아있는데, 이미 여러분들은.... 3번째 인자가 레코드셋의 커서타입을 의미한다는 것을 알고 있을 겁니다.

만일, 전혀 첨 듣는 이야기라면 이 강좌 이전에 게시판의 페이지나누기 부분을 읽어보셔야 합니다. 여기서는 반드시 레코드셋의 커서타입이 1 (adOpenKeyset) 아니면 2 (adOpenDynamic)로 지정되어져야만 합니다.

기본타입인 포워드 온리 타입은 레코드 셋의 업데이트가 불가능하기에.. 커서타입을 지정하지 않거나, 0으로 지정하면 이 레코드셋을 통한 업데이트 방법은 시용할 수가 없습니다.

그리고, 네번째 인자인 Lock 타입은 2 (adLockPessimistic) 로 지정하시는 것이 좋습니다. adLockPessimistic 로 지정하게 되면, 한 사용자가 편집을 위해서 이 레코드를 열고있는 동안에는 다른 사용자가 이 레코드를 변경, 수정하지 못하게 락을 거는, 즉 잠그는 역할을 하니까요... 어렵나요?

아마도 초보자라면 정말로 어려운 이야기일 것입니다. 무슨 이야기인지 하나도 이해가 안 갈 것임에 틀림없슴다. 불과 얼마전까지의 제가 그랬으니까요.. 하지만, 이 이야기는 데이터베이스에 대한 어느정도의 지식이 없다면 아무리 설명해 주어도 이해가 안 가는 부분이 될 것입니다. 꼬옥~~ 데이터베이스에 대해서 어느정도 공부하시기 바랍니다. 그리고 난 다음에 이 부분을 공부하시면 그제서는 이해가 모두 될 것일테니까요....
(특히나 데이터베이스에서 커서와 락에 대해서 꼭 공부하도록 하세요 ^^)

새롭게 데이터를 추가하기 위해서는 위에서처럼 데이터를 저장할 테이블을 수정이 가능한 커서타입과 락타입으로 오픈한 뒤에 레코드셋의 AddNew 메소드를 사용해서 먼저 데이터가 새로이 들어갈 레코드를 하나 추가해 주어야 합니다. 그리고 난 다음에는 각각의 컬럼에 데이터를 넣구요... 반드시 레코드셋 개체의 Update 메소드를 사용해 주어야 합니다. 이 순간 데이터는 실제로 데이터베이스에 반영이 되는 것이니까요... ^^

이것을 간단하게 표시하자면...

rs.AddNew ----> 레코드셋에 새로운 데이터가 들어갈 자리를 확보한다
rs.Fields("name") = name --> name 컬럼에 값을 넣는다.
rs.Fields("Email") = email --> Email 컬럼에 값을 넣는다.
rs.Fields("title") = title --> title 컬럼에 값을 넣는다.
rs.Fields("memo") = memo --> memo 컬럼에 값을 넣는다.
rs.Fields("writeday") = date --> writeday 컬럼에 값을 넣는다.
rs.Update ----> 실제로 현재 수정, 추가된 데이터를 데이터베이스에 반영한다. ^^
rs.Close

레코드셋을 통해서 Insert 하는 방법에 대해서 간략하게나마 알아보았는데요.. 그 지식을 잘 정리시구요..
강좌는 다시 첨부터 시작하는 맘으로 시작해 보도록 하겠습니다. 이 강좌에서는 레코드셋을 통해서 데이터를 저장, 수정, 삭제하는 것을 이야기해보도록 하겠습니다. Insert, Update, Delete 를 말입니다....

그럼 이번 강좌를 위해 필요한 것을 준비해 봅시다. 먼저 사용할 테이블입니다. 예제용 테이블이니 다음 그림처럼 간단하게 만들어보세요~



고집부리지 마시고, 위와 같이 만들어주시기 바랍니다요~~~ ^___^ 준비가 다 되었으면 이제 시작해 보겠습니다. 먼저, 이 테이블에 데이터를 입력하는 Insert 방법입니다. (물론, 이것은 위에서 간단히 알아보았습니다만.. 확인차원에다 다시금 해보도록 하자구요.. ^^)

1. Data 를 Insert 하기

<!--METADATA TYPE="typelib" FILE="C:program FilesCommon FilesSystemadomsado15.dll"-->
<%
'OLE DB를 통한 SQL 서버의 접속문자열
strConnect="Provider=SQLOLEDB;Data Source=서버네임; Initial Catalog=디비; User id=**; Password=** "

Dim Rs
Set Rs= Server.CreateObject("ADODB.Recordset")
with Rs
.Open "guest", strconnect, adOpenDynamic, adLockOptimistic
.AddNew
.Fields("name") = "taeyo"
.Fields("Email") = "taeyo@A.com"
.Fields("title") = "제목이다"
.Fields("memo") = "본문내용이다"
.Update
End with

Response.write "Insert 되었습니다.<p>"
Rs.Close
Set Rs = nothing
%>


먼저, 이 소스를 동작시켜 보세요... 그럼, 여러분은 데이터베이스에 칼같이 멋지게 데이터가 들어가는 것을 알수가 있습니다. VBScript 5.0 Engine 이 설치되지 않은 서버(2000은 기본 장착)는 위의 소스를 다음과 같이 하셔야 합니다. 이유는 그곳에서는 With 구문이 적용되지 않기 때문입니다. With구문은.. VBScript 5에서 새로이 지원되기 시작한 구문이거든요.(하긴 지금쯤이면 대부분의 서버가 W2K 일 것이고.. 이 IE 5.5나 6.0 혹은 그 이상을 사용할테니.. 문제는 없겠네요 ^^)

<!--METADATA type="typelib" FILE="C:program FilesCommon FilesSystemadomsado15.dll"-->
<%
strConnect="Provider=SQLOLEDB;Data Source=서버네임; Initial Catalog=디비; User id=**; Password= **"

Dim Rs
Set Rs= Server.CreateObject("ADODB.Recordset")
Rs.Open "guest", strconnect, adOpenDynamic, adLockOptimistic

Rs.AddNew
Rs.Fields("name") = "taeyo"
Rs.Fields("Email") = "taeyo@A.com"
Rs.Fields("title") = "제목이다"
Rs.Fields("memo") = "본문내용이다"
Rs.Update

Response.write "Insert 되었습니다.<p>"
Rs.Close
Set Rs = nothing
%>


그러면 이제 소스에 대한 설명을 같이 한번 들어볼까요?? ^^

1. <!--METADATA TYPE="typelib" FILE=".... 부분.
이 부분은 전 강좌에서 이미 설명이 된 타입라이브러리에 관계된 것입니다.
이 부분에서 막히시면 이전 강좌를 읽어보시기 바랍니다.
이 라이브러리를 연결함으로써 이 ASP 페이지에서는 adOpenDynamic, adLockOptimistic 와 같은
ADO용 상수를 사용할수 있게됩니다.

2.strConnect="Provider=SQLOLEDB;Data Source....
이 부분은 서버로의 연결을 위한 접속 문자열을 만드는 부분입니다.
이전에는 ODBC를 자주 사용하고는 하였습니다만. 요즘에는 ODBC보다는
OLE DB를 통해서 바로 디비로 연결하는 방식이 많이 사용됩니다.
이것이 속도의 향상효과가 있기 때문이지요...
각각의 데이터베이스로의 OLE DB 접근문자열은 아래의 박스 기사로 준비했습니다.

3. Rs.Open "guest", strconnect, adOpenDynamic, adLockOptimistic
이 부분이 참 중요한 부분입니다.
- 첫번째 인자는 가져올 데이터를 나타내는데,
여기에는 테이블 이름, 쿼리문자열, 스토어드 프로시져등이 올 수 있습니다.
- 두번째 인자는 데이터베이스 연결객체(Connection) 이나 데이터베이스 연결문자열이 사용됩니다.
이 Open 메소드의 두번쨰 인자로는 디비 Connection 객체가 아닌 ODBC 연결 문자열이나, DB 접속 문자열이
올 수가 있습니다. 그렇게되면, 자동으로 Connecton 객체를 백그라운드에서 만들고 자동으로 접속을 합니다.
즉, 내부적으로 커넥션 객체는 만들어진다는 점을 기억하시기 바랍니다.
- 세번째, 네번째 인자로는 이미 이야기했듯이 커서타입과 릭타입이 오게 되구요...
- 다섯번째 인자로는 첫번째 인자가 어떤 형식인지를 알려주는 것으로 가급적 꼭 기입하시기 바랍니다.
만일 첫번째 인자가 쿼리 문자열 이라면 adCmdText
만일 첫번째 인자가 테이블 이름 이라면 adCmdTable
만일 첫번째 인자가 저장 프로시져 라면 adCmdStroedProc

4. Rs.AddNew .......... Rs.Update
이 부분은 이미 위에서 모두 설명드린 부분이니 ... ^^

SQL서버 : DSN 없이 ODBC 연결방법
Driver= {SQL Server}; Server= 디비서버이름;Database=디비이름; UID=아이디; PWD=비밀번호
ex) Driver={SQL Server}; Server= taeyo;Database=taeyoDB; UID=taeyo; PWD=11

SQL서버 : OLE DB 직접 접근 방법
Provider=SQLOLEDB; Data Source=디비서버이름;Initial Catalog= ;디비이름; User id= 아이디;
password= 비밀번호
ex) Provider= SQLOLEDB;Data Source= taeyo;Initial Catalog= taeyo;User id=taeyo; password= 11

Ms-Access OLE DB 직접접근 방법
Provider=Microsoft.Jet.OLEDB.4.0;Data Source= MDB파일의 물리적인 전체경로
ex) Provider=Microsoft.Jet.OLEDB.4.0;Data Source= C:workMyDb.mdb




2. Data 를 Update 하기

<!--METADATA type="typelib" FILE="C:program FilesCommon FilesSystemadomsado15.dll"-->
<%
strConnect="Provider=SQLOLEDB;Data Source=서버네임; Initial Catalog=디비; User id=**; Password= **"

Dim Rs
Set Rs= Server.CreateObject("ADODB.Recordset")
SQL= "SELECT * FROM guest WHERE guest_idx = 1 "
with Rs
.Source = SQL
.ActiveConnection = strconnect
.CursorType = adOpenStatic
.LockType = adLockOptimistic
.Open
.Fields("name") = "Guest"
.Fields("Email") = "taeyo@A.com"
.Fields("title") = "제목이다"
.Update
End with

Response.write "Update 되었습니다."
Rs.Close
Set Rs = nothing
%>


이번의 내용은 특정 레코드를 업데이트(수정) 하는 작업입니다.. 이전의 Addnew 방법과 그다지 차이는 없습니다만... 이번에는 불러오는 레코드가 특정 레코드로 지정이 되어져 있고, Addnew 는 사용하지 않습니다. 또한, 주의해야할 점은 CursorType 과 LockType 입니다. 레코드 셋 객체를 통해서 레코드의 값을 업데이트하고자 하는 경운, 그 CursorType 이 가급적 adOpenStatic 로 지정이 되어져야 합니다.(다른 커서타입도 있지만 이 타입이 보편적으로 가장 나아보입니다) adOpenStatic 이 되어야 레코드셋 객체를 통해 추가, 수정, 삭제한 데이터가 반영되기 때문입니다. (물론, adOpenDynamic 도 가능합니다. 그러나, 이것은 속도가 느립니다.)

또한, 그와 동시에 LockType 도 adLockOptimistic 혹은 adLockPessimistic로 지정이 되어져야만 합니다. 그래야, 두 사람이상의 사용자가 같은 레코드를 수정하려고 할 경우. 문제가 발생하는 것을 막을 수가 있게 되지요. adLockOptimistic 가 바로 그런 역할을 합니다. 공유잠금이라고 하여, 데이터의 수정시에만 레코드를 잠그는 일을 합니다요. 그것만을 주의하시면 됩니다. 역시나 이 방법도 기존의 Query 를 통해서 처리한 것보다 훨씬 직관적이지요?

그리고, 아시는 이야기이게지만.. 위의 소스에서 여러줄로 나누어 쓴 아래와 같은 소스 부분 말입니다.

with Rs
.Source = SQL
.ActiveConnection = strconnect
.CursorType = adOpenStatic
.LockType = adLockOptimistic
.Open

이것은 다음의 한줄로 바꾸어 쓸 수도 있습니다. 여러분이 맘에 드는 방법으로 쓰시면 됩니다.

Rs.Open SQL, strConnect, adOpenStatic,adLockOptimistic

이 방법(레코드셋을 통해서 데이터를 수정하는 방법)의 또 한가지 좋은 점은 어떤 컬럼의 데이터를 수정하다가 에러가 날 경우.. 그 에러가 나는 라인이 명확하여, 어떤 컬럼에 데이터를 넣다가 실패했는지를 확연히 알수 있다는 사실입니다. 이것은 쿼리 문자열을 사용하여 같은 처리를 할 경우에 자주 만나는 에러를 잡기위해 낭비하는 아까운 시간들을.. 상당히 줄여주지요.. ^__^ 맘에 드시나요?

그렇다면, 데이터를 삭제하는 방법은 어떨까요? 이것은 더욱 간단하지 않을까요? 그렇습니다. 뭐든지 만들고, 바꾸는 것은 어렵지만..지워버리는 것은 아주 간단하지요..



3. Data 를 Delete 하기

<!--METADATA type="typelib" FILE="C:program FilesCommon FilesSystemadomsado15.dll"-->
<%
strConnect="Provider=SQLOLEDB;Data Source=서버네임; Initial Catalog=디비; User id=**; Password= **"

Dim Rs
Set Rs= Server.CreateObject("ADODB.Recordset")
SQL= "SELECT * FROM guest WHERE guest_idx = 1 "
with Rs
.Source = SQL
.ActiveConnection = strconnect
.CursorType = asOpenDynamic
.LockType = adLockOptimistic
.Open
.Delete
End with

Response.write "Delete 되었습니다."
Rs.Close
Set Rs = nothing
%>


거의 모든 소스가 Update 시와 비슷하지요? 그렇습니다. 이 부분도 같은 레코드를 두 사람 이상이 삭제하고자 할 경우를 대비해서 LockType 이 잡혀져 있는 것을 확인할 수가 있을 것입니다... 이전 두가지의 예제를 잘 하셨다면, 이 부분은 그리 문제없이 이해가 가는 부분일 것입니다.

그렇지요? 자..어떤가요? 유용하지 않은가요?? 이미 알고있는 내용이었다구요? 그렇다고 해도 유용한 시간이었을 것이라고 생각됩니다. 왜냐하면, 이 부분이 국내 ASP 서적에는 거의 없기 때문입니다...(적어도 2000년 1월까지는 그랬습니다) 물론, VB 책에는 있지요.. 그러니 사실 ASP를 더욱 깊이 공부하시려면 VB를 하셔야 합니다. ASP와 VB는 떨어질수 없는 관계이니까요... 어떻게 보면 ASP는 VB의 자식과 같은 존재이니까요...

이제, IIS 5 가 등장하면서 ASP는 더욱 VB와 같은 모습을 갖추기 시작했습니다.. ^___^ 하지만, 여전히 머리가 아픈 문제중에 하나는 웹은 상태가 없는 곳이라는 점입니다. 일반 C/S 프로그램은 서버와의 상태유지가 되기 때문에, 서버와의 연결뒤 계속적인 어떤 데이터의 교환이 이루어질 수 있지만, 웹에서는 상태라는 것이 없기에 매번 페이지마다 서버와 연결해서 데이터를 가져와야 하는 구성을 갖게됩니다.