login register Sysop! about ME  
qrcode
    최초 작성일 :    2001년 04월 17일
  최종 수정일 :    2001년 07월 19일
  작성자 :    taeyo
  편집자 :    Taeyo(김 태영)
  읽음수 :    168,159

강좌 목록으로 돌아가기

필자의 잡담~

드뎌 2001년 4월 10일 자로 태오의 새로운 책(taeyo's Advanced ASP)이 나왔답니다. ^^

이번 시간에는 게시판의 메인이라 볼 수 있는 게시판 List 를 만들어 보겠는데요.. 게시판 List 강좌는 일단 이번을 시작으로 해서. 이후 여러 강좌를 통해서 계속적으로 업데이트가 될 것이랍니다. ^^ 이 List 에 추가할 기능들이 앞으로도 많으니까요..  ^^ 이번 강좌에서는 가장 기본적인 리스트의 모습을 갖추게 할 것이구요.. 이를 기반으로 서서히 보강해 나가려 합니다.

강좌를 시작하면서요.. 여러분에게 부탁드릴 것은 이미 기존에 만들어놓은 write.htm 폼을 통해서... 데이터를 적당히 미리 테이블에 넣어주시기를 바란다는 겁니다. 적어도 20개 이상 말이지요.. 전 적당히 25개의 데이터를 미리 넣어보았습니다. 해서 나온 그림이 다음과 같지요... 그리고, 이것이 이번 강좌에서 우리가 같이 만들어 나갈 List 이기도 하구요..

디자인이 썰렁하다구요?  원하는 기능이 부족하다구여? 당연히 그렇죠. 이것은 가장 기본적인 모습의 list 이니까요.. 이제부터 추가적인 기능은 이어질 여러번의 강좌에 걸쳐 여러분의 Comment 를 반영하여 이루어질 것이니까요...  ^^ 같이 만들어 나가는 강좌...  바로 태오가 이번 강좌를 기획한 방향입니다. 히히...

자..  그럼.. 이제 어떻게 이러한 list 를 만들 수 있을지 한번 그 전체소스를 한번 먼저 살펴볼까요?

List.asp

<!--METADATA TYPE="typelib" NAME="ADODB Type Library"
    File="C:\Program Files\Common Files\System\ado\msado15.dll" -->
<% Option Explicit %>
<% Response.Expires=-1 %>
<!--#include file="config.asp"-->
<html>
<head> <title>게시판 리스트</title>
<style type="text/css">
  A {text-decoration: none; color:navy }
  A:hover {text-decoration: underline; color:#ff4500}
  td{ font-family:돋움; font-size:12 }
</style>
</head>
<%
  Dim Gotopage
  Dim Dbcon, Rs
  Dim pagecount, recordCount
  Dim SQL

  GotoPage = Request("GotoPage")
  if GotoPage = "" then GotoPage = 1

  Set Dbcon = Server.CreateObject("ADODB.Connection")
  Dbcon.Open strConnect

  SQL = "select count(board_idx) as recCount from MyBoard"
  Set Rs = Dbcon.Execute(SQL)

  recordCount = Rs(0)
  pagecount = int((recordCount-1)/pagesize) +1

  SQL = "SELECT TOP " & pagesize & " * FROM MyBoard "
  SQL = SQL & " WHERE board_idx not in "
  SQL = SQL & "(SELECT TOP " & ((GotoPage - 1) * pagesize) & " board_idx FROM MyBoard"
  SQL = SQL & " ORDER BY board_idx DESC) order by board_idx desc"

  Set Rs = Dbcon.Execute(SQL)
%>

<body topmargin="5" leftmargin="20">
<br>
<table cellpadding="0" cellspacing="0" border="0" width="600">
  <tr>
    <td bgcolor="white" height="30" width="400" style="padding-top:5px;">
      글의 갯수 : <%=recordCount%> &nbsp;&nbsp;

      [<a href="write.asp">글쓰기</a>] &nbsp;
      <% if int(gotopage) > 1 then %>
        [<ahref="list.asp?gotopage=<%=gotopage-1%>">이전</a>]
      <% else %>
        <font color="gray">[이전]</font>
      <% end if %>
      &nbsp;
      <% if int(gotopage) < int(pagecount) then %>
        [<ahref="list.asp?gotopage=<%=gotopage+1%>">다음</a>]
      <% else %>
        <font color="gray">[다음]</font>
      <% end if %>
    </td>
    <td width="200" align="right">
      page ( <%=gotopage%> / <%=pagecount%> )
    </td>
  </tr>
</table>
<table cellpadding="1" cellspacing="0" width="600" style="border:1px solid #cfcfdf">
  <tr bgcolor="#cfcfdf" height="25">
    <td width="340" align="center">제&nbsp; 목</td>
    <td width="20" align="center">
      <img src="images/clipw.gif" WIDTH="13" HEIGHT="13"></td>
    <td width="60" align="center">글쓴이</td>
    <td width="50" align="center">읽음수</td>
    <td width="130" align="center">날짜</td>
  </tr>
<%
  Dim board_idx, name, mail, title, yymmdd, strNew
  Dim yy, mm, dd, h, mi, re_level, readnum

  Do until Rs.EOF

    board_idx = rs("board_idx")
    name = rs("b_name")
    mail = rs("b_email")

    If Len(name) > 4 Then name = Mid(name,1,4) & ".."
    if name="" then name="無名"

    title = rs("b_title")
    If Len(title) > 22 Then title = Mid(title,1,23) & "..."
    If Trim(title) = "" then title = "[제목없음]"

    yymmdd = rs("b_date")
    strNew = ""
    if datediff ("n",yymmdd,Now()) < 1440 then
      strNew = " <img src='images/new.gif' border=0>"
    end if

    yy= year(yymmdd)
    mm = right("0" & month(yymmdd),2)
    dd = right("0" & day(yymmdd),2)
    h = right("0" & hour(yymmdd),2)
    mi = right("0" & minute(yymmdd),2)
    yymmdd = yy & "/" & mm & "/" & dd & " (" & h & ":" & mi & ")"

    readnum = rs("b_readnum")
%>

  <tr bgcolor= "white">
    <td height="20"style="padding-left:10px;">
      <a href="content.asp?board_idx=<%=board_idx%>&GotoPage=<%=GotoPage%>">
        <%=title%> <%=strNew%></td>
    <td align="center">&nbsp;</td>
    <td align="center">
      <% if mail <>"" then %>
        <a href="mailto:<%= mail%>"><%=name%></a>
      <%else%>
        <%=name%>
      <%end if%>
    </td>
    <td align="center"><%=readnum%></td>
    <td align="center"><%=yymmdd%></td>
  </tr>
<%
    Rs.Movenext
  Loop

  Rs.close
  Dbcon.close
  Set Rs = Nothing
  Set Dbcon = Nothing
%>

</table>
</body>
</html>

소스가 조금 길지만...  그렇게 어려운 내용은 아닙니다. ^^ 그렇다면 이제 소스를 하나하나 살펴보도록 하자구요. 소스 중에서우리가 가장 먼저 만나는 코드는다음과 같을 것입니다.

<!--METADATA TYPE="typelib"  NAME="ADODB Type Library"
      File="C:\Program Files\Common Files\System\ado\msado15.dll" -->
<% Option Explicit %>
<% Response.Expires=-1 %>

이 것은... 이미 이전 강좌들에서 한번씩은 이야기를 했었던 것들이죠? 가장 첫 코드는 ADO의 타입 라이브러리 설정입니다. 이것을 설정하면 이제 해당 ASP 페이지에서는ADO 관련 상수들을 맘대로 사용할 수있는 것이지요...  ^^

두번째 오렌지색 코드인 Option Explicit 라는 옵션은 이전 강좌에서도 강조했듯이.. 변수를 선언하고 사용하게끔 제약하는 옵션입니다. 이것은 지정하면 이후 모든 페이지레벨의 변수들을 Dim 으로 일단 선언한 뒤에 사용하셔야 합니다. 이것을사용하는 것이 성능의 향상에 도움이 된다는 것을다시금 기억하시기 바랍니다.

그리고 이어지는 코드는 페이지의 캐쉬만료시간을 과거시간인 -1 로 잡는다는 설정입니다. 말이 어려워 보이는데요. 다르게 설명하면 현재의 ASP 페이지를 사용자가 요청할 때마다.. 서버로부터 새로이 불러오겠다고 설정한다는 것이랍니다. 어떤 특정 ASP 페이지가 자주 수정되는 페이지라고 예상한다면 그 페이지의 상단에.. Response.Expires = -1 처럼 지정해 주시면 그 페이지는 매번호출될 때마다.. 서버에서 매번 수행되고, 새롭게 만들어진페이지를 가져오게 됩니다..

하지만, 수정이 자주 일어나지 않는 페이지라면 이러한 설정은 하지 않으시는 것이 좋습니다. 매번 페이지 요청시마다 서버에서 이 ASP를 실행하기에 부하가 걸릴 수 있으니까요.. 하지만, 현재 우리가 만드는 List.asp는 사용자가 수시로 데이터를 올리고.. 수시로 그 내용이 바뀌는 것이니까요.. 이Expires를 과거로 지정해서 매번 새로이 페이지를 동적으로 만들게 해야할 것이랍니다. ^^

<!--#include file= "config.asp"-->

위의 소스는 인클루드 파일입니다. config.asp 라는 파일 안에는 단지  다음과 같은소스만이 들어 있습니다.

Config.asp


<%
Dim StrConnect, pagesize
strConnect="Provider=SQLOLEDB;Data Source=(local);Initial Catalog=MyDatabase;user ID=sa;password=xx;"
'만일, Access를 사용하신다면 위의 한줄을 다음처럼 바꾸시면 됩니다.
'strConnect="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Study\MyDataBase.mdb"


pagesize=10
%>

소스를 보시면 알겠지만, SQL 서버 OLE DB 연결문자열인 strConnect 를 지정하고 있구요. 우리의 List 페이지가 몇 개의 글 단위로 보여줄 것인지를 위해서 pagesize 라는 변수를 지정하고 있습니다. 우리는 한 페이지에 10개의 글을 보여줄 것이기에 pagesize 를 10 으로 지정하고 있죠.. ^^

이렇게 인클루드로 따로 정보를 뺴 놓은 이유는... 데이터베이스와 연결하는 다른 페이지에서도 이러한 연결문자열을 사용할 것이기에.. 쉽게 그냥 이 파일을 인클루드해서 사용하게 끔 하기 위함이구요.. 만일, 연결 문자열이 바뀔 경우에 이 config.asp 페이지에서만 바꿔서 모든 페이지에 그 변경된 내용이  다 적용될 수 있게 하려 함이져

   Dim Gotopage
   Dim Dbcon, Rs
   Dim pagecount, recordCount
   Dim SQL   

이 부분은 페이지에서 사용할 변수들을 일단 선언하는 부분입니다. ASP 에서는 변수의 타입을 설정하지는 못합니다...  무조건 Dim 으로 선언만 합니다만 ASP.NET 에 들어서서는 타입을 지정할 수 있게 되었다는 것은 알고 계시죠? 어쩌면 이제 알게 되었죠? ^^ 그 이야기는 .NET 에 들어가면 프로그래밍이 조금은 진짜 프로그래밍처럼 바뀐다는 이야기이고.. 많은 공부를 해야한다는 것을의미합니다..  세상에 쉬운것은 없다지만... 그렇죠? 

그래서 또 파이팅입니다

  GotoPage = Request("GotoPage")
  if GotoPage = "" then GotoPage = 1

이 소스는 페이징을 위한 소스인데요.. 우리의 게시판의 리스트를 페이지로 나누어서 보여주게 끔 하는 것이지요.... 우리는 10개 단위로 글들의 리스트를 보여줄 것인데요.... 사용자가 다음 페이지의 글을 보고 싶다던지, 이전 페이지를 보고 싶다던지 할 경우.. 하이퍼링크를 통해서 GET 방식으로 그 해당 페이지의 번호가 넘어오게 됩니다. 그렇게 될 경우 그 넘어오는 변수의 이름은 GotoPage 라는 것을 사용하기로 합니다. ^^ 물론, 이 변수의이름은 자신이정하기 나름이지요? ^^

여러분 맘대로 바꾸어도 좋지만, 그것은 일단, 이 예제를 완전히 따라하신 다음에 바꾸도록 하세요... 그리고, 이 List.asp 페이지가 처음 로딩될 경우는 GotoPage 란 인자로 넘어오는 값이 없지요? 그 경우는 그 값이 없기에 즉, 무작정 처음 이 List.asp 가 실행될 경우에는  첫번째 페이지를 보여주어야 합니다. 그래서 IF 문에서는 GotoPage 값이 없을 때, Gotopage 라는 변수의 값을 1로 지정하는 것입니다. ^^ Gotopage 란 변수는 반드시 값을 가지고 있어야하니까요..  아래의 코드에서이 값을 사용하거든요..

   Set Dbcon = Server.CreateObject("ADODB.Connection")
   Dbcon.Open strConnect

이 부분은 이미 익숙한 부분이 되었지요?  데이터베이스를 연결하는 부분이지요..  ^^ 이 부분은 어려운 것이 없을것 같네요 ^^

   SQL = "select count(board_idx) as recCount from MyBoard"
   Set Rs = Dbcon.Execute(SQL)

   recordCount = Rs(0)

이번에는 서버로 쿼리를 날려서 현재의 테이블에 총 몇개의 레코드가 있는지를 알아내는 코드입니다. 이것은 현재 총 글이 몇개나 있는지을 알아내고, 그 수를 페이지 단위수(우리의 경우 10개)로 나누어서.. 현재 몇 페이지인지를 알아내고자 하는 목적을 가지고 있답니다.... 물론, 기존의 페이징 방법을 사용하게 되면 RecordSet의 RecordCount 라는 속성을 이용해서 그 값을 얻어낼 수도 있을 것입니다만... 기존의 제 책(Taeyo's ASP)에서 소개한 그 페이징 방법은.. 구현은 쉽지만 대단히 서버에 부하를 주는 코드였습니다.

해서, 이번에는 그러한 문제를 조금은 보완한 방법을 사용하고자 하는 것이지요.... 해서, 조금은 페이징의 방법이 어려워 보일 수도 있습니다. ^^  이 이야기는 잠시후 계속하구요... 어쨋든 우리는 총 글의 수와 페이지의 수를 구하기 위해서 위와 같은 쿼리를 통해... 일단, 총 글의 수를 RecordCount 라는 변수에 담아내 보았습니다.

pagecount = int((recordCount-1)/pagesize) + 1

이 부분은 현재의 총 레코드 수를 페이지로 나누면 몇 페이지가 될 것인지를 알아내기 위한 로직인데요. 기존의 태오보드에서 사용한 로직을 조금 더 간단하게 바꾼 로직입니다. 이것이 머리 아픈 이유는 레코드가 23 개인 경우 페이지는 3개가 되어야 하구요 레코드가 20 개인 경우도 페이지는 2개가 되어야 합니다. 레코드가 30개인 경우는 페이지가 3개이어야 하구요....

이러한 것을 고려해서 기존의 코드를 다이어트 시켜서 여러 라인의 코드가 필요했던 것을 단 한줄의 코드로 줄여본 것이랍니다. 수학이나 산수를 좋아하시는 분은 이 로직이 레코드 수와 무관하게 적절하게 해당 페이지 갯수를 얻어올 수 있다는 것을 금방 알아내시겠지요?  한번 도전해 보세요.. 작은 로직이지만 꽤나 재미있는 로직이랍니다. ^^ 

참고로 int 란 함수는 소수점 이하는 버리는 함수입니다. 정수부분만을 추출해 주는 함수이지요 ^^

자.. 어쨋든 이제 총 글의 수와 그것을 pagesize 로 나누어서 얻어낸 페이지의 수까지 얻어와 보았네요. 이제부터가 머리가 조금 아픈 부분인데요... 기존의 그러니깐 Taeyo's ASP 책에 나온 페이징하는 방법은.... 사실상 서버에 상당한 부하를 주는 부분 방법이었습니다. (기존에는 이 방법을.. 사용해서... 저도 그 방법을 사용했었지요)

그 문제의 방법은 일단 테이블에 있는 모든 데이터를 몽땅 다 레코드셋으로 만든 다음에... 우리가 필요한 페이지에 해당하는 레코드로 찾아가서 데이터를 출력해 주는 방법이었거든요... 만일, 우리가 가진 레코드가 1만건이고, 우리는 페이지를 10 페이지로 나누었다고 생각하면 말이죠... 그 경우 우리가 3번째 페이지를 보고 싶다고 할 경우..  서버에서는 일단, 1만건의 데이터를 레코드셋에 담구요.. 그 레코드셋에서 3번째 페이지의 위치인 30번쨰 레코드로 이동을 하고, 거기서부터 우리가 레코드를 가지고 올 수 있게끔 해주는 것이었습니다. 생각만해도 뭔가 비합리적이져?

이 방법의 문제는 테이블에 레코드가 늘어날 때마다 그 모든 엄청난 데이터를 가져오고... 지정한 페이지에 맞는 레코드의 위치로 커서를 옮기기에 엄청난 부하가 걸린다는 것입니다. 대량의 데이터를 레코드셋에 담을 때도 엄청난 부하가 걸리지만... 그에 못지않게 레코드셋 사이에서 커서가 이동할 경우도 많은 부하를 걸리게 하거든요... 그러다보니 현재에 이르러서는 예전의 페이징 방법은 거부되다시피 하고 있구요.. 좀 더 개선할 수 있는 방법이 등장하고 있습니다.

가장 좋은 방법은 레코드셋에는 우리가 필요한 만큼의 데이터가 담겨야 한다는 것에서 출발합니다. 기존의 방법은 테이블의 모든 데이터를 다 담기에.. 데이터가 늘어날 수록.. 서버에 부하가 걸려서 무지하게 느려지고는 하였습니다.

그러므로 이 것을 해결하기 위해서 무조건 데이터베이스 서버에서는 우리가 필요한 수만큼의 레코드를 가져와서 레코드셋에 담게 하는 것이지요.  웹서버의 레코드셋에다가 모든 데이터를 다 담은뒤에.. 우리가 필요한 레코드로 이동해서 데이터를 출력하는 것 보다는.... 우리가 필요한 만큼의 데이터를 균일하게 언제나 10개씩의 가져오는 것이 더욱 합리적이니까요 우리의 경우라면 10개가 되겠지요?

그렇다면, 어떻게 우리가 원하는 페이지에 해당하는 레코드를 필요한 부분만 달랑 10개만을 가져와서.. 레코드셋에 담을 수 있느냐? 이것이 관건이 되겠네요.  그렇다면.... 해결방법은 잘 만들어진 쿼리라는 것을 느낄 수 있을 겁니다... 물론 더 좋은 방법이 있을 수도 있겠죠...

이 부분에 대해서는 많은 토론이 있는 편입니다만.. 일단, 여러가지 방법중에 한가지를 모델로 설명드리고자 합니다(당연히, 이 방법이 최선의 방법은 아닙니다. 사실상 솔직히는 이 방법도 약간의 문제점이 있지요... 더 좋은 방법도 많이 있구요. 이것은 스스로 고민해 보아야 하는 부분입니다. 그러나, 이러한 부분을 잘 구성하려면 역시나 경험적인 스킬이 상당히 요구될 것입니다.  ^^...  결국 데이터베이스를 잘하는 길이 프로그래밍도 잘하는 길이라는...  무언의 압박을 받게되지요..  -_-;)

여기서 사용하는 방법은 예전에 카이스트에 어떤 분이 알려주신 방법인데요...  그것은 곧 알려드릴 것이구요 더 좋은 방법, 더 나은 방법이 있으신 분들은 Web-Tip 게시판에서 토론해 주시면 감사하겠습니다. 이 부분에 대해서는 이미 한 차례 격렬한(?) 토론이 지나갔지요?  공개 자료실에서도 토론이 한번 불기는 했었습니다. 아무래도 주관적인 경험론들이 많아서..  확실히 좋은 방법이라는 것은 도출하지 못했습니다만.. 나름대로는 괜찮은 여러가지 방법이 나왔었습니다. 아직도 그 글들이 남아있으니 관심이 있으신 분들은 한번 읽어보도록 하세요...

이것을 잘 하려면 역시나 데이터베이스 매니지먼트와 쿼리능력, 퍼포먼스를 고려할 수 있는 능력이 뛰어나야 하기에 결국 데이터베이스를 얼마나 잘 다루느냐에 달려있는 것 같습니다. 그러다보면 테이블 구조도 바꾸어야 할 수 있구요. 접근방법을 바꾸어야 할 가능성도 있어보이기는 합니다. 어쨋든 그러한 고급스러운 내공은 이 자리에서는 다루기가 넘 버거우니까요... 우리는 우리에게 현재 필요한 정도만을 알아보도록 하자구요.. 현재 제 게시판에서 사용하는 방법말이죠

이 방법은 푸서리 사이트홍진기(아마도 카이스트에 계신 분?)라는 분이 남겨주신 방법으로  다음 글은 푸서리 사이트의 ASP 게시판에 올라와 있는 그 분의 글을 그대로 인용한 것이랍니다.

수고 많으십니다.
새로운 페이징 방법에 대한 글을 읽고 올립니다.
운영자님께서 말씀하신 방법를 조금만 더 고치면 보다 더 좋은 paging방법이 될껍니다.
게시판에 올라와있는 방법으로라면, 뒷페이지로 가면 갈수록, 보다더 많은 레코드를 가
져오게 되겠지여~  궁극적으로는, 목적한 10개씩만을 가져오게 top을 사용하면 되는데~
이는 SubQuery를 이용하면 손쉽게 원하는 갯수만큼씩만 가져올수 있게 되는거지여~

Select top (원하는record갯수) * from WEB-BOARD
Where ID not in
   (Select top ((전달된PAGE수-1) *원하는 Record갯수) )
      from WEB-BOARD order by 작성날짜 DESC)
Order by 작성날짜 DESC

구러니깐, SubQuery에선, ((전달된PAGE수-1) *원하는 Record갯수) ) 에
들지 않는 놈들을 뽑아네게 되구여~
메인쿼리에서는 그 놈들중에서 top (원하는 record갯수) 만을 걸러내게 되는겁니다.
그렇게 되면 결국은 우리가 원하는 record갯수들 만을 쿼리해올수 있게 되는거지여~
헤헤~  어때여? 한줄만 더 추가하니깐, 훨 좋아지지여?  빠~잉~

해서 나온 쿼리가 바로 다음과 같은 것입니다. 저의 경우는 이것을 SQL 서버의 스토어드 프로시져로 만들어서 사용하기도 하였습니다....

   SQL = "SELECT TOP " & pagesize & " * FROM MyBoard "
   SQL = SQL & " WHERE board_idx not in "
   SQL = SQL & "(SELECT TOP " & ((GotoPage - 1) * pagesize) & " board_idx FROM MyBoard"
   SQL = SQL & " ORDER BY board_idx DESC)  order by board_idx desc"

   Set Rs = Dbcon.Execute(SQL)

이 쿼리를 사용하게 되면 지정된 페이지에 맞게.. 그에 해당하는 10개의 데이터만을 데이터베이스에서 가져오게 됩니다. 해서, 이를 Rs 라는 레코드셋에 담는 것이지요....

********************* 2001년 6월 2일 추가 커멘트입니다. *********************

SQL 전문가 중 한분이신 우철웅님-인브레인 이사-의 조언에 의하면 현재 제가 제시하는 쿼리는 아주 바람직한 것은 아니라고 하시네요.규모가 상당히 큰 사이트의 경우 지금 제가 제시하는 방법은 그다지 만족스럽지 않을 수 있다고 합니다. 이에 대해서는 차후에 더 나은 쿼리를 어떻게든 알아내서 알려드리도록 하겠습니다... 그리고, 이 강좌 밑에 커멘트 달린 글중에도 좋은 쿼리가 많이 보이는 듯 합니다. 이 또한 참고하지 아니할 수 없겠죠? 유쾌상쾌통쾌쾌쾌.. 입니다.

**********************************************************************

잠깐!! MS Access 쓰시는 분들은 참고하세요

위의 쿼리문은 Access에서는 오류를 발생시킬 것입니다. 이유는 Access에서는 Select top 0 이란 것을 이해하지 못하기 때문입니다요... 0개의 데이터를 가져온다는 말을 이해하지 못하기에 문제가 있는 것입니다. 고로 Access 를 쓰시는 분들은 이 쿼리를 다음과 같이 바꾸어서 해결하실 수 있을 것입니다

SQL = "SELECT TOP " & pagesize & " * FROM MyBoard "
  if int(gotopage) > 1 then
    SQL = SQL & " WHERE board_idx not in "
    SQL = SQL & "(SELECT TOP " & ((GotoPage - 1) * pagesize) & " board_idx FROM MyBoard"
    SQL =SQL & " ORDER BY board_idx DESC) "
  end if
  SQL = SQL & " order by board_idx desc"

  Set Rs = Dbcon.Execute(SQL)

위의 방법은 현재 페이지가 1 인 경우는 쿼리가 Select top 0 이 들어가는 다음과 같은 문장이 되기에 문제가 생길 수 있으니

  SELECT TOP 10 * FROM MyBoard
  WHERE board_idx not in
    (SELECT TOP 0 board_idx FROM MyBoard ORDER BY board_idx DESC)
  Order by board_idx desc

  Set Rs = Dbcon.Execute(SQL)

그 경우 그냥 SELECT TOP 10 * FROM MyBoard Order by board_idx desc 을 하게 하는 것입니다. 즉, 현재의 페이지가 2 이상일 경우는 원래대로 그 희안한 쿼리를 동작시키게 하구요.. 페이지가 1 인 경우에는 SELECT TOP 10 * FROM MyBoard Order by board_idx desc 라는 심플한 쿼리를 실행시키는 것이지요.. ^^ 어차피 첫 페이지는 가장 최근 레코드 10개만 가져오면 되니까요 ^^

그러면, 이 문제를 피해 나갈 수 있을 것이랍니다. ^^ 쫌 어렵죠?
하지만, 시간이 지나면 이해하실 수 있을 것이라 믿는답니다. 저도 그랬으니까요.

필요한 데이터를 레코드셋에 담았으니.. 이제는 무엇을 하면 되지요? 그렇습니다.. 루프를 돌면서 각각의 컬럼들을 화면에 출력해 주면 되는 것이랍니다. 하지만, 소스중에서는 각각의 데이터들을 출력하기 전에 먼저 이전 페이지와 다음 페이지로 이동할 수 있는 링크를 추가해 주고 있네요...  ^^

         <% if int(gotopage) > 1 then %>
           [<a href="list.asp?gotopage=<%=gotopage-1%>">이전</a>]
         <% else %>
            <font color="gray">[이전]</font>
         <% end if %>
         &nbsp;
         <% if int(gotopage) < int(pagecount) then %>
           [<ahref="list.asp?gotopage=<%=gotopage+1%>">다음</a>]
         <% else %>
            <font color="gray">[다음]</font>
         <% end if %> 

이전 페이지로 가는 링크는요.. 현재의 페이지의 값이 1보다 크다면 나타나야 하겠지요? 현재의 페이지 값이 1 이라면 이전 페이지라는 것은 존재하지 않을테니까여.... 그래서 첫번째 if 문은 바로 그러한 것을 나타내고 있는 것이랍니다.

그런데, 왜 gotopage 라는 것을 int 함수를 사용해서 숫자타입으로의 전환을 하고 있을까요? 어차피 Gotopage 라는 것이 숫자인데 말입니다... 그것은 Request 로 받은 모든 변수들은 기본적으로 그 모습이 variant 라는 타입이기 때문입니다. 그러므로, 그것은 문자일수도 있구요, 숫자일수도 있답니다.

"1" 과 1 은 전혀 같지 않습니다. "1"은 문자이구요. 1은 숫자이니까요.....

그래서 어쩌면 "1" 일수 있는 Gotopage 라는 값을 int() 함수를 통해서 확실히 숫자 1로 바꾸어주고 있는 것입니다. 확인사살...  이라고 볼 수 있겠습니다. 네~~~

그리고, 이어지는 if 문은  다음 페이지라는 링크를 나타나게 하는 것인데요.... 현재의 페이지가 가장 마지막 페이지가 아니라면 다음 페이지라는 것이 있을 수 있지요? 해서 만일, 현재 페이지가 가장 마지막 페이지가 아니라면 다음 페이지로 이동할 수 있는 하이퍼링크를 거는 것이랍니다.  ^^  어렵지 않지요?  그럴 것입니다. 이미 게시판을 아시는(아마도) 여러분이라면... 말이죠. 그래서, 페이지 이동을 하는 링크부분의 코드는 됐구요...

이젠 본격적인 출력부분입니다.

<%
      Dim board_idx, name, mail, title, yymmdd, strNew
      Dim yy, mm, dd, h, mi, re_level, readnum
     
      Do until Rs.EOF

         board_idx = rs("board_idx")
         name = rs("b_name")
         mail = rs("b_email")

         If Len(name) > 4 Then name = Mid(name,1,4) & ".."   '(1)
         if name="" then name="無名"

         title = rs("b_title")
         If Len(title) > 22 Then title = Mid(title,1,23) & "..."    '(2)
         If Trim(title) = "" then title = "[제목없음]"

         yymmdd = rs("b_date")
         strNew = ""
         if datediff ("n",yymmdd,Now()) < 1440 then               '(3)
            strNew = " <img src='images/new.gif' border=0>"
         end if
     
         yy= year(yymmdd)
         mm = right("0" & month(yymmdd),2)
         dd =right("0" & day(yymmdd),2)
         h = right("0" & hour(yymmdd),2)
         mi =right("0" & minute(yymmdd),2)
         yymmdd = yy & "/" & mm & "/" & dd & " (" & h & ":" & mi & ")"

         readnum = rs("b_readnum")
%>

이미 이 부분은 익숙하실만한 부분인데요... 레코드셋에 담겨져 있는 각각의 컬럼값들을...  루프를 돌면서 먼저 변수에 담는 부분입니다. 이렇게 사용전에 각각의 값들을 변수에 담은 뒤 사용하는 방법은.... 속도면에서도 좋구요. 그리고, 어쩌다 나타날 수 있는 값이 사라지는 버그도 방지할 수 있는 방법이지요. 하지만, 가급적이면 각각의 컬럼값들을 변수에 담을 경우는요... select 태그에서 불러온 컬럼순서대로, 내지는 테이블에 존재하는 컬럼순서대로... 각각 변수에 차례대로 넣어주는 것이 좋습니다. 그것이 가장 정석이구요. 가장 안정성있지요..  ^^

가급적 순서대로 변수에 넣어주는 습관을 길러주시도록 하세요...  ^^

그리고, 아시는 이야기일 수 있습니다만.... 소스중에

(1) 이라는 부분은요...  만일, 사용자의 이름이 4글자를 넘어선다면... 그 4글자만을 떼어내고, 그 뒤에는 ... 으로 처리하고자 그렇게 하는 것입니다.. 만일, 사용자의 이름이 "초슈퍼울트라맨" 이라고 한다면.... 출력될 경우는 "초슈퍼울트라..." 이라고 나오게 된다는 것이지요...  ^^

(2)의 경우도 마찬가지 인데요.. 이번에는 제목이 넘 길 경우에 ... 처리를 하는 것이랍니다. 조금은 깔끔하게 출력되게 하기 위해서 말이지요...  ^^

(3)의 경우는 최근에 올라온 글을 부각시켜 나타나게 하기 위한 부분인데요....이미 datediff 라는 함수에 대한 사용방법은 FSO 시간에 알려드린 VBScript 온라인 도움말 있죠? 그것을 참고해 주시기 바래요.  거기에 매우 자세하게  이 함수의 사용법에 대해서 나와있으니까요..  ^^

이 함수를 쓰면.... 특정 두 날짜를 시간, 분, 초 등으로... 비교해서 그 간격을 알아낼 수 있답니다. 우리의 경우 '분'으로 그 사이를 알아보았는데요.. '분'으로 따질경우 1440 분 이내의 글이라면 올라온지 만 하루가 안된 글이기에.... 최근에 올라온 글로 표시될 자격이 충분하지요? 해서.. 현재의 데이터가 그렇다면 strNew 라는 변수에 최근글 이미지에 해당하는 태그를 저장하게 하는 것이랍니다.

그 이하의 소스들은요.. 이제 각각의 변수에 저장된 컬럼의 값들을 출력해 주는 부분이랍니다. 어려운 부분은 없어보이는데요... 굳이 설명할 부분이 있다면...

<ahref="content.asp?board_idx=<%=board_idx%>&GotoPage=<%=GotoPage%>">

라는 부분이 되겠네요. 그중에서도 content.asp 로 현재의 페이지값을 넘기는 부분말입니다. 굳이 Gotopage 라는 현재 페이지의 번호를 content.asp로 보낼 이유는 없습니다. 그 값을 가지고 content.asp 에서 뭔가를 처리할 것은 없으니까요..

하지만, 그 값을 넘기는 이유는.. content.asp 에서 뭔가를 하려함이 아니라..  content.asp 에서 자기할 일을 다 하고난 뒤 list.asp로 다시금 넘겨주기 위함입니다.  그러면, 글의 본문을 본 다음에 list.asp로 돌아온다고 하더라도 자신이 원래에 있던 그 해당 페이지로 올 수 있게하려 함이지요..

만일, 자신이 12 페이지의 내용을 보고 있었다면, 글의 본문을 본 다음에는 마찬가지로 12 페이지로 돌아와야 하겠지요? 1번째 페이지로 돌아온다면 사용자는 조금 짜증이 날테니까요...  ^^ 그래서, 그 값을 넘겨주었다가 다시 돌려받기 위해서 content.asp로 보내는 것이랍니다. 물론, 자신이 12 페이지의 어떤 글을 읽는 사이에 게시물이 많이 더 올라왔거나, 많은 글이 삭제되었거나 한다면 12 페이지로 가도 현재 읽은 글이 목록에 없을 수도 있습니다. 하지만, 적어도 비슷한 페이지로 찾아가주기는 할테니 ... 조금은 사용자에게 도움이 될 것입니다.

이번에 같이 살펴본 list.asp는 간단한 수준이었습니다만.. 기본적인 모습은 다 살펴본 것 같습니다. 이번 강좌를 통해서 많은 것을 느끼신 분이 있을 수도 있구요.. 전혀 새로운 이야기로 강좌가 받아들여지시는 분도 있을 것입니다. 또한, 강좌가 무척이나 어렵다고 느껴지시는 분들도 있을 수 있습니다. 그러한 분들은 일단은 이해하시려 애쓰시구요. 정히 이해가 안된다면 일단 외우세요...  ^^  암기암기.. 히히

밑줄 쫙~~~

으하함.....  벌써 새벽 3시네요....  그래도 이번 강좌는 그림이 적은 편이어서.. 제가 노가다는 조금 적게 했습니다.  그림이 많으면 그거 편집하는데 시간이 많이 걸리는데.... 그럼 다음 강좌에서 만나볼까요? 다음 강좌는 본문 내용보기 강좌입니다...


authored by

  shoopoonk
  2009-07-07(15:54)
오타 신고합니다.
a태그 몇부분에 ahref 이런식으로 붙여쓰여져 있네요.


 
 
.NET과 Java 동영상 기반의 교육사이트

로딩 중입니다...

서버 프레임워크 지원 : NeoDEEX
based on ASP.NET 3.5
Creative Commons License
{5}
{2} 읽음   :{3} ({4})