Глава 5. Пример приложения
Прежде чем с головой погрузиться в процесс разработки электронного магазина на основе концепций проектирования баз данных, описанных в главе 3, мы построим очень простое коммерческое приложение с использованием технологий Active Server Pages и SQL Server. Это поможет вам лучше освоиться со средой разработки ASP.
Наше приложение представляет собой простую форму для подписки на некоторое издание. На форме вводится имя подписчика, адрес и данные кредитной карты.

Построение таблицы данных
Прежде всего нам потребуется простая таблица в базе данных, в которой будут храниться данные о подписчиках. Очевидно, в таблице необходимо предусмотреть поля для имени подписчика, его адреса, данных кредитной карты и т. д. - см. листинг 5.1.
Листинг 5.1. Таблица с данными о подписчиках
 CREATE TABLE dbo.Subscriptions (
   idSubscription int IDENTITY (1, 1) NOT NULL ,
   chrFirstName varchar (100) NULL ,
   chrLastName varchar (100) NULL ,
   chrAddress varchar (150) NULL ,
   chrCity varchar (100) NULL ,
   chrState varchar (10) NULL ,
   chrZipCode varchar (15) NULL ,
   chrPhone varchar (25) NULL ,
   chrEmail varchar (100) NULL ,
   chrCardType varchar (50) NULL ,
   chrCardNumber varchar (25) NULL ,
   chrExpDate varchar (50) NULL ,
   intProcessed tinyint NULL CONSTRAINT DF_Subscripti_intProcesse3__12 DEFAULT (0),
   dtEntered datetime NULL CONSTRAINT DF_Subscripti_dtEntered_2__12 DEFAULT (getdate()),
   intLength tinyint NULL ,
   chrCardName varchar (150) NULL ,
   CONSTRAINT PK___1__12 PRIMARY KEY CLUSTERED
   (
      idSubscription
   )
)
В таблицу входят два служебных поля. Поле intProcessed содержит признак обработки заказа, что упрощает выборку информации о новых подписчиках. По умолчанию это поле должно быть равно 0 (признак "необработанного" состояния). Во втором служебном поле, dtEntered, хранится дата включения подписчика в базу данных. По умолчанию поле заполняется текущей датой.

Построение формы HTML
Откройте проект, созданный в главе 4. Щелкните правой кнопкой мыши на имени проекта в окне проекта и выберите в контекстном меню команду Add. В открывшемся подменю выберите Active Server Page. Введите в диалоговом окне имя ASP-страницы подписки, subscription.asp.
В результате на Web-сервере создается новый файл. Теперь можно приступать к построению HTML-структуры страницы. При создании страницы ASP генерируется базовый шаблон, который далее редактируется в Visual InterDev. В вашем распоряжении три режима просмотра: Design, Source и Quick View. Как правило, в процессе разработки используется режим просмотра исходного текста Source. Режим Design View предназначен для построения HTML в режиме WYSIWYG (What You See Is What You Get - что видите, то и получаете). Режим Quick View используется для просмотра HTML в интерфейсе броузера, но без обработки программного кода ASP.
Чтобы построить страницу HTML, необходимо создать форму HTML и разместить на ней элементы HTML Затем мы построим сценарную страницу для обработки данных, введенных пользователем.
Первая часть страницы устроена элементарно (см. листинг 5.2). В ней создаются стандартные заголовки HTML для страницы. Кроме того, наша форма передает результаты странице ProcessSub.asp, где и выполняется обработка данных подписчиков.
СЕАНСОВЫЕ ПЕРЕМЕННЫЕ
В стандартной Web-технологии не существует простых средств для сохранения данных состояния между Web-страницами. Например, если пользователь где-то ввел свой почтовый индекс и продолжает просматривать остальные страницы сайта, вам придется немало потрудиться для отслеживания этих данных по URL или с применением скрытых элементов HTML. К счастью, в IIS/ASP Microsoft реализовала возможность создания сеансовых переменных. Все, что от вас требуется - присвоить значение переменной на одной странице и затем читать его по мере необходимости на других страницах. Учтите, что сеансовые переменные существуют в течение интервала тайм-аута, по умолчанию равного 30 минутам. В действительности мы никогда не знаем точно, когда посетитель покинул сайт, поэтому при отсутствии операций в течение заданного периода тайм-аута сеансовые данные пропадают.

