home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Internet 2001 November / MICD2001_11_NR1.iso / Www / WebArea / index.php@id=11 < prev    next >
Text File  |  2001-09-26  |  89KB  |  2,276 lines

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4//PL">
  2. <html>
  3. <head>
  4. <title>WEB-AREA.org - serwis webmaster≤w</title>
  5. <link href="style.css" rel="stylesheet" type="text/css">
  6. <LINK REL="SHORTCUT ICON" HREF="favicon.ico"> 
  7. <meta http-equiv="Creation-date" content="28.08.2001">
  8. <meta http-equiv="Reply-to" content="web-area@web-area.org">
  9. <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-2">
  10. <meta name="author" content="Jakub & Jan Filipowscy">
  11. <meta name="description" content="Serwis webmasterow. Znajdziesz tu kilka kursow popularnych internetowych jezykow programowania takich jak: HTML, CSS, WML, SGML, XML, PHP, Perl i Java. Zamiescilismy tu rowniez wiele skryptow JavaScript, PHP i CGI. Przeczytac mozna kilka artykulow i sciagnac kilka szablonow. Dla poczatkujacych jest dzial BeginnerZone. ">
  12. <meta http-equiv="keywords" content="WEB-AREA, web-area, web area, web, area, WEB-AREA.org, web-area.org, webara.org,strefa webmastera, strefa, webmastera, webmaster, WEBMASTER, Webmaster, tworzenie stron www, www, strona www, internet, world wide web, design, designerswo, designer, programowanie, jΩzyki, jΩzyk programowania, php, cgi, html, java, javascript, sgml, wml, PHP, CGI, HTML, Java, JavaScript, SGML, WML, wap, standarty, skrypty php, skrypty cgi, applety java, aplety, aplety java, aplety javy, applety javy, javascripty, JavaScripty, skrypty javy, publikowanie witryny, witryna, tworzenie witryn, tworzenie sklep≤w internetowych, edytory html, tekstowe edytory html, projekt syf, szablony, Szablony, free, darmowe, zadarmo, subskrypcja, lista mailingowa, mailing list, lista subskrypcyjna, bannery, formularze, liczniki, ksiΩgi go╢ci, linki, fora, pliki i operacje na nich, statystyki, wyszukiwarki, rankingi, darmowe skrypty, Jakub Filipowski, Jan Filipowski, katalog, Katalog stron zwi▒zanych z tematyk▒ webmasterstwa, webmasterswo, magazyn www, style, CSS, XML, ASP, jΩzyki skryptowe, generatory, anarchizm">
  13. </head>
  14. <body>
  15.  
  16.  
  17. <div align="left">
  18. <table border="0" cellpadding="0" cellspacing="0" width="770">
  19. <tr>
  20. <td width="770" valign="top" colspan="3">
  21.  
  22.     <table border="0" cellpadding="0" cellspacing="0" width="770">
  23.     <tr>
  24.     <td width="166" valign="top"><a href="index.php"><img src="img/logo.gif" border="0" width="166" height="70" alt="WEB-AREA.org - serwis webmaster≤w"></a></td>
  25.     <td width="604" height="70" background="img/gora.gif" align="right"><iframe src="banner.php" MARGINWIDTH="0" MARGINHEIGHT="0" HSPACE="0" VSPACE="0" FRAMEBORDER="0" SCROLLING="NO" WIDTH="468" HEIGHT="60">
  26. </iframe></td>
  27.     </tr></table>
  28.  
  29. </td>
  30. </tr><tr>
  31. <td width="770" valign="top" colspan="3">
  32.     <table border="0" cellpadding="1" cellspacing="0" width="770">
  33.         <tr><form method="post" action="szukaj.php">
  34.         <td width="260">    <input type="text" name="zapytanie" size="15"> <input type="submit" value="SZUKAJ"> <span class="m"><a href="index.php@url=redakcja_2Fszukaj">Jak szukaµ?</a></span></td></form>
  35.         <td width="510">
  36.         
  37.         <p align="center">
  38.         <a href="index.php@id=206" class="gora">Konkurs</a>   
  39.         <a href="subskrypcja/nowa.php" class="gora">Za│≤┐ subskrypcjΩ</a>    
  40.         <a href="index.php@id=128" class="gora">Katalog</a>    
  41.         <a href="forum.php" class="gora">Forum</a>    
  42.         <a href="index.php@id=15" class="gora">BeginnerZone</a>
  43.         
  44.         </td>
  45.     </tr></table>
  46. </td>
  47. </tr>
  48. <tr>
  49. <td width="142" valign="top">
  50.     
  51.     <br>
  52.     <table border="0" cellpadding="0" cellspacing="0" width="142">
  53.     <tr>
  54.     <td width="142" valign="top"><img src="img/menu.gif" border="0" width="142" height="13" alt="MENU"></td>
  55.     </tr>
  56.     <tr>
  57.     <td width="142" valign="top" background="img/okno1.gif">
  58.     <img src="img/s.gif" width="9" height="8"><b class="menu1">KURSY</b><br>
  59.       - <a href="index.php@id=50" class="menu">HTML</a><br>
  60.       - <a href="index.php@id=40" class="menu">CSS</a><br>
  61.       - <a href="index.php@id=62" class="menu">Java</a><br>
  62.       - <a href="index.php@id=145" class="menu">PHP</a><br>
  63.       - <a href="index.php@id=39" class="menu">CGI</a><br>
  64.       - <a href="index.php@id=5" class="menu">ASP</a><br>
  65.       - <a href="index.php@id=182" class="menu">WML</a><br>
  66.       - <a href="index.php@id=190" class="menu">XML</a><br>
  67.       - <a href="index.php@id=159" class="menu">SGML</a><br>
  68.  
  69.     <img src="img/s.gif" width="9" height="8"><b class="menu1">SKRYPTY</b><br>
  70.       - <a href="index.php@id=78" class="menu">JavaScript</a><br>
  71.       - <a href="index.php@id=135" class="menu">PHP</a><br>
  72.       - <a href="index.php@id=30" class="menu">CGI</a><br>
  73.  
  74.     <img src="img/s.gif" width="9" height="8"><b class="menu1">INNE</b><br>
  75.       - <a href="index.php@id=59" class="menu">Szablony</a><br>
  76.       - <a href="forum.php" class="menu">Forum</a><br>
  77.       - <a href="index.php@id=61" class="menu">Webmasterska lista</a><br>
  78.       - <a href="index.php@id=128" class="menu">Katalog</a><br>
  79.       - <a href="index.php@id=15" class="menu">BeginnerZone</a><br>
  80.       - <a href="index.php@id=206" class="menu">Konkurs</a><br>
  81.     
  82.     <img src="img/s.gif" width="9" height="8"><b class="menu1">SUBSKRYPCJA</b><br>
  83.       - <a href="subskrypcja/nowa.php" class="menu">Za│≤┐</a><br>
  84.       - <a href="subskrypcja/admin.php" class="menu">Administracja</a><br>
  85.  
  86.     <img src="img/s.gif" width="9" height="8"><b class="menu1">REDAKCJA</b><br>
  87.       - <a href="index.php@id=156" class="menu">Sk│ad</a><br>
  88.       - <a href="index.php@id=157" class="menu">Wsp≤│praca</a><br>
  89.       - <a href="index.php@id=158" class="menu">Reklama</a></td>
  90.     </tr>
  91.     <tr>
  92.     <td width="142" valign="top"><img src="img/okno2.gif" border="0" width="142" height="10"></td>
  93.     </tr></table>
  94.  
  95. </td>
  96. <td width="486" valign="top"><br>
  97.     <div align="center">
  98.     <table border="0" cellpadding="0" cellspacing="0" width="460">
  99.     <tr>
  100.     <td width="460" valign="top"><table border="0" cellpadding="0" cellspacing="0" width="460">
  101.         <tr>
  102.         <td width="460" valign="top"><img src="img/zobacz.gif" border="0" width="460" height="13" alt="ZOBACZ JESZCZE"></td>
  103.         </tr>
  104.         <tr>
  105.         <td width="460" valign="top" background="img/okno11.gif"><div align="center">
  106.                 <table border="0" cellpadding="0" cellspacing="0" width="450"><tr><td width="450"><a class="menu" href="index.php@id=6">Praca w ASP</a>
  107.  <a class="menu" href="index.php@id=7">Warunki i pΩtle</a>
  108.  <a class="menu" href="index.php@id=8">Wysy│anie i odbieranie danych od u┐ytkownika</a>
  109.  <a class="menu" href="index.php@id=9">Obiekt Sessions i Cookies</a>
  110.  <a class="menu" href="index.php@id=10">Wysy│anie i odbieranie poczty e-mail</a>
  111.  <a class="menu" href="index.php@id=12">Pliki</a>
  112.  <a class="menu" href="index.php@id=13">U┐ycie XML</a>
  113.  <a class="menu" href="index.php@id=14">Typy zmiennych</a> </td></tr></table></div></td>
  114.         </tr>
  115.         <tr>
  116.         <td width="460" valign="top"><img src="img/okno21.gif" border="0" width="460" height="10"></td>
  117.         </tr></table><span class="nag">Kurs ASP</span>
  118. <h2>Bazy danych.</h2>
  119.  
  120. <h3>6.1 DostΩp do danych.</h3>
  121.  
  122. <p align="justify">W tym rozdziale zajmiemy siΩ wykorzystaniem baz danych do
  123. przechowywania informacji zebranych na stronie WWW. Zostanie
  124. zaprezentowana metoda po│▒czenia siΩ z baz▒ danych poprzez <code>ADO</code>
  125. (ActiveX Data Object), kt≤re zapewnia po│▒czenie ASP z baz▒
  126. danych. ASP umo┐liwia po│▒czenie siΩ z ka┐d▒ baz▒ danych
  127. maj▒c▒ dostΩp do <code>OLE DB</code> (Object Linking and Embedding Database)
  128. lub <code>ODBC</code> (Open Database Connectivity). Przyk│ady bΩd▒ zawiera│y
  129. po│▒czenia z bazami danych utworzonych w <code>MS Access</code> oraz <code>SQL
  130. Server</code>.</p>
  131.  
  132. <p align="justify"><code>ADO</code> jest zbiorem interfejs≤w (poziom aplikacji), kt≤re umo┐liwiaj▒
  133. dostΩp do danych <code>OLE DB</code> przy u┐yciu dowolnego jΩzyka
  134. programowania, tak┐e VBScript. <code>ADO</code> jest bardzo │atwe w u┐yciu,
  135. zapewnia szybki dostΩp do danych przy niewielkich
  136. zapotrzebowaniach pamiΩci.</p>
  137.  
  138. <p align="justify"><code>OLE DB</code> jest zbiorem interfejs≤w na poziomie systemu, umo┐liwiaj▒cych
  139. dostΩp do r≤┐nych danych i ╝r≤de│ danych umieszczonych w r≤┐nych
  140. miejscach.</p>
  141.  
  142. <p align="justify"><code>ODBC</code> stanowi interfejs umo┐liwiaj▒cy dostΩp aplikacjom do
  143. danych, tj. bazy danych, pliki tekstowe, itd. Poprzez <code>ODBC</code> mo┐na
  144. pod│▒czyµ siΩ do baz danych MS Access, MS SQL Server, dBase,
  145. Oracle, DB2 i wielu innych.</p>
  146.  
  147. <p align="justify"><code>ADO</code> posiada wiele obiekt≤w, kt≤re umo┐liwiaj▒ pod│▒czenie
  148. do bazy danych i operowanie na danych w nich zawartych. Oto g│≤wne
  149. z nich:</p>
  150.  
  151. <table border="0">
  152. <TBODY>    <tr>
  153.         <td valign="top">Connection</td>
  154.         <td valign="top">-</td>
  155.         <td valign="top">stanowi po│▒czenie z ╝r≤d│em
  156.         danych</td>
  157.     </tr>
  158.     <tr>
  159.         <td valign="top">Recordset</td>
  160.         <td valign="top">-</td>
  161.         <td valign="top">zawiera rekordy zwr≤cone
  162.         po wykonaniu zapytania na bazie danych</td>
  163.     </tr>
  164.     <tr>
  165.         <td valign="top">Field</td>
  166.         <td valign="top">-</td>
  167.         <td valign="top">zawiera dane z
  168.         pojedynczej kolumny i informacje na temat tych danych;
  169.         obiekt <code>Recordset</code> zawiera grupΩ <code>Fields</code>, kt≤ra z kolei
  170.         zawiera wszystkie obiekty <code>Field</code></td>
  171.     </tr>
  172.     <tr>
  173.         <td valign="top">Property</td>
  174.         <td valign="top">-</td>
  175.         <td valign="top"> </td>
  176.     </tr>
  177.     <tr>
  178.         <td valign="top">Error</td>
  179.         <td valign="top">-</td>
  180.         <td valign="top">zawiera rozszerzon▒
  181.         informacjΩ o zwracanych b│Ωdach; wszystkie b│Ωdy
  182.         dostΩpu do bazy danych mog▒ byµ dostΩpne przez grupΩ
  183. <code>        Errors</code></td>
  184.     </tr>
  185.     <tr>
  186.         <td valign="top">Command</td>
  187.         <td valign="top">-</td>
  188.         <td valign="top">umo┐liwia definiowanie
  189.         specjalnych komend, kt≤re s▒ wykorzystywane do
  190.         wykonania operacji na bazie danych kilka razy wraz ze
  191.         zmian▒ parametr≤w</td>
  192.     </tr>
  193.     <tr>
  194.         <td valign="top">Parameter</td>
  195.         <td valign="top">-</td>
  196.         <td valign="top">jest to pojedynczy
  197.         parametr lub argument skojarzony z obiektem <code>Command</code> bazuj▒cym
  198.         na sparametryzowanym zapytaniu lub procedurze
  199.         przechowywanej</td>
  200.     </tr>
  201. </TBODY></table>
  202.  
  203. <p align="justify"><code>Procedury przechowywane</code> s▒ wykorzystywane w bazach SQL Server.
  204. Pobieraj▒ one argumenty i wykonuj▒ polecenia bezpo╢rednio na
  205. serwerze SQL.</p>
  206.  
  207. <p align="justify">NajczΩ╢ciej u┐ywanymi obiektami w skryptach s▒: <code>Connection</code>,
  208. <code>Recordset</code> i <code>Field</code>. Relacje miΩdzy nimi s▒ nastΩpuj▒ce:</p>
  209.  
  210. <p align="center"></p>
  211.  
  212. <p align="justify">Obiekt <code>Recordset</code> mo┐na stworzyµ poprzez wykonanie metody <code>Execute</code>
  213. na obiekcie <code>Connection</code>. Odwrotnie, w│a╢ciwo╢µ <code>ActiveConnection</code>
  214. obiektu <code>Recordset</code> wskazuje po│▒czenie do kt≤rego bie┐▒cy
  215. obiekt <code>Recordset</code> nale┐y. Obiekt <code>Recordset</code> posiada grupΩ <code>Fields</code>,
  216. kt≤ra zawiera wszystkie obiekty <code>Field</code> obiektu <code>Recordset</code>. Obiekt <code>Field</code>
  217. reprezentuje pojedyncz▒ kolumnΩ danych. Mo┐na u┐yµ domy╢lnej
  218. w│a╢ciwo╢ci <code>Value</code> w celu ustawienia lub zwr≤cenia danych z
  219. bie┐▒cego rekordu.</p>
  220.  
  221. <h3>6.2 DostΩp do bazy
  222. danych.</h3></p>
  223.  
  224. <p align="justify">W celu pobrania danych z bazy nale┐y:</p>
  225.  
  226. <table border="0" cellspacing="4">
  227. <TBODY>    <tr>
  228.         <td class="LEFT">1.</td>
  229.         <td class="LEFT">Otworzyµ po│▒czenie z baz▒ danych.</td>
  230.     </tr>
  231.     <tr>
  232.         <td class="LEFT">2.</td>
  233.         <td class="LEFT">Stworzyµ obiekt umo┐liwiaj▒cy dostΩp
  234.         do p≤l danych ka┐dego rekordu.</td>
  235.     </tr>
  236.     <tr>
  237.         <td class="LEFT">3.</td>
  238.         <td class="LEFT">Pobraµ dane ze stworzonego obiektu.</td>
  239.     </tr>
  240.     <tr>
  241.         <td class="LEFT">4.</td>
  242.         <td class="LEFT">Zamkn▒µ obiekt oraz po│▒czenie z baz▒
  243.         danych.</td>
  244.     </tr>
  245. </TBODY></table>
  246.  
  247. <p align="justify">Poni┐szy przyk│ad pokazuje jak mo┐na to zrealizowaµ:</p>
  248.  
  249. <table border="0">
  250. <TBODY>    <tr>
  251.         <td valign="top">1:<br>
  252.         2:<br>
  253.         3:<br>
  254.         4:<br>
  255.         5:<br>
  256.         6:<br>
  257.         7:<br>
  258.         8:<br>
  259.         9:<br>
  260.         10:<br>
  261.         11:<br>
  262.         12:<br>
  263.         13:<br>
  264.         14:<br>
  265.         15:<br>
  266.         16:<br>
  267.         17:<br>
  268.         18:<br>
  269.         19:<br>
  270.         20:</td>
  271.         <td valign="top"> </td>
  272.         <td colspan="2"><% <code>@LANGUAGE = VBScript</code> %><br>
  273.         <%<br>
  274. <code>        Option Explicit<br>
  275.         Response.Expires = 0<br>
  276.         Dim objConn, objRS, strQuery<br>
  277.         Dim strConnection<br>
  278.         Set objConn = Server.CreateObject("ADODB.Connection")<br>
  279.         strConnection = "DSN=Northwind;Database=Northwind;"<br>
  280.         strConnection = strConnection & "UID=sa;PWD=;"<br>
  281.         objConn.Open strConnection<br>
  282.         strQuery = "SELECT ProductName, UnitPrice, FROM
  283.         Products "<br>
  284.         strQuery = strQuery & "ORDER BY ProductName"<br>
  285.         Set objRS = objConn.Execute(strQuery)</code><br>
  286.         %><br>
  287.         <HTML><br>
  288.         <BODY><br>
  289.         <p>Wszystkie produkty znajduj▒ce siΩ w tabeli
  290.         Products, <br>
  291.         posortowane wed│ug nazwy produktu:</p><br>
  292.         <%<br>
  293. <code>        While Not objRS.EOF</code></td>
  294.     </tr>
  295.     <tr>
  296.         <td valign="top">21:<br>
  297.         22:<br>
  298.         23:</td>
  299.         <td valign="top"> </td>
  300.         <td> </td>
  301.         <td><code>Response.Write objRS("ProductName")
  302.         & " ("<br>
  303.         Response.Write FormatCurrency(objRS("InitPrice"))
  304.         & ")<BR>"<br>
  305.         objRS.MoveNext</code></td>
  306.     </tr>
  307.     <tr>
  308.         <td valign="top">24:<br>
  309.         25:<br>
  310.         26:<br>
  311.         27:<br>
  312.         28:<br>
  313.         29:<br>
  314.         30:<br>
  315.         31:</td>
  316.         <td valign="top"> </td>
  317.         <td colspan="2"><code>Wend<br>
  318.         objRS.Close<br>
  319.         objConn.Close<br>
  320.         Set objRS = Notning<br>
  321.         Set objConn = Nothing</code><br>
  322.         %><br>
  323.         </BODY><br>
  324.         </HTML></td>
  325.     </tr>
  326. </TBODY></table>
  327.  
  328. <p align="justify">Linia 4 nakazuje przegl▒darce aby nie przechowywa│a (nie
  329. keszowa│a) tej strony. Przy braku tej linii, przegl▒darka
  330. przechowywa│aby stronΩ i u┐ytkownik, w razie zmiany zawarto╢ci
  331. bazy danych, widzia│by przestarza│e dane. Linie 5-6 zawieraj▒
  332. wszystkie deklaracje zmiennych. <code>ObjConn</code> i <code>objRS</code> s▒ obiektami <code>Connection</code>
  333. i <code>Recordset</code>. Zmienna <code>strQuery</code> zawiera zapytanie SQL, kt≤re
  334. spowoduje pobranie wszystkich produkt≤w z tabeli <code>Products</code>. <code>StrConnection</code>
  335. zawiera │a±cuch po│▒czenia, kt≤ry okre╢la <code>DSN</code> (╝r≤d│o
  336. danych ODBC) jako ╝r≤d│o danych. W linii 7 utworzony zosta│
  337. obiekt <code>Connection</code> i przechowywany jest w zmiennej <code>objConn</code>.
  338. Poniewa┐ skrypt zak│ada fizyczne po│▒czenie do ╝r≤d│a
  339. danych, to musi je opisaµ. Opis po│▒czenia (│a±cuch po│▒czenia)
  340. znajduje siΩ w liniach 8-9 w zmiennej <code>strConnection</code>. úa±cuch
  341. po│▒czenia wygl▒da nastΩpuj▒co:</p>
  342.  
  343. <table border="0">
  344. <TBODY>    <tr>
  345.         <td>"DSN=Northwind;Database=Northwind;UID=sa;PWD=;"</td>
  346.     </tr>
  347. </TBODY></table>
  348.  
  349. <p align="justify">úa±cuch po│▒czenia zawiera seriΩ argument≤w wraz z ich
  350. warto╢ciami oddzielonymi ╢rednikami. W przyk│adzie u┐yto nastΩpuj▒cych
  351. argument≤w:</p>
  352.  
  353. <table border="0">
  354. <TBODY>    <tr>
  355.         <td valign="top">DSN</td>
  356.         <td>okre╢la nazwΩ ╝r≤d│a danych ODBC
  357.         po│▒czenia</td>
  358.     </tr>
  359.     <tr>
  360.         <td valign="top">Database</td>
  361.         <td>okre╢la bazΩ danych, z kt≤r▒
  362.         zostanie nawi▒zane po│▒czenie; chocia┐ ten parametr
  363.         jest opcjonalny, dobrze jest go umie╢ciµ</td>
  364.     </tr>
  365.     <tr>
  366.         <td valign="top">UID</td>
  367.         <td>zawiera nazwΩ u┐ytkownika (identyfikacja)
  368.         loguj▒cego siΩ do bazy danych, w celu okre╢lenia
  369.         uprawnie± do dokonywania na bazie okre╢lonych operacji</td>
  370.     </tr>
  371.     <tr>
  372.         <td valign="top">PWD</td>
  373.         <td>zawiera has│o u┐ytkownika loguj▒cego
  374.         siΩ do bazy danych; UID i PWD to jedna nieroz│▒czna
  375.         para, kt≤ra nadaje prawa dostΩpu do bazy danych</td>
  376.     </tr>
  377. </TBODY></table>
  378.  
  379. <p align="justify">Istnieje mo┐liwio╢µ dostΩpu do baz danych MS Access bez u┐ycia
  380. ODBC. Poni┐ej znajduje siΩ odpowiednik linii 8-9 dla takiego
  381. przypadku:</p>
  382.  
  383. <table border="0">
  384. <TBODY>    <tr>
  385.         <td>strConnection = "DRIVER={Microsoft
  386.         Access Driver (*.mdb)};DBQ=" & Server.MapPath(vsciezka)
  387.         & ";"</td>
  388.     </tr>
  389. </TBODY></table>
  390.  
  391. <p align="justify">gdzie <code>vsciezka</code> to wirtualna ╢cie┐ka do pliku bazy danych MS
  392. Access (*.mdb). Metoda <code>MapPath</code> obiektu <code>Server</code> zwarca rzeczywist▒
  393. (fizyczn▒) ╢cie┐kΩ do pliku.</p>
  394.  
  395. <p align="justify">W linii 10 zosta│o otwarte po│▒czenie do bazy danych
  396. poprzez u┐ycie │a±cucha po│▒czenia znajduj▒cego siΩ w <code>strConnection</code>.
  397. W linii 11 i 12 do zmiennej <code>strQuery</code> zapisane zosta│o zapytanie
  398. skierowane do bazy danych i wykonane w linii 13 poprzez
  399. wykorzystanie metody <code>Execute</code>. Rezultat zapytanie przechowywany
  400. jest w obiekcie <code>Recordset</code>, tj. <code>objRS</code>. Zapytanie SQL jest
  401. wykonywane przez sterownik ODBC lub bazΩ danych, nie przez
  402. Active Server Pages. Obiekt <code>objRS</code> zawiera wszystkie wiersze, kt≤re
  403. zosta│y zwr≤cone z bazy danych jako rezultat wykonania
  404. zapytania SQL. NastΩpnym krokiem jest wy╢wietlenie rezultatu na
  405. ekranie przegl▒darki. W liniach 15-18 zosta│y wys│ane
  406. znaczniki HTML wraz z informacj▒ na temat wy╢wietlonych danych.<br>
  407. W liniach 20-24 nastΩpuje wys│anie do przegl▒darki wszystkich
  408. wierszy rezultatu zapytania SQL. Jest to zrealizowane przy pomocy
  409. pΩtli <code>While</code>. Po otwarciu zbioru otrzymanych rekord≤w (wykonaniu
  410. zapytania) aktywnym rekordem jest rekord pierwszy. Je┐eli rekord
  411. istnieje to warto╢ci▒ zwr≤con▒ po wywo│aniu w│a╢ciwo╢ci <code>EOF</code>
  412. (end of file) bΩdzie <code>FALSE</code>. W naszym przyk│adzie przed
  413. warunkiem znajduje siΩ operator <code>Not</code>, kt≤ry zmienia warto╢µ
  414. wykonanego warunku na przeciwny, czyli je╢li rekord bΩdzie
  415. istnia│ (<code>objRS.EOF = FALSE</code>), to wykona siΩ pΩtla <code>While</code>.</p>
  416.  
  417. <p align="justify">Dane z p≤l bazy uzyskiwane s▒ poprzez odczytanie w│a╢ciwo╢ci
  418. <code>Value</code> z obiektu <code>Field</code> z grupy <code>Fields</code> obiektu <code>Recordset</code>. Komenda
  419. taka powinna w naszym przypadku wygl▒daµ nastΩpuj▒co:</p>
  420.  
  421. <table border="0">
  422. <TBODY>    <tr>
  423.         <td>objRS.Fields.Item("ProductName").Value</td>
  424.     </tr>
  425. </TBODY></table>
  426.  
  427. <p align="justify">jednak VBScript pozwala nam tak▒ komendΩ skr≤ciµ do
  428. postaci:</p>
  429.  
  430. <table border="0">
  431. <TBODY>    <tr>
  432.         <td>objRS("ProductName")</td>
  433.     </tr>
  434. </TBODY></table>
  435.  
  436. <p align="justify">Funkcja <code>FormatCurrency(</code>warto╢µ<code>)</code> powoduje dodanie symbolu
  437. waluty oraz poprawnego zapisu warto╢ci jako warto╢ci walutowej
  438. wed│ug ustawie± lokalnych serwera lub skryptu.</p>
  439.  
  440. <p align="justify">Linia 23 nakazuje przej╢cie do nastΩpnego rekordu. Nale┐y o
  441. niej pamiΩtaµ, gdy┐ jej brak mo┐e doprowadziµ do wyra╝nego
  442. pogorszenia wydajno╢ci serwera WWW do momentu up│ywu czasu
  443. wykonywania skryptu.<br>
  444. Kiedy skrypt wy╢wietli ca│▒ zawarto╢µ p≤l rekord≤w i zako±czy
  445. wykonywanie pΩtli, obiekty <code>Recordset</code> (<code>objRS</code>) oraz <code>Connection</code> (<code>objConn</code>)
  446. zostaj▒ zamkniΩte (linie 25-26). W celu zwolnienia zasob≤w
  447. systemu, obiekty <code>Recordset</code> (<code>objRS</code>) oraz <code>Connection</code> (<code>objConn</code>)
  448. zosta│y zamkniΩte po ich u┐yciu. W celu usuniΩcia obiekt≤w
  449. ca│kowicie z pamiΩci zosta│a przyporz▒dkowana im warto╢µ <code>Nothing</code>
  450. (linie 27-28).</p>
  451.  
  452. <h3>6.3 Pobieranie danych z bazy danych.</h3>
  453.  
  454. <p align="justify">Przyk│ad z poprzedniego podrozdzia│u (<a href="#podrozdz62"
  455. class="LINK">podrozdzia│ 6.2</a>), pokaza│ w jaki spos≤b mo┐na
  456. pobraµ dane z bazy przy pomocy metody <code>Execute</code> obiektu <code>Connection</code>.
  457. Teraz zostanie pokazany jeszcze inny spos≤b pobierania danych z
  458. bazy. Do tego celu wykorzystana zostanie metoda <code>Open</code> obiektu <code>Recordset</code>.
  459. Oto przyk│ad:</p>
  460.  
  461. <table border="0">
  462. <TBODY>    <tr>
  463.         <td valign="top">1:<br>
  464.         2:<br>
  465.         3:<br>
  466.         4:<br>
  467.         5:<br>
  468.         6:<br>
  469.         7:<br>
  470.         8:<br>
  471.         9:<br>
  472.         10:<br>
  473.         11:<br>
  474.         12:<br>
  475.         13:<br>
  476.         14:<br>
  477.         15:<br>
  478.         16:<br>
  479.         17:<br>
  480.         18:<br>
  481.         19:<br>
  482.         20:<br>
  483.         21:<br>
  484.         22:<br>
  485.         23:<br>
  486.         24:<br>
  487.         25:<br>
  488.         26:<br>
  489.         27:<br>
  490.         28:<br>
  491.         29:<br>
  492.         30:</td>
  493.         <td valign="top"> </td>
  494.         <td colspan="2"><% <code>@LANGUAGE = VBScript</code> %><br>
  495.         <%<br>
  496. <code>        Option Explicit<br>
  497.         Response.Expires = 0<br>
  498.         Dim objConn, objRS, strQ<br>
  499.         Dim strConnection<br>
  500.         <br>
  501.         Set objConn = Server.CreateObject("ADODB.Connection")<br>
  502.         strConnection = "Data Source=Northwind;"<br>
  503.         strConnection = strConnection & "User ID=sa;Password=;"<br>
  504.         objConn.Open strConnection<br>
  505.         <br>
  506.         Set objRS = Server.CreateObject("ADODB.Recordset")</code><br>
  507. <code>        Set objRS.ActiveConnection = objConn<br>
  508.         strQ = "SELECT Customers.CompanyName, "<br>
  509.         strQ = strQ & "COUNT(Orders.OrderID) AS
  510.         NumOrders "<br>
  511.         strQ = strQ & "FROM Customers INNER JOIN Orders
  512.         ON "<br>
  513.         strQ = strQ & "Customers.CustomerID = Orders.CustomerID
  514.         "<br>
  515.         strQ = strQ & "GROUP BY Customers.CompanyName
  516.         "<br>
  517.         strQ = strQ & "HAVING COUNT(Orders.OrderID) >
  518.         7 "<br>
  519.         strQ = strQ & "ORDER BY COUNT(Orders.OrderID)"<br>
  520.         objRS.Open strQ</code><br>
  521.         %><br>
  522.         <HTML><br>
  523.         <BODY><br>
  524.         <p>Lista nazwy firm wszystkich klient≤w, kt≤rzy
  525.         maj▒ po <br>
  526.         ponad 7 zam≤wie± wraz z ich ilo╢ci▒ zam≤wie±. <br>
  527.         Lista jest posortowana rosn▒co wed│ug ilo╢ci zam≤wie±.</p><br>
  528.         <%<br>
  529. <code>        While Not objRS.EOF</code></td>
  530.     </tr>
  531.     <tr>
  532.         <td valign="top">31:<br>
  533.         32:<br>
  534.         33:</td>
  535.         <td valign="top"> </td>
  536.         <td> </td>
  537.         <td><code>Response.Write objRS("CompanyName")
  538.         & ": "<br>
  539.         Response.Write objRS("NumOrders") & "
  540.         zam≤wie±<BR>"<br>
  541.         objRS.MoveNext</code></td>
  542.     </tr>
  543.     <tr>
  544.         <td valign="top">34:<br>
  545.         35:<br>
  546.         36:<br>
  547.         37:<br>
  548.         38:<br>
  549.         39:<br>
  550.         40:<br>
  551.         41:</td>
  552.         <td valign="top"> </td>
  553.         <td colspan="2"><code>Wend<br>
  554.         objRS.Close<br>
  555.         objConn.Close<br>
  556.         Set objRS = Notning<br>
  557.         Set objConn = Nothing</code><br>
  558.         %><br>
  559.         </BODY><br>
  560.         </HTML></td>
  561.     </tr>
  562. </TBODY></table>
  563.  
  564. <p align="justify">Aby przyk│ad m≤g│ poprawnie dzia│aµ nale┐y mieµ
  565. ustawione (skonfigurowane) ╝r≤d│o danych <code>ODBC</code> o nazwie <b><i>Northwind</i></b>
  566. do bazy <code>Northwind</code>, kt≤re w tej czΩ╢ci nie bΩdzie omawione.
  567. PrzejdΩ od razu do om≤wienia przyk│adu. Linie 1-11 by│y
  568. omawiane w poprzednich rozdzia│ach, wiΩc my╢lΩ, ┐e nie
  569. trzeba do tego wracaµ. Ma│a r≤┐nica jest mo┐e w przypadku │a±cucha
  570. po│▒czenia, gdzie:</p>
  571.  
  572. <p align="justify">- <code>Data Source</code> jest r≤wnowa┐ne zapisowi <code>DNS</code> z poprzedniego
  573. przyk│adu;<br>
  574. - <code>User ID</code> jest r≤wnowa┐ne zapisowi <code>UID</code> z poprzedniego przyk│adu;<br>
  575. - <code>Password</code> jest r≤wnowa┐ne zapisowi <code>PWD</code> z poprzedniego przyk│adu.</p>
  576.  
  577. <p align="justify">Nowo╢ci▒ jest linia 13, w kt≤rej jest tworzony obiekt <code>Recordset</code>
  578. nazwany <code>objRS</code> przy pomocy metody <code>Server.CreateObject</code> z parametrem
  579. <code>ADODB.Recordset</code>. Kiedy zosta│ stworzony obiekt <code>Connection</code> (<code>objConn</code>)
  580. oraz <code>Recordset</code> (<code>objRS</code>) nale┐a│oby umo┐liwiµ obiektowi <code>Recordset</code>
  581. wykorzystaµ po│▒czenie zdefiniowane w obiekcie <code>Connection</code>.
  582. Linia 14 wykonuje to zadanie, przez co obiekt <code>Connection</code> zosta│
  583. przypisany do w│a╢ciwo╢ci <code>ActiveConnection</code> obiektu <code>Recordset</code> (<code>objRS</code>).
  584. Teraz wszystkie operacje tj. odczyt rekord≤w, poprawianie,
  585. wstawianie oraz kasowanie, wykonywane przy u┐yciu <code>objRS</code> bΩd▒
  586. korzysta│y z po│▒czenia okre╢lonego przez <code>objConn</code>. Linie 15-21
  587. przypisuj▒ zmiennej <code>strQ</code> │a±cuch odpowiadaj▒cy zapytaniu SQL.
  588. Zapytanie SQL powoduje wybranie z bazy rekord≤w z pola <code>CompanyName</code>
  589. z tabeli <code>Customers</code> oraz liczbΩ <code>OrderID</code> (nazwan▒ <code>NumOrders</code>) z
  590. tabeli <code>Orders</code>. Pola <code>OrderID</code> s▒ przypisane do ka┐dej firmy
  591. poprzez u┐ycie sk│adni <code>INNER JOIN</code> na tabelach <code>Customers</code> i <code>Orders</code>.
  592. Stworzone po│▒czenie m≤wi, ┐e pola <code>CustomerID</code> w obu tabelach
  593. (<code>Customers</code>, <code>Orders</code>) s▒ ze sob▒ powi▒zane. Sk│adnia wygl▒da
  594. nastΩpuj▒co:</p>
  595.  
  596. <table border="0" cellspacing="0">
  597. <TBODY>    <tr>
  598.         <td colspan="3">SELECT Customers.CompanyName,
  599.         Orders.OrderID AS NumOrders<br>
  600.         FROM Customers INNER JOIN Orders ON</td>
  601.     </tr>
  602.     <tr>
  603.         <td> </td>
  604.         <td> </td>
  605.         <td>Customers.CustomerID = Orders.CustomerID</td>
  606.     </tr>
  607. </TBODY></table>
  608.  
  609. <p align="justify">Powy┐sze zapytanie zwraca wszystkie wiersze bazy danych z po│▒czonych
  610. tabel <code>Customers</code> i <code>Orders</code>. W przyk│adzie zliczane s▒ pola <code>OrderID</code>
  611. dla ka┐dego klienta. Aby zastosowaµ to do powy┐szego zapytania
  612. trzeba u┐yµ funkcji sumuj▒cej <code>Count(</code>pole<code>)</code>. Funkcja zlicza ilo╢µ
  613. wszystkich <code>OrderID</code>, kt≤re s▒ przydzielone do jednego klienta (firmy).
  614. Nale┐y tak┐e pogrupowaµ rekordy, kt≤rych pola <code>Customers.CompanyName</code>
  615. s▒ takie same (ten sam klient). Teraz dopiero funkcja <code>COUNT(Orders.OrderID)</code>
  616. zwr≤ci liczbΩ <code>OrderID</code> przyporz▒dkowan▒ jednemu klientowi (firmie).
  617. W celu uwzglΩdnienia rekord≤w, kt≤rych ilo╢µ zam≤wie± bΩdzie
  618. wiΩksza ni┐ <code>7</code>, tzn. warto╢µ <code>COUNT(Orders.OrderID)</code> bΩdzie wiΩksza
  619. od <code>7</code>, nale┐y u┐yµ cz│onu <code>HAVING</code>. Cz│on <code>HAVING</code> jest u┐yty
  620. dla okre╢lenia warunku dla sk│adni <code>GROUP BY</code>. Nie mo┐na u┐yµ
  621. cz│onu <code>WHERE</code>, gdy┐ nie obj▒│by on cz│onu <code>GROUP BY</code>. Cz│on <code>ORDER
  622. BY</code> sortuje rekordy wynikowe, w naszym przypadku sortowanie jest
  623. rosn▒ce (domy╢lne) wed│ug ilo╢ci wyst▒pie± p≤l <code>Orders.OrderID</code>.</p>
  624.  
  625. <p align="justify">W linii 22 u┐yta zosta│a metoda <code>Open</code> obiektu <code>Recordset</code> w po│▒czeniu
  626. z zapytaniem SQL, kt≤re znajduje siΩ w zmiennej <code>strQ</code>. Powoduje
  627. ona wykonanie siΩ zapytania SQL na bazie danych. W liniach 24-28
  628. znajduje siΩ czΩ╢µ zwyk│ego HTML, kt≤r▒ nie trzeba chyba
  629. omawiaµ. W liniach 30-34 znajduje siΩ pΩtla <code>While</code>, kt≤ra
  630. podobnie jak w przyk│adzie z poprzedniego podrozdzia│u (<a
  631. href="#podrozdz62" class="LINK">podrozdza│ 6.2</a>) powoduje wys│anie
  632. rezultatu wykonania zapytania SQL do przegl▒darki. Po wys│aniu
  633. wszystkich rekord≤w (zako±czeniu wykonywania pΩtli <code>While</code>) nastΩpuje
  634. zamkniΩcie <code>objRS</code> i <code>objConn</code> oraz zostaj▒ zwolnione ich zasoby na
  635. serwerze.</p>
  636.  
  637. <p align="justify"><code>Pobieranie wielu zbior≤w danych</code></p>
  638.  
  639. <p align="justify">Czasami zapytanie SQL zwraca wiΩcej ni┐ jeden zbi≤r rekord≤w
  640. i sk│ada siΩ z dw≤ch innych zapyta±, np.:</p>
  641.  
  642. <table border="0">
  643. <TBODY>    <tr>
  644.         <td>SELECT MAX(UnitPrice) FROM Products<br>
  645.         SELECT COUNT(*) FROM Orders</td>
  646.     </tr>
  647. </TBODY></table>
  648.  
  649. <p align="justify">MS Access nie obs│uguje takich z│o┐onych zapyta± SQL, wiΩc
  650. poni┐szy przyk│ad bΩdzie dotyczy│ tylko MS SQL Server.</p>
  651.  
  652. <table border="0">
  653. <TBODY>    <tr>
  654.         <td valign="top">1:<br>
  655.         2:<br>
  656.         3:<br>
  657.         4:<br>
  658.         5:<br>
  659.         6:<br>
  660.         7:<br>
  661.         8:<br>
  662.         9:<br>
  663.         10:<br>
  664.         11:<br>
  665.         12:<br>
  666.         13:<br>
  667.         14:<br>
  668.         15:</td>
  669.         <td valign="top"> </td>
  670.         <td colspan="3"><% <code>@LANGUAGE = VBScript</code> %><br>
  671.         <%<br>
  672. <code>        Option Explicit<br>
  673.         Response.Expires = 0<br>
  674.         Dim objConn, objRS, strQ<br>
  675.         Dim strConnection<br>
  676.         <br>
  677.         Set objConn = Server.CreateObject("ADODB.Connection")<br>
  678.         strConnection = "Data Source=Northwind;"<br>
  679.         strConnection = strConnection & "User ID=sa;Password=;"<br>
  680.         objConn.Open strConnection<br>
  681.         <br>
  682.         Set objRS = Server.CreateObject("ADODB.Recordset")</code><br>
  683. <code>        Set objRS.ActiveConnection = objConn<br>
  684.         If objConn.Properties("DBMS Name") <>
  685.         "Microsoft SQL Server" Then</code></td>
  686.     </tr>
  687.     <tr>
  688.         <td valign="top">16:<br>
  689.         17:<br>
  690.         18:</td>
  691.         <td valign="top"> </td>
  692.         <td> </td>
  693.         <td colspan="2"><code>Response.Write "<p>Ten
  694.         skrypt mo┐e byµ u┐yty tylko "<br>
  695.         Response.Write "do korzystania z bazy MS SQL Server.</p>"<br>
  696.         Response.End</code></td>
  697.     </tr>
  698.     <tr>
  699.         <td valign="top">19:<br>
  700.         20:<br>
  701.         21:<br>
  702.         22:<br>
  703.         23:<br>
  704.         24:<br>
  705.         25:<br>
  706.         26:<br>
  707.         27:<br>
  708.         28:<br>
  709.         29:<br>
  710.         30:<br>
  711.         31:<br>
  712.         32:</td>
  713.         <td valign="top"> </td>
  714.         <td colspan="3"><code>End If<br>
  715.         <br>
  716.         strQ = "SELECT MAX(UnitPrice) AS "<br>
  717.         strQ = strQ & "'Cena maksymalna' FROM Products;"<br>
  718.         strQ = strQ & "SELECT COUNT(*) AS 'Liczba
  719.         zamowien' "<br>
  720.         strQ = strQ & "FROM Orders"<br>
  721.         objRS.Open strQ</code><br>
  722.         %><br>
  723.         <HTML><br>
  724.         <BODY><br>
  725.         <p>Tutaj jest maksymalna cena produktu oraz <br>
  726.         liczba zam≤wie± znajduj▒cych siΩ w bazie Northwind.</p><br>
  727.         <%<br>
  728. <code>        Do Until objRS Is Nothing</code></td>
  729.     </tr>
  730.     <tr>
  731.         <td valign="top">33:</td>
  732.         <td valign="top"> </td>
  733.         <td> </td>
  734.         <td colspan="2"><code>Do While Not objRS.EOF</code></td>
  735.     </tr>
  736.     <tr>
  737.         <td valign="top">34:<br>
  738.         35:</td>
  739.         <td valign="top"> </td>
  740.         <td> </td>
  741.         <td> </td>
  742.         <td><code>Response.Write objRS(0).Name &
  743.         ": " & objRS(0) & "<BR>"<br>
  744.         objRS.MoveNext</code></td>
  745.     </tr>
  746.     <tr>
  747.         <td valign="top">36:<br>
  748.         37:</td>
  749.         <td valign="top"> </td>
  750.         <td> </td>
  751.         <td colspan="2"><code>Loop<br>
  752.         Set objRS = objRS.NextRecordset</code></td>
  753.     </tr>
  754.     <tr>
  755.         <td valign="top">38:<br>
  756.         39:<br>
  757.         40:<br>
  758.         41:<br>
  759.         42:<br>
  760.         43:</td>
  761.         <td valign="top"> </td>
  762.         <td colspan="3"><code>Loop<br>
  763.         objConn.close<br>
  764.         Set objConn = Nothing</code><br>
  765.         %><br>
  766.         </BODY><br>
  767.         </HTML></td>
  768.     </tr>
  769. </TBODY></table>
  770.  
  771. <p align="justify">Linie 1-14 s▒ zrozumia│e, gdy┐ by│y wcze╢niej omawiane. W
  772. liniach 15-19 skrypt sprawdza czy po│▒czenie opisane w <code>objConn</code>
  773. jest po│▒czeniem bo bazy SQL Server poprzez sprawdzenie czy w│a╢ciwo╢µ
  774. <code>DBMS Name</code> po│▒czenia jest r≤wna "Microsoft SQL Server".
  775. Je┐eli baza danych jest inna ni┐ SQL Server to zostaje wy╢wietlony
  776. komunikat umieszczony w liniach 16-17 i skrypt ko±czy swoje dzia│anie
  777. na linii 18. W liniach 21-24 nastΩpuje przypisanie zmiennej <code>strQ</code>
  778. │a±cucha bΩd▒cego zapytaniem SQL. W linii 25 nastΩpuje
  779. wykonanie zapytania na bazie danych. Linie 27-30 zawieraj▒
  780. znaczniki HTML i tekst wys│any do przegl▒darki. Linie 32-38
  781. zawieraj▒ dwie zagnie┐d┐one pΩtle <code>Do</code>. ZewnΩtrzna pΩtla jest
  782. wykonywana do chwili a┐ zbi≤r rekord≤w w <code>objRS</code> bΩdzie warto╢ci▒
  783. <code>Nothing</code>, co bΩdzie wskazywa│o, ┐e nie ma wiΩcej zbior≤w
  784. rekord≤w okre╢lonych przez <code>objRS</code>. W pΩtli wewnΩtrznej (linie
  785. 33-36) pobierane s▒ krok po kroku wszystkie wiersze bie┐▒cego
  786. zbioru rekord≤w oraz wysy│ana jest nazwa i warto╢µ pierwszego
  787. pola, kt≤rego indeks jest r≤wny <code>zero</code>, do przegl▒darki u┐ytkownika
  788. (klienta). Kiedy wewnΩtrzna pΩtla dojdzie do ko±ca bie┐▒cego
  789. zbioru rekord≤w, jest zako±czana i nastΩpuje przej╢cie (linia
  790. 37) do nastΩpnego zbioru rekord≤w. Kiedy bie┐▒cy zbi≤r
  791. rekord≤w bΩdzie ostatnim zbiorem, metoda <code>NextRecordset</code> ustali
  792. warto╢µ <code>objRS</code> na warto╢µ <code>Nothing</code>, co pozwoli zewnΩtrznej pΩtli
  793. <code>Do</code> zako±czyµ jej wykonywanie. W liniach 39-40 nastΩpuje zamkniΩcie
  794. <code>objConn</code> i zwolnienie jej zasob≤w.</p>
  795.  
  796. <h3>6.4 Umieszczanie danych w tabeli.</h3>
  797.  
  798. <p align="justify">Dynamiczne strony WWW pobieraj▒ dane z bazy danych i
  799. przekazuj▒ je u┐ytkownikowi oraz umo┐liwiaj▒ pobranie
  800. informacji od u┐ytkownika i umieszenie ich w bazie danych.
  801. Umieszczenie informacji w bazie danych mo┐na zrealizowaµ na
  802. wiele sposob≤w, oto dwa spo╢r≤d nich:</p>
  803.  
  804. <table border="0" cellspacing="0">
  805. <TBODY>    <tr>
  806.         <td valign="top" class="LEFT">-</td>
  807.         <td valign="top" class="LEFT">wykonanie zapytania SQL
  808.         zawieraj▒cego komendΩ <code>INSERT</code>,</td>
  809.     </tr>
  810.     <tr>
  811.         <td valign="top" class="LEFT">-</td>
  812.         <td valign="top" class="LEFT">otwarcie objektu <code>Recordset</code>,
  813.         do│▒czenie rekordu za pomoc▒ metody <code>AddNew</code> i uzupe│nienie
  814.         p≤l rekordu i zapisanie rekord≤w do bazy danych poprzez
  815.         u┐ycie metody <code>Update</code>.</td>
  816.     </tr>
  817. </TBODY></table>
  818.  
  819. <p align="justify"><code>U┐ycie komendy INSERT w zapytaniu SQL</code></p>
  820.  
  821. <p align="justify">Poni┐ej zostanie przedstawiony skrypt zapisuj▒cy rekord do
  822. tabeli <code>Shippers</code> bazy Northwind, u┐ywaj▒c zapytania SQL z komend▒
  823. <code>INSERT</code>. NastΩpnie zostan▒ pobrane wszystkie rekordy z tabeli <code>Shippers</code>
  824. i wy╢wietlone w oknie przegl▒darki. Za ka┐dym razem, kiedy
  825. skrypt bΩdzie uruchomiony, do tabeli <code>Shippers</code> zostanie dopisany
  826. nowy rekord z warto╢ciami <code>Kiosk przy Rotundzie</code> w polu <code>CompanyName</code>
  827. i <code>(075) 75 112 233</code> w polu <code>Phone</code>.</p>
  828.  
  829. <table border="0">
  830. <TBODY>    <tr>
  831.         <td valign="top">1:<br>
  832.         2:<br>
  833.         3:<br>
  834.         4:<br>
  835.         5:<br>
  836.         6:<br>
  837.         7:<br>
  838.         8:<br>
  839.         9:<br>
  840.         10:<br>
  841.         11:<br>
  842.         12:<br>
  843.         13:<br>
  844.         14:<br>
  845.         15:<br>
  846.         16:<br>
  847.         17:<br>
  848.         18:<br>
  849.         19:<br>
  850.         20:</td>
  851.         <td colspan="2"><% <code>@LANGUAGE = VBScript</code> %><br>
  852.         <%<br>
  853. <code>        Option Explicit<br>
  854.         Response.Expires = 0<br>
  855.         Dim objConn, objRS, strQ, strConn, strOutout<br>
  856.         <br>
  857.         set objConn = Server.CreateObject("ADODB.Connection")<br>
  858.         strConn = "Data Source=Northwind;User ID=sa;Password=;"<br>
  859.         objConn.Open strConn<br>
  860.         <br>
  861.         strQ = "INSERT INTO Shippers (CompanyName, Phone)
  862.         VALUES "<br>
  863.         strQ = strQ & "('Kiosk przy Rotundzie', '(075)
  864.         75 112 233')"<br>
  865.         objConn.Execute strQ<br>
  866.         <br>
  867.         Set objRS = objConn.Execute("SELECT * FROM Shippers")<br>
  868.         %><br>
  869.         <HTML><BODY><br>
  870.         <p>Wszyscy spedytorzy:</p><br>
  871.         <%<br>
  872.         While Not objRS.EOF</code></td>
  873.     </tr>
  874.     <tr>
  875.         <td valign="top">21:<br>
  876.         22:<br>
  877.         23:</td>
  878.         <td> </td>
  879.         <td><code>strOutput = objRS("CompanyName")
  880.         & " " & objRS("Phone")<br>
  881.         Response.Write Server.HTMLEncode(strOutput) & "<BR>"<br>
  882.         objRS.MoveNext</code></td>
  883.     </tr>
  884.     <tr>
  885.         <td valign="top">24:<br>
  886.         25:<br>
  887.         26:<br>
  888.         27:<br>
  889.         28:<br>
  890.         29:</td>
  891.         <td colspan="2"><code>Wend<br>
  892.         <br>
  893.         objRS.Close : objConn.Close<br>
  894.         Set objRS = Nothing : Set objConn = Nothing</code><br>
  895.         %><br>
  896.         </BODY></HTML></td>
  897.     </tr>
  898. </TBODY></table>
  899.  
  900. <p align="justify">Linie 1-9 s▒ zrozumia│e, wiΩc nie bΩd▒ omawiane. W
  901. liniach 11-12 nastΩpuje przypisanie do zmiennej <code>strQ</code> │a±cucha
  902. bΩd▒cego zapytaniem SQL. Zapytanie ma postaµ:</p>
  903.  
  904. <table border="0">
  905. <TBODY>    <tr>
  906.         <td>INSERT INTO Shippers (CompanyName, Phone)
  907.         <br>
  908.         VALUES ('Kiosk przy Rotundzie', '(075) 75 112 233')</td>
  909.     </tr>
  910. </TBODY></table>
  911.  
  912. <p align="justify">Komenda dodaje nowy rekord do tabeli <code>Shippers</code> i umieszcza
  913. warto╢ci z listy <code>Values</code>, tj. "<code>Kiost przy Rotundzie</code>" i
  914. "<code>(075) 75 112 233</code>", w polach <code>CompanyName</code> i <code>Phone</code>.</p>
  915.  
  916. <p align="justify">W linii 13 nastΩpuje wykonanie zapytania SQL na bazie danych.
  917. W liniach 15 i 20-24 pobierane s▒ wszystkie rekordy z tabeli <code>Shippers</code>
  918. (tak jak jest to opisane w zapytaniu w linii 15) i wy╢wietlane w
  919. oknie przegl▒darki. Przed zapisaniem zawarto╢ci zmiennej <code>strOutput</code>,
  920. w kt≤rej znajduj▒ siΩ zawarto╢ci p≤l <code>CompanyName</code> i <code>Phone</code>,
  921. jest ona konwertowana na tekst zrozumia│y dla przegl▒darki (dokument
  922. HTML). Linia 26 zamyka obiekty <code>Recordset</code> (<code>objRS</code>) i <code>Connection</code> (<code>objConn</code>),
  923. a nastΩpnie w linii 27 zwalnia ich zasoby.<br>
  924. Skrypt zapisuj▒cy do bazy ca│y czas te same warto╢ci nie jest
  925. zbyt u┐ytecznym. Bardziej u┐ytecznym bΩdzie skrypt umieszczaj▒cy
  926. dane z wype│nionego i wys│anego przez u┐ytkownika formularza.</p>
  927.  
  928. <p align="justify"><code>U┐ycie metody AddNew</code></p>
  929.  
  930. <p align="justify">U┐ycie metody <code>AddNew</code> ma wiele zalet, np. nie trzeba ╢ledziµ
  931. wszystkich apostrof≤w, kt≤rych niepoprawna kolejno╢µ mo┐e
  932. wywo│aµ b│Ωdy w wykonywanym skrypcie. Wad▒ metody <code>AddNew</code>
  933. jest to, ┐e w por≤wnaniu ze sk│adni▒ <code>INSERT</code> zapytania SQL
  934. zajmuje ona wiΩcej kodu. Poza tym przed dodaniem danych do
  935. tabeli poprzez u┐ycie metody <code>AddNew</code> nale┐y najpierw stworzyµ
  936. obiekt <code>Recordset</code>. Poni┐szy przyk│ad pokazuje spos≤b u┐ycia
  937. metody <code>AddNew</code>.</p>
  938.  
  939. <table border="0">
  940. <TBODY>    <tr>
  941.         <td valign="top">1:<br>
  942.         2:<br>
  943.         3:<br>
  944.         4:<br>
  945.         5:<br>
  946.         6:<br>
  947.         7:<br>
  948.         8:<br>
  949.         9:<br>
  950.         10:<br>
  951.         11:<br>
  952.         12:<br>
  953.         13:<br>
  954.         14:<br>
  955.         15:<br>
  956.         16:</td>
  957.         <td colspan="4"><% <code>@LANGUAGE = VBScript</code> %><br>
  958.         <%<br>
  959. <code>        Option Explicit<br>
  960.         Response.Expires = 0</code><br>
  961.         %><br>
  962.         <!--#include file="adovbs.inc"--><br>
  963.         <%<br>
  964. <code>        Dim objConn, objRS, strConn, strOut<br>
  965.         Dim strCN, strPh, lngShipperID<br>
  966.         <br>
  967.         set objConn = Server.CreateObject("ADODB.Connection")<br>
  968.         strConn = "Data Source=Northwind;User ID=sa;Password=;"<br>
  969.         objConn.Open strConn<br>
  970.         set objRS = Server.CreateObject("ADODB.Recordset")<br>
  971.         <br>
  972.         If (Request.ServerVariables("CONTENT_LENGTH")
  973.         > 0) Then</code></td>
  974.     </tr>
  975.     <tr>
  976.         <td valign="top">17:<br>
  977.         18:<br>
  978.         19:</td>
  979.         <td> </td>
  980.         <td colspan="3"><code>strCN = Trim(Request.Form("Nazwa"))<br>
  981.         strCN = Left(strCN, 40)<br>
  982.         If Len(strCN) > 0 Then</code></td>
  983.     </tr>
  984.     <tr>
  985.         <td valign="top">20:<br>
  986.         21:<br>
  987.         22:<br>
  988.         23:<br>
  989.         24:<br>
  990.         25:<br>
  991.         26:<br>
  992.         27:<br>
  993.         28:<br>
  994.         29:<br>
  995.         30:</td>
  996.         <td> </td>
  997.         <td> </td>
  998.         <td colspan="2"><code>objRS.CursorLocation =
  999.         adUseServer<br>
  1000.         objRS.CursorType = adOpenKeyset<br>
  1001.         objRS.LockType = adLockOptimistic<br>
  1002.         objRS.Open "Shippers", objConn, , , adCmdTable<br>
  1003.         <br>
  1004.         objRS.AddNew<br>
  1005.         objRS("CompanyName") = strCN<br>
  1006.         <br>
  1007.         strPh = Trim(Request.Form("Telefon"))<br>
  1008.         strPh = Left(strPh, 24)<br>
  1009.         If Len(strPh) > 0 Then</code></td>
  1010.     </tr>
  1011.     <tr>
  1012.         <td valign="top">31:</td>
  1013.         <td> </td>
  1014.         <td> </td>
  1015.         <td> </td>
  1016.         <td><code>objRS("Phone") = strPh</code></td>
  1017.     </tr>
  1018.     <tr>
  1019.         <td valign="top">32:<br>
  1020.         33:<br>
  1021.         34:<br>
  1022.         35:<br>
  1023.         36:<br>
  1024.         37:<br>
  1025.         38:<br>
  1026.         39:</td>
  1027.         <td> </td>
  1028.         <td> </td>
  1029.         <td colspan="2"><code>End If<br>
  1030.         <br>
  1031.         objRS.Update<br>
  1032.         lngShipperID = objRS("ShipperID")<br>
  1033.         Responase.Write "<p>Tw≤j nowy rekord posiada
  1034.         ID "<br>
  1035.         Response.Write lngShipperID & ".</p>"<br>
  1036.         <br>
  1037.         objRS.Close</code></td>
  1038.     </tr>
  1039.     <tr>
  1040.         <td valign="top">40:</td>
  1041.         <td> </td>
  1042.         <td colspan="3"><code>Else</code></td>
  1043.     </tr>
  1044.     <tr>
  1045.         <td valign="top">41:</td>
  1046.         <td> </td>
  1047.         <td> </td>
  1048.         <td colspan="2"><code>Response.Write "<p>ProszΩ
  1049.         wype│niµ formularz!</p>"</code></td>
  1050.     </tr>
  1051.     <tr>
  1052.         <td valign="top">42:</td>
  1053.         <td> </td>
  1054.         <td colspan="3"><code>End If</code></td>
  1055.     </tr>
  1056.     <tr>
  1057.         <td valign="top">43:<br>
  1058.         44:<br>
  1059.         45:<br>
  1060.         46:<br>
  1061.         47:<br>
  1062.         48:<br>
  1063.         49:<br>
  1064.         50:<br>
  1065.         51:<br>
  1066.         52:<br>
  1067.         53:</td>
  1068.         <td colspan="4"><code>End If<br>
  1069.         <br>
  1070.         objRS.Cursor Location = adUseClient<br>
  1071.         objRS.CursorType = adOpenForwardOnly<br>
  1072.         objRS.LockType = adLockReadOnly<br>
  1073.         objRS.Open "Shippers", objConn, , , adCmdTable</code><br>
  1074.         %><br>
  1075.         <HTML><BODY><br>
  1076.         <TABLE><TR><TD>ID</TD><TD>Firma</TD><TD>Telefon</TD></TR><br>
  1077.         <%<br>
  1078. <code>        While Not objRS.EOF</code></td>
  1079.     </tr>
  1080.     <tr>
  1081.         <td valign="top">54:<br>
  1082.         55:<br>
  1083.         56:<br>
  1084.         57:</td>
  1085.         <td> </td>
  1086.         <td colspan="3"><code>strOut = "<TR><TD>"
  1087.         & objRS("ShipperID") & "</TD><TD>"<br>
  1088.         strOut = strOut & objRS("CompanyName")
  1089.         & "</TD><TD>" & objRS("Phone")<br>
  1090.         Response.Write strOut & "</TD></TR>"<br>
  1091.         objRS.MoveNext</code></td>
  1092.     </tr>
  1093.     <tr>
  1094.         <td valign="top">58:<br>
  1095.         59:<br>
  1096.         60:<br>
  1097.         61:<br>
  1098.         62:<br>
  1099.         63:<br>
  1100.         64:</td>
  1101.         <td colspan="4"><code>Wend<br>
  1102.         <br>
  1103.         objRS.Close : objConn.Close<br>
  1104.         Set objRS = Nothing : Set objConn = Nothing</code><br>
  1105.         %><br>
  1106.         </TABLE><br>
  1107.         <FORM ACTION="<%<code>= Request.ServerVariables("SCRIPT_NAME")</code>
  1108.         %>"</td>
  1109.     </tr>
  1110.     <tr>
  1111.         <td valign="top">65:</td>
  1112.         <td> </td>
  1113.         <td> </td>
  1114.         <td colspan="2">METHOD="POST"></td>
  1115.     </tr>
  1116.     <tr>
  1117.         <td valign="top">66:<br>
  1118.         67:<br>
  1119.         68:<br>
  1120.         69:<br>
  1121.         70:</td>
  1122.         <td colspan="4">Nazwa firmy: <INPUT TYPE="TEXT"
  1123.         NAME="Nazwa"><BR><br>
  1124.         Telefon: <INPUT TYPE="TEXT" NAME="Telefon"><BR><br>
  1125.         <INPUT TYPE="SUBMIT"><br>
  1126.         </FORM><br>
  1127.         </BODY></HTML></td>
  1128.     </tr>
  1129. </TBODY></table>
  1130.  
  1131. <p align="justify">Pierwsza czΩ╢µ, zawieraj▒ca linie 1-14, do│▒cza sta│e
  1132. ADO, deklaruje zmienne, tworzy po│▒czenie do bazy <code>Northwind</code>
  1133. poprzez ODBC, tworzy obiekt <code>Recordset</code>. W linii 6 znajduje siΩ
  1134. dyrektywa do│▒czaj▒ca plik <code>adovbs.inc</code> do skryptu. Plik <code>adovbs.inc</code>
  1135. powinien znajdowaµ siΩw katalogu <code>X:\Program Files\Common Files\System\ado\</code>,
  1136. gdzie X: jest napΩdem, na kt≤rym zainstalowany jest system. W
  1137. pliku znajduj▒ siΩ deklaracje wszystkich sta│ych ADO, z kt≤rych
  1138. niekt≤re zosta│y u┐yte w skrypcie. NastΩpna czΩ╢µ (linie
  1139. 16-43) sprawdza czy jakie╢ informacje zosta│y wys│ane do
  1140. skryptu (serwera). Je╢li tak zostaje wykonana czΩ╢µ zawarta w
  1141. liniach 17-42. Je╢li jakie╢ informacje zosta│y wys│ane, tzn.
  1142. u┐ytkownik wype│ni│ formularz (linie 64-69) i go wys│a│,
  1143. skrypt odczyta zawarto╢µ p≤l <code>Nazwa</code> i <code>Telefon</code> i zapisze te
  1144. warto╢ci do tabeli <code>Shippers</code> bazy danych. Pole <code>ShipperID</code> w tabeli
  1145. <code>Shippers</code> jest polem kt≤rego nie mo┐na edytowaµ, jest to pole
  1146. typu autonumerycznego. W nim znajduje siΩ unikalny numer rekordu
  1147. w tabeli <code>Shippers</code>. Zawarto╢µ tego pola mo┐e zostaµ odczytana
  1148. dziΩki przypisaniu <code>CursorLocation</code> warto╢ci <code>adUseServer</code>. W linii
  1149. 17 nastΩpuje przypisanie zawarto╢ci pola <code>Nazwa</code> wype│nionego
  1150. formularza, po uprzednim usuniΩciu wszystkich odstΩp≤w (klawiszy
  1151. spacji) poprzedzaj▒cych nazwΩ (funkcja <code>Trim()</code>). Funkcja <code>Left(</code>ciag,
  1152. limit<code>)</code> pozwala wyci▒µ z │a±cucha <code>ciag</code> tak▒ ilo╢µ znak≤w
  1153. jak▒ okre╢la <code>limit</code>. Linia 18 jest pewnego rodzaju ograniczeniem
  1154. na maksymaln▒ ilo╢µ wprowadzonych znak≤w do pola tabeli. W
  1155. linii 19 znajduje siΩ warunek sprawdzaj▒cy czy pole wype│nionego
  1156. formularza <code>Nazwa</code> nie zosta│o pozostawione puste. Je╢li w polu
  1157. by│y jakie╢ informacje zostaje wykonana czΩ╢µ znajduj▒ca siΩ
  1158. w liniach 20-39, w przeciwnym wypadku wykona siΩ linia 41,
  1159. nakazuj▒ca wype│niµ formularz. Instrukcja (linia 20):</p>
  1160.  
  1161. <table border="0">
  1162. <TBODY>    <tr>
  1163.         <td>objRS.CursorLocation = adUseServer</td>
  1164.     </tr>
  1165. </TBODY></table>
  1166.  
  1167. <p align="justify">nakazuje dokonywanie zmian w bazie danych. Kursor musi
  1168. znajdowaµ siΩ w bazie danych, gdy┐ jest potrzeba pobrania
  1169. warto╢ci z pola autonumerycznego <code>ShipperID</code>. W linii 21 typ
  1170. kursora zostaje okre╢lony warto╢ci▒ <code>adOpenKeyset</code>. To
  1171. przypisanie jest niezbΩdne poniewa┐ typ kursora <code>adOpenKetyset</code>
  1172. sprawia, ┐e bΩdzie mo┐na pobraµ warto╢µ z pola
  1173. autonumerycznego po dodaniu rekordu do bazy danych. Instrukcja</p>
  1174.  
  1175. <table border="0">
  1176. <TBODY>    <tr>
  1177.         <td>objRS.LockType = adLockOptimistic</td>
  1178.     </tr>
  1179. </TBODY></table>
  1180.  
  1181. <p align="justify">okre╢la spos≤b zapisu danych do bazy. Warto╢µ <code>adLockOptimistic</code>
  1182. wskazuje na zapis rekordu do bazy po wywo│aniu metody <code>Update</code>.
  1183. Takie rozwi▒zanie jest wskazane je╢li do bazy zapisywany jest
  1184. jednorazowo jeden rekord. Je╢li trzeba by│oby zapisaµ wiΩksz▒
  1185. ilo╢µ rekord≤w do bazy, co odbywa│oby siΩ poprzez u┐ycie
  1186. metody <code>UpdateBatch</code>, nale┐a│oby zamiast warto╢ci <code>adLockOptimistic</code>
  1187. u┐yµ warto╢ci <code>adLockBatchOptimistic</code>. Je╢li za╢ istnia│aby
  1188. potrzeba zapisu do bazy po ka┐dej zmianie zawarto╢ci rekordu
  1189. nale┐a│oby u┐yµ warto╢ci <code>adLockPessimistic</code>, za╢ je╢li nie
  1190. ma potrzeby zapisywania zawarto╢ci rekordu do bazy mo┐na u┐yµ
  1191. warto╢ci <code>adLockReadOnly</code>. W linii 24 nastΩpuje otwarcie rekordu:</p>
  1192.  
  1193. <table border="0">
  1194. <TBODY>    <tr>
  1195.         <td>objRS.Open "Shippers", objConn,
  1196.         , , adCmdTable</td>
  1197.     </tr>
  1198. </TBODY></table>
  1199.  
  1200. <p align="justify">Pierwszy parametr ("<code>Shippers</code>") okre╢la dane ╝r≤d│owe,
  1201. tabelΩ. Drugi parametr (<code>objConn</code>) okre╢la po│▒czenie do bazy
  1202. danych. Pi▒ty parametr (<code>adCmdTable</code>) wskazuje, ┐e ╝r≤d│em
  1203. danych bΩdzie tabela. Parametr trzeci i czwarty s▒ tutaj zbΩdne,
  1204. gdy┐ okre╢laj▒ one warto╢ci <code>CursorType</code> i <code>LockType</code>, kt≤re
  1205. zosta│y ju┐ okre╢lone w liniach 21-22. Nowy rekord zostaje
  1206. utworzony w momencie wywo│ania metody <code>AddNew</code> (linia 25). W
  1207. liniach 26 i 31 zawarto╢µ p≤l zostaje uzupe│niona. W linii 28
  1208. zostaj▒ usuniΩte wszystkie odstΩpy (klawisze spacji)
  1209. poprzedzaj▒ce numer telefonu (funkcja <code>Trim()</code>), je╢li takie wystΩpuj▒,
  1210. nastΩpnie numer jest ograniczany co do d│ugo╢ci, tj. 24 znaki.
  1211. Je╢li d│ugo╢µ ci▒gu w polu <code>Telefon</code> w formularzu jest wiΩksza
  1212. od zera nastΩpuje przypisanie zawarto╢ci pola do pola bazy
  1213. danych <code>Phone</code>. Linia 34 powoduje zapisanie wszystkich zmian
  1214. rekordu do bazy danych, przy u┐yciu metody <code>Update</code>. W wyniku tego
  1215. nastΩpuje wygenerowanie warto╢ci w polu autonumerycznym bazy <code>ShipperID</code>
  1216. i przypisanie do zmiennej <code>lngShipperID</code> (linia 35). Jest to mo┐liwe
  1217. ze wzglΩdu na to, ┐e kursor znajduje siΩ jeszcze na pozycji
  1218. dodanego przed chwil▒ rekordu. Linie 36-37 wysy│aj▒ do przegl▒darki
  1219. tekst powiadamiaj▒cy u┐ytkownika o jego numerze ID. W linii 39
  1220. nastΩpuje zamkniΩcie obiektu <code>Recordset</code>. NastΩpna czΩ╢µ
  1221. skryptu wy╢wietla zawarto╢µ tabeli <code>Shippers</code> (linie 45-61).
  1222. Instrukcja</p>
  1223.  
  1224. <table border="0">
  1225. <TBODY>    <tr>
  1226.         <td>objRS.CursorLocation = adUseClient</td>
  1227.     </tr>
  1228. </TBODY></table>
  1229.  
  1230. <p align="justify">powoduje, ┐e kursor jest znajduje siΩ po stronie klienta,
  1231. nie w bazie danych. Poniewa┐ kursor bΩdzie przemieszcza│ siΩ
  1232. tylko w jednym kierunku (odczytanie danych od pocz▒tku do ko±ca),
  1233. w│a╢ciwo╢ci <code>CursorType</code> zosta│a przypisana warto╢µ <code>adForwardOnly</code>.
  1234. W│a╢ciwo╢µ <code>LockType</code> posiada warto╢µ <code>adLockReadOnly</code>, poniewa┐
  1235. nie ma potrzeby dokonywania zmian w zawarto╢ci rekord≤w w bazie
  1236. danych. Linie 51-52 to zwyk│y HTML. W linii 52 tworzona jest
  1237. tabela. W liniach 54-56 nastΩpuje wypisanie zawarto╢ci rekordu
  1238. bie┐▒cego do nowoutworzonej rubryki tabeli w przegl▒darce. W
  1239. linii 57 nastΩpuje przej╢cie do nastΩpnego rekordu. W liniach
  1240. 60-61 nastΩpuje zamkniΩcie obiekt≤w <code>Recordset</code> i <code>Connection</code> i
  1241. zwolnienie ich zasob≤w. Linie 63 i 65-70 to zwyk│y HTML. W
  1242. linii 63 nastΩpuje zamkniΩcie tabeli. Linie 64-69 zawieraj▒
  1243. formularz, do kt≤rego u┐ytkownik mo┐e wprowadziµ dane w celu
  1244. wprowadzenia ich do bazy danych. W linii 64 warto╢µ atrybutu <code>ACTION</code>
  1245. formularza okre╢lona jest przez zmienn▒ <code>SCRIPT_NAME</code>, kt≤ra
  1246. zawiera adres WWW bie┐▒cego skryptu ASP.</p>
  1247.  
  1248. <p align="justify">Podsumowuj▒c, u┐ywaj▒c metody <code>AddNew</code> w celu dodania rekordu
  1249. do tabeli z ponad 1000 rekord≤w, nie trzeba otwieraµ ca│ej
  1250. tabeli, a to mog│oby do╢µ znacznie obci▒┐yµ zasoby serwera
  1251. WWW i bazy danych.</p>
  1252.  
  1253. <p align="justify"><code>Za│▒czanie du┐ych tekst≤w i binarnych p≤l danych</code></p>
  1254.  
  1255. <p align="justify">Je╢li w polu bazy danych znajduje siΩ obiekt du┐ego
  1256. rozmiaru (czΩsto oznaczany jako <code>BLOB</code>, binary large object). Aby
  1257. pobraµ dane z takiego pola w tabeli nale┐y u┐yµ metody <code>GetChunk</code>,
  1258. za╢ w celu dodania zawarto╢ci pola do tabeli nale┐y u┐yµ
  1259. metody <code>AppendChunk</code>. Odczytanie zwyk│ego pola z tabeli bazy
  1260. danych odbywa siΩ poprzez komendΩ:</p>
  1261.  
  1262. <table border="0">
  1263. <TBODY>    <tr>
  1264.         <td>zmienna = Recordset("NazwaPola")</td>
  1265.     </tr>
  1266. </TBODY></table>
  1267.  
  1268. <p align="justify">za╢ odczytanie zawarto╢ci pola BLOB sk│ada siΩ z dw≤ch czΩ╢ci:</p>
  1269.  
  1270. <table border="0">
  1271. <TBODY>    <tr>
  1272.         <td>rozmiar = Recordset("NazwaPola").ActualSize<br>
  1273.         wartosc = Recordset("NazwaPola").GetChunk(rozmiar)</td>
  1274.     </tr>
  1275. </TBODY></table>
  1276.  
  1277. <p align="justify">Jak widaµ metoda <code>GetChunk</code> potrzebuje parametru okre╢laj▒cego
  1278. rozmiar (w bajtach lub znakach) pola typu <code>BLOB</code>. Warto╢µ okre╢laj▒c▒
  1279. rozmiar zawarto╢ci pola zwraca w│a╢ciwo╢µ <code>ActualSize</code>.<br>
  1280. W celu zapisania danych do zwyk│ego pola w tabeli danych nale┐y
  1281. wpisaµ:</p>
  1282.  
  1283. <table border="0">
  1284. <TBODY>    <tr>
  1285.         <td>Recordset("NazwaPola") =
  1286.         wartosc</td>
  1287.     </tr>
  1288. </TBODY></table>
  1289.  
  1290. <p align="justify">za╢ do pola typu <code>BLOB</code> nale┐y wpisaµ:</p>
  1291.  
  1292. <table border="0">
  1293. <TBODY>    <tr>
  1294.         <td>Recordset("NazwaPola").AppendChunk
  1295.         wartosc</td>
  1296.     </tr>
  1297. </TBODY></table>
  1298.  
  1299. <p align="justify">Poni┐ej znajduje siΩ przyk│adowy fragment przedstawiaj▒cy
  1300. odczyt zawarto╢µ pola typu <code>BLOB</code>.</p>
  1301.  
  1302. <table border="0">
  1303. <TBODY>    <tr>
  1304.         <td colspan="2">wRozmiar = RozmiarCzesci<br>
  1305.         Rozmiar = Recordset("NazwaPola").ActualSize<br>
  1306.         Offset = 0<br>
  1307.         Do While Offset < Rozmiar</td>
  1308.     </tr>
  1309.     <tr>
  1310.         <td> </td>
  1311.         <td>Wartosc = Recordset("NazwaPola").Getchunk(wRozmiar)<br>
  1312.         warBLOB = warBLOB & Wartosc<br>
  1313.         Offset = Offset + wRozmiar</td>
  1314.     </tr>
  1315.     <tr>
  1316.         <td colspan="2">Loop</td>
  1317.     </tr>
  1318. </TBODY></table>
  1319.  
  1320. <p align="justify">Poni┐ej znajduje siΩ przyk│adowy fragment skryptu zapisuj▒cego
  1321. dane do pola typu <code>BLOB</code>.</p>
  1322.  
  1323. <table border="0">
  1324. <TBODY>    <tr>
  1325.         <td colspan="2">wRozmiar = RozmiarCzesci<br>
  1326.         Rozmiar = LenB(warBLOB)<br>
  1327.         Offset = 0<br>
  1328.         Do While Offset < Rozmiar</td>
  1329.     </tr>
  1330.     <tr>
  1331.         <td> </td>
  1332.         <td>Wartosc = LeftB(RightB(warBLOB, Rozmiar
  1333.         - Offset), wRozmiar)<br>
  1334.         Recordset("NazwaPola").AppendChunk Wartosc<br>
  1335.         Offset = Offset + wRozmiar</td>
  1336.     </tr>
  1337.     <tr>
  1338.         <td colspan="2">Loop</td>
  1339.     </tr>
  1340. </TBODY></table>
  1341.  
  1342. <p align="justify">Odczyt i zapis, dla przyk│adu 200KB pola w przypadku 1000 u┐ytkownik≤w,
  1343. zu┐yje 200MB zasob≤w serwera. Jak widaµ z tymi polami trzeba
  1344. dzia│aµ do╢µ ostro┐nie, tzn. nie nale┐y ich nadu┐ywaµ.</p>
  1345.  
  1346. <h3>6.5 Modyfikowanie tabel danych.</h3>
  1347.  
  1348. <p align="justify">W tej czΩ╢ci zostanie pokazane jak zmieniaµ zawarto╢µ p≤l
  1349. w istniej▒cych ju┐ rekordach oraz w jaki spos≤b usuwaµ
  1350. rekordy z bazy danych.</p>
  1351.  
  1352. <p align="justify">Uzupe│nienie p≤l istniej▒cych rekord≤w mo┐na realizowaµ
  1353. na dwa sposoby:</p>
  1354.  
  1355. <table border="0">
  1356. <TBODY>    <tr>
  1357.         <td valign="top">-</td>
  1358.         <td valign="top" class="LEFT">poprzez u┐ycie komendy
  1359.         UPDATE w zapytaniu SQL,</td>
  1360.     </tr>
  1361.     <tr>
  1362.         <td valign="top">-</td>
  1363.         <td valign="top" class="LEFT">poprzez uaktualnienie
  1364.         obiektu Recordset.</td>
  1365.     </tr>
  1366. </TBODY></table>
  1367.  
  1368. <p align="justify"><code>U┐ycie komendy UPDATE w zaytaniu SQL</code></p>
  1369.  
  1370. <p align="justify">Sk│adnia zapytania wygl▒da nastΩpuj▒co:</p>
  1371.  
  1372. <table border="0">
  1373. <TBODY>    <tr>
  1374.         <td>UPDATE NazwaTebeli SET NazwaKolumny1 =
  1375.         Wartosc1, NazwaKolumny2 = Wartosc2<br>
  1376.         WHERE Warunek</td>
  1377.     </tr>
  1378. </TBODY></table>
  1379.  
  1380. <p align="justify">W zapytaniu mo┐na u┐yµ wiele par <code><i>NazwaKolumny = Wartosc</code></i>.<br>
  1381. Zalet▒ tego rozwi▒zania jest mo┐liwo╢µ zmiany warto╢ci w
  1382. wielu kolumnach rekordu. Poza tym u┐ycie komendy <code>UPDATE</code> w
  1383. zapytaniu SQL w mniejszym stopniu zu┐ywa zasoby serwera WWW ni┐
  1384. u┐ycie metody <code>Update</code> na obiekcie <code>Recordset</code> poniewa┐ jest to
  1385. wykonane wy│▒cznie na serwerze bazy danych i nie potrzeba
  1386. tworzyµ i przechowywaµ ┐adnego obiektu. Komenda <code>UPDATE</code>
  1387. zapytania SQL jest wywo│ywana w skrypcie podobnie jak inne,
  1388. czyli poprzez zastosowanie metody <code>Execute</code> na obiekcie <code>Connection</code>
  1389. z parametrem w postaci zapytania SQL. Wygl▒da to nastΩpuj▒co:</p>
  1390.  
  1391. <table border="0">
  1392. <TBODY>    <tr>
  1393.         <td>Connection.Execute skladnia_UPDATE</td>
  1394.     </tr>
  1395. </TBODY></table>
  1396.  
  1397. <p align="justify">Je╢li jest potrzeba zmiany zawarto╢ci okre╢lonych p≤l
  1398. rekord≤w, mo┐na pos│u┐yµ siΩ cz│onem <code>WHERE</code>, np.:</p>
  1399.  
  1400. <table border="0">
  1401. <TBODY>    <tr>
  1402.         <td>UPDATE Towar SET Cena = 1700<br>
  1403.         WHERE Nazwa = 'Telewizor' AND Producent='SONY'</td>
  1404.     </tr>
  1405. </TBODY></table>
  1406.  
  1407. <p align="justify"><code>Uaktualnianie jednej kolumny obiektu Recordset</code></p>
  1408.  
  1409. <p align="justify">Druga metoda uaktualnienia zawarto╢ci bazy danych jest
  1410. realizowana poprzez otwarcie rekordu i dokonanie zmian w kolumnie
  1411. (polu). W celu dokonania uaktualnienia trzeba bΩdzie wywo│aµ
  1412. metodΩ <code>Update</code> lub <code>UpdateBatch</code>. Nale┐y pamiΩtaµ, ┐e je╢li u┐ywa
  1413. siΩ tych metod trzeba ustaliµ odpowiedni▒ warto╢µ w│a╢ciwo╢ci
  1414. <code>LockType</code> (<code>adLockOptimistic</code> lub <code>adLockBatchOptimistic</code>). Poni┐szy
  1415. przyk│ad przedstawia spos≤b uaktualnienia jednego pola w
  1416. rekordzie.</p>
  1417.  
  1418. <table border="0">
  1419. <TBODY>    <tr>
  1420.         <td valign="top">1:<br>
  1421.         2:<br>
  1422.         3:<br>
  1423.         4:<br>
  1424.         5:<br>
  1425.         6:<br>
  1426.         7:<br>
  1427.         8:<br>
  1428.         9:<br>
  1429.         10:<br>
  1430.         11:<br>
  1431.         12:<br>
  1432.         13:<br>
  1433.         14:<br>
  1434.         15:<br>
  1435.         16:<br>
  1436.         17:<br>
  1437.         18:<br>
  1438.         19:<br>
  1439.         20:<br>
  1440.         21:</td>
  1441.         <td valign="top"><% <code>@LANGUAGE = VBScript</code>
  1442.         %><br>
  1443.         <%<br>
  1444. <code>        Option Explicit<br>
  1445.         Response.Expires = 0</code><br>
  1446.         %><br>
  1447.         <!--#include file="adovbs.inc"--><br>
  1448.         <%<br>
  1449. <code>        Dim objConn, objRS, strOut<br>
  1450.         <br>
  1451.         set objConn = Server.CreateObject("ADODB.Connection")<br>
  1452.         objConn.Open "Data Source=Northwind;User ID=sa;Password=;"</code><br>
  1453.         %><br>
  1454.         <HTML><BODY><br>
  1455.         <p>Skrypt zmienia numer telefonu spedytora "United
  1456.         Package":</p><br>
  1457.         <%<br>
  1458. <code>        set objRS = Server.CreateObject("ADODB.Recordset")<br>
  1459.         objRS.CursorLocation = adUseServer<br>
  1460.         objRS.CursorType = adOpenForwardOnly<br>
  1461.         objRS.LockType = adLockOptimistic<br>
  1462.         <br>
  1463.         objRS.Open "SELECT * FROM Shippers WHERE CompanyName
  1464.         ='United Package'", objConn, , , adCmdTable</code></td>
  1465.     </tr>
  1466.     <tr>
  1467.         <td valign="top">22:<br>
  1468.         23:<br>
  1469.         24:<br>
  1470.         25:<br>
  1471.         26:<br>
  1472.         27:<br>
  1473.         28:<br>
  1474.         29:<br>
  1475.         30:<br>
  1476.         31:<br>
  1477.         32:<br>
  1478.         33:<br>
  1479.         34:<br>
  1480.         35:<br>
  1481.         36:<br>
  1482.         37:<br>
  1483.         38:<br>
  1484.         39:<br>
  1485.         40:<br>
  1486.         41:<br>
  1487.         42:</td>
  1488.         <td valign="top"><code>objRS("Phone") =
  1489.         "(503) 112-233"<br>
  1490.         Response.Write "<p>Numer telefonu zmieniony na
  1491.         " & objRS("Phone") & ".</p>"<br>
  1492.         objRS.Update<br>
  1493.         Response.Write "<p>Rekord uaktualniony.</p>"<br>
  1494.         objRS("Phone") = "(503) 332-211"<br>
  1495.         Response.Write "<p>Numer telefonu zmieniony na
  1496.         " & objRS("Phone") & ".</p>"<br>
  1497.         objRS.CancelUpdate<br>
  1498.         Response.Write "<p>Uaktualnionie przerwane.</p>"<br>
  1499.         Response.Write "<p>Numer telefonu teraz jest
  1500.         " & objRS("Phone") & ".</p>"<br>
  1501.         <br>
  1502.         objRS.Requery</code><br>
  1503.         %><br>
  1504.         <BR><p>Kolumna pobrana z bazy danych:</p><br>
  1505.         <%<br>
  1506. <code>        strOut = objRS("CompanyName") & "
  1507.         " & objRS("Phone")<br>
  1508.         Response.Write Server.HTMLEncode(strOut) & "<BR>"<br>
  1509.         <br>
  1510.         objRS.Close : objConn.Close<br>
  1511.         Set objRS = Nothing : Set objConn = Nothing</code><br>
  1512.         %><br>
  1513.         </BODY></HTML></td>
  1514.     </tr>
  1515. </TBODY></table>
  1516.  
  1517. <p align="justify">W celu uaktualnienia jednego pola nale┐y przed otwarciem
  1518. rekordu ustaliµ warto╢µ w│a╢ciwo╢ci <code>LockType</code> na <code>adLockOptimistic</code>,
  1519. a po zmianie zawarto╢ci pola (kolumny) wywo│aµ metodΩ <code>Update</code>.
  1520. Nowymi elementami w powy┐szym skrypcie s▒ linie 24, 28 i 32.
  1521. Pozosta│a czΩ╢µ skryptu by│a ju┐ wcze╢niej omawiana. Linia
  1522. 24, tj.:</p>
  1523.  
  1524. <table border="0">
  1525. <TBODY>    <tr>
  1526.         <td>objRS.Update</td>
  1527.     </tr>
  1528. </TBODY></table>
  1529.  
  1530. <p align="justify">uaktualnia pole rekordu w bazie danych mimo, ┐e w linii 22
  1531. zawarto╢µ pola <code>Phone</code> zosta│a ju┐ zmieniona. Jednak linia 22
  1532. zmienia zawarto╢µ pola rekordu tylko na serwerze WWW, a nie w
  1533. bazie danych. Zapisanie do bazy danych odbywa siΩ w│a╢nie
  1534. poprzez wywo│anie metody <code>Update</code> tego┐ rekordu. Linia 28</p>
  1535.  
  1536. <table border="0">
  1537. <TBODY>    <tr>
  1538.         <td>objRS.CancelUpdate</td>
  1539.     </tr>
  1540. </TBODY></table>
  1541.  
  1542. <p align="justify">sprawia, ┐e zawarto╢µ pola <code>Phone</code> zostaje niezmieniona, tzn.
  1543. ┐e przypisanie znajduj▒ce siΩ dwie linie wy┐ej jest
  1544. traktowane jak by go nie by│o. W linii 34, tj.:</p>
  1545.  
  1546. <table border="0">
  1547. <TBODY>    <tr>
  1548.         <td>objRS.Requery</td>
  1549.     </tr>
  1550. </TBODY></table>
  1551.  
  1552. <p align="justify">ca│a zawarto╢µ rekordu jest od╢wie┐ana i zawarto╢µ p≤l
  1553. pobierana jest z bazy danych. Metoda <code>Requery</code> jest r≤wnowa┐na
  1554. wywo│aniu kolejno metody <code>Close</code> i metody <code>Open</code>.</p>
  1555.  
  1556. <p align="justify"><code>Uaktualnianie grupy kolumn obiektu Recordset</code></p>
  1557.  
  1558. <p align="justify">Istnieje mo┐liwo╢µ przechowania wielu zmian jednego lub
  1559. wielu rekord≤w lokalnie przed przekazaniem ich do bazy danych.
  1560. Oto przyk│ad:</p>
  1561.  
  1562. <table border="0">
  1563. <TBODY>    <tr>
  1564.         <td valign="top">1:<br>
  1565.         2:<br>
  1566.         3:<br>
  1567.         4:<br>
  1568.         5:<br>
  1569.         6:<br>
  1570.         7:<br>
  1571.         8:<br>
  1572.         9:<br>
  1573.         10:<br>
  1574.         11:<br>
  1575.         12:<br>
  1576.         13:<br>
  1577.         14:<br>
  1578.         15:<br>
  1579.         16:<br>
  1580.         17:<br>
  1581.         18:<br>
  1582.         19:<br>
  1583.         20:<br>
  1584.         21:</td>
  1585.         <td valign="top" colspan="4"><% <code>@LANGUAGE
  1586.         = VBScript</code> %><br>
  1587.         <%<br>
  1588. <code>        Option Explicit<br>
  1589.         Response.Expires = 0</code><br>
  1590.         %><br>
  1591.         <!--#include file="adovbs.inc"--><br>
  1592.         <%<br>
  1593. <code>        Dim objConn, objRS, strOut<br>
  1594.         <br>
  1595.         set objConn = Server.CreateObject("ADODB.Connection")<br>
  1596.         objConn.Open "Data Source=Northwind;User ID=sa;Password=;"</code><br>
  1597.         %><br>
  1598.         <HTML><BODY><br>
  1599.         <p>Skrypt zmienia numer telefonu spedytor≤w "United
  1600.         Package" oraz "Speedy Express".</p><br>
  1601.         <%<br>
  1602. <code>        set objRS = Server.CreateObject("ADODB.Recordset")<br>
  1603.         objRS.CursorLocation = adUseServer<br>
  1604.         objRS.CursorType = adOpenKeyset<br>
  1605.         objRS.LockType = adLockBatchOptimistic<br>
  1606.         <br>
  1607.         objRS.Open "SELECT * FROM Shippers WHERE Phone LIKE
  1608.         '(503)%'", objConn, , , adCmdTable</code></td>
  1609.     </tr>
  1610.     <tr>
  1611.         <td valign="top">22:<br>
  1612.         23:</td>
  1613.         <td valign="top" colspan="4"><code>Response.Write
  1614.         "<p>Kolumny zwr≤cone przez sk│adniΩ SELECT:
  1615.         " & objRS.RecordCount & "</p>"<br>
  1616.         While Not(objRS.EOF)</code></td>
  1617.     </tr>
  1618.     <tr>
  1619.         <td valign="top">24:</td>
  1620.         <td valign="top"> </td>
  1621.         <td valign="top" colspan="3"><code>Select Case
  1622.         objRS("CompanyName")</code></td>
  1623.     </tr>
  1624.     <tr>
  1625.         <td valign="top">25:</td>
  1626.         <td valign="top"> </td>
  1627.         <td valign="top"> </td>
  1628.         <td valign="top" colspan="2"><code>Case "United
  1629.         Package"</code></td>
  1630.     </tr>
  1631.     <tr>
  1632.         <td valign="top">26:</td>
  1633.         <td valign="top"> </td>
  1634.         <td valign="top"> </td>
  1635.         <td valign="top"> </td>
  1636.         <td valign="top"><code>objRS("Phone") =
  1637.         "(503) 123-456"</code></td>
  1638.     </tr>
  1639.     <tr>
  1640.         <td valign="top">27:</td>
  1641.         <td valign="top"> </td>
  1642.         <td valign="top"> </td>
  1643.         <td valign="top" colspan="2"><code>Case "Speedy
  1644.         Express"</code></td>
  1645.     </tr>
  1646.     <tr>
  1647.         <td valign="top">28:</td>
  1648.         <td valign="top"> </td>
  1649.         <td valign="top"> </td>
  1650.         <td valign="top"> </td>
  1651.         <td valign="top"><code>objRS("Phone") =
  1652.         "(503) 987-654"</code></td>
  1653.     </tr>
  1654.     <tr>
  1655.         <td valign="top">29:<br>
  1656.         30:</td>
  1657.         <td valign="top"> </td>
  1658.         <td valign="top" colspan="3"><code>End Select<br>
  1659.         objRS.MoveNext</code></td>
  1660.     </tr>
  1661.     <tr>
  1662.         <td valign="top">31:<br>
  1663.         32:<br>
  1664.         33:<br>
  1665.         34:<br>
  1666.         35:<br>
  1667.         36:<br>
  1668.         37:<br>
  1669.         38:</td>
  1670.         <td valign="top" colspan="4"><code>Wend<br>
  1671.         objRS.UpdateBatch<br>
  1672.         <br>
  1673.         objRS.Requery</code><br>
  1674.         %><br>
  1675.         <BR><p>Wszystkie kolumny pobrane z tabeli
  1676.         Shippers:</p><br>
  1677.         <%<br>
  1678. <code>        While Not(objRS.EOF)</code></td>
  1679.     </tr>
  1680.     <tr>
  1681.         <td valign="top">39:<br>
  1682.         40:<br>
  1683.         41:</td>
  1684.         <td valign="top" colspan="2"> </td>
  1685.         <td valign="top" colspan="2"><code>strOut = objRS("CompanyName")
  1686.         & " " & objRS("Phone")<br>
  1687.         Response.Write Server.HTMLEncode(strOut) & "<BR>"<br>
  1688.         objRS.MoveNext</code></td>
  1689.     </tr>
  1690.     <tr>
  1691.         <td valign="top">42:<br>
  1692.         43:<br>
  1693.         44:<br>
  1694.         45:<br>
  1695.         46:<br>
  1696.         47:</td>
  1697.         <td valign="top" colspan="4"><code>Wend<br>
  1698.         <br>
  1699.         objRS.Close : objConn.Close<br>
  1700.         Set objRS = Nothing : Set objConn = Nothing</code><br>
  1701.         %><br>
  1702.         </BODY></HTML></td>
  1703.     </tr>
  1704. </TBODY></table>
  1705.  
  1706. <p align="justify">W skrypcie przypisano w│a╢ciwo╢ci <code>CursorLocation</code> warto╢µ
  1707. sta│ej <code>adUseServer</code> oraz w│a╢ciwo╢ci <code>LockType</code> warto╢µ <code>adOpenKeyset</code>.
  1708. Je╢li <code>LockType</code> przypisanoby warto╢µ tak▒, jak w poprzednim
  1709. przyk│adzie, tj. <code>adOpenForwardOnly</code>, podczas wykonywania skryptu
  1710. mog│yby wyst▒piµ b│Ωdy. Nale┐y pamiΩtaµ, ┐e w przypadku
  1711. u┐ycia metody <code>UpdateBatch</code> kursor przemie╢ci siΩ do ty│u (na
  1712. sam pocz▒tek) po uaktualnieniu pierwszej ca│ej kolumny z grupy.
  1713. W wyniku wykonania siΩ zapytania SQL, znajduj▒cego siΩ w linii
  1714. 21, zostan▒ zwr≤cone wszystkie rekordy, kt≤rych warto╢µ w
  1715. polu <code>Phone</code> bΩdzie zaczyna│a siΩ od "<code>(503)</code>". W linii
  1716. 22 zostanie wy╢wietlona ilo╢µ zwr≤conych kolumn, kt≤r▒ mo┐na
  1717. odczytaµ z w│a╢ciwo╢ci <code>RecordCount</code> obiektu <code>Recordset</code>. W│a╢ciwo╢µ
  1718. <code>RecordCount</code> mo┐na wykorzystaµ tylko w przypadku, gdy w│a╢ciwo╢µ
  1719. <code>CursorType</code> bΩdzie posiada│a warto╢µ <code>adOpenKeyset</code> lub <code>adOpenStatic</code>,
  1720. poniewa┐ w pozosta│ych przypadkach w│a╢ciwo╢µ <code>RecordCount</code>
  1721. zwr≤ci b│Ωdn▒ warto╢µ. U┐ycie w│a╢ciwo╢ci <code>RecordCount</code>
  1722. razem z przypisaniem <code>CursorLocation</code> warto╢ci <code>adUseServer</code> mo┐e
  1723. spowodowaµ zmniejszenie osi▒g≤w co do szybko╢ci wykonania
  1724. skryptu. Kiedy u┐yjemy jej z warto╢ci▒ <code>adUseClient</code> przypisan▒
  1725. do <code>CursorLocation</code>, wtedy u┐ycie <code>RecordCount</code> nie bΩdzie mia│o
  1726. wp│ywu na szybko╢µ, gdy┐ wszystkie informacje s▒
  1727. przechowywane na serwerze WWW i nie trzeba bΩdzie odwo│ywaµ siΩ
  1728. do bazy danych.<br>
  1729. PΩtla <code>While</code> (23-31) przemieszcza siΩ po wszystkich kolumnach
  1730. rekord≤w i zmienia warto╢ci p≤l <code>Phone</code> (numery telefonu) w zale┐no╢ci
  1731. od zawarto╢ci pola <code>CompanyName</code>. Wszystkie zmiany s▒
  1732. przechowywane na serwerze WWW i nie s▒ wprowadzane do bazy. PΩtlΩ
  1733. mo┐na zast▒piµ zapisem:</p>
  1734.  
  1735. <table border="0">
  1736. <TBODY>    <tr>
  1737.         <td>objRS.Filter = "CompanyName = 'United
  1738.         Package'"<br>
  1739.         objRS("Phone") = "(503) 123-456"<br>
  1740.         objRS.Filter = "CompanyName = 'Speedy Express'"<br>
  1741.         objRS("Phone") = "(503) 987-654"<br>
  1742.         objRS.Filter = ""</td>
  1743.     </tr>
  1744. </TBODY></table>
  1745.  
  1746. <p align="justify">Opis powy┐szych komend bΩdzie omawiany za chwilΩ. Po zako±czeniu
  1747. dokonywania zmian (zako±czeniu wykonywania pΩtli <code>While</code>), zostaj▒
  1748. zapisane wszystkie zmiany do bazy danych po wywo│aniu metody <code>UpdateBatch</code>
  1749. (linia 32). Wynik aktualizacji danych jest wy╢wietlany na
  1750. ekranie przegl▒darki. Wykonuje to pΩtla <code>While</code> znajduj▒ce siΩ
  1751. w liniach 38-42.<br>
  1752. G│≤wna r≤┐nica pomiΩdzy u┐yciem metod <code>Update</code> i <code>UpdateBatch</code>
  1753. jest to, ┐e w przypadku metody <code>UpdateBatch</code> nale┐y ustaliµ
  1754. warto╢µ <code>CursorLock</code> na <code>adLockBatchOptimistic</code> i warto╢µ <code>adOpenKeyset</code>
  1755. zamiast <code>adOpenStatic</code> dla w│asno╢ci <code>CursorType</code>.</p>
  1756.  
  1757. <p align="justify">W│a╢ciwo╢µ <code>Filter</code> s│u┐y do selekcji (filtracji) rekord≤w
  1758. z bie┐▒cej grupy rekord≤w. Kiedy w│a╢ciwo╢µ <code>Filter</code> jest
  1759. ustawiona, kursor przemieszcza siΩ na pierwsz▒ pozycjΩ, spe│niaj▒c▒
  1760. warunek filtracji.<br>
  1761. Przyk│ad u┐ycia metody w przypadku je╢li jest potrzeba
  1762. filtracji rekord≤w kt≤rych pole <code>Telefon</code> bΩdzie zaczyna│o siΩ
  1763. od ci▒gu "<code>(503)</code>", a pole <code>Nazwa</code> rozpoczyna│o siΩ od
  1764. ci▒gu "<code>Sklep</code>", w│a╢ciwo╢µ <code>Filter</code> powinna przyj▒µ
  1765. nastΩpuj▒c▒ warto╢µ:</p>
  1766.  
  1767. <table border="0">
  1768. <TBODY>    <tr>
  1769.         <td>Recordset.Filter = "Telefon LIKE '(503)%'
  1770.         AND Nazwa LIKE 'Sklep%'"</td>
  1771.     </tr>
  1772. </TBODY></table>
  1773.  
  1774. <p align="justify">Wy│▒czenie filtracji wykonuje siΩ w nastΩpuj▒cy spos≤b:</p>
  1775.  
  1776. <table border="0">
  1777. <TBODY>    <tr>
  1778.         <td>Recordset.Filter = ""</td>
  1779.     </tr>
  1780. </TBODY></table>
  1781.  
  1782. <p align="justify">czyli w│a╢ciwo╢µ <code>Filter</code> przyjmuje warto╢µ │a±cucha o
  1783. zerowej d│ugo╢ci.</p>
  1784.  
  1785. <p align="justify"><code>Usuwanie danych z bazy</code></p>
  1786.  
  1787. <p align="justify">Wa┐n▒ operacj▒ na bazie danych jest tak┐e usuwanie rekord≤w
  1788. (danych). Podobnie jak w poprzednich przypadkach istniej▒ dwa
  1789. rozwi▒zania:</p>
  1790.  
  1791. <table border="0" cellspacing="0">
  1792. <TBODY>    <tr>
  1793.         <td valign="top">-</td>
  1794.         <td valign="top" colspan="2">poprzez u┐ycie
  1795.         komendy <code>DELETE</code> w zapytaniu SQL, zalety:</td>
  1796.     </tr>
  1797.     <tr>
  1798.         <td valign="top"> </td>
  1799.         <td valign="top">*</td>
  1800.         <td valign="top">│atwy spos≤b usuwania
  1801.         danych spe│niaj▒cych okre╢lone kryteria w bazie danych</td>
  1802.     </tr>
  1803.     <tr>
  1804.         <td valign="top"> </td>
  1805.         <td valign="top">*</td>
  1806.         <td valign="top">zu┐ywa tylko zasoby
  1807.         serwera WWW</td>
  1808.     </tr>
  1809.     <tr>
  1810.         <td valign="top"> </td>
  1811.         <td valign="top">*</td>
  1812.         <td valign="top">nie ma potrzeby tworzenia
  1813.         i otwierania obiektu <code>Recordset</code></td>
  1814.     </tr>
  1815.     <tr>
  1816.         <td valign="top">-</td>
  1817.         <td valign="top" colspan="2">poprzez u┐ycie
  1818.         metody <code>Delete</code>, zalety:</td>
  1819.     </tr>
  1820.     <tr>
  1821.         <td valign="top"> </td>
  1822.         <td valign="top">*</td>
  1823.         <td valign="top">mo┐liwo╢µ
  1824.         natychmiastowego usuniΩcia rekordu podczas przegl▒dania
  1825.         rekord≤w</td>
  1826.     </tr>
  1827.     <tr>
  1828.         <td valign="top"> </td>
  1829.         <td valign="top">*</td>
  1830.         <td valign="top">mo┐liwo╢µ usuniΩcia
  1831.         wszystkich rekord≤w zawartych w obiekcie <code>Recordset</code>, spe│niaj▒cych
  1832.         kryteria znajduj▒ce siΩ we w│a╢ciwo╢ci <code>Filter</code></td>
  1833.     </tr>
  1834. </TBODY></table>
  1835.  
  1836. <p align="justify"><code>U┐ycie komendy DELETE w zapytaniu SQL</code></p>
  1837.  
  1838. <p align="justify">Sk│adnia zapytania SQL zawieraj▒cego komendΩ <code>DELETE</code> wygl▒da
  1839. nastΩpuj▒co:</p>
  1840.  
  1841. <table border="0">
  1842. <TBODY>    <tr>
  1843.         <td>DELETE FROM NazwaTabeli WHERE Warunek</td>
  1844.     </tr>
  1845. </TBODY></table>
  1846.  
  1847. <p align="justify">na przyk│ad:</p>
  1848.  
  1849. <table border="0" cellspacing="4">
  1850. <TBODY>    <tr>
  1851.         <td>DELETE FROM Pracownicy WHERE Data < #03/02/66#</td>
  1852.         <td valign="top"> </td>
  1853.         <td valign="top">- w przypadku MS Access</td>
  1854.     </tr>
  1855.     <tr>
  1856.         <td>DELETE FROM Pracownicy WHERE Data < '03/02/66'</td>
  1857.         <td valign="top"> </td>
  1858.         <td valign="top">- w przypadku SQL Server</td>
  1859.     </tr>
  1860. </TBODY></table>
  1861.  
  1862. <p align="justify">Zapytanie SQL jest wykonywane po wywo│aniu metody <code>Execute</code>
  1863. obiektu <code>Connection</code>.</p>
  1864.  
  1865. <p align="justify"><code>U┐ycie metody Delete</code></p>
  1866.  
  1867. <p align="justify">Podczas przemieszczania siΩ poprzez grupΩ rekord≤w (obiekt <code>Recordset</code>),
  1868. mo┐na usun▒µ bie┐▒cy rekord lub wszystkie rekordy poprzez
  1869. wywo│anie metody <code>Delete</code>. Na przyk│ad, przemieszczaj▒c siΩ po
  1870. obiekcie <code>objRS</code> wewn▒trz pΩtli <code>While</code>, usuniΩte zostan▒
  1871. wszystkie rekordy, kt≤re w polu <code>Imie</code> zawieraj▒ warto╢µ "<code>Jan</code>":</p>
  1872.  
  1873. <table border="0">
  1874. <TBODY>    <tr>
  1875.         <td colspan="3">While Not(objRS.EOF)</td>
  1876.     </tr>
  1877.     <tr>
  1878.         <td> </td>
  1879.         <td colspan="2">If objRS("Imie") =
  1880.         "Jan" Then</td>
  1881.     </tr>
  1882.     <tr>
  1883.         <td> </td>
  1884.         <td> </td>
  1885.         <td>objRS.Delete</td>
  1886.     </tr>
  1887.     <tr>
  1888.         <td> </td>
  1889.         <td colspan="2">End If<br>
  1890.         objRS.MoveNext</td>
  1891.     </tr>
  1892.     <tr>
  1893.         <td colspan="3">Wend</td>
  1894.     </tr>
  1895. </TBODY></table>
  1896.  
  1897. <p align="justify">Je╢li istnieje potrzeba usuniΩcia wszystkich rekord≤w z
  1898. obiektu <code>Recordset</code>, mo┐na u┐yµ nastΩpuj▒cej instrukcji:</p>
  1899.  
  1900. <table border="0">
  1901. <TBODY>    <tr>
  1902.         <td>Recordset.Delete adAffectGroup</td>
  1903.     </tr>
  1904. </TBODY></table>
  1905.  
  1906. <p align="justify">co jest r≤wnowa┐ne zapisowi</p>
  1907.  
  1908. <table border="0">
  1909. <TBODY>    <tr>
  1910.         <td>Recordset.Delete 2</td>
  1911.     </tr>
  1912. </TBODY></table>
  1913.  
  1914. <h3>6.6 Stronicowanie zbior≤w rekord≤w.</h3>
  1915.  
  1916. <p align="justify">Wiadomo ju┐ jak mo┐na dopisywaµ, uaktualniaµ i kasowaµ
  1917. rekordy z bazy danych. Znane ju┐ s▒ mo┐liwo╢ci i r≤┐nice
  1918. wykorzystania zapyta± SQL oraz tworzenia obiekt≤w <code>Recordset</code> i
  1919. wywo│ywania ich metod. Teraz skrypt mo┐e pobieraµ tysi▒ce
  1920. rekord≤w a nawet jeszcze wiΩcej, lecz co z wys│aniem tak du┐ej
  1921. ilo╢ci do klienta (przegl▒darki)? Wysy│anie tak du┐ej ilo╢ci
  1922. danych do klienta (przegl▒darki), to nie najlepszy pomys│. Nale┐a│oby
  1923. znale╝µ lepsze rozwi▒zanie. Takim rozwi▒zaniem bΩdzie
  1924. technika zwana <code>stronicowaniem</code> (ang. paging). Polega ona na tym,
  1925. ┐e wysy│ana jest tylko czΩ╢µ rekord≤w do klienta (przegl▒darki),
  1926. po czym klient (u┐ytkownik) mo┐e za┐▒daµ kolejnej czΩ╢ci
  1927. danych, itd. Takie rozwi▒zanie zu┐yje mniejsz▒ ilo╢µ zasob≤w
  1928. serwera i skr≤ci czas │adowania siΩ strony.</p>
  1929.  
  1930. <p align="justify">Przyk│adowy skrypt zostanie podzielony na siedem czΩ╢ci, tj.:</p>
  1931.  
  1932. <table border="0">
  1933. <TBODY>    <tr>
  1934.         <td valign="top">a)</td>
  1935.         <td valign="top">deklaracja - w tej czΩ╢ci
  1936.         nast▒pi zdeklarowanie i ustawienie warto╢ci zmiennych i
  1937.         sta│ych;</td>
  1938.     </tr>
  1939.     <tr>
  1940.         <td valign="top">b)</td>
  1941.         <td valign="top">okre╢lenie numeru wy╢wietlonej
  1942.         strony - skrypt okre╢li numer wcze╢niej wy╢wietlanej
  1943.         strony i wyb≤r u┐ytkownika co do przemieszczenia siΩ
  1944.         na kolejn▒ stronΩ, tzn. sk▒d siΩ tutaj dosta│ i co
  1945.         wybra│;</td>
  1946.     </tr>
  1947.     <tr>
  1948.         <td valign="top">c)</td>
  1949.         <td valign="top">przygotowanie rekord≤w
  1950.         do stronicowania - ustawienie parametr≤w obiektu
  1951.         Recordset w celu wykorzystania metod i w│a╢ciwo╢ci
  1952.         potrzebnych do stronicowania;</td>
  1953.     </tr>
  1954.     <tr>
  1955.         <td valign="top">d)</td>
  1956.         <td valign="top">otwarcie rekord≤w -
  1957.         otwarcie rekord≤w (obiektu Recordset) i wykonanie
  1958.         zapytania SQL w celu pobrania odpowiednich danych z bazy;</td>
  1959.     </tr>
  1960.     <tr>
  1961.         <td valign="top">e)</td>
  1962.         <td valign="top">przemieszczanie siΩ
  1963.         kursora po rekordach - ustawienie pozycji kursora na
  1964.         rekordach, kt≤re powinny byµ wy╢wietlone na bie┐▒cej
  1965.         stronie WWW;</td>
  1966.     </tr>
  1967.     <tr>
  1968.         <td valign="top">f)</td>
  1969.         <td valign="top">wys│anie danych z bazy
  1970.         do klienta - wys│anie danych do klienta;</td>
  1971.     </tr>
  1972.     <tr>
  1973.         <td valign="top">g)</td>
  1974.         <td valign="top">stworzenie element≤w umo┐liwiaj▒cych
  1975.         nawigacjΩ - utworzenie element≤w (przycisk≤w) umo┐liwiaj▒cych
  1976.         u┐ytkownikowi nawigacjΩ, stronicowanie.</td>
  1977.     </tr>
  1978. </TBODY></table>
  1979.  
  1980. <p align="justify">a) <code>deklaracja</code></p>
  1981.  
  1982. <table border="0">
  1983. <TBODY>    <tr>
  1984.         <td valign="top">1:<br>
  1985.         2:<br>
  1986.         3:<br>
  1987.         4:<br>
  1988.         5:<br>
  1989.         6:<br>
  1990.         7:<br>
  1991.         8:<br>
  1992.         9:<br>
  1993.         10:</td>
  1994.         <td valign="top"><% <code>@LANGUAGE = VBScript</code>
  1995.         %><br>
  1996.         <%<br>
  1997. <code>        Option Explicit<br>
  1998.         Response.Expires = 0</code><br>
  1999.         %><br>
  2000.         <!--#include file="adovbs.inc"--><br>
  2001.         <%<br>
  2002. <code>        Const rozmiarStrony = 10<br>
  2003.         Dim biezacaStrona, objConn, objRS, strQ<br>
  2004.         Dim razemStron, pozycjaR</code></td>
  2005.     </tr>
  2006. </TBODY></table>
  2007.  
  2008. <p align="justify">Linia 4 informuje przegl▒darkΩ aby nie przechowywa│a strony
  2009. WWW. Jest to do╢µ wa┐ne, poniewa┐ zawarto╢µ strony bΩdzie
  2010. siΩ zmieniaµ za ka┐dym razem, kiedy u┐ytkownik przejdzie do
  2011. kolejnej grupy rekord≤w. Ilo╢µ rekord≤w znajduj▒cych siΩ na
  2012. jednej stronie jest okre╢lona przez zmienn▒ <code>rozmiarStrony</code> i
  2013. zawiera warto╢µ 10 (linia 8). Zmienna <code>biezacaStrona</code> zawiera
  2014. numer aktualnie wy╢wietlanej strony (grupy rekord≤w). <code>objConn</code> i
  2015. <code>objRS</code> zawieraj▒ obiekty <code>Connection</code> i <code>Recordset</code>. Zmienna <code>razemStron</code>
  2016. zawiera ilo╢µ wszystkich stron, za╢ zmienna <code>pozycjaR</code> zawiera
  2017. numer porz▒dkowy rekordu na bie┐▒cej stronie.</p>
  2018.  
  2019. <p align="justify">b) okre╢lenie numeru wy╢wietlonej strony</p>
  2020.  
  2021. <table border="0">
  2022. <TBODY>    <tr>
  2023.         <td valign="top">11:</td>
  2024.         <td valign="top" colspan="4"><code>If Request.ServerVariables("CONTENT_LENGTH")
  2025.         = 0 Then</code></td>
  2026.     </tr>
  2027.     <tr>
  2028.         <td valign="top">12:</td>
  2029.         <td valign="top"> </td>
  2030.         <td valign="top" colspan="3"><code>biezacaStrona =
  2031.         1</code></td>
  2032.     </tr>
  2033.     <tr>
  2034.         <td valign="top">13:</td>
  2035.         <td valign="top" colspan="4"><code>Else</code></td>
  2036.     </tr>
  2037.     <tr>
  2038.         <td valign="top">14:<br>
  2039.         15:</td>
  2040.         <td valign="top"> </td>
  2041.         <td valign="top" colspan="3"><code>biezacaStrona =
  2042.         CInt(Request.Form("BiezacaStrona"))<br>
  2043.         Select Case Request.Form("Akcja")</code></td>
  2044.     </tr>
  2045.     <tr>
  2046.         <td valign="top">16:</td>
  2047.         <td valign="top"> </td>
  2048.         <td valign="top"> </td>
  2049.         <td valign="top" colspan="2"><code>Case "Poprzednia"</code></td>
  2050.     </tr>
  2051.     <tr>
  2052.         <td valign="top">17:</td>
  2053.         <td valign="top"> </td>
  2054.         <td valign="top"> </td>
  2055.         <td valign="top"> </td>
  2056.         <td valign="top"><code>biezacaStrona =
  2057.         biezacaStrona - 1</code></td>
  2058.     </tr>
  2059.     <tr>
  2060.         <td valign="top">18:</td>
  2061.         <td valign="top"> </td>
  2062.         <td valign="top"> </td>
  2063.         <td valign="top" colspan="2"><code>Case "Nastepna"</code></td>
  2064.     </tr>
  2065.     <tr>
  2066.         <td valign="top">19:</td>
  2067.         <td valign="top"> </td>
  2068.         <td valign="top"> </td>
  2069.         <td valign="top"> </td>
  2070.         <td valign="top"><code>biezacaStrona =
  2071.         biazacaStrona + 1</code></td>
  2072.     </tr>
  2073.     <tr>
  2074.         <td valign="top">20:</td>
  2075.         <td valign="top"> </td>
  2076.         <td valign="top" colspan="3"><code>End Select</code></td>
  2077.     </tr>
  2078.     <tr>
  2079.         <td valign="top">21:</td>
  2080.         <td valign="top" colspan="4"><code>End If</code></td>
  2081.     </tr>
  2082. </TBODY></table>
  2083.  
  2084. <p align="justify">Je┐eli skrypt nie otrzyma danych z wype│nionego i wys│anego
  2085. formularza (linia 11), bie┐▒cy numer strony jest ustawiany na
  2086. warto╢µ r≤wn▒ 1 (linia 12). Je┐eli u┐ytkownik kliknie na
  2087. jeden z przycisk≤w nawigacyjnych skrypt odczyta numer
  2088. poprzedniej strony z przes│anych informacji z formularza (linia
  2089. 14). Pobrany numer strony jest zwiΩkszany (linia 17) w przypadku,
  2090. gdy u┐ytkownik klikn▒│ na przycisk <code>Nastepna</code>, a zmniejszany (linia
  2091. 19), je╢li klikn▒│ na <code>Poprzednia</code>.</p>
  2092.  
  2093. <p align="justify">c) <code>przygotowanie rekord≤w do stronicowania</code></p>
  2094.  
  2095. <table border="0">
  2096. <TBODY>    <tr>
  2097.         <td valign="top">22:<br>
  2098.         23:<br>
  2099.         24:<br>
  2100.         25:<br>
  2101.         26:<br>
  2102.         27:</td>
  2103.         <td valign="top"><code>Set objConn = Server.CreateObject("ADODB.Connection")<br>
  2104.         objConn.Open "Data Source=northwind;User ID=sa;Password=;"<br>
  2105.         Set objRS = Server.CreateObject("ADODB.Recordset")<br>
  2106.         objRS.CursorLocation = adUseClient<br>
  2107.         objRS.CursorType = adOpenStatic<br>
  2108.         objRS.CacheSize = rozmiarStrony</code></td>
  2109.     </tr>
  2110. </TBODY></table>
  2111.  
  2112. <p align="justify">W tej czΩ╢ci skrypt tworzy obiekt <code>Recordset</code> (linia 24) i
  2113. przygotowuje go w taki spos≤b, aby dostarczyµ metod i w│a╢ciwo╢ci
  2114. niezbΩdnych do dokonania stronicowania. W liniach 22-23 tworzone
  2115. jest i ustalane po│▒czenie z baz▒ danych. Linia 25 to przyporz▒dkowanie
  2116. w│a╢ciwo╢ci <code>CursorLocation</code> warto╢ci <code>adUseClient</code>. Nie jest to
  2117. obowi▒zkowe, ale jest zalecane w celu zmniejszenia obci▒┐enia
  2118. bazy danych. W nastΩpnej linii w│a╢ciwo╢µ <code>CursorType</code>
  2119. przyjmuje warto╢µ sta│ej <code>adOpenStatic</code>. Przypisanie zmieni
  2120. warto╢µ domy╢ln▒ w│a╢ciwo╢ci z <code>adOpenForwardOnly</code>, kt≤ra
  2121. nie pozwoli│aby odczytaµ liczby stron w zbiorze rekord≤w
  2122. poprzez u┐ycie w│a╢ciwo╢ci <code>PageCount</code>. Kolejna w│a╢ciwo╢µ
  2123. to <code>CacheSize</code> (linia 27), przyjmuje ona warto╢µ r≤wn▒ ilo╢ci
  2124. rekord≤w na ka┐dej stronie. Ustawienie tej w│a╢ciwo╢ci
  2125. poprawia osi▒gi, szczeg≤lnie samego skryptu ASP, poniewa┐ od
  2126. tego czasu czytanie i przechowywanie wszystkich rekord≤w okre╢lonej
  2127. strony odbywa siΩ od razu.</p>
  2128.  
  2129. <p align="justify">d) <code>otwarcie rekord≤w</code></p>
  2130.  
  2131. <table border="0">
  2132. <TBODY>    <tr>
  2133.         <td valign="top">28:<br>
  2134.         29:<br>
  2135.         30:<br>
  2136.         31:<br>
  2137.         32:<br>
  2138.         33:</td>
  2139.         <td valign="top"><code>strQ = "SELECT
  2140.         Customers.CompanyName, Orders.OrderDate "<br>
  2141.         strQ = strQ & "FROM Orders INNER JOIN Customers
  2142.         ON "<br>
  2143.         strQ = strQ & "Orders.CustomerID = Customers.CustomerID
  2144.         "<br>
  2145.         strQ = strQ & "ORDER BY Orders.OrderDate, "<br>
  2146.         strQ = strQ & "Customers.CompanyName"<br>
  2147.         objRS.Open strQ, objConn, , , adCmdText</code></td>
  2148.     </tr>
  2149. </TBODY></table>
  2150.  
  2151. <p align="justify">W tej czΩ╢ci do zmiennej <code>strQ</code> przypisywana jest zawarto╢µ
  2152. zapytania SQL, kt≤ra wygl▒da nastΩpuj▒co:</p>
  2153.  
  2154. <table border="0">
  2155. <TBODY>    <tr>
  2156.         <td valign="top" colspan="2">SELECT
  2157.         Customers.CompanyName, Orders.OrderDate<br>
  2158.         FROM Orders INNER JOIN Customers</td>
  2159.     </tr>
  2160.     <tr>
  2161.         <td valign="top"> </td>
  2162.         <td valign="top">ON Orders.CustomerID =
  2163.         Customers.Customer
  2164. </table>
  2165.  
  2166. <hr size="1" color="#FFFFFF"><span class="stopa">
  2167. <b>Autor:</b> <a href="mailto:stelmi@friko2.onet.pl" class="stopka">Krzysztof Stelmach</a><br>
  2168. <b>Artyku│ ze strony:</b> <a href="http://www.asp.z.pl/" class="stopka" target="_blank">http://www.asp.z.pl/</a>
  2169. </span><br></td>
  2170.     </tr></table>
  2171.     </div>
  2172. </td>
  2173. <td width="142" valign="top">
  2174.  
  2175.         <br>
  2176.         <table border="0" cellpadding="0" cellspacing="0" width="142">
  2177.         <tr>
  2178.         <td width="142" valign="top"><img src="img/login.gif" border="0" width="142" height="13" alt="LOGIN"></td>
  2179.         </tr>
  2180.         <tr>
  2181.         <td width="142" valign="top" background="img/okno1.gif">
  2182.         
  2183.             
  2184.             <div align="center">
  2185.             <table cellpadding="0" cellspacing="2" border="0" width="98%">
  2186.             <form method="post" action="subskrypcja/login.php">
  2187.             <tr><td width="30%"><span class="t">Login:</span></td><td width="68%"><input type="text" name="login" size="15" class="login"></td></tr>
  2188.             <tr><td width="30%"><span class="t">Has│o:</span></td><td width="68%"><input type="password" name="haslo" size="15" class="login"></td></tr>
  2189.             
  2190.             <tr><td colspan="2"><center><input type="image" src="img/ok.gif"></td></tr>
  2191.             </form></table></div>
  2192.         
  2193.         </td>
  2194.         </tr>
  2195.         <tr>
  2196.         <td width="142" valign="top"><img src="img/okno2.gif" border="0" width="142" height="10"></td>
  2197.         </tr></table>
  2198.  
  2199.         <br>
  2200.         <table border="0" cellpadding="0" cellspacing="0" width="142">
  2201.         <tr>
  2202.         <td width="142" valign="top"><img src="img/art.gif" border="0" width="142" height="13" alt="ARTYKULY"></td>
  2203.         </tr>
  2204.         <tr>
  2205.         <td width="142" valign="top" background="img/okno1.gif">
  2206.         
  2207.         <span class="m">
  2208.         
  2209.          -<a href="index.php@id=1" class="menu">"Edytory HTML'a"</a><br>
  2210.          -<a href="index.php@id=2" class="menu">"Publikowanie witryny"</a><br>
  2211.          -<a href="index.php@id=3" class="menu">"PHP w domu"</a><br>
  2212.          -<a href="index.php@id=4" class="menu">"Przeszukiwanie stron"</a><br>
  2213.          -<a href="index.php@id=204" class="menu">"Wprowadzenie do Javy"</a><br>
  2214.          -<a href="index.php@id=210" class="menu">"Grafika w PHP"</a>
  2215.         </span>
  2216.         
  2217.         </td>
  2218.         </tr>
  2219.         <tr>
  2220.         <td width="142" valign="top"><img src="img/okno2.gif" border="0" width="142" height="10"></td>
  2221.         </tr></table>
  2222.         
  2223.         <br>
  2224.         <table border="0" cellpadding="0" cellspacing="0" width="142">
  2225.         <tr>
  2226.         <td width="142" valign="top"><img src="img/stat.gif" border="0" width="142" height="13" alt="ARTYKULY"></td>
  2227.         </tr>
  2228.         <tr>
  2229.         <td width="142" valign="top" background="img/okno1.gif"><div align="left"><table border="0" cellpadding="0" cellspacing="0" width="138"><tr><td width="138"><ol><li><a href="index.php@id=135" class="stat">PHP - przyk│adowe skrypty</a> <span class="maleczarne">(1491)</span><br><li><a href="index.php@id=59" class="stat">Szablony 1</a> <span class="maleczarne">(833)</span><br><li><a href="index.php@id=145" class="stat">Kurs PHP</a> <span class="maleczarne">(817)</span><br><br><span class="maleczarne">ú▒cznie: 24126</span>        </ol>
  2230.         <center><a href="http://stat.webmedia.pl/cgi-bin/anal?webarea" target="_blank">
  2231. <img border=0 src="http://stat.webmedia.pl/cgi-bin/stat?webarea&stat4ur" alt="stat4u" width="40" height="10"></a></center>
  2232.         </td></tr></table></div>
  2233.         </td>
  2234.         </tr>
  2235.         <tr>
  2236.         <td width="142" valign="top"><img src="img/okno2.gif" border="0" width="142" height="10"></td>
  2237.         </tr></table>
  2238.         
  2239.         <br>
  2240.         <table border="0" cellpadding="0" cellspacing="0" width="142">
  2241.         <tr>
  2242.         <td width="142" valign="top"><img src="img/sponsor.gif" border="0" width="142" height="13" alt="SPONSOR"></td>
  2243.         </tr>
  2244.         <tr>
  2245.         <td width="142" valign="top" background="img/okno1.gif"><br>
  2246.         <center><EMBED src="img/beep2.swf" quality=high bgcolor=#000000 WIDTH=120 HEIGHT=30></center>                            
  2247.         </td>
  2248.         </tr>
  2249.         <tr>
  2250.         <td width="142" valign="top"><img src="img/okno2.gif" border="0" width="142" height="10"></td>
  2251.         </tr></table>
  2252.  
  2253.         <br>
  2254.             <div align="center"><table border="0" cellpadding="2" cellspacing="0" width="120">
  2255.             <tr>
  2256.             <td width="120"><a href="button.php@id=1" target="_blank"><img src="img/cgi.gif" border="0"></a></td>
  2257.             </tr>
  2258.             <tr>
  2259.             <td width="120"><a href="button.php@id=2" target="_blank"><img src="img/ygreg.gif" border="0"></a></td>
  2260.             </tr>
  2261.             <tr>
  2262.             <td width="120"></td>
  2263.             </tr>
  2264.             </table>
  2265.             </div>
  2266.         
  2267.  
  2268. </td>
  2269. </tr>
  2270. <tr>
  2271. <td width="770" valign="top" colspan="3" align="right"><br><br><span class="m">All rights reserved by <a href="mailto:web-area@web-area.org">J&J Filipowscy Design & Code</a></td>
  2272. </tr></table></div>
  2273.  
  2274.  
  2275. </body>
  2276. </html>