ASP 강의 8: ASP와 데이터베이스 (3)
저자:Eve Cole
업데이트 시간:2009-05-30 19:55:00
지난 두 강의에서는 ASP에서 데이터베이스의 기본적인 사용법을 설명했습니다. 오늘은 몇 가지 매우 실용적인 기술을 소개하겠습니다.
1. 페이징 기술 데이터의 양이 적을 경우에는 이렇게 간단한 출력 처리가 가능하지만, 데이터 양이 수백, 수천 개에 달하는 경우에는 데이터를 검색하여 브라우저에 출력하는 방법을 소개했습니다. , 한 번에 너무 많은 데이터를 클라이언트에 출력하는 것은 비현실적입니다. 첫째, 페이지가 위에서 아래로 너무 길어집니다. 둘째, 클라이언트가 너무 오래 기다립니다. 셋째, 서버의 부하가 너무 큽니다. 따라서 페이징된 출력을 수행하는 것이 매우 필요합니다.
요구 사항: Northwind.mdb의 "제품" 테이블에 있는 데이터를 브라우저에 출력하고 각 페이지에 10개의 항목을 표시합니다.
wuf60.asp를 예로 들어보겠습니다. 이 코드는 아직 좀 어렵습니다. AdoAccess.asp는 더 많이 읽고 경험해 보아야 합니다.
참고: 이 루틴은 일부 책의 좋은 부분을 통합하여 선언합니다.
<%@ LANGUAGE="VBSCRIPT" %>
<!--#include file="AdoAccess.asp"-->
<!--#include 파일="adovbs.inc"-->
<%
희미한 RecordPerPage, absPageNum, TotalPages, absRecordNum, rsTest, StrSQL
'absPageNum - 현재 페이지는 어떤 페이지인가요?
'TotalPages - 총 페이지 수
'absRecordNum - 현재 페이지에 있는 레코드의 일련 번호(예: 1-10)
RecordPerPage = 10 '페이지당 표시되는 레코드 수
' 출력 데이터의 현재 페이지 번호를 가져옵니다.
Request.ServerVariables("CONTENT_LENGTH") = 0인 경우
'폼에서 제출한 데이터가 수신되지 않는 경우(페이지를 처음 로드할 때 등) 1페이지부터 표시됩니다.
절대페이지번호 = 1
또 다른
'버튼을 누르면 페이지 번호를 가져옵니다
absPageNum = CInt(Request.Form("PressPageNum"))
'이전 페이지를 누르면 페이지 번호가 -1이 되고, 다음 페이지를 누르면 페이지 번호가 +1됩니다.
Request.Form("Submit") = "이전 페이지"인 경우
ABSPageNum = ABSPageNum - 1
ElseIf Request.Form("Submit") = "다음 페이지" Then
ABSPageNum = ABSPageNum + 1
종료 조건
종료 조건
'레코드세트 객체 생성
rsTest = Server.CreateObject("ADODB.Recordset") 설정
rsTest.CursorLocation = adUseClient '이 설정은 데이터베이스 부하를 줄일 수 있습니다.
rsTest.CursorType = adOpenStatic '커서는 앞뒤로 이동해야 하며 앞으로만 이동하도록 설정할 수 없습니다.
rsTest.CacheSize = RecordPerPage '이 옵션을 설정하면 성능이 향상됩니다.
StrSQL = "SELECT * FROM productOrder By productID"
rsTest.Open StrSQL, Cnn, , , adCmdText
rsTest.PageSize = RecordPerPage '페이지당 레코드 수를 설정합니다.
그렇지 않은 경우(rsTest.EOF) 그러면
rsTest.AbsolutePage = ABSPageNum
종료 조건
TotalPages = rsTest.PageCount
%>
<% '다음 부분은 현재 페이지의 데이터를 브라우저에 출력합니다%>
<Html><바비>
<테이블 colspan=8 cellpadding=5 테두리=0>
<tr>
<td align=CENTER bgcolor="#800000" width="109"> <font style="ARIAL NARROW" color="#ffffff" size="2">단가</font></td>
<td align=CENTER width=459 bgcolor="#800000"> <font style="ARIAL NARROW" color="#ffffff" size="2">제품 이름</font></td>
</tr>
<% '루프를 사용하여 현재 페이지에 10개의 데이터를 출력합니다.
AbsRecordNum = 1 ~ rsTest.PageSize의 경우
%>
<tr>
<td bgcolor="f7efde" align=CENTER> <font style="ARIAL NARROW" size="2"><%= rsTest("unit Price")%></font></td>
<td bgcolor="f7efde" align=CENTER> <font style="ARIAL NARROW" size="2"><%= rsTest("제품 이름")%></font></td>
</tr>
<%
rsTest.MoveNext
rsTest.EOF이면
Exit For ' 레코드 끝에 도달한 경우 종료 - 데이터의 마지막 페이지가 가득 차지 않은 경우.
종료 조건
다음
rsTest.Close : Cnn.Close
rsTest = 없음 설정: Cnn = 없음 설정
%>
</table>
<% '하단에는 "이전 페이지" "다음 페이지" 버튼 2개가 있습니다 %>
<양식 작업 = "<%= Request.ServerVariables("SCRIPT_NAME") %>" Method="Post">
<Input Type="Hidden" Name="PressPageNum" Value="<%= absPageNum%>">
<%
If absPageNum > 1 그러면 '현재 페이지가 첫 번째 페이지가 아닌 경우 이전 페이지 버튼 표시%>
<Input Type="제출" Name="제출" Value="이전 페이지">
<% 종료 조건
If absPageNum <> TotalPages Then '현재 페이지가 마지막 페이지가 아니면 다음 페이지 버튼 표시%>
<Input Type="제출" Name="제출" 값="다음 페이지">
<% 종료 조건 %>
</양식>
<P><중앙> [페이지<font color="#CC0033"><%= absPageNum %></font>,
총<font color="#CC0033"><%= TotalPages %></font> 페이지] </Center></P>
</BODY></HTML>
분석하다:
1. Recordset 개체의 몇 가지 유용한 속성은 다음과 같습니다.
l rsTest.CursorLocation = adUseClient: 이 문장을 생략할 수도 있지만 그렇게 하면 데이터베이스 로드가 줄어들 수 있습니다.
l rsTest.CacheSize = RecordPerPage: CacheSize 속성은 클라이언트가 매번 데이터베이스 서버에서 얻는 데이터의 양을 결정하는 데 사용됩니다.
l rsTest.PageSize: PageSize 속성은 각 페이지의 레코드 수를 설정하는 데 사용됩니다.
l rsTest.AbsolutePage: AbsolutePage 속성은 Recordset 개체에 있는 현재 데이터의 절대 페이지 수를 설정합니다.
l rsTest.PageCount: PageCount 속성은 레코드 세트의 총 페이지 수를 가져오는 데 사용됩니다.
2. 이 예제 양식은 숨겨진 필드 PressPageNum을 사용하여 버튼을 클릭할 때 페이지를 전달합니다.
2. 오류 처리 코드를 실행하는 동안 코드 자체의 문제, 네트워크 연결 끊김 등 다양한 이유로 오류가 발생할 수 있으므로 프로그램에서 오류 캡처 및 처리를 설정하는 것이 매우 필요합니다. ASP에서는 Connection 개체의 Errors 데이터 수집을 통해 코드 실행 시 발생하는 오류 또는 경고 정보를 얻을 수 있습니다.
1. Connection 개체에서 직접 사용하십시오.
Errs = Cnn.Errors 설정
또는
Cnn.오류
2. Recordset 개체 또는 Command 개체를 설정한 후 ActiveConnection 속성을 통해 Connection 개체를 사용합니다.
Errs = rsTest.ActiveConnection.Errors 설정
또는
rsTest.ActiveConnection.Errors
너무 조잡하게 들리므로 예를 들어보겠습니다: wuf61.asp
<%@ LANGUAGE="VBSCRIPT" %>
<% 옵션 명시적 %>
<!--#include 파일="adovbs.inc"-->
<%
응답.만료 = 0
'다음 문장은 다음을 보장합니다. 스크립트에 오류가 발생하더라도 다음 문장을 계속 실행합니다.
오류 발생 시 다음 재개
Dim Cnn, rsTest, Errs, I
Cnn = Server.CreateObject("ADODB.Connection") 설정
'CommandTimeout - 데이터베이스 연결을 위한 최대 대기 시간, 기본값은 15초
Cnn.CommandTimeout = 5
'SQL Server를 예로 들면 다음 세 가지 상황에서 오류를 감지할 수 있습니다.
'1 - 완전히 정확합니다. 2 - 초기 데이터베이스가 설정되지 않았습니다. 3 - 데이터베이스 이름이 잘못되었습니다.
Cnn.Open "공급자=sqloledb; 사용자 ID=sa; 비밀번호=; 초기 카탈로그=pubs; 데이터 소스=ICBCZJP"
'Cnn.Open "공급자=sqloledb; 사용자 ID=sa; 비밀번호=; 초기 카탈로그=; 데이터 소스=ICBCZJP"
'Cnn.Open "공급자=sqloledb; 사용자 ID=sa; 비밀번호=; 초기 카탈로그=pvbs; 데이터 소스=ICBCZJP"
I = 0의 경우 Cnn.Errors.Count - 1
'Source 속성은 오류의 소스를 나타냅니다.
응답.쓰기 "[ " & Cnn.Errors(I).소스 & " ] "
'설명 속성은 오류의 이유나 설명을 나타냅니다.
응답.쓰기 Cnn.오류(I).설명 & "<br>"
다음
Cnn.Errors.Count > 0인 경우
Response.Write "연결하는 동안 발생했습니다" & Cnn.Errors.Count & " 오류" & "<br>"
종료 조건
rsTest = Server.CreateObject("ADODB.Recordset") 설정
rsTest.Open "작업",Cnn,adOpenForwardOnly,adLockReadOnly,adCmdTable
rsTest.ActiveConnection.Errors.Count > 0인 경우
Session("Errs") = rsTest.ActiveConnection.Errors 설정
응답.리디렉션 "ErrorHandle.asp"
종료 조건
Cnn.닫기
rsTest = 없음 설정: Cnn = 없음 설정
%>
ErrorHandle.asp 코드:
<%
나는 어둡다
I = 0의 경우 Session("Errs").Count - 1
응답.Write "[ " & Session("Errs")(I).Source & " ] "
응답.쓰기 세션("Errs")(I).설명 & "<br>"
다음
%>
분석하다:
이런 경우에는 연결 중 오류가 발생한 것일 수도 있고, 연결은 맞았지만 Recordset 개체를 사용하는 중에 오류가 발생한 것일 수도 있습니다.
또한 다음 코드에서는 페이지 간에 호출할 수 있도록 오류 컬렉션을 세션 개체에 넣습니다. 오류가 발생하면 오류 처리 페이지 ErrorHandle.asp를 참조하세요.
실제로 Recordset 개체를 Session 개체에 할당하여 페이지 간 레코드 집합 호출을 구현할 수도 있습니다.
3. 거래를 활용한다는 개념은 매우 간단하고 중요하며, 그 활용을 설명하기 위해 먼저 다음과 같은 상황을 가정해 보겠습니다. 예를 들어 전자상거래에서 온라인으로 송금할 때 일정 금액을 차감해야 합니다. 계정 금액을 선택하고 해당 금액을 다른 계정에 추가합니다. 어떤 업데이트가 실패하더라도 계정 잔액의 불균형이 발생합니다(여기서는 공제가 있지만 증가가 없거나, 공제가 없지만 증가가 있습니다). . 이러한 변경을 위해 트랜잭션을 사용하는 경우 모든 변경을 수행하거나 변경하지 않음(완전히 수정되거나 완전히 취소됨)만 선택할 수 있습니다.
트랜잭션은 세 가지 트랜잭션 관련 메서드가 있는 Connection 개체에 속합니다.
l BeginTrans는 새로운 트랜잭션을 시작합니다.
l CommitTrans는 모든 변경 사항을 저장하고 현재 트랜잭션을 종료합니다.
l RollbackTrans는 현재 트랜잭션의 모든 변경 사항을 취소하고 트랜잭션을 종료합니다. 이를 종종 "롤백"이라고 합니다.
wuf62.asp 예제를 살펴보는 것이 좋습니다.
<%@ LANGUAGE="VBSCRIPT" %>
<% 옵션 명시적 %>
<!--#include 파일="adovbs.inc"-->
<%
응답.만료 = 0
오류 발생 시 다음 재개
DimCnn, StrSQL, rsTest
Cnn = Server.CreateObject("ADODB.Connection") 설정
Cnn.Open "공급자=sqloledb; 사용자 ID=sa; 비밀번호=; 초기 카탈로그=pubs; 데이터 소스=ICBCZJP"
'거래 시작
Cnn.BeginTrans
StrSQL = "작업 삽입(job_desc, min_lvl, max_lvl) 값('Finance',16,86)"
Cnn.StrSQL 실행
'아래 첫 번째 문장은 틀렸고, 두 번째 문장은 맞습니다.
StrSQL = "job_err SET 업데이트 job_desc = '트랜잭션', job_id = 14"
'StrSQL = "작업 업데이트 SET job_desc = '트랜잭션' 여기서 job_id = 14"
Cnn.StrSQL 실행
Cnn.Errors.Count > 0인 경우
Response.Write "오류가 발생했습니다. 시스템이 트랜잭션 시작 시 상태를 복원하므로 새로운 추가나 수정이 이루어지지 않습니다." & "<br>"
Cnn.롤백트랜스
또 다른
Response.Write "오류 없음, 데이터베이스에 변경 사항 저장, 새 데이터 추가, 데이터 수정" 및 "<br>"
Cnn.CommitTrans
종료 조건
Set rsTest = Cnn.Execute("Select * From jobs where job_id>=14")
rsTest.EOF가 아닌 동안
응답.rstest(0) & rstest(1) & rstest(2) & rstest(3) & "<br>"를 작성하세요.
rsTest.MoveNext
향하게 하다
'이 예제는 테스트용이므로 데이터베이스의 원본 데이터를 복원하세요.
Cnn.Execute "작업 업데이트 SET job_desc = 'Designer', job_id = 14"
Cnn.Execute "job_id > 14인 작업 삭제"
Cnn.Close: Cnn = 없음으로 설정
%>
이 예에서는 Insert와 Update가 동시에 발생하거나 둘 중 하나가 발생하지 않습니다. 데이터가 추가되었지만 문 오류로 인해 수정이 발생하지 않는 경우가 있습니다. 데이터베이스를 프로그래밍할 때 트랜잭션을 사용하는 것은 매우 좋은 습관입니다.
4. 여러 레코드 세트 처리 동시에 두 테이블에서 데이터를 가져와야 하는 경우가 있습니다. 하나의 SQL 문으로 반환하면 네트워크 전송이 줄어들고 운영 효율성이 향상됩니다.
wuf64.asp를 예로 들어 이 예제에서는 루프를 사용하여 필드 값을 출력하는 방법도 설명합니다. (과거에는 "rsTest(0) & rsTest(1) &..."와 같은 어리석은 메서드를 사용하여 출력했습니다. . 필드가 2~3개뿐인 경우 이 방법이 더 간결합니다.) 지금 이해가 안 되시면 더 간단한 wuf63.asp를 다운로드하세요. 기억하세요! .
<%@ LANGUAGE="VBSCRIPT" %>
<%
옵션 명시적
응답.만료 = 0
Dim Cnn, StrSQL, rsTest, I
Cnn = Server.CreateObject("ADODB.Connection") 설정
Cnn.Open "공급자=sqloledb; 사용자 ID=sa; 비밀번호=; 초기 카탈로그=pubs; 데이터 소스=ICBCZJP"
rsTest = Server.CreateObject("ADODB.Recordset") 설정
'여러 레코드세트 검색
StrSQL = "직원에서 '직원 수'로 COUNT(*)를 선택하고 * 작업에서 선택"
rsTest.Open StrSQL, Cnn ', , ,adCmdText
rsTest는 아무것도 아니지만
Response.Write "<테이블 테두리 = 2><tr>"
'rsTest.Fields.Count - 레코드세트의 필드 수
I = 0의 경우 rsTest.Fields.Count - 1
'rsTest(I).Name - I 필드의 필드 이름
응답.쓰기 "<td>" & rsTest(I).이름 & "</td>"
다음
응답."</tr>" 쓰기
rsTest.EOF가 아닌 동안
응답."<tr>" 쓰기
'루프를 사용하여 각 필드의 값을 출력합니다.
I = 0의 경우 rsTest.Fields.Count - 1
응답.Write "<td>" & rsTest(I) & "</td>"
다음
응답."</tr>" 쓰기
rsTest.MoveNext
향하게 하다
'다음 Recordset 개체를 읽습니다.
rsTest = rsTest.NextRecordset 설정
향하게 하다
Cnn.닫기
rsTest = 없음 설정: Cnn = 없음 설정
%>
참고: SQL Server 데이터베이스는 여러 레코드 집합을 지원하지만 Access 데이터베이스는 지원하지 않습니다.
5. 리소스를 해제하려면 최대한 빨리 연결을 닫으세요.
이전 예제에서는 연결이 마지막에 닫혔지만 실제로는 아래 wuf65.asp에서 제공하는 방법에 따라 연결을 더 일찍 닫을 수 있습니다.
<% @LANGUAGE = VBScript %>
<!--#include file="AdoAccess.asp"-->
<!--#include 파일="adovbs.inc"-->
<% ' wuf65.asp
희미한 StrSQL, rsTest
StrSQL = "* 배송업체에서 선택"
rsTest = server.CreateObject("ADODB.Recordset") 설정
'클라이언트 커서를 사용해야 합니다. 그렇지 않으면 작동하지 않습니다.
rsTest.CursorLocation = adUseClient
rsTest.Open StrSQL,Cnn,,,adCmdText
'Connection 개체에 대한 레코드세트의 종속성을 제거합니다.
rsTest.ActiveConnection = 아무것도 설정하지 않음
'가능한 한 빨리 연결을 닫으십시오.
Cnn.close: Cnn = 없음으로 설정
rsTest.EOF가 아닌 동안 수행
Response.Write rsTest(0) & " " & rsTest(1) & " " & rsTest(2) & " " & "<BR>"
rsTest.MoveNext
고리
rsTest = 없음 설정
%>