Листинг 5.2. Страница subscription.asp
<%@ Language=VBScript %>
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
</HEAD>
<BODY>
<BR><BR>
<center>
<!-- Setup the Header -->
<font size="4" color="blue"><b>
XYZ Publication
</b></font>
<!-- Start the form that will post to the
ProcessSub.asp page. -->
<form method="post" action="ProcessSub.asp">
В следующей части страницы находится форма с таблицей, в которой отображаются поля для ввода данных. Здесь выполняется несколько ключевых операции. Во-первых, при вводе пользователем неправильных данных мы хотим вернуть его к этой форме и повторно заполнить ее введенными данными.
Для повторного заполнения формы страница читает сеансовые переменные, значения которых присваиваются страницей ProcessSub.asp при обнаружении ошибок. Первая проблема - срок подписки (поле intLength). Если пользователь выбрал двух- или трехгодичную подписку, мы устанавливаем соответствующий переключатель. В противном случае устанавливается переключатель подписки на один год.
Листинг 5.3. subscription.asp (продолжение)
<!-- Next the table starts that will layout the
data entry form
-->
<table border=1>
<!-- Subscription Length -->
<tr>
<td align="right">Subscription Length:</td>
<td>
<%
' Check to see if a length was set. If so
' then default the radio button selected.
if session("intLength") = "1" then
CheckOne = "Checked"
Flag = 1
end if
if session("intLength") = "2" then
CheckTwo = "Checked"
Flag = 1
end if
if session("intLength") = "3" then
CheckThree = "Checked"
Flag = 1
end if

' If this is the first time the form is
' displayed in the session then default to
' a length of one year.
if Flag <> 1 then CheckOne = "Checked"

%>
<!-- Radio buttons for selecting the length -->
<input type="radio" value="1" name="intLength" <%=CheckOne%>>One Year
<input type="radio" value="2" name="intLength" <%=CheckTwo%>>Two Year
<input type="radio" value="3" name="intLength" <%=CheckThree%>>Three Year
</td>
</tr>
<!-- First Name -->
<tr>
<td align="right">First Name:</td>
<!-- Input field for the first name -->
<td><input type="text" value="<%=session("chrFirstName")%>" name="chrFirstName"></td>
</tr>
<!-- Last Name -->
<tr>
<td align="right">Last Name:</td>
<!-- Input field for the last name -->
<td><input type="text" value="<%=session("chrLastName")%>" name="chrLastName"></td>
</tr>
<!-- Address -->
<tr>
<td align="right">Address:</td>
<!-- Input field for the address -->
<td><input type="text" value="<%=session("chrAddress")%>" name="chrAddress"></td>
</tr>
<!-- City-->
<tr>
<td align="right">City:</td>
<!-- Input field for the city -->
<td><input type="text" value="<%=session("chrCity")%>" name="chrCity"></td>
</tr>
<tr>
<td align="right">State:</td>
<td><input type="text" value="<%=session("chrState")%>" name="chrState" size=2></td>
</tr>
<!-- Zip Code -->
<tr>
<td align="right">Zip Code:</td>
<!-- Input field for the zip code -->
<td><input type="text" value="<%=session("chrZipCode")%>" name="chrZipCode"></td>
</tr>
<!-- Phone Number -->
<tr>
<td align="right">Phone:</td>
<!-- Input field for the phone number -->
<td><input type="text" value="<%=session("chrPhone")%>" name="chrPhone"></td>
</tr>
<!-- Email Address -->
<tr>
<td align="right">Email Address:</td>
<!-- Input field for the email address -->
<td><input type="text" value="<%=session("chrEmail")%>" name="chrEmail"></td>
</tr>
<!-- Name on Card -->
<tr>
<td align="right">Name on Card:</td>
<!-- Input field for the email address -->
<td><input type="text" value="<%=session("chrCardName")%>" name="chrCardName"></td>
</tr>
Тип кредитной карты обрабатывается примерно так же, как срок подписки. Если пользователь выбрал карту Master Card или American Express, то при возвращении к форме мы восстанавливаем его выбор.
Листинг 5.4. subscription.asp (продолжение)
<!-- Input field for the credt card type -->
<tr>
<td align="right">Card Type:</td>
<td>
<%
' Check to see which card was selected previously
' if there was an error.
if session("chrCardType") = "Visa" then
SelVisa = "Selected"
end if
if session("chrCardType") = "MasterCard" then
SelMC = "Selected"
end if
if session("chrCardType") = "AmEx" then
SelAmEx = "Selected"
end if
%>
<!-- Select box for the type of cards -->
<select name="chrCardType">
<option value="Visa" <%=SelVisa%> >Visa
<option value="MasterCard" <%=SelMC%>>Master Card
<option value="AmEx" <%=SelAmEx%>>American Express
</select>

</td>
</tr>
<!-- Credit Card Number -->
<tr>
<td align="right">Card Number:</td>
<!-- Input field for teh credt ciard number -->
<td><input type="text" value="<%=session("chrCardNumber")%>" name="chrCardNumber"></td>
</tr>
<!-- Credit card experiation date -->
<tr>
<td align="right">Expiration Date:</td>
<!-- Input field for the expiration date -->
<td><input type="text" value="<%=session("chrExpDate")%>" name="chrExpDate"></td>
</tr>
В последнем фрагменте страницы создается кнопка HTML типа Submit, передающая серверу данные формы. Затем форма и страница закрываются соответствующими тегами.
Листинг 5.5. subscription.asp (продолжение)
<!-- Submit button -->
<tr>
<td colspan="2" align="center">
<input type="submit" value="Subscribe!" name="submit">
</td>
</tr>
</table>
</center>
<!-- Closing tag for the end of the form -->
</form>
</BODY>
</HTML>
Страница ввода данных тоже устроена весьма прямолинейно. Новичкам в программировании ASP чередование сценарного кода и тегов HTML на одной странице поначалу кажется непривычным. Но именно эта плодотворная интеграция и превращает ASP в столь перспективную среду разработки коммерческих Web-приложений.

Программирование сценария
По-настоящему интересное программирование начинается с обработки запроса подписчика. Страница должна решать сразу несколько задач. Во-первых, мы получаем данные от пользователя и проверяем их. Необходимо убедиться в том, что все обязательные поля были заполнены, и по возможности проверить правильность данных.
Во-вторых, в случае ошибки необходимо организовать обратную связь с пользователем. Программа должна сообщить пользователю о том, что некоторые поля содержат неверную информацию, и вывести ссылку для возвращения к исходной странице. Именно в этот момент в игру вступают сеансовые переменные и повторное заполнение формы.
В-третьих, если данные были введены правильно, пользователя следует поблагодарить. В нашем примере введенные данные для пущей надежности отображаются заново. И конечно, информация о подписчике заносится в базу данных для последующей обработки.
Страница ProcessSub.asp, как и subscription.asp, начинается с основных тегов ITML. В листинге 5.6 показано начало страницы.
Листинг 5.6. Страница ProcessSub.asp
<%@ Language=VBScript %>
<HTML>
<BODY BGCOLOR="WHITE">
Наша первая задача - чтение данных из формы. Для получения данных по именам полей формы используется объект Request. Прочитанные данные сохраняются в переменных для последующего использования.
ПРИМЕЧАНИЕ
Сохранять переменные в данных формы необязательно - вы можете использовать объект Request на всей странице. Впрочем, переменные упрощают последующую обработку данных.

Листинг 5.7. ProcessSub.asp (продолжение)
<%
' Retrieve all of the data that the user entered
' by using the request object.
intLength = request("intLength")
chrFirstName = request("chrFirstName")
chrLastName = Request("chrLastName")
chrAddress = Request("chrAddress")
chrCity = Request("chrCity")
chrState = Request("chrState")
chrZipCode = Request("chrZipCode")
chrPhone = Request("chrPhone")
chrEmail = Request("chrEmail")
chrCardName = Request("chrCardName")
chrCardType = Request("chrCardType")
chrCardNumber = Request("chrCardNumber")
chrExpDate = Request("chrExpDate")
Следующим шагом является проверка правильности заполнения полей. Для большинства полей мы просто убеждаемся в том, что поле не пусто. В поле chkState нужна дополнительная проверка - мы проверяем, что длина названия штата не превышает двух символов. Правильность даты, введенной в поле срока действия кредитной карты, проверяется функцией IsDate().
Листинг 5.8. ProcessSub.asp (продолжение)
' Check to see if the first name was entered.
if chrFirstName = "" then
' Give an error if not.
strError = "You did not enter in your first name.<BR>"

end if
' Check to see if a last name was entered.
if chrLastName = "" then
strError = strError & "You did not enter in your last name.<BR>"
end if
' Check to see if an address was entered
if chrAddress = "" then
strError = strError & "You did not enter in your address.<BR>"
end if
' Check to see if a city was entered.
if chrCity = "" then
strError = strError & "You did not enter in your city.<BR>"
end if
' Check to see if the state was entered of if the length
' is more than two characters.
if chrState = "" or len(chrState) > 2 then
strError = strError & "You did not enter in a valid state.<BR>"
end if
' Check to see if a zip code was entered.
if chrZipCode = "" then
strError = strError & "You did not enter in your zip code.<BR>"
end if
' Check to see if the card name was entered.
if chrCardName = "" then
strError = strError & "You did not enter in the name on your credit card.<BR>"
end if
' Check to see if the card number was entered
if chrCardNumber = "" then
strError = strError & "You did not enter in your credit card number.<BR>"
end if
' Check to see if the card expiration date was entered
if (chrExpDate = "") or (isdate(chrExpDate) = false) then
strError = strError & "You did not enter in a valid credit card expiration date.<BR>"
end if

После проверки даты все готово к выполнению намеченных действий. Мы проверяем переменную strErrorn смотрим, было ли ей присвоено значение. Если переменная содержит текст, значит введенные данные содержат ошибку. Если переменная равна пустой строке, ошибки не было.
' Проверить, были ли обнаружены ошибки
if strError <> "" then
%>
Если произошла ошибка, мы просто выводим соответствующее сообщение и описываем в него строковое описание ошибок. Однако при этом крайне важно охранить полученные данные, чтобы при возвращении к форме их можно было прочитать и вывести. Лучше всего сделать это при помощи сеансовых переменных, которые остаются живыми на протяжении всего сеанса работы данного пользователя. Значения этих переменных можно прочитать и вывести на форме подписки.
<!-- Note the error -->
<B><font color="red">
There is an error in your subscription request:<BR><BR>
</b></font>
<%
' Write out the error messages
Response.Write strError
%>
<!-- Link back to the subscription page -->
<BR>
Click <a href="subscription.asp">here</a> to update.
<%
' Set session variables to the subscription form can be
' re-populated
Session("intLength") = request("intLength")
Session("chrFirstName") = request("chrFirstName")
Session("chrLastName") = Request("chrLastName")
Session("chrAddress") = Request("chrAddress")
Session("chrCity") = Request("chrCity")
Session("chrState") = Request("chrState")
Session("chrZipCode") = Request("chrZipCode")
Session("chrPhone") = Request("chrPhone")
Session("chrEmail") = Request("chrEmail")
session("chrCardName") = Request("chrCardName")
Session("chrCardType") = Request("chrCardType")
Session("chrCardNumber") = Request("chrCardNumber")
Session("chrExpDate") = Request("chrExpDate")
else
%>
Если все данные верны, можно переходить к обработке формы. Страница выводит благодарственное сообщение и краткую сводку данных формы.
Листинг 5.9. ProcessSub.asp (продолжение)
<!-- Thank the customer for the order -->
<font size="4" color="blue">Thank you for your order!
It will be processed immediately.</font>

<!-- Redisplay the data entered into the subscription -->
<BR><BR>
<Table>
<tr><td align="right"><B>Name:</b></td>
<td><i> <% = chrFirstName & " " & chrLastName %></i></td></tr>

<tr><td align="right"><B>Address:</b></td>
<td><i> <% = chrAddress %></i></td></tr>

<tr><td align="right"><B>City:</b></td>
<td><i> <% = chrCity %></i></td></tr>

<tr><td align="right"><B>State:</b></td>
<td><i> <% = chrState %></i></td></tr>

<tr><td align="right"><B>Zip Code:</b></td>
<td><i> <% = chrZipCode %></i></td></tr>

<tr><td align="right"><B>Phone:</b></td
><td><i> <% = chrPhone %></i></td></tr>

<tr><td align="right"><B>Email:</b></td>
<td><i> <% = chrEmail %></i></td></tr>

<tr><td align="right"><B>Card Name:</b></td>
<td><i> <% = chrCardName %></i></td></tr>

<tr><td align="right"><B>Card Type:</b></td>
<td><i> <% = chrCardType %></i></td></tr>

<tr><td align="right"><B>Card Number:</b></td>
<td><i> <% = chrCardNumber %></i></td></tr>

<tr><td align="right"><B>Expiration Date:</b></td>
<td><i> <% = chrExpDate %></i></td></tr>

</ul>
Все готово к следующей важной операции - занесению данных в базу. Первым шагом является создание объекта подключения ADO к базе данных. Для подключения к базе потребуется ODBC DSN - не забудьте создать его. Обратите внимание на то, что хотя в данном примере и используется файловый DSN, вместо него вполне можно создать системный DSN. Учтите, что пользовательские DSN работают только в контексте пользователя, для которого они были созданы, что делает их непригодными для использования в IIS.
Затем необходимо провести предварительную обработку данных для занесения в базу. Все одиночные апострофы удваиваются, чтобы они правильно заносились в базу и не были ошибочно приняты за разделители. Эта проблема возникает в фамилиях (например, О'Брайен), названиях городов, адресах и т. д. Команда Rep! асе легко заменяет эти одиночные апострофы двойными. В нашем примере проверяются поля имени, фамилии, адреса, владельца кредитной карты и города.
СОВЕТ
SQL Server интерпретирует два апострофа, идущих подряд, как один символ. Все апострофы внутри строковых данных, сохраняемых в полях, необходимо удвоить. Значения, вставляемые в базу, должны начинаться с одиночного апострофа и заканчиваться одиночным апострофом.

После подготовки данных мы строим команду SQL для занесения данных в базу. Затем построенная команда SQL выполняется страницей.
Листинг 5.10. ProcessSub.asp (продолжение)
<%
' Create an ADO database connection
set dbSubs = server.createobject("adodb.connection")

' Open the connection using our ODBC file DSN
dbSubs.open("filedsn=SubForm")
' If any of our names have a single quote, we will
' need to double it to insert it into the database
chrFirstName = replace(chrFirstName, "'", "''")
chrLastName = replace(chrLastName, "'", "''")
chrAddress = replace(chrAddress, "'", "''")
chrCardName = replace(chrCardName, "'", "''")
chrCity = replace(chrCity, "'", "''")
' SQL insert statement to insert the subscription
' data into the database
sql = "insert into subscriptions(" & _
"chrFirstName, " & _
"chrLastname, " & _
"chrAddress, " & _
"chrCity, " & _
"chrState, " & _
"chrZipCode, " & _
"chrPhone, " & _
"chrEmail, " & _
"chrCardName, " & _
"chrCardType, " & _
"chrCardNumber, " & _
"chrExpDate, " & _
"intLength) " & _
"values (" & "'" & _
chrFirstName & "', '" & _
chrLastName & "', '" & _
chrAddress & "', '" & _
chrCity & "', '" & _
chrState & "', '" & _
chrZipCode & "', '" & _
chrPhone & "', '" & _
chrEmail & "', '" & _
chrCardName & "', '" & _
chrCardType & "', '" & _
chrCardNumber & "', '" & _
chrExpDate & "', " & _
intLength & ")"

' Execute the SQL statement
dbSubs.execute(sql)
end if
%>
</body>
</html>
На этом программирование на стороне пользователя закончено. В части 3 мы рассмотрим процесс загрузки введенных данных средствами Web.

Тестирование приложения
Перейдем к тестированию приложения.

Заполните форму данными. Некоторые данные следует ввести с ошибками, чтобы мы могли протестировать обработку ошибок. Обратите внимание на неверно заданный срок действия карты. Завершив ввод данных, нажмите кнопку Subscribe, чтобы передать форму странице ProcessSub.asp.
Страница ProcessSub.asp обрабатывает введенные данные. Если все было сделано правильно, в броузере появляется сообщение об ошибке, допущенной при вводе срока действия карты.
Щелкните на ссылке и вернитесь к странице подписки. При этом форма заново заполняется данными подписчика.
СОВЕТ
Имена полей, содержащих ошибочные данные, можно выделить красным цветом.

Исправьте данные и заново передайте форму. При этом выводится благодарность и сводка введенных данных. Кроме того, вы можете проверить данные, заносимые в базу.
Разобравшись с тем, что происходит на стороне пользователя, перейдем к обработке данных. Нам понадобятся средства для получения информации о новой подписке.
Управление приложением
Последним компонентом нашего приложения является отчетная форма. Она предназначена для построения отчета о подписке, оформленной с момента последней обработки данных. Кроме того, форма дает возможность пометить текущие данные подписки как обработанные. Начало страницы SubReport.asp приведено в листинге 5.11.
Листинг 5.11. SubReport.asp
<%@ Language=VBScript %>
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
</HEAD>
<BODY>
Работа начинается с создания подключения к базе данных. Затем мы проверяем, нужно ли пометить данные подписки как обработанные. В этом случае URL будет содержать параметр idSubscription; он передается позднее в коде страницы, при сбросе признака обработки. При наличии этого параметра все записи с идентификатором, меньшим либо равным заданного, помечаются как обработанные. Все записи с идентификатором больше заданного считаются необработанными и отображаются.
Листинг 5.12. SubReport.asp (продолжение)
<%
' Create an ADO database connection
set dbSubs = server.createobject("adodb.connection")
set rsSubs = server.CreateObject("adodb.recordset")
' Open the connection using our ODBC file DSN
dbSubs.open("filedsn=SubForm")
' Retrieve any subscription IDs on the URL
idSubscription = Request("idSubscription")
' Check to see if there is a value.
if idSubscription <> "" then

' Built an SQL update statement to process teh subs.
sql = "update subscriptions set intProcessed = 1 where idSubscription <= " & _
idSubscription

' Execute the SQL statement
dbSubs.execute sql

end if
На следующем шаге мы читаем всю необработанную подписку. Страница строит команду SQL с соответствующей секцией WHERE. В результате выполнения команда возвращает набор записей.
' Построить команду SQL для чтения всех необработанных данных подписки
sql = "select * from subscriptions where intProcessed = 0"

' Выполнить команду и получить набор записей
set rsSubs = dbSubs.Execute(sql)
%>
Теперь можно перейти к построению таблицы, в которой будут выводиться сведения о необработанной подписке. Таблица имеет очень простой формат; в левом столбце выводятся названия полей, а в правом - данные.
СОВЕТ
Возможно, в программе следует реализовать дополнительную логику для вывода сведений в несколько столбцов вместо одного. При обработке большого количества записей это позволит уменьшить количество отображаемых страниц.

Листинг 5.13. SubReport.asp (продолжение)
<!-- Start the table to display the subs. -->
<Table border="1">
<%
' Check to see if no subs are returned
if rsSubs.EOF then

' If so, then write
Response.Write "No subscriptions to report."

else
' Loop through the subs
do until rsSubs.eof
%>
<!-- Display the subscription data -->
<TR>
<TD align="right">First Name:</TD>
<TD> <%=rsSubs("chrFirstName")%></TD>
</TR>
<TR>
<TD align="right">Last Name:</TD>
<TD> <%=rsSubs("chrLastName")%></TD>
</TR>
<TR>
<TD align="right">Address:</TD>
<TD> <%=rsSubs("chrAddress")%></TD>
</TR>
<TR>
<TD align="right">City:</TD>
<TD> <%=rsSubs("chrCity")%></TD>
</TR>
<TR>
<TD align="right">State:</TD>
<TD> <%=rsSubs("chrState")%></TD>
</TR>
<TR>
<TD align="right">Zip Code:</TD>
<TD> <%=rsSubs("chrZipCode")%></TD>
</TR>
<TR>
<TD align="right">Phone:</TD>
<TD> <%=rsSubs("chrPhone")%></TD>
</TR>
<TR>
<TD align="right">Email:</TD>
<TD> <%=rsSubs("chrEmail")%></TD>
</TR>
<TR>
<TD align="right">Card Name:</TD>
<TD> <%=rsSubs("chrCardName")%></TD>
</TR>
<TR>
<TD align="right">Card Number:</TD>
<TD> <%=rsSubs("chrCardNumber")%></TD>
</TR>
<TR>
<TD align="right">Expiration Date:</TD>
<TD> <%=rsSubs("chrExpDate")%></TD>
</TR>
<TR>
<TD align="right">Date Entered:</TD>
<TD> <%=rsSubs("dtEntered")%></TD>
</TR>
<TR>
<TD align="right">Subscription Length:</TD>
<TD> <%=rsSubs("intLength")%></TD>
</TR>
<TR>
<TD>&nbsp;</TD>
<TD>&nbsp;</TD>
</TR>
Идентификатор последней выведенной записи необходимо сохранить, чтобы вернуть его странице для установки признака обработки записей. Идентификатор текущей записи сохраняется в переменной idSubscription, после чего мы переходим к следующей записи набора.
Листинг 5.14. SubReport.asp (продолжение)
<%
' Store the last subscription id
idSubscription = rsSubs("idSubscription")
' Move to the next sub
rsSubs.MoveNext

loop
end if
%>
</table>
<BR><BR>
Остается создать ссылку, которая вызывает текущую страницу и передает идентификатор последней выведенной записи. Как говорилось выше, этот идентификатор включается в URL при помощи параметра idSubscription.
Листинг 5.15. SubReport.asp (продолжение)
<!-- Link to this page with the last subscription ID -->
Click <a href="SubReport.asp?idSubscription=<%=idSubscription%>">here</a>
to clear this report.
</BODY>
</HTML>
Все готово к запуску страницы. Проследите за тем, чтобы в базе данных присутствовали записи. Обратите внимание на ссылку для сброса необработанных данных.

Щелкните на ссылке, чтобы сбросить сведения о новой подписке. Страница загружается повторно с включенным в URL идентификатором последней записи. При этом выполняется фрагмент кода, в котором новые записи помечаются как обработанные. Проверьте поле intProcessed и убедитесь в том, что ему было присвоено значение 1. На экране появляются сведения о новой подписке или сообщение об ее отсутствии.
Можно было бы предусмотреть усовершенствованный интерфейс для поиска любых записей, обработанных и необработанных. Поиск может осуществляться по дате создания записи, сроку подписки и т. д.

Итоги
В рассмотренном примере были представлены ключевые средства, используемые при создании коммерческих приложений - ASP, SQL Server, HTML и броузер. Если вам понадобится простой способ сбора данных о подписчиках, зарегистрированных пользователях и т. д., такой формы будет более чем достаточно.
При создании подобных форм необходимо учитывать некоторые обстоятельства. Первое - это безопасность. Разумеется, форму необходимо зашифровать с использованием SSL (Secure Sockets Layer), чтобы предотвратить перехват данных в Интернете. Проследите за тем, чтобы имена и пароли для доступа к базе данных нельзя было легко подобрать или угадать. Кроме того, страница управления не должна быть доступной для всех желающих. Организуйте парольную защиту на уровне формы средствами SQL или воспользуйтесь механизмом списка управления доступом (ACL, Access Control List) Windows NT для того каталога, в котором находится страница.
Во-вторых, пользователю, оформившему заказ, можно сообщить номер заказа, чтобы в дальнейшем он мог обращаться за справками. Лучше всего создать хранимую процедуру, которая сохраняет данные заказа и возвращает в качестве параметра значение столбца-счетчика в таблице. Это значение можно включить в благодарственное сообщение.
Наконец, если вы хотите организовать немедленную обработку данных кредитной карты, рассмотрите возможность использования таких средств, как Cyber-Cash или HP/Veriphone. Если данные успешно проходят проверку, пользователю можно немедленно предоставить доступ к необходимой информации.
На этом первая часть книги завершается. Изложенный материал позволяет перейти к следующей фазе - программированию нашего электронного магазина.

 

 
На главную | Содержание | < Назад....Вперёд >
С вопросами и предложениями можно обращаться по nicivas@bk.ru. 2013 г. Яндекс.Метрика