[ebook] learn asp

286
http://www.learnASP.com/learn/index.asp by Charles M. Carroll Page 1 /learn Table of Contents Quick Lessons - Table of Contents (/learn/index.asp) - Page 1 Credits & Instructions (/learn/credits.asp) - Page 2 Core Ideas (/learn/core.asp) - Page 3 What is ASP? (/learn/whatis.asp) - Page 4 Simple ASP Page, Server Scripting (/learn/whatisexample.asp) - Page 5 MS Online Documentation (/learn/docs.asp) - Page 6 Response: Basics (/learn/res.asp) - Page 7 Response: Buffers, Redirect (/learn/res2.asp) - Page 8 Response: Redirection (/learn/res3.asp) - Page 9 Response: Quotes & Special Characters (/learn/res4.asp) - Page 10 Response: Encoding URLs, HTML (/learn/res5.asp) - Page 11 Include: Basics (/learn/inc.asp) - Page 12 Include: Dynamic FileName (/learn/includedynamic.asp) - Page 13 Include: Sample Exercise (/learn/booksample.asp) - Page 14 Format: Numbers #1 (/learn/formatnumbers.asp) - Page 15 Format: Numbers #2 (/learn/formatnumbers2.asp) - Page 16 Format: Dates #1 (/learn/formatdates.asp) - Page 17 Date/Time on ASP Pages by Tony Arguelles (/learn/datetime.asp) - Page 18 Loops: DO WHILE/UNTIL #1 (/learn/DoLoop.asp) - Page 19 Loops: Timeouts #2 (/learn/DoLoop2.asp) - Page 20 Loops: Intercepting Timeouts #3 (/learn/DoLoop3.asp) - Page 21 Server Variables: Popular Ones (/learn/server.asp) - Page 22 Server Variables: Domain/Host Name (/learn/server2.asp) - Page 23 Server Variables: Displaying All (/learn/serverall.asp) - Page 24 Random Content/Rotating Info (/learn/randomadvice.asp) - Page 25 Browser Detection (/learn/browserdetect.asp) - Page 26 Browscap: Basics (/learn/bc.asp) - Page 27 Browscap: Intricate Details (/learn/bcdetails.asp) - Page 28 BrowserHawk: Determing Browser Type (/learn/bhbrowtype.asp) - Page 29 BrowserHawk: older AOL browsers (/learn/bhaol.asp) - Page 30 Browserhawk: MS-Wallet (/learn/bhwallet.asp) - Page 31 BrowserHawk - Reverse DNS lookups (/learn/bhresolveip.asp) - Page 32 BrowserHawk - Frame support (/learn/bhframes.asp) - Page 33 Troubleshooting, Error Trapping (/learn/troubles.asp) - Page 34 Errors: Basics (/learn/errors1.asp) - Page 35 Errors: Trapping EVERY Error (/learn/dbtablewitherrortrap.asp) - Page 36 Errors: DB Error Information Trapping (/learn/dbtroubleshoot.asp) - Page 37 DBFAQ: Operation must use Updatable Query (/learn/FAQdbUpdate.asp) - Page 38 DBFAQ: User Entered ' in field (/learn/FAQdbSinglequote.asp) - Page 39 DBFAQ: LIKE operator * not working (/learn/FAQdbLIKE.asp) - Page 40 DBFAQ: retrieving MEMO/BLOBs generates error (/learn/FAQdbMEMO.asp) - Page 41

Upload: api-19817955

Post on 18-Nov-2014

310 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: [ebook] Learn ASP

http://www.learnASP.com/learn/index.asp by Charles M. Carroll Page 1

/learn Table of Contents

Quick Lessons - Table of Contents (/learn/index.asp) - Page 1Credits & Instructions (/learn/credits.asp) - Page 2Core Ideas (/learn/core.asp) - Page 3 What is ASP? (/learn/whatis.asp) - Page 4 Simple ASP Page, Server Scripting (/learn/whatisexample.asp) - Page 5 MS Online Documentation (/learn/docs.asp) - Page 6 Response: Basics (/learn/res.asp) - Page 7 Response: Buffers, Redirect (/learn/res2.asp) - Page 8 Response: Redirection (/learn/res3.asp) - Page 9 Response: Quotes & Special Characters (/learn/res4.asp) - Page 10 Response: Encoding URLs, HTML (/learn/res5.asp) - Page 11 Include: Basics (/learn/inc.asp) - Page 12 Include: Dynamic FileName (/learn/includedynamic.asp) - Page 13 Include: Sample Exercise (/learn/booksample.asp) - Page 14 Format: Numbers #1 (/learn/formatnumbers.asp) - Page 15 Format: Numbers #2 (/learn/formatnumbers2.asp) - Page 16 Format: Dates #1 (/learn/formatdates.asp) - Page 17 Date/Time on ASP Pages by Tony Arguelles (/learn/datetime.asp) - Page 18 Loops: DO WHILE/UNTIL #1 (/learn/DoLoop.asp) - Page 19 Loops: Timeouts #2 (/learn/DoLoop2.asp) - Page 20 Loops: Intercepting Timeouts #3 (/learn/DoLoop3.asp) - Page 21 Server Variables: Popular Ones (/learn/server.asp) - Page 22 Server Variables: Domain/Host Name (/learn/server2.asp) - Page 23 Server Variables: Displaying All (/learn/serverall.asp) - Page 24 Random Content/Rotating Info (/learn/randomadvice.asp) - Page 25

Browser Detection (/learn/browserdetect.asp) - Page 26 Browscap: Basics (/learn/bc.asp) - Page 27 Browscap: Intricate Details (/learn/bcdetails.asp) - Page 28 BrowserHawk: Determing Browser Type (/learn/bhbrowtype.asp) - Page 29 BrowserHawk: older AOL browsers (/learn/bhaol.asp) - Page 30 Browserhawk: MS-Wallet (/learn/bhwallet.asp) - Page 31 BrowserHawk - Reverse DNS lookups (/learn/bhresolveip.asp) - Page 32 BrowserHawk - Frame support (/learn/bhframes.asp) - Page 33

Troubleshooting, Error Trapping (/learn/troubles.asp) - Page 34 Errors: Basics (/learn/errors1.asp) - Page 35 Errors: Trapping EVERY Error (/learn/dbtablewitherrortrap.asp) - Page 36 Errors: DB Error Information Trapping (/learn/dbtroubleshoot.asp) - Page 37 DBFAQ: Operation must use Updatable Query (/learn/FAQdbUpdate.asp) - Page 38 DBFAQ: User Entered ' in field (/learn/FAQdbSinglequote.asp) - Page 39 DBFAQ: LIKE operator * not working (/learn/FAQdbLIKE.asp) - Page 40 DBFAQ: retrieving MEMO/BLOBs generates error (/learn/FAQdbMEMO.asp) - Page 41

Page 2: [ebook] Learn ASP

DBFAQ: Syntax Error in SQL Statement (/learn/FAQdbSQLSyntax.asp) - Page 42 Errors: Trapping Open Connections (/learn/dbtroubleshootopen.asp) - Page 43 Troubleshoot: Getting Help from Lists! (/learn/asptroubles.asp) - Page 44 Troubleshoot: Worldwide (/learn/asptroubles2.asp) - Page 45 Troubleshoot: Specialized (/learn/asptroubles3.asp) - Page 46 Troubleshoot: Version of ASP Sofware (/learn/versioncheck.asp) - Page 47 Troubleshoot: Registered Components (/learn/componentchecker.asp) - Page 48 Troubleshoot: DB Drivers by Christophe Wille (/learn/connectioninfo.asp) - Page 49 PWS: Personal Web Server Introduction (/learn/PWS.asp) - Page 50

Forms/Decisions (/learn/Form.asp) - Page 51 Forms: Introduction (/learn/formintro.asp) - Page 52 Forms: Text Box (/learn/formtextbox.asp) - Page 53 Forms: Text Area (/learn/formtextarea.asp) - Page 54 Forms: Check Box (/learn/formcheckbox.asp) - Page 55 Forms: Radio Buttons (/learn/formradio.asp) - Page 56 Forms: List Box (/learn/formlistbox.asp) - Page 57 Forms: CASE syntax #1 (/learn/case.asp) - Page 58 Forms: CASE syntax #2 (/learn/case2.asp) - Page 59 Forms: IF syntax #1 (/learn/if.asp) - Page 60 Forms: IF syntax #2 (/learn/if2.asp) - Page 61 Forms: IF syntax #3 (/learn/if3.asp) - Page 62 Forms: IF syntax #4 (/learn/if4.asp) - Page 63 Forms: For Each Iteration (/learn/formforeach.asp) - Page 64 Forms: mailing w/ASPMail (/learn/formsendmail.asp) - Page 65 Cookies: Reading Them (/learn/cookiesform.asp) - Page 66 Cookies: Writing Them (/learn/cookiesformrespond.asp) - Page 67 Cookies: Deleting Them (/learn/cookiesforget.asp) - Page 68 Cookies: Simplified by Paul Rigor (/learn/cookiesub.asp) - Page 69

State Management (/learn/statemanagement.asp) - Page 70 State Management Introduction (/learn/stateintro.asp) - Page 71 What are ASP Sessions? (/learn/sessionswhat.asp) - Page 72 State Methods: Pros and Cons (/learn/stateproscons.asp) - Page 73 Pass Data w/Hidden Fields (/learn/hidden.asp) - Page 74 Pass Data w/Cookies (/learn/cookies.asp) - Page 75 Pass Data w/Session Vars (/learn/statesessions.asp) - Page 76 Pass Data w/ID tied to database (/learn/statedb.asp) - Page 77 State Managment Resources (/learn/statemore.asp) - Page 78 [aspStateManagement] Listserver (/learn/aspstatemanagement.asp) - Page 79

Databases (/learn/database.asp) - Page 80 DB: Troubleshooting Part 1 (/learn/dbtroubles.asp) - Page 81 DB: Troubleshooting Part 2 (/learn/dbtroubles2.asp) - Page 82 DB: Displaying Table w/Simple Code (/learn/dbsimple.asp) - Page 83 DB: Table Displayed Generically (/learn/dbtable.asp) - Page 84 DB: List Box Displayed Generically (/learn/dblist.asp) - Page 85 Database to ListBox Online Resources (/learn/dblistmore.asp) - Page 86 DB: Generic DB by Eli Robillard (/learn/genericdb.asp) - Page 87 DB: More ways To Display Tables (/learn/dbtablemore.asp) - Page 88 DB: DSNLess Connections (/learn/dbopen.asp) - Page 89

Page 3: [ebook] Learn ASP

DB: DSN Setup #1 by Rob Martinson (/learn/dsn1.asp) - Page 90 DB: DSN Setup #2 by Rob Martinson (/learn/dsn2.asp) - Page 91 DB: DSN Setup #3 by Rob Martinson (/learn/dsn3.asp) - Page 92 DB: DSN Setup #4 by Rob Martinson (/learn/dsn4.asp) - Page 93 DB: DSN Setup #5 by Rob Martinson (/learn/dsn5.asp) - Page 94 DB: DSN Setup #6 by Rob Martinson (/learn/dsn6.asp) - Page 95 DB: Full Cycle #1 Show/Edit/Update (/learn/dbfull1.asp) - Page 96 DB: Full Cycle #2 Show/Edit/Update (/learn/dbfull2.asp) - Page 97 DB: Full Cycle #3 Show/Edit/Update (/learn/dbfull3.asp) - Page 98 DB: Converting a DB to a Comma-Delimited file (/learn/dbconvert.asp) - Page 99 DB: Deleting a Record w/SQL (/learn/dbSQLdelete.asp) - Page 100 DB: Access vs. SQL Server (/learn/accessSQLserver.asp) - Page 101 DB: Oracle and ASP (/learn/oracle.asp) - Page 102

ASPDB - A Component That Simplifies Databases (/learn/aspdb.asp) - Page 103 ASP DB Sample #1: Displaying Data (/learn/aspdb1.asp) - Page 104 ASP DB Sample #2: Editing, Adding Data (/learn/aspdb2.asp) - Page 105

Database: Useful ADO Features (/learn/ado.asp) - Page 106 Getstring to display database table (/learn/dbtablegetstring.asp) - Page 107 Getrows to display database table (/learn/dbtablegetrows.asp) - Page 108 Disconnected Recordsets, Display Table (/learn/dbtabledisconnected.asp) - Page 109 ADO: Limiting Number of Records (/learn/dbmaxrecs.asp) - Page 110 ADO: Paging Records (/learn/dbtablepaged.asp) - Page 111 ADO: Count Records in Query (/learn/dbcount.asp) - Page 112 ADO: Cursor Types by Phil Paxton (/learn/adocursortypes.asp) - Page 113 ADO: Input Form (/learn/dbnewrec.asp) - Page 114 ADO: Input Form, added w/SQL (/learn/dbnewSQL.asp) - Page 115 ADO: Input Form, Added w/ADO .addnew (/learn/dbnewADO.asp) - Page 116 ADO: GetString function (/learn/dbgetstring.asp) - Page 117 ADO: Tables within Databases (/learn/dbtablelists.asp) - Page 118 ADO: Schemas to access table lists (/learn/dbschemas.asp) - Page 119 ADO: Schemas to access All Data (/learn/dbschemasall.asp) - Page 120 ADO: SQL Mistakes (/learn/dbtroubleshoot2.asp) - Page 121 ADO: Show Table,1 param (/learn/db1parm.asp) - Page 122 ADO: Update/edit Record (/learn/dbupdate.asp) - Page 123

SQL Basics, Searching Databases (/learn/SQL.asp) - Page 124 SQL Troubles (/learn/SQLtroubles.asp) - Page 125 SQL: Example Tables (/learn/SQLexamples.asp) - Page 126 SQL: Where Clause Basics (/learn/SQLwhere.asp) - Page 127 SQL: Where Clause Examples (/learn/SQLwhere2.asp) - Page 128 SQL: Search Forms #1 (/learn/SQLwhereform1.asp) - Page 129 SQL: Search Forms #2 (/learn/SQLwhereform2.asp) - Page 130 SQL: Search Forms #3 (/learn/SQLwhereform3.asp) - Page 131 SQL: Search AND/OR Operators (/learn/SQLandor.asp) - Page 132 SQL: Search AND/OR Examples (/learn/SQLandor2.asp) - Page 133 SQL: COUNT, GROUPBY (/learn/SQLcount.asp) - Page 134 SQL: SUM, MIN, AVE, MAX (/learn/SQLaggregate.asp) - Page 135 SQL Joins by Aaron Alexander (/learn/dbjoin.asp) - Page 136

Authentication & Security (/learn/authenticate.asp) - Page 137

Page 4: [ebook] Learn ASP

Authenticate: Overview by Kevin Flick (/learn/authenticateoverview.asp) - Page 138 Authenticate: Comparison by Kevin Flick (/learn/authenticatecomparisons.asp) - Page 139 Authenticate: NT Challenge/Response by Kevin Flick (/learn/authenticatentcr.asp) - Page 140 Authenticate: Basic Authentication by Kevin Flick (/learn/authenticatebasic.asp) - Page 141 Authenticate: Cookies by Kevin Flick (/learn/authenticatecookies.asp) - Page 142 Authenticate: Certificates by Kevin Flick (/learn/authenticatecertificate.asp) - Page 143 Authenticate: Build Your Own by Kevin Flick (/learn/authenticatebuild.asp) - Page 144 Authenticate: Protect Pages via Login #1 (/learn/security.asp) - Page 145 Authenticate: Protect Pages via Login #2 (/learn/security2.asp) - Page 146 Authenticate: 3rd Party by Kevin Flick (/learn/authenticate3rdparty.asp) - Page 147

Mastering ASP: Quality, Re-Use, More... (/learn/qualitycode.asp) - Page 148 Strings: Core Functions (/learn/strings.asp) - Page 149 Strings: SPLIT Function (/learn/stringsplit.asp) - Page 150 Strings: REPLACE Function (/learn/stringreplace.asp) - Page 151 Strings: JOIN Function (/learn/stringjoin.asp) - Page 152 Arrays: Basics (/learn/arrays.asp) - Page 153 Arrays: Variable Size (/learn/arrays2.asp) - Page 154 Arrays: Best Way To Load (/learn/arrays3.asp) - Page 155 Dictionary Objects (/learn/dictionary.asp) - Page 156 Subroutine: Working with Dates #1 (/learn/subdates.asp) - Page 157 Subroutine: Working with Dates #2 (/learn/subdates2.asp) - Page 158 Subroutine: Query2Table (/learn/subdbtable.asp) - Page 159 Subroutine: Query2List (/learn/subdblist.asp) - Page 160 Subroutine: Highly Reusable (/learn/subreusable.asp) - Page 161 Subroutine: List Box w/optional params (/learn/subDBlistbest.asp) - Page 162 Subroutine: Abstract HTML by Phil Paxton (/learn/libhtml.asp) - Page 163 Function: Working Days (/learn/functionworkingdays.asp) - Page 164 New Features in VBScript version5 (/learn/vbs5.asp) - Page 165

Editors designed for ASP (/learn/editors.asp) - Page 166 Visual Interdev + Admunsen Resources (/learn/admunsen.asp) - Page 167 ASPExpress: HOT ASP Editor (/learn/aspexpress.asp) - Page 168 Homesite: HTML editor (/learn/homesite.asp) - Page 169

Code Speed, Scalability... (/learn/speedscale.asp) - Page 170 Application Data (/learn/sessionsapps.asp) - Page 171 Application Data: Worlds Fastest ListBox (/learn/speedappdata.asp) - Page 172 Sessions: What are they? (/learn/sessionswhat.asp) - Page 173 Sessions: Global.asa Events (/learn/global.asp) - Page 174 Session Overview & Myths (/learn/sessionoverview.asp) - Page 175 Sessions: Global.asa and Scalability (/learn/globalproblems.asp) - Page 176 Global.asa Resources (/learn/globalmore.asp) - Page 177 Speed: Server Optimization (/learn/speedserver.asp) - Page 178 Speed: Research Online (/learn/speedresearch.asp) - Page 179 Time Tasks with Millisecond Accuracy (/learn/speedtimer.asp) - Page 180 Speed: Coding Tips (/learn/speedtips.asp) - Page 181 Speed: Database Percieved Speed (/learn/speedtables.asp) - Page 182 Speed: Database Retrieval Speed (/learn/speedtablesall.asp) - Page 183 Speed: OLEDB & ODBC Drivers differences (/learn/speedtablesdrivers.asp) - Page 184 Scale: IsClientConnected & Stray Tasks (/learn/isclientconnected.asp) - Page 185

Page 5: [ebook] Learn ASP

Scale: Virtues of Nothing (/learn/nothing.asp) - Page 186 Scale: Connection Pooling (/learn/dbpooling.asp) - Page 187 Thread Safety Issues (/learn/threadsafe.asp) - Page 188 Round-Robin Code Execution (/learn/roundrobin.asp) - Page 189 Why Buffer? (/learn/whybuffer.asp) - Page 190 Why GetRows or Getstring to get Data (/learn/whygetrows.asp) - Page 191 ASP Scalability Listserver (/learn/aspscalability.asp) - Page 192

Related Web/Com Technologies (/learn/webcom.asp) - Page 193 Index Server via ADO (/learn/indexserver.asp) - Page 194 Commerce and ASP (/learn/commerce.asp) - Page 195 Server JavaScript: Resources (/learn/javascript.asp) - Page 196 Validation Resources (/learn/validationmore.asp) - Page 197 Listboxes: Linked Dynamically w/JavaScript (/learn/listdynamic.asp) - Page 198 Dynamic ListBox Online Examples (/learn/listdynamicmore.asp) - Page 199 Listboxes: Linked Dynamically from Database w/JavaScript (/learn/listdynamicdb.asp) - Page 200 Listboxes: Easy Choices by Bill Wilkinson (/learn/listdual.asp) - Page 201 Server Perlscript: Resources (/learn/perlscript.asp) - Page 202 Remote Scripting Simple Example (/learn/remotescripting.asp) - Page 203 Remote Scripting Microsoft Example (/learn/remotescriptingms.asp) - Page 204 RDS: Remote Data Services Intro (/learn/rds.asp) - Page 205 RDS Resources by Carl Prothman (/learn/prothman.asp) - Page 206 ADSI: Active Directory Services Interface Intro (/learn/ADSI.asp) - Page 207 MSMQ: Overview (/learn/MSMQ.asp) - Page 208 Usability: Resources (/learn/usability.asp) - Page 209 Usability: Safe Color Pallete (/learn/safecolors.asp) - Page 210

ASP Books & Online Resources (/learn/research.asp) - Page 211 Must Buy Component Building Book (/learn/bookcomponents.asp) - Page 212 ASP101.com Scripts for your site (/learn/asp101.asp) - Page 213 4GuysFromRolla.com Tons of ASP Material (/learn/4guysfromrolla.asp) - Page 214 ASPToday.com from WROX (/learn/asptoday.asp) - Page 215

Advice For Better Coding! (/learn/advice.asp) - Page 216 advice: Cache No More by Phil Paxton (/learn/cachenomore.asp) - Page 217 advice:Option Explicit (/learn/explicit.asp) - Page 218 advice: Encode with Redirects (/learn/encode.asp) - Page 219 advice: Write Your SQL (/learn/sqlwrite.asp) - Page 220 advice: Named constants for ADO are better (/learn/namedconstants.asp) - Page 221 advice: Clean Up Your Room, I mean Objects (/learn/cleanup.asp) - Page 222 advice: Server.MapPath is Good (/learn/pathmap.asp) - Page 223 advice: Just Say No to Session COM objects (/learn/nosessionobjects.asp) - Page 224 advice: Don't Read COM Properties Twice (/learn/propertyexpense.asp) - Page 225 advice: Secure Code and Data (/learn/securecode.asp) - Page 226 advice: Encaspulate Code! (/learn/encapsulate.asp) - Page 227 advice: CASE reads better than IF (/learn/caseisbetter.asp) - Page 228 advice: Error Trapping Strategies (/learn/errorstrategies.asp) - Page 229 advice: Error Trapping Secrets (/learn/errorsecrets.asp) - Page 230 advice: You Should... (/learn/shoulds.asp) - Page 231

Advanced Topics (/learn/more.asp) - Page 232 Text Files: Reading Them off Server (/learn/txtread.asp) - Page 233

Page 6: [ebook] Learn ASP

Text Files: Writing Them on Server (/learn/txtwrite.asp) - Page 234 Text Files: Meyers-Briggs parsing #1 (/learn/mb1.asp) - Page 235 Text Files: Meyers-Briggs parsing #2 (/learn/mb2.asp) - Page 236 Text Files: Meyers-Briggs parsing #3 (/learn/mb3.asp) - Page 237 Content Linker: Prev/Next Page (/learn/cl.asp) - Page 238 Content Linker: Table of Contents (/learn/cl2.asp) - Page 239 Content Linker: Listbox of contents (/learn/cl3.asp) - Page 240 File Objects: Read Directory (/learn/fileobjects.asp) - Page 241 File Objects: Display Directory as Links/Graphics (/learn/fileobjects2.asp) - Page 242 File Objects: Read Disk Drive by Steven Harper (/learn/fileobjects3.asp) - Page 243 File Objects: Show Dir List by Tim Foster (/learn/fileobjects4.asp) - Page 244 Graphic Size Detector (/learn/graphicdetect.asp) - Page 245

VB ASP Components Building (/learn/buildcomponents.asp) - Page 246 VB Components: Simple Component (/learn/buildvbsimple.asp) - Page 247 VB Components: Registering Component (/learn/buildregister.asp) - Page 248 VB Components: ADO, Run It! (/learn/buildvbado.asp) - Page 249 VB Components: ADO, Build It! (/learn/buildvbado2.asp) - Page 250 VB Components: VB Warnings/Guidelines (/learn/buildvbguidelines.asp) - Page 251 VB Components: General Building Guidelines (/learn/buildvb.asp) - Page 252 VB Components: Installation Requirements (/learn/buildvb2.asp) - Page 253 VB Components: Threading Models (/learn/buildvbthreads.asp) - Page 254

Java ASP Components Building (/learn/buildjava.asp) - Page 255C++/ATL ASP Component Building (/learn/buildc.asp) - Page 256Microsoft Transaction Server (MTS) (/learn/buildmtx.asp) - Page 257 MTS: Overview (/learn/buildmtxoverview.asp) - Page 258 MTS: Essentials (/learn/buildmtx2.asp) - Page 259 MTS: Transactional ASP pages (/learn/buildmtxasp.asp) - Page 260 MTS: Book (/learn/booksmtx.asp) - Page 261 MTS: Book (/learn/booksmtx2.asp) - Page 262 MTS: Registering Components (/learn/buildmtxregister.asp) - Page 263

3rd Party Components (/learn/components.asp) - Page 264 ASPMail: Simple Example (/learn/serverobjectsmail.asp) - Page 265 Upload: Simple Example (/learn/uploadsimple.asp) - Page 266 Upload: Multi-part form (/learn/uploadmultipart.asp) - Page 267 Upload: Limit Size (/learn/uploadlimitsize.asp) - Page 268 Upload: Many Files (/learn/uploadmanyfiles.asp) - Page 269 Perf Counters on ASP page (/learn/perfcounters.asp) - Page 270

New Lessons (/learn/new.asp) - Page 271Recently Modified Lessons (/learn/changed.asp) - Page 272Beginners Lessons (/learn/newbie.asp) - Page 273Frequently Asked Questions (/learn/faqs.asp) - Page 274 Commerce: certificates, https:// (/learn/FAQCommerceCertif.asp) - Page 275 Commerce: online charging (/learn/FAQCommerceCharge.asp) - Page 276 Commerce: components, shopping carts (/learn/FAQCommerceCarts.asp) - Page 277 Jscript: closing DB Connections (/learn/FAQJscriptCleanUp.asp) - Page 278 Jscript: online references (/learn/FAQJscriptRefs.asp) - Page 279 Jscript: display databases (/learn/FAQJscriptDB.asp) - Page 280

Page 7: [ebook] Learn ASP

Oracle: I can't connect (/learn/FAQOracleconnect.asp) - Page 281 Oracle: Know any good books? (/learn/FAQOraclebooks.asp) - Page 282 Oracle: Calling Stored Procs (/learn/FAQOraclestoredproc.asp) - Page 283 VB: DLL overwrite problems (/learn/FAQvbDLLoverwrite.asp) - Page 284 VB: Recommended books (/learn/FAQvbBooks.asp) - Page 285

Overview: What the Heck is ASP? (/learn/overview.asp) - Page 286 ASP Objects: Built In (/learn/aspobjects.asp) - Page 287 ASP Objects: Created when Needed (/learn/aspobjects2.asp) - Page 288

Alphabetical Index (/learn/alphaindex.asp) - Page 289Coming Soon/Very Rough Drafts! (/learn/comingsoon.asp) - Page 290 Data Types: VBScript (/learn/types.asp) - Page 291 Data Types: Conversion (/learn/convert.asp) - Page 292 Loops: FOR NEXT #1 (/learn/ForNext.asp) - Page 293 Loops: FOR NEXT #2 (/learn/ForNext2.asp) - Page 294 Ad Rotator (/learn/ad.asp) - Page 295 Content Rotator (/learn/cr.asp) - Page 296 DB: Command Object (/learn/command.asp) - Page 297 DB: Command Object/Queries (/learn/commandquery.asp) - Page 298 DB: Command Object/Create Tables (/learn/commandcreate.asp) - Page 299 Reporting: Simple Example (/learn/reportsimple.asp) - Page 300 Reporting: Powerful Example (/learn/reportpowerful.asp) - Page 301 Dictionaries: Different Approach #1 By Paul Rigor (/learn/dictionaryadvanced.asp) - Page 302 Dictionaries: Different Approach #2 by Paul Rigor (/learn/dictionaryadvanced2.asp) - Page 303 Validate data (/learn/validate.asp) - Page 304 3rd Party: WebJam (/learn/webjam.asp) - Page 305 Time Tasks: VB Component by Sunny Yu #1 (/learn/asptime.asp) - Page 306 Time Tasks: VB Component by Sunny Yu #2 (/learn/asptimer.asp) - Page 307

http://www.learnASP.com/learn/credits.asp by Charles M. Carroll Page 2

ASP Quick Lessons is a on-line book published @http://www.learnasp.com

All material not specifically noted otherwise is ©1998,1999 by Charles Carroll. All rights reserved. May be used and printedfor any single individual with no restriction. Cannot be reprinted, resold, or commercially made available without the written consentof Charles Carroll.

Primary Writer: Charles M. Carroll

Inspiration, Assistance, Production: Naoko Yoshitsugu, Hitoshi Carroll

Additional Writers: Aaron Alexander, Kevin Flick, Steve Genusa, Steven Harper, John Kauffman. Andrew Laken, Juan Llibre, Rob Martinson, PhilPaxton, Paul Rigor, Christophe Wille, David Wihl and Sunny Yu.

Page 8: [ebook] Learn ASP

Instructions, Hints, TipsA complete printout suitable for printing off-line is available @http://www.learnasp.com/learn/printout.asp

All the ASP programs used in this tutorial can be obtained @http://www.learnasp.com/learn/download.asp

http://www.learnASP.com/learn/core.asp by Charles M. Carroll Page 3

What is ASP? (whatis.asp) - Page 4 Simple ASP Page, Server Scripting (whatisexample.asp) - Page 5 MS Online Documentation (docs.asp) - Page 6 Response: Basics (res.asp) - Page 7 Response: Buffers, Redirect (res2.asp) - Page 8 Response: Redirection (res3.asp) - Page 9 Response: Quotes & Special Characters (res4.asp) - Page 10 Response: Encoding URLs, HTML (res5.asp) - Page 11 Include: Basics (inc.asp) - Page 12 Include: Dynamic FileName (includedynamic.asp) - Page 13 Include: Sample Exercise (booksample.asp) - Page 14 Format: Numbers #1 (formatnumbers.asp) - Page 15 Format: Numbers #2 (formatnumbers2.asp) - Page 16 Format: Dates #1 (formatdates.asp) - Page 17 Date/Time on ASP Pages by Tony Arguelles (datetime.asp) - Page 18 Loops: DO WHILE/UNTIL #1 (DoLoop.asp) - Page 19 Loops: Timeouts #2 (DoLoop2.asp) - Page 20 Loops: Intercepting Timeouts #3 (DoLoop3.asp) - Page 21 Server Variables: Popular Ones (server.asp) - Page 22 Server Variables: Domain/Host Name (server2.asp) - Page 23 Server Variables: Displaying All (serverall.asp) - Page 24 Random Content/Rotating Info (randomadvice.asp) - Page 25

http://www.learnASP.com/learn/whatis.asp by Charles M. Carroll Page 4

(surprisingly even though ASP was shipped in Feb 1996, most explanations are still HUGE in books and use quite scary technicalterms) We will try to present this all in clear, concise terms and be complete as well. Hang on. Here we go.

ASP is:an abbreviation for Active Server Pages1. FREE and already built into Win2000.2. FREE for NT4 if one installs the NT4 Option Pack. Can be downloaded fromhttp://www.microsoft.com/ntserver/nts/downloads/recommended/NT4OptPk/default.asp

3.

ASP can be installed on Win 95/98 computers to test ASP scripts; thus we can conclude the NT Option Pack4 has avery misleading name since it installs on Win 9x as well.

4.

The code inside ASP is mixed in with standard HTML and is NEVER seen by the browser. ASP pages run in ALL browsersUNLESS the person making the page uses HTML or browser commands outside of the ASP portions.

5.

Page 9: [ebook] Learn ASP

More ASP facts:See www.learnasp.com/hosts for links to FREE hosts if you want to develop a site on the WWW web without spendingmoney; Commercial hosts are also listed to serve busy corporate sites you build.

1.

It is part of IIS (Internet Information Server) which takes care of all the non-asp chores (FTP, serving plain HTML, servingvideo). IIS is also FREE with NT4 or Win2000.

2.

It can be purchased for Unix, Notes/Domino, Novell servers and other platforms. Two vendors currently offer this: Chilisoftand Halcyonsoft (see www.learnasp.com/hosts for links to them)

3.

Are you one of those unlucky folks who gets cryptic errors or has trouble Installing Asp? Just joinhttp://www.asplists.com/asplists/aspinstall.asp and submit your problem by email. Others will help you!

http://www.learnASP.com/learn/whatisexample.asp by Charles M. Carroll Page 5

Now let us go over the essential mechanisms that are ASP:

A user asks for a page say:http://www.coyoteindustries.com/hi.asp

1.

The Web Server find the file and then processes all the ASP code between <% ... %> before handing back the page.Code between <% ... %> never arrives at the browser.

2.

<html><head><TITLE>hi.asp</TITLE></head><body bgcolor="#FFFFFF">Today is <%=now%> and all is well<br><%if hour(now())>13 THEN%>Good Morning<%ELSE%>Good Day!<%END IF%></body></html>

The webserver file

<<<<<<<

ASP compiler grabs pageInterprets all the <% %> markers

before browser sees page!<html><head><TITLE>hi.asp</TITLE></head><body bgcolor="#FFFFFF">Today is Tue 10:30am and all is well<br>Good Morning</body></html>

Before 12pm the user at the browser receives

<<<<<<<<html><head><TITLE>hi.asp</TITLE></head><body bgcolor="#FFFFFF">Today is Tue 02:00pm and all is well<br>Good Day!</body></html>

After 12pm the user at the browser receives

<<<<<<<

http://www.learnASP.com/learn/docs.asp by Charles M. Carroll Page 6

Page 10: [ebook] Learn ASP

Microsoft DocumentationThere is quite a bit of online documentation that comes with Microsoft Active Server Pages. Our tutorial was written with the expresspurpose of being a friendlier, easier to understand set of lessons than the free documentation Microsoft gives you below:

IIS4 Docs NT4 Option Pak /iishelpASP objects reference /iishelp/iis/htm/asp/intr1orp.htmEx Air /IISSamples/ExAir/default.aspInstallable Components for ASP /iishelp/iis/htm/asp/comp275c.htmJScript Language Reference /iishelp/JScript/htm/JStoc.htmVBScript Language Reference /iishelp/VBScript/htm/VBStoc.htmServer Side Include Reference /iishelp/iis/htm/asp/iissiref.htmASP Quick reference card /iishelp/iis/htm/asp/iiwaref.htmASP Tutorial* click here

IIS3 Docs Roadmap / Official IIS3 Docs /iasdocs/aspdocs/roadmap.aspIIS3 Code Samples /aspsamp/samples/samples.htmAdventureWorks /AdvWorks/default.asp

* ASP Tutorial resides at this ridiculously long URL:/iishelp/iis/htm/asp/iiselect.asp?LessonFile=%2Fiishelp%2Fiis%2Fhtm%2Fasp%2Fiiatmd1%

http://www.learnASP.com/learn/res.asp by Charles M. Carroll Page 7

Response ObjectThe response object is useful, feature rich, and subtle. We are going to focus on it's most fundamental capabilities -- the 20% you willuse 80% of the time. The capabilities we think are vital include:

response.write●

response.write alternate syntax <%= %> which allows ASP simply placed in HTML●

response.end which effectively halts a script in it's tracks.●

response.redirect which transfers control to another page●

Here is a script utilizing response.write to send some information to the browser. It also uses dateadd, a built-in functiondocumented at http://help.activeserverpages.com/iishelp/VBScript/htm/vbs90.htm.1 <html><head>2 <title>response.asp</title>&3 <body color="#FFFFFF">4 <%5 when=now()6 tommorow=dateadd("d",1,when)7 twoweekslater=dateadd("ww",2,when)8 fourteenweekdayslater=dateadd("w",14,when)9 monthlater=dateadd("m",1,when)10 11 sixminuteslater=dateadd("n",6,when)12 sixhourslater=dateadd("h",6,when)13 fortysecslater=dateadd("s",40,when)14 15 response.write "Now <b>" & when & "</b><br>"16 response.write "tommorow <b>" & tommorow & "</b><br>"17 response.write "2 weeks from Now <b>" & twoweekslater & "</b><br>"18 response.write "fourteen working days from Now <b>" & fourteenweekdayslater & "</b><br>"19 response.write "1 month from Now <b>" & monthlater & "</b><br>"

Page 11: [ebook] Learn ASP

20 %>21 six minutes from now <b> <%=sixminuteslater%> </b><br>22 six hours from now <b> <%=sixhourslater%> </b><br>23 fourty seconds later <b> <%=fortysecslater%> </b><br>24 </body></html>

Here is a script utilizing response.end to prematurely end a page:1 <html><head>2 <title>end.asp</title>&3 <body color="#FFFFFF">4 <%5 when=now()6 tommorow=dateadd("d",1,when)7 twoweekslater=dateadd("w",2,when)8 monthlater=dateadd("m",1,when)9 sixminuteslater=dateadd("n",6,when)10 sixhourslater=dateadd("h",6,when)11 12 response.write "Now <b>" & when & "</b><br>"13 response.write "1 month from Now <b>" & monthlater & "</b><br>"14 response.end15 response.write "2 weeks from Now <b>" & twoweekslater & "</b><br>"16 %>17 six minutes from now <b> <%=sixminuteslater%> </b><br>18 six hours from now <b> <%=sixhourslater%> </b><br>19 </body></html>

.

http://www.learnASP.com/learn/res2.asp by Charles M. Carroll Page 8

Response Object Part2 - Buffer ExplanationResponse object error 'ASP 0156 : 80004005'Header Errorwhatever.asp, line #The HTTP headers are already written to the client browser. Any HTTP header modifications must be made before writing pagecontent.

Does this error message plague you?

<%response.buffer=true%>needs to be added as the very first line to any pages made by any HTML document that mixes redirects and content. That line willdo away with all browser complaints that "headers are already sent". Normally a page has a header --or-- text not both.

If the browser writes any text, you can never response.redirect because once the browser writes text it can't change "horses inmidstream" -- it either writes content OR redirects.

<%response.buffer=true%>

which essentially tells the browser don't write anything at all untila) response.end executes thus stopping the page dead in tracks and sending to browserb) response.flush executesc) 100% of the page is executed and it finishes all the ASP and HTML.d) response.redirect is sent, that and no content or text has been sent with response.flush.

The only drawback to: <%response.buffer=true%> is if a page takes a while to compose (i.e. a couple thousand records from adatabase) people see nothing until the page is completely rendered. In that situation to avoid appearing as the page is dead, anoccassionalresponse.flushlets readers see portions of the page being built. We explain why BUFFER=true and flushing is the ideal way to achieve overallspeed @

Page 12: [ebook] Learn ASP

/advice/whybuffer.asp

Here is a non-working page that will display the error:

1 <%response.buffer=false%>2 <html><head>3 <title>dailystuff.asp</title>4 </head>5 <body>6 <%7 whatweekday=Weekday(now())8 select case whatweekday9 case vbSunday10 response.redirect "http://www.cnn.com"11 case vbMonday12 response.redirect "http://www.activeserverpages.com"13 case vbTuesday14 response.redirect "http://www.aspalliance.com"15 case vbWednesday16 response.redirect "http://www.aspconvention.com"17 case vbThursday18 response.redirect "http://www.aspmagazine.com"19 case vbFriday20 response.redirect "http://www.dilbert.com"21 case vbSaturday22 response.redirect "http://www.movielink.com"23 end select24 %>25 </body>26 </html>

Here is the fixed page that will NOT display the error:

1 <%response.buffer=true%>2 <html><head>3 <title>dailystuff.asp</title>4 </head>5 <body>6 <%7 whatweekday=Weekday(now())8 select case whatweekday9 case vbSunday10 response.redirect "http://www.cnn.com"11 case vbMonday12 response.redirect "http://www.activeserverpages.com"13 case vbTuesday14 response.redirect "http://www.aspalliance.com"15 case vbWednesday16 response.redirect "http://www.aspconvention.com"17 case vbThursday18 response.redirect "http://www.aspmagazine.com"19 case vbFriday20 response.redirect "http://www.dilbert.com"21 case vbSaturday22 response.redirect "http://www.movielink.com"23 end select24 %>25 </body>26 </html>

.

http://www.learnASP.com/learn/res3.asp by Charles M. Carroll Page 9

Page 13: [ebook] Learn ASP

Response Object Part3 - Page Redirection CodeThe response object can be used to decide what page to send a user to next. Specifically the response.redirect method will work inthat capacity. We have made a script formjump.asp that takes advantage of this.

1 <html><head>2 <TITLE>FormJump.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <form action="FormJumpRespond.asp" method="get">5 <SELECT NAME="wheretogo">6 <OPTION SELECTED VALUE="fun">Fun</OPTION>7 <OPTION value="news">Daily News</OPTION>8 <OPTION value="docs">ASP IIS3 Roadmap/Docs</OPTION>9 <OPTION value="main">MainPage of ActiveServerPages.com</OPTION>10 <OPTION value="sample">IIS 3 Sample ASP scripts</OPTION>11 </SELECT>12 <input type=submit value="Choose Destination">13 </form>14 </body></html>

The responder that reacts to this form is:

1 <%response.buffer=true%>2 <html><head>3 <title>formjumprespond.asp</title>&4 <body bgcolor="#FFFFFF">5 <%6 ' My ASP program that redirects to URL7 thisURL="http://www.activeserverpages.com"8 where=Request.QueryString("Wheretogo")9 Select Case where10 case "main"11 response.redirect thisURL & "/"12 case "samples"13 response.redirect thisURL & "/aspsamp/samples/samples.htm"14 case "docs"15 response.redirect thisURL & "/iasdocs/aspdocs/roadmap.asp"16 case "news"17 response.redirect "http://www.cnn.com"18 case "fun"19 response.redirect "http://www.dilbert.com"20 End Select21 response.write "All dressed up and I don't know where to go<br>"22 response.write "I recommend --> " & "<br>"23 response.write server.htmlencode(thisURL & "/learn/test/res2.asp?where=fun") & "<br>"24 response.write "for a good laugh!" & "<P>"25 %>26 </body></html>

http://www.learnASP.com/learn/res4.asp by Charles M. Carroll Page 10

Response Object #4 by Charles CarrollThe response object is often used with a variety of syntax variations which we will detail here.

1 <html><head>2 <title>res4.asp</title>3 </head><body bgcolor="#FFFFFF">4 <%5 ' The response object can be used to write text a variety of ways6 ' depending on what style you personally prefer

Page 14: [ebook] Learn ASP

7 8 ' Various permutations of writing to the browser9 response.write "<form>"10 response.write "Hello, Joe<br>"11 12 who="Joe"13 response.write "Hello, " & who & "<br>"14 %>15 16 Hello, <%=who%><br>17 18 Which Book? <input type="TEXT" name="book" value="The Stand"><br>19 20 <%21 response.write "Which Book? <input type=""TEXT"" name=""book"" value=""The Stand""><br>"22 %>23 24 <%25 response.write "Which Book? <input type='TEXT' name='book' value='The Stand'><br>"26 %>27 28 <%29 quote=chr(34)30 response.write "Which Book? <input type=" & quote & "TEXT" & quote & " name=" & quote &"book" & quote & " value=" & quote & "The Stand" & quote & "><br>"31 %>32 33 34 <%bookname="The Stand"%>35 Which Book? <input type="TEXT" name="book" value="<%=bookname%>"><br>36 37 <%38 response.write "Which Book? <input type=""TEXT"" name=""book"" value=""" & bookname &"""><br>"39 %>40 </form>41 </body></html>

http://www.learnASP.com/learn/res5.asp by Charles M. Carroll Page 11

Response Object #5 by Charles CarrollThe response object is often used in conjunction with various kinds of codi9ng schemes. No discussion of response would becomplete without a discussion of how to "handle" or "escape" special characters. This sample script demonstrates commonconversion and transformation commands that make sense to use with the response.write command:

1 <html><head>2 <title>res5.asp</title>3 </head><body bgcolor="#FFFFFF">4 <%5 ' The response object can be used to write text6 ' but sometimes some functions must be used to transform7 ' the text instead of sending as is to the browser8 9 response.write "<B>Hyperion</b> by <I>Dan Simmons</i> is a great novel"10 response.write "<p>"11 response.write server.htmlencode("<B>Hyperion</b> by <I>Dan Simmons</i> is a great novel")12 response.write "<p>"13 14 15 response.write "Joe Smith & Hilda = a team"16 response.write "<p>"

Page 15: [ebook] Learn ASP

17 response.write server.URLencode("Joe Smith & Hilda = a team")18 %>19 20 </body></html>

http://www.learnASP.com/learn/inc.asp by Charles M. Carroll Page 12

Include FilesThe include option is the heart of making efficient ASP files and re-usable chunks. It basically has two forms and now we will presentthe forms and their differences:

<!--#include virtual="/whatever.asp"-->would include any file on your site (in this example, whatever.asp is in the web server's root directory) but you must fully qualify thefilename with a path.

<!--#include file="whatever.asp"-->can include the whatever.asp file in the directory of the script that contains the statement. It ASSUMES the current directory!

Example #1<!--#include virtual="/sally/filename.asp"-->could include a file from sally's directory, even if the page with this statement is (for example) in the /fred/finance folder.

Example #2:<!--#include file="/sally/filename.asp"-->will fail from fred's directory.

Example #3:<!--#include file="../sally/filename.asp"-->will succed from fred's directory but if the script that contains it is moved to a different level in the tree structure it will fail to locate thefile. INCLUDE VIRTUAL is better if a script may be moved and is immune to relative path issues.

IMPORTANT: Include files are always processed and inserted before ASP scripts on the page are calculated. Thus apage with many IFs and SELECT CASEs that selectively include files in fact always include the file before the scriptbegins executing.

http://www.learnASP.com/learn/includedynamic.asp by Charles M. Carroll Page 13

Include Files Dynamically by Charles CarrollThe include files are gathered and processed BEFORE any ASP code. Soif your code looks like this:

<%SELECT CASE CASE 1 %> <!--#include virtual="whatever1.asp"--> CASE 2 %> <!--#include virtual="whatever2.asp"--> CASE 3 %> <!--#include virtual="whatever3.asp"--><%END SELECT%>

Three includes are performed before any ASP code is executed.

YOU CANNOT DO:

Page 16: [ebook] Learn ASP

<% whichfile="1"%> <!--#include virtual="whatever<%=whichfil%>.asp"-->

Though this is a reasonable idea.

<!--#include virtual="whatever.asp"-->The alternative is:

1 <html><head>2 <TITLE>includedynamic.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <%5 whichfile="bookscifi.asp"6 Call ReadDisplayFile(whichfile)7 response.write "<hr>"8 9 whichfile="bookhorror.asp"10 Call ReadDisplayFile(whichfile)11 response.write "<hr>"12 13 14 whichfile="/learn/test/bookmarketing.asp"15 Call ReadDisplayFile(whichfile)16 response.write "<hr>"17 %>18 19 </body></html>20 <%21 SUB ReadDisplayFile(FileToRead)22 whichfile=server.mappath(FileToRead)23 Set fs = CreateObject("Scripting.FileSystemObject")24 Set thisfile = fs.OpenTextFile(whichfile, 1, False)25 tempSTR=thisfile.readall26 response.write tempSTR27 thisfile.Close28 set thisfile=nothing29 set fs=nothing30 END SUB31 %>

The only downside to this method is no ASP Code ( i.e. anything in <% %> ) will be parsed or executed in the included file.

http://www.learnASP.com/learn/booksample.asp by Charles M. Carroll Page 14

Book Sample by Charles CarrollThe Recommend Book Sample Files provides you with several files that when created, prepare you for applying several unrelatedbut powerful content management tools in the following pages. The features detailed will include:

Include files that implement pages headers, footers●

sessions and application variables to track users accessing these pages●

the content linker component●

all come together in this example.

Here is the code for bookheader.asp:

1 Recommended Books for <%=session("fname")%> &nbsp; <%=session("lname")%><br><hr>

Here is the code for bookfooter.asp:

1 <hr><br>

Page 17: [ebook] Learn ASP

2 Recommended Books has <%=application("howmany")%> people reading it now!

Here is the code for bookfuture.asp:

1 <html><head>2 <title>bookfuture.asp</title>&3 <!--#include file="bookheader.asp"-->4 <body>5 <h1>Future Books</h1>6 <ul>7 <li><b><i>Visions</b></i><br>Michio Kaku</li>8 <li><b><i>Future Magic</b></i><br>Robert Forward</li>9 </ul>10 <!--#include file="bookfooter.asp"-->11 </body></html>

Here is the code for bookhorror.asp:

1 <html><head>2 <title>bookhorror.asp</title>&3 <!--#include file="bookheader.asp"-->4 <body>5 <h1>Horror Books</h1>6 <ul>7 <li><b><i>Carrion Comfort</b></i><br>Dan Simmons</li>8 <li><b><i>The Stand</b></i><br>Steven King</li>9 <li><b><i>Children of Darkness</b></i><br>Dan Simmons</li>10 <li><b><i>Thinner</b></i><br>Steven King</li>11 <li><b>Fires of Eden<i></b></i><br>Dan Simmons</li>12 </ul>13 <!--#include file="bookfooter.asp"-->14 </body></html>

Here is the code for bookmarketing.asp:

1 <html><head>2 <title>bookMarketing.asp</title>&3 <!--#include file="bookheader.asp"-->4 <body>5 <h1>Marketing Books</h1>6 <ul>7 <li><b><i>22 Immutable Laws of Branding</b></i><br>Reiss and Reiss</li>8 <li><b><i>22 Immutable Laws of Marketing</b></i><br>Reiss and Trout</li>9 <li><b><i>Marketing Warfare</b></i><br>Reiss and Trout</li>10 <li><b><i>Horse Sense</b></i><br>Reiss and Trout</li>11 <li><b><i>Words That Sell</b></i><br>by ??</li>12 </ul>13 <!--#include file="bookfooter.asp"-->14 </body></html>

Here is the code for booknovels.asp:

1 <html><head>2 <title>booknovels.asp</title>&3 <!--#include file="bookheader.asp"-->4 <body>5 <h1>Recommended Novels</h1>6 <ul>7 <li><b><i>A Prayer for Owen Meaney</b></i><br>John Irving</li>8 <li><b><i>Cider House Rules</b></i><br>John Irving</li>9 <li><b><i>Heart of the Country</b></i><br>Greg Mathhews</li>10 <li><b><i>All That Remains</b></i><br>Patricia Cornwell</li>11 <li><b><i>Presumed Innocent</b></i><br>Scott Turrow</li>12 <li><b><i>Time to Kill</b></i><br>John Grisham</li>13 <li><b><i>Disclosure</b></i><br>Michael Chrichton</li>14 <li><b><i>Mount Dragon</b></i><br>Lincoln and Childs</li>15 </ul>16 <!--#include file="bookfooter.asp"-->

Page 18: [ebook] Learn ASP

17 </body></html>

Here is the code for bookscifi.asp:

1 <html><head>2 <title>bookscifi.asp</title>&3 <!--#include file="bookheader.asp"-->4 <body>5 <h1>Science Fiction Recommended Books</h1>6 <ul>7 <li><b><i>Ender's Game</b></i><br>Orson Scott Card</li>8 <li><b><i>Hyperion</b></i><br>Dan Simmons</li>9 <li><b><i>Childhood's End</b></i><br>Arthur Clarke</li>10 <li><b><i>TommyKnockers</b></i><br>Steven King</li>11 </ul>12 <!--#include file="bookfooter.asp"-->13 </body></html>

Here is the code for bookselfhelp.asp:

1 <html><head>2 <title>bookselfhelp.asp</title>&3 <!--#include file="bookheader.asp"-->4 <body>5 <h1>Self Help Books</h1>6 <ul>7 <li><b><i>Road Less Travelled</b></i><br>Scott Peck</li>8 <li><b><i>The Seven Habits of Highly Effective People</b></i><br>Steven Covey</li>9 <li><b><i>First Things First</b></i><br>Steven Covey</li>10 </ul>11 <!--#include file="bookfooter.asp"-->12 </body></html>

http://www.learnASP.com/learn/formatnumbers.asp by Charles M. Carroll Page 15

Format Numbers - ReferenceFrequently you want a number to appear in a certain format. The most commands requests are for a set total number of digits and aset number of digits to the right of the decimal place. Less frequently there is a call for negative amounts displayed in parenthesis orthat there should be leading zeros.

The FormatNumber function takes the contents of a number type variable and returns the contents in the specified format.

Syntax: FormatNumber(expression, iDigits, bleadingDigit, bParen, bGroupDigits)

argument meaningexpression the variable holding the raw numberiDigits number of digits to right of decimal point

bleadingDigit 1 for leading zeros0 for no leading zeros

bParen 1 for parenthesis around negative numbers0 for no parenthesis around negative numbers

bGroupDigits 1 to display numbers as per regional settings in the Control Panel0 to over-ride settings in the Control Panel

http://www.learnASP.com/learn/formatnumbers2.asp by Charles M. Carroll Page 16

Page 19: [ebook] Learn ASP

Format Numbers Part2 (by Charles Carroll)The easiest way to demonstrate format numbers is just have some sample code that tries evry permutation of the command.

1 <html><head>2 <TITLE>formatnumbers2.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <%5 ' My ASP formatting number sample6 mynumber=123.45677 response.write "<hr>" & mynumber & "<br>"8 response.write "formatnumber(mynumber,0)" & "<br>"9 response.write formatnumber(mynumber,0) & "<hr>"10 response.write "formatnumber(mynumber,2)" & "<br>"11 response.write formatnumber(mynumber,2) & "<hr>"12 response.write "formatnumber(mynumber,6)" & "<br>"13 response.write formatnumber(mynumber,6) & "<hr>"14 15 mynumber=.456716 response.write mynumber & "<br>"17 '0 means means no leading zeroes18 response.write "formatnumber(mynumber,2,0)" & "<br>"19 response.write formatnumber(mynumber,2,0) & "<hr>"20 '1 means means pad with leading zeroes21 'response.write "formatnumber(mynumber,2,1)" & "<br>"22 'response.write formatnumber(mynumber,2,1) & "<hr>"23 24 'mynumber=-123.456725 'response.write mynumber & "<br>"26 '0 means means no parentheses for negative numbers27 'response.write "formatnumber(mynumber,2,0,0)" & "<br>"28 'response.write formatnumber(mynumber,2,0,0) & "<hr>"29 '1 means means yes parentheses for negative numbers30 'response.write "formatnumber(mynumber,2,0,1)" & "<br>"31 'response.write formatnumber(mynumber,2,0,1) & "<hr>"32 %>33 </body></html>

http://www.learnASP.com/learn/formatdates.asp by Charles M. Carroll Page 17

Format Dates (by Charles Carroll)The easiest way to demonstrate formatting dates is just have some sample code that tries evry permutation of the command.

1 <html><head>2 <title>formatdates.asp</title>3 </head><body bgcolor="#FFFFFF"><html>4 <%'My ASP program that formats dates5 response.write "<hr>"6 for counter=0 to 47 currentdate=now()8 response.write "today is..." & "<br>"9 response.write currentdate & "<P>"10 select case counter11 case 012 whichformat="vbgeneraldate"13 case 114 whichformat="vblongdate"15 case 216 whichformat="vbshortdate"17 case 3

Page 20: [ebook] Learn ASP

18 whichformat="vblongtime"19 case 420 whichformat="vbshorttime"21 end select22 response.write "FormatDate(now()," & whichformat & ")="23 response.write Formatdatetime(currentdate,counter) & "<P><HR>"24 next%>25 </body></html>

http://www.learnASP.com/learn/datetime.asp by Charles M. Carroll Page 18

Adding the date and time to your ASP pagesBy Tony Arguelles [email protected]

Summary

Including the date and/or time on a web page can be a subtle yet valuable addition when designing a web site. The addition of thedate to the home page can create the impression that a site is constantly being updated with new content since each time a visitorloads the page, the current date will be displayed.

In this tutorial I'll teach you how to add the date and time to your ASP pages using the VBScript FormatDateTime() function. I'llexplain how the function works, teach you how to integrate it into your ASP pages and illustrate the output you'll get depending onthe arguments you pass. I'll round out the tutorial of the FormatDateTime() function by covering a few limitations that it has, whichmight or might not be a big deal depending on your specific needs.

Just FYI, this article assumes you know basic HTML and how to add ASP scripts to your web pages.

The FormatDateTime() Function

Microsoft provides a ton of predefined VBScript functions designed to reduce coding time. The FormatDateTime() function is one ofthose powerful functions and is really easy to use, too. This function uses the following format:

FormatDateTime(date, format)

There are two arguments the function accepts: date and format. Table 1-1 below describes these arguments in greater detail:

Table 1-1: The FormatDateTime() function and its arguments

Argument Argument Descriptiondate This argument is required and can be any valid date expression

such as Date or Now

format This format constant or format value specifies how the dateand/or time will be displayed on your ASP page.

When specifying the format argument, you can either type theVisual Basic constant name (name in left column), or theconstant's corresponding value (0 - 4, from the middle column).They do the same thing, it's just less typing if you use the value.

Constant Format Value Format Description

Page 21: [ebook] Learn ASP

vbGeneralDate 0 This is the default. Notspecifying a value orspecifying 0 will produce adate in the format ofmm/dd/yy.

If the date expression is Now,it will also return the time,after the date, in hh:mm:ssPM/AM format.

vbLongDate 1 This is my personal favorite:-) Passing this value willproduce a date in the formatofweekday, month day, year*

* The year is Y2K compliant:-).

vbShortDate 2 Passing this value returns adate formatted just like thedefault of 0 (mm/dd/yy).

vbLongTime 3 Passing this value returns thetime in hh:mm:ss PM/AMformat.

vbShortTime 4 Passing this value returnsmilitary time in this formathh:mm

Table 1-1 is a good reference once you've got a feel for how the FormatDateTime() function works or if you're an experiencedprogrammer. For those of you that aren't clear on how all the information in table 1-1 relates to "real world" implementations, let'stake a look at some examples:

Returning the Current Date

If you would like to display the current date, here are a few different ways to do it along with the results they produce:

<%= FormatDateTime(Date) %> returns: 1/25/00(You would get the same result by coding this: <%= FormatDateTime(Date, 0) %>)

<%= FormatDateTime(Date, 1) %> returns: Tuesday, January 25, 2000

<%= FormatDateTime(Date, 2)%> returns: 1/25/00

Returning the Current Time

If you would like to return the current time, here are a couple of ways to do that:

<%= FormatDateTime(Now, 3)%> returns: 9:55:29 PM

<%= FormatDateTime(Now, 4)%> returns: 21:55

Returning the Current Date and Time

If you would like to return the current date and time together, here's how to do just that:

<%= FormatDateTime(Now) %> returns: 1/25/00 9:55:29 PM

If you're like me, you probably don't like the way the date and time displays above; it's not very cool looking, is it? In cases like this,you can actually include two FormatDateTime() functions next to each other, in order to get the date and time in a more desriptiveformat, like this:

<%= FormatDateTime(Date, 1) %>&nbsp;&nbsp;<%= FormatDateTime(Now, 3)%> returns:

Page 22: [ebook] Learn ASP

Tuesday, January 25, 2000 9:55:29 PM

Adding the code to your page

Integrating the code into your ASP pages is really easy; here is how the code would look on a page with basic HTML to display thedate:

<html><head><title>Here's the date</title></head>

<body>

Thank you for coming to this page. The current date is: <%= FormatDateTime(Date, 1) %>

</body>

</html>

Limitations of the FormatDateTime() function

The FormatDateTime() function is an extremely handy bit of code that can help you add a touch of flair almost instantly. I would liketo mention four limitations that stick out in my mind, which may be an issue to you (or your clients) depending on the project at hand:

Limitation 1: The unneeded zero

On the first through ninth days of a month the day shows up in the format of "Month 01, Year". I know it seems like a small thing buttrust me, it's can be a big deal to some.

Limitation 2: Only basic formatting allowed

You are limited to basic formatting of the string that's returned by the FormatDateTime() function. Since the date and/or time functionreturns is a single string, you can bold, italicize and change the whole date/time by adding HTML or style sheet tags around it, butyou can't change the display properties for a single part (e.g., the month).

With the FormatDateTime() function, you can do this:

<b><%= FormatDateTime(Date, 1) %></b> which would return this: Tuesday, January 25, 2000

But you can't do this:

Wednesday, January 1, 1999

If limitations 1 or 2 are a major hang up for you, you'll need to use different ASP/VBScript techniques to add the date to your page. I'llcover those in my next article!

Limitation 3: The time isn't necessarily "their" time.

Limitation 3 is more of a by-product than a limitation, but I figured I would keep the naming conventions the same for this section. Ifyou use the the FormatDateTime() function (or any other date related function) on the server side, the date/time returned will bewhatever the server's date and time is, not your client's time from their system.

If you want to ensure that the date and/or time a visitor sees on your page is the date in their part of the coutry or world, thenconsider using client side VBScript as an Internet Explorer only solution, or switch to client side JavaScript for a universal browsersolution.

Limitation 4: It's static.

Think of the displayed date or time as a "snap shot" of when the page was requested by the visitor. You cant use this function todisplay a "clock" that updates every second, or automatically update the date on the page when one day turns to the next.

If you wanted to display a dynamic clock on your page, you would need to use client side JavaScript, or VBScript (IE only) to handlethat task.

I hope you've enjoyed this article on the FormatDateTime() function. I'll be back soon with more date and time related ASP fun! If youhave any questions or comments, send me an Email at: [email protected]

Page 23: [ebook] Learn ASP

http://www.learnASP.com/learn/DoLoop.asp by Charles M. Carroll Page 19

Do Loop Part #1 by Charles CarrollTo execute a code sequence more than once ASP provides:

DO, LOOP●

WHILE, WEND●

Either of these statements can be followed by UNTIL or WHILE.

DO UNTIL .....code to be repeated...LOOP

DO .....code to be repeated...LOOP UNTIL

http://www.learnASP.com/learn/DoLoop2.asp by Charles M. Carroll Page 20

Do Loop and Timeouts by Charles CarrollA loop that is infinite will not run forever. IIS will timeout the script (default is 90 seconds).

Here is an infinite loop that IIS will timeout:1 <%response.buffer=true%>2 <TITLE>doloop1.asp</TITLE>3 <body bgcolor="#FFFFFF">4 <HTML>5 <%6 DO7 counter=counter+18 response.write counter & "<br>"9 response.flush10 LOOP11 %>12 </BODY>13 </HTML>14

Here is an infinite loop that we explicitly set a timeout for:1 <%2 response.buffer=true3 server.scripttimeout=204 %>5 <TITLE>loop2.asp</TITLE>6 <body bgcolor="#FFFFFF">7 <HTML>8 <%9 DO10 counter=counter+111 response.write counter & "<br>"12 response.flush13 LOOP14 %>15 </BODY>

Page 24: [ebook] Learn ASP

16 </HTML>17 18

It has been assumed that a timed out script was impossible to intercept, but the next lesson shows how to use the transactionalaspect of an ASP script to capture this elusive condition.

http://www.learnASP.com/learn/DoLoop3.asp by Charles M. Carroll Page 21

Do Loop Intercept Timeouts by Charles CarrollThe transactional nature of ASP pages can be used to intercept a script timeout.loop3.asp traps a timeout:1 <%@ TRANSACTION=Required%>2 <%3 response.buffer=true4 server.scripttimeout=205 %>6 <HTML>7 <TITLE>loop3.asp</TITLE>8 <body bgcolor="#FFFFFF">9 </BODY>10 <%11 DO12 counter=counter+113 response.write counter & "<br>"14 LOOP15 response.flush16 response.write "Script executed without incident"17 %>18 </HTML>19 <%20 Sub OnTransactionAbort()21 response.clear22 Response.Write "The Script Timed Out"23 end sub24 %>

loop4.asp succeeds and does not trigger the trap:1 <%@ TRANSACTION=Required%>2 <%3 response.buffer=true4 server.scripttimeout=405 %>6 <HTML>7 <TITLE>loop4.asp</TITLE>8 <body bgcolor="#FFFFFF">9 </BODY>10 <%11 DO UNTIL counter=40012 counter=counter+113 response.write counter & "<br>"14 LOOP15 response.flush16 response.write "Script Exexuted without incident!"17 %>18 </HTML>19 <%20 Sub OnTransactionAbort()21 response.clear22 Response.Write "The Script Timed Out"

Page 25: [ebook] Learn ASP

23 end sub24 %>

http://www.learnASP.com/learn/server.asp by Charles M. Carroll Page 22

Server Variables by Charles CarrollAvailable Server Variables are the result of a combination of the browser software and the server software. They are not alwaysexactly the same on your server and with specific browsers as we document here. Server Variables are retrieved withrequest.servervariables("variablename"), for example:sn=request.servervariables("script_name") name of script, i.e./learn/server.asp in this caseref=request.servervariables("http_referer") name of site page (unless they just typed the URL)

they clicked on to get here.br=request.servervariables("http_user_agent") Identification string emitted by browser.lan=request.servervariables("http_accept_language") en for english. Basically indicates language the

browser is targetted to.user=request.servervariables("logon_user") IE passes back NT logon in this variable!

This script below demonstrates accessing a couple of these variables:1 <html><head>2 <title>server.asp</title>&3 <body>4 <%5 sn=request.servervariables("script_name")6 response.write "Script Name=" & sn & "<br>"7 8 ref=request.servervariables("http_referer")9 response.write "Page thats links to this=" & ref & "<br>"10 11 ua=request.servervariables("http_user_agent")12 response.write "Browser String=" & ua & "<br>"13 14 lan=request.servervariables("http_accept_language")15 response.write "Browser Language=" & lan & "<br>"16 17 user=request.servervariables("logon_user")18 response.write "NT Logon Name=" & user & "<br>"19 %>20 </body></html>

http://www.learnASP.com/learn/server2.asp by Charles M. Carroll Page 23

Server Variables #2 by Charles CarrollServer Variables have many uses. We will show you a popular one here. Web sites are typically attached to an IP address, butsometimes several domain names may point to the same IP. A clever ASP script could display the same page different waysdepending on which domain name was typed utilizing the HTTP_HOST. Our site, for example has three domain names tied to thesame IP ( activeserverpages.com, asptraining.com, learnasp.com, help.activeserverpages.com ) and the following script will providedifferent results depending on what domain name it is called from:1 <html><head>2 <title>server2.asp</title>&3 <body>4 <%5 host=lcase(request.servervariables("HTTP_HOST"))6 SELECT CASE host

Page 26: [ebook] Learn ASP

7 CASE "www.asptraining.com"8 response.write "Welcome Training Customer!"9 CASE "www.activeserverpages.com"10 response.write "Welcome To Our Reference Site!"11 CASE "www.learnasp.com"12 response.write "Welcome To Our Tutorial!"13 CASE "www.aspeuro.com"14 response.write "Welcome To Our European Site!"15 CASE "www.asplists.com","www.asplist.com"16 response.write "Welcome To Our ASP listservers!"17 CASE "www.aspconventions.com","www.aspconvention.com"18 response.write "Welcome To Our ASP convention site!"19 CASE ELSE20 response.write "Welcome!"21 END SELECT22 %>23 </body></html>

http://www.learnASP.com/learn/serverall.asp by Charles M. Carroll Page 24

Listing All Server Variables by Charles CarrollThe available Server Variables vary based on the result of a combination of the browser software and the server software. They arenot always exactly the same on your server and with specific browsers as we document here. There is an easy way to obtain a list. Ifthe script is executed on a given browser, the Server Variables displayed will reflect that browser plus your server.

1 <%2 for each thing in request.servervariables3 tempvalue=request.servervariables(thing)4 response.write thing & "=" & tempvalue & "<br>"5 next6 %>

Since the above script appears in dozens of books and websites, we wanted to provide you with a better version. This script mayprove useful as it will

list all the available server variables●

skipping the variables ALL_HTTP and ALL-RAW since they are just a "glob" of all the other vars●

place blank variables at the end●

display code to retrieve that variable so you can cut and paste into script●

1 <html><head>2 <TITLE>serverall.asp</TITLE>&3 <body bgcolor="#FFFFFF">4 <%5 Response.Write("<P><B>Server Variables</b><br>")6 BlankVars="<P><B>Blank Server Variables</b><br>" & vbcrlf7 quote=chr(34)8 For Each Key in Request.ServerVariables9 If instr(Key,"_ALL")+instr(key,"ALL_")=0 then10 tempvalue=trim(request.servervariables(Key))11 If len(tempvalue)=0 then12 BlankVars=BlankVars & Key & ", "13 Else14 response.write "request.servervariables(" & quote15 response.write Key & quote & ") "16 response.write " =<br><B>" & tempvalue & "</b><p>" & vbcrlf17 End If18 end if19 Next20 response.write mid(BlankVars,1,len(BlankVars)-2)21 %>

Page 27: [ebook] Learn ASP

22 </body></html>

If the server has been secured with https:// then the following script will display some additional variables:https://secure.activeserverpages.com/learn/test/serverall.asp

http://www.learnASP.com/learn/randomadvice.asp by Charles M. Carroll Page 25

Random Advice / Rotating Information by Charles CarrollThis page demonstrates how to use several commands together to serve varying content based on a random number:

RND function●

INT function●

SELECT CASE●

The script randomadvice.asp shows different advice every time the pge is refreshed:

1 <html><head>2 <TITLE>randomadvice.asp</TITLE>3 </head>4 <body bgcolor="#FFFFFF">5 <%6 ' generate a random number 1-67 randomize8 randomnum=int(rnd*6)+19 SELECT CASE randomnum10 CASE 1,2,3%>11 Plant your crops early this year<br>12 No frost expected<br>13 <%CASE 4%>14 Never play cards<br>with a man named after a city<br>15 <%CASE 5%>16 You can never be too rich, too thin or backup too often<br>17 <%CASE 6%>18 A swallow keeps away the stork<br>19 <%END SELECT%>20 </body></html>

http://www.learnASP.com/learn/browserdetect.asp by Charles M. Carroll Page 26

Browscap: Basics (bc.asp) - Page 27 Browscap: Intricate Details (bcdetails.asp) - Page 28 BrowserHawk: Determing Browser Type (bhbrowtype.asp) - Page 29 BrowserHawk: older AOL browsers (bhaol.asp) - Page 30 Browserhawk: MS-Wallet (bhwallet.asp) - Page 31 BrowserHawk - Reverse DNS lookups (bhresolveip.asp) - Page 32 BrowserHawk - Frame support (bhframes.asp) - Page 33

Page 28: [ebook] Learn ASP

http://www.learnASP.com/learn/bc.asp by Charles M. Carroll Page 27

Browser CapabilitesThe script below demonstrates the most commonly used property of the Browser Capabilites component.

1 <html><head>2 <TITLE>bc.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <% Set bc = Server.CreateObject("MSWC.BrowserType") %>5 Browser Name: <%=bc.browser %><p>6 Browser Version: <%=bc.version%><p>7 <% if (bc.frames = TRUE) then %>8 I noticed you do frames<p>9 <% else %>10 I noticed you are frame challenged<p>11 <% end if %>12 <% if (bc.tables = TRUE) then %>13 I noticed you do tables<p>14 <% else %>15 I noticed you can't do tables<p>16 <% end if %>17 <% if (bc.BackgroundSounds = TRUE)then %>18 I noticed you allow me to play music<p>19 <% else %>20 I noticed you aren't a music listener<p>21 <% end if %>22 23 <% if (bc.vbscript = TRUE) then %>24 I noticed you are VBscript capable<p>25 <% else %>26 I noticed you can't understand VB Script<p>27 <% end if %>28 29 <% if (bc.javascript = TRUE) then %>30 I noticed you understand JScript<p>31 <% else %>32 I noticed you don't understand JScript<p>33 <%34 end if35 set bc=nothing36 %>37 </body></html>

http://www.learnASP.com/learn/bcdetails.asp by Charles M. Carroll Page 28

Browser Capability Details (by Charles Carroll)Any ASP script attempting to detect a browser needs to realize the following:

Currently any new version of a browser is reported as unknown, unless you get an updated browscap.ini file. Even a minorrelease of a browser may be reported as unknown. The technology this DLL uses cannot "guess" that a new browser withslightly different characteristics is just like the previous one.

There are two ways to get a known, reliable browscap.ini. which are explained below.●

Page 29: [ebook] Learn ASP

Cyscape offer a downloadable latest, greatest BROWSCAP.INI and even offers e-mail subscriptions so you get the latest one sentto you. Visit http://www.cyscape.com/browscap to pick it up and/or subscribe. You can test in advance whether your browser isrecognized by this file at http://www.cyscape.com/browtest.asp.

The latest, greatest BROWSCAP.ZIP from Juan Llibre is available at http://www.asptracker.com.Juan Libre's Detect Your Screen Res articles is another sample making use of BROWSCAP.INI.

These two sources give you the means to correctly identify the latest browser.

The BrowserHawk Component at http://www.cyscape.com/browserhawk offers accuracy far better than what anybrowscap file can provide. It also provides information on more than twice as many properties, including FileUpload, MouseOver,SSL, DHTML, StyleSheets, Authenticode, OSDetails, Language, and many more! It will even download and install updated browserdefinition files for you automatically! Evaluation download available at:http://www.cyscape.com/browserhawk/download.asp

http://www.learnASP.com/learn/bhbrowtype.asp by Charles M. Carroll Page 29

How to Determine the Browser Type and VersionOften you will want to send content to the client only if you know their browser can support it. You may alreadyhave created pages that are designed to work only in IE and Netscape, version 4 or greater. Or for example youmay have situations where a specific browser type and or version creates a page layout problem. In this lessonwe present the technique used to detect specific browsers that you want to handle things differently for.

For starters, assume you receive complaints that your favorite shade of blue used for some font text on your pageis extremely difficult to read when viewed on WebTV (colors are typically an issue with WebTV due to contrastand other problems). What are you do to - remove the blue color all together? Change it for a boring share ofgrey? Of course not!

The trick here is first finding a alternative color suitable for viewing on WebTV, and only using that color when thevisitor is using a WebTV browser. Otherwise you use your blue font as originally planned. Here's how you wouldimplement that:1 <%2 set bh = server.createobject("cyScape.browserObj")3 if (bh.browser = "WebTV") then4 fontColor = "003366" 'a suitable alternate color for WebTV folks only5 else6 fontColor = "000066" 'your favorite shade of blue for all folks7 end if8 %>9 <html>10 11 <head>12 <title></title>13 </head>14 15 <body>16 17 <p>Welcome to my page. The <font color="<%=fontColor%>important" text</font>is highlighted18 for your convenience. </p>19 </font>20 </body>21 </html>

Page 30: [ebook] Learn ASP

This technique of testing for a specific browser type is also useful if you have specific tags and scripts that onlywork with certain browsers. For example, say you had certain pages that required Netscape or IE versions 4 orhigher. Instead of going through and conditionally including all the v4-only tags, scripts and objects, this examplewill show how to use this technique to detect when a browser is not Netscape or IE v4 or higher, and redirect theuser to an alternate page suitable for the other browsers.1 <%2 set bh = server.createobject("cyScape.browserObj")3 if (bh.majorver >=4 ) and (bh.Browser ="IE" or bh.Browser ="Netscape") then4 else5 response.redirect("PageForNonIEorNNv4.asp")6 end if7 set bh = nothing8 %>9 <html><body> </body></html>10

Remember that the response.redirect code should go before any of the HTML content on the page. You can keepthis check script in a separate file, and include it at the top of all pages within an application.

Another example is the title attribute for HTML elements which, currently, is only supported by IE 4 or greater.While the title attribute degrades fine in other browsers, it is sometimes desirable to limit the amount ofsuperfluous code being sent to the browser... regardless of how insignificant it may seem. This example will showyou a quick and easy way to let BrowserHawk decide for you whether or not to use that title attribute.

Here is an example of the title attribute. Since you are using IE4 or greater, if you hold your mouse over thefollowing link for a few seconds, you will see a tooltip, similar to the kind you see when you hold your mouse overa button on an application's toolbar. This allows you to include a lot more information in a small space, such as anavigation frame or a slim table cell.

Hover here

Using two methods of BrowserHawk, we can quickly and easily check if the visitor is using a browser whichsupports the title element (namely, that it is Internet Explorer AND that it is version 4 or greater). Here is what thecode looks like:1 <%2 set bh = server.createobject("cyScape.browserObj")3 if bh.version>=4 and bh.browser="IE" then4 %>5 <a href='x.asp' title=' This is the alternate text. '>6 <% else %>7 </a>8 <a href='x.asp'>9 <%10 end if11 set bh = nothing12 %>13 <p>14 Hover here</a>15

This logic could be used for any feature that you know is only supported by certain browser versions. Sometimesit is worth it to prevent the waste of bandwidth caused by adding elements and features to a page when they can'tbe viewed anyway. But more likely then not, you'll use this approach to avoid inconsistencies with layout andscripting across browsers.

Need a copy of BrowserHawk? See our section on Getting Started.Copyright (c) 1999 cyScape, Inc. All rights reserved. This material may not be published, distributed, or reprinted without written consent from cyScape.

Page 31: [ebook] Learn ASP

http://www.learnASP.com/learn/bhaol.asp by Charles M. Carroll Page 30

Detecting older AOL browsersMany people ask about how to detect older versions of AOL browsers, particularly AOL version 3.0 and earlier. This isbecause they find that certain form submissions may not work properly, or specific functionality, such as Macromedia Flash,will not work properly for their audience.

Regardless of the reason, should you find it necessary to detect older versions of AOL browsers, you can easily use thefollowing script to do so. Note also that you can easily modify this script to detect other browser types and versions as well. This example is based on the same concept presented in the previous lesson for detecting a browser type and version, but istargeted here specifically to AOL browsers.

1 <%2 set bh = Server.CreateObject("cyScape.browserObj")3 if bh.browser = "AOL" and bh.majorver <= 3 then4 response.redirect "noaol3.asp"5 end if6 %>7 <html>8 9 <head>10 <title>AOL check script</title>11 </head>12 13 <body>14 15 <p>You are not using AOL v3 or lower</p>16 </body>17 </html>

Need a copy of BrowserHawk? See our section on Getting Started.Copyright (c) 1999 cyScape, Inc. All rights reserved. This material may not be published, distributed, or reprinted without written consent from cyScape.

http://www.learnASP.com/learn/bhwallet.asp by Charles M. Carroll Page 31

Detecting if the MS Wallet is supportedMany developers are chosing to use the Microsoft Wallet for securely taking customer credit card / payment information fortheir e-commerce site. The MS Wallet is implemented as a client-side ActiveX control. This means that in order for yourcustomers to purchase using the MS Wallet, their browser needs to support ActiveX controls.

Unfortunately not all browsers have this ability, including several popular browsers such those from Netscape and Opera (noteven in the latest versions). Therefore if you are implementing the MS Wallet in your site, you'll want to make sure toprovide an alternative form of secure payment for those visitors without support for this component.

Microsoft provides useful scripts for implementing the Wallet in your ASP code. Unfortunately their scripts rely on the MSbrowser capability component, which frequently misidentifies browsers and ActiveX support in particular. Therefore relyingon the MS component for this information will result in situations where you send the Wallet to those who can not handle it,and several cases where you do not send it to users when you should have..

To work around this problem, simply search through the MS scripts related to the Wallet and change all occurances of theclass string "MSWC.BrowserType" in the CreateObject statements in the scripts to "cyScape.browserObj". This will ensure

Page 32: [ebook] Learn ASP

that you accurately identify which users can support the Wallet and provide alternatives for those who can not.

For simple demonstration purposes, the following code snippet is provided. For real-world uses of this technique start withthe scripts available for MS Wallet and change the class string as instructed above.

1 <html>2 3 <head>4 <title>Purchase</title>5 </head>6 7 <body>8 9 <p>Payment info:<br>10 <%11 set bh = Server.CreateObject("cyScape.browserObj")12 if bh.ActiveXControls then13 response.write "... send MS Wallet control"14 else15 response.write "... send alternative code for collecting payment info"16 end if17 %></p>18 19 <p>%&gt;</p>20 </body>21 </html>

Need a copy of BrowserHawk? See our section on Getting Started.Copyright (c) 1999 cyScape, Inc. All rights reserved. This material may not be published, distributed, or reprinted without written consent from cyScape.

http://www.learnASP.com/learn/bhresolveip.asp by Charles M. Carroll Page 32

How to resolve IP address to host namesHave you ever looked at an IP address and wondered where the user came from? Take 198.137.240.91 for example. Certainly "www.whitehouse.gov" has quite a lot more meaning.

At one time or another you'll likely find yourself wanting to resolve IP addresses to host names. This is known in the biz as"reverse DNS lookups". So why would someone want to resolve an IP address? Well there are several possible uses for thisinformation, but for this example we'll talk about using this information to help reduce fraud on your web site.

For example, consider for a moment the issue of credit card fraud. Certainly providing fraudulent credit card information (orusing someone elses card) over the Internet seems much easier than doing the same in person. This is because it seems easyto hide behind the anonymous nature of an HTTP connection. What the user may not realize, however, is that based on theirIP address you can likely determine who their their employer or ISP is - and can use that information to track down someoneproviding fradulent credit card information or abusing your site in other ways.

The host name, therefore, can serve as a decent deterrent by showing the host name to the visitor. This way they realize it ispossibly that their identify could be determined based on this information. For example, showing someone with dishonestintentions that you know they are connected through "pop5.erols.net" may make them think twice before entering fraudulentcredit card information. Afterall, it may not prove all that difficult for the authorities to obtain records from their ISP todetermine their identity.

As was mentioned earlier, there are several possible uses for this information. Whatever your reasons may be, BrowserHawkmakes it easy to to obtain the host name for the current visitor or for any other IP address you'd like to look up.

To determine the host name for the current site visitor, simply call the BrowserHawk ResolveIP method as demonstrated in

Page 33: [ebook] Learn ASP

the example below:

1 <html>2 3 <head>4 <title>Resolve IP</title>5 </head>6 7 <body>8 9 <p>Hello user connected from <%10 set bh = Server.CreateObject("cyScape.browserObj")11 hostname = bh.ResolveIP12 if hostname <> "" then13 response.write hostname14 else15 response.write "Unknown"16 end if17 %> </p>18 19 <p>%&gt;</p>20 </body>21 </html>

Similarly, you can also obtain the host name for any given IP address as well. You simply call the ResolveIP method andpass in the IP address to be resolved as a parameter to the method. This is demonstrated in the example below:

1 <html>2 3 <head>4 <title>Resolve IP</title>5 </head>6 7 <body>8 <%9 ipToLookup = "198.137.240.91"10 %>11 12 <p>The host name for <%=ipToLookup%> is <%13 set bh = Server.CreateObject("cyScape.browserObj")14 hostname = bh.ResolveIP(ipToLookup)15 if hostname <> "" then16 response.write hostname17 else18 response.write "Unknown"19 end if20 %> </p>21 22 <p>%&gt;</p>23 </body>24 </html>

Copyright (c) 1999 cyScape, Inc. All rights reserved. This material may not be published, distributed, or reprinted without written consent from cyScape.

http://www.learnASP.com/learn/bhframes.asp by Charles M. Carroll Page 33

Handling browsers that do not support framesJust about all "modern" browsers today support frames. Unfortunately though there are still several browsers in use todaythat do not. Just which ones do and which ones don't? Well, that's a tricky questions - but fortunately we don't need toconcern ourselves with that.

Page 34: [ebook] Learn ASP

Instead, we simply ask BrowserHawk to determine this for us at run-time, based on the particular browser that a user visitswith. If the browser supports frames, we load the frames set as expected and all is peachy.

If the browser does not support frames, you have a couple of choices on how to handle this. The easiest thing to do of courseis just display a page that tells the user that their browser does not support frames and ask them to upgrade their browser. Unfortunately this is the least elegant and can leave your visitor soured. As a result, many developers have two versions oftheir web site - one that is frames enabled and one that is not.

In this case you use BrowserHawk to determine whether the visitor can support frames. If they can, you simply load theframeset and off they go. If they do not support frames, however, then we redirect them to the no frames version of the site.The following code demonstrates this approach. For simplicity sake we will display text that says to "load the frameset here"rather than actually load a frameset.

1 <%2 set bh = Server.CreateObject("cyScape.browserObj")3 if not bh.frames then 'note: this could also be written as "if bh.frames = false"4 response.redirect "noframes.asp"5 end if6 %>7 <html>8 9 <head>10 <title></title>11 </head>12 13 <body>14 15 <p>HTML code to load your frameset goes here </p>16 </body>17 </html>

Need a copy of BrowserHawk? See our section on Getting Started.Copyright (c) 1999 cyScape, Inc. All rights reserved. This material may not be published, distributed, or reprinted without written consent from cyScape.

http://www.learnASP.com/learn/troubles.asp by Charles M. Carroll Page 34

Errors: Basics (errors1.asp) - Page 35 Errors: Trapping EVERY Error (dbtablewitherrortrap.asp) - Page 36 Errors: DB Error Information Trapping (dbtroubleshoot.asp) - Page 37 DBFAQ: Operation must use Updatable Query (FAQdbUpdate.asp) - Page 38 DBFAQ: User Entered ' in field (FAQdbSinglequote.asp) - Page 39 DBFAQ: LIKE operator * not working (FAQdbLIKE.asp) - Page 40 DBFAQ: retrieving MEMO/BLOBs generates error (FAQdbMEMO.asp) - Page 41 DBFAQ: Syntax Error in SQL Statement (FAQdbSQLSyntax.asp) - Page 42 Errors: Trapping Open Connections (dbtroubleshootopen.asp) - Page 43 Troubleshoot: Getting Help from Lists! (asptroubles.asp) - Page 44 Troubleshoot: Worldwide (asptroubles2.asp) - Page 45 Troubleshoot: Specialized (asptroubles3.asp) - Page 46 Troubleshoot: Version of ASP Sofware (versioncheck.asp) - Page 47 Troubleshoot: Registered Components (componentchecker.asp) - Page 48 Troubleshoot: DB Drivers by Christophe Wille (connectioninfo.asp) - Page 49 PWS: Personal Web Server Introduction (PWS.asp) - Page 50

Page 35: [ebook] Learn ASP

http://www.learnASP.com/learn/errors1.asp by Charles M. Carroll Page 35

Error Trapping #1 by Charles CarrollNow we will demonstrate how to trap VBScript errors that occur in your scripts with code. The script below runs without incident. Allthe syntax in the script is correct.

1 <TITLE>errordivide1.asp</TITLE>2 <body bgcolor="#FFFFFF">3 <%4 ' ASP program that works if numbers are legit5 x=76 y=27 z=x/y8 response.write z & "<br>"9 %>10 </body></html>

Now even though all the syntax in the script is correct, since one of the numbers has the effect of creating a "division by zero" errorthe script fails.

1 <TITLE>errordivide2.asp</TITLE>2 <body bgcolor="#FFFFFF">3 <%4 ' ASP program that works if numbers are legit5 x=76 y=2 ' if changed to 0 this will crash7 z=x/y8 response.write z & "<br>"9 %>10 </body></html>

Now we use the VBScript error trapping to present a message instead of a catastrophic script error.

1 <TITLE>errordivide3.asp</TITLE>2 <body bgcolor="#FFFFFF">3 <%4 ' ASP program that works if numbers are legit5 on error resume next6 x=77 y=08 z=x/y9 response.write z & "<br>"10 11 If err.number=0 then12 response.end13 end if14 pad="&nbsp;&nbsp;&nbsp;&nbsp;"15 response.write "<b>VBScript Errors Occured!<br>"16 response.write parm_msg & "</b><br>"17 response.write pad & "Error Number= #<b>" & err.number & "</b><br>"18 response.write pad & "Error Desc.= <b>" & err.description & "</b><br>"19 response.write pad & "Help Context= <b>" & err.HelpContext & "</b><br>"20 response.write pad & "Help File Path=<b>" & err.helpfile & "</b><br>"21 response.write pad & "Error Source= <b>" & err.source & "</b><br><hr>"22 %>23 </body></html>

http://www.learnASP.com/learn/dbtablewitherrortrap.asp by Charles M. Carroll Page 36

Page 36: [ebook] Learn ASP

Displaying A Table from Query w/Bells & WhistlesDisplaying a table take very little code. A veteran will expand the basic code to deal with many errors that a novice will not haveencountered until testing their web on a large scale.

1 <TITLE>dbtablewitherrortrap.asp</TITLE>2 <body bgcolor="#FFFFFF">3 <!--#include file="lib_errors.asp"-->4 <%5 on error resume next6 attempt="create connection object"7 set conntemp=server.createobject("adodb.connection")8 Call ErrorVBScriptReport(attempt)9 10 attempt="opening DSN"11 conntemp.open "DSN=Student;uid=student;pwd=magic"12 Call ErrorVBScriptReport(attempt)13 Call ErrorADOReport(attempt,conntemp)14 15 attempt="select * from authors where AU_ID<16"16 set rstemp=conntemp.execute(attempt)17 Call ErrorVBScriptReport(attempt)18 Call ErrorADOReport(attempt,conntemp)19 If rstemp.eof then20 response.write "No records matched your query" & "<P>"21 response.write attempt22 response.end23 end if24 25 attempt="counting fields"26 howmanyfields=rstemp.fields.count -127 Call ErrorVBScriptReport(attempt)28 Call ErrorADOReport(attempt,conntemp)29 %>30 <table border=1>31 <tr>32 <% 'Put Headings On The Table of Field Names33 for i=0 to howmanyfields %>34 <td><b><%=rstemp(i).name %></B></TD>35 <% next %>36 </tr>37 38 <% ' Now lets grab all the records39 do while not rstemp.eof %>40 <tr>41 <% for i = 0 to howmanyfields%>42 <td valign=top><%=rstemp.fields(i)%></td>43 <% next %>44 </tr>45 <%46 rstemp.movenext47 loop48 rstemp.close49 set rstemp=nothing50 conntemp.close51 set conntemp=nothing52 %>53 </table>54 </BODY>55 </HTML>

The error trapping library looks like this:

1 <%2 SUB ErrorVBScriptReport(parm_msg)3 If err.number=0 then4 exit sub

Page 37: [ebook] Learn ASP

5 end if6 pad="&nbsp;&nbsp;&nbsp;&nbsp;"7 response.write "<b>VBScript Errors Occured!<br>"8 response.write parm_msg & "</b><br>"9 response.write pad & "Error Number= #<b>" & err.number & "</b><br>"10 response.write pad & "Error Desc.= <b>" & err.description & "</b><br>"11 response.write pad & "Help Context= <b>" & err.HelpContext & "</b><br>"12 response.write pad & "Help File Path=<b>" & err.helpfile & "</b><br>"13 response.write pad & "Error Source= <b>" & err.source & "</b><br><hr>"14 END SUB15 16 SUB ErrorADOReport(parm_msg,parm_conn)17 HowManyErrs=parm_conn.errors.count18 IF HowManyErrs=0 then19 exit sub20 END IF21 pad="&nbsp;&nbsp;&nbsp;&nbsp;"22 response.write "<b>ADO Reports these Database Error(s) executing:<br>"23 response.write SQLstmt & "</b><br>"24 for counter= 0 to HowManyErrs-125 errornum=parm_conn.errors(counter).number26 errordesc=parm_conn.errors(counter).description27 response.write pad & "Error#=<b>" & errornum & "</b><br>"28 response.write pad & "Error description=<b>"29 response.write errordesc & "</b><p>"30 next31 END SUB32 %>

http://www.learnASP.com/learn/dbtroubleshoot.asp by Charles M. Carroll Page 37

Error Trapping Database Code (by Charles Carroll)Before you use http://www.asplists.com and send a mail to get your question answered let us take a couple of minutes and try thefollowing and see if it identifies your problem. There are tons of frightening messages that come up like:Microsoft OLE DB Providerfor ODBC Drivers error'80040e07'[Microsoft][ODBC MicrosoftAccess 97 Driver] Datatype mismatch in criteriaexpression./somewhere/something.asp,line 12

Error #-2147217900Error desc. ->[Microsoft][ODBC SQLServer Driver][SQLServer]Line 1: Incorrectsyntax near ','.

Error #-2147217900Error desc. ->[Microsoft][ODBC MicrosoftAccess 97 Driver] Syntaxerror in UPDATE statement.

Here are our guidelines for getting to the heart of the matter. First add some error code to the script to display the messages and badSQL that causes the problem, for example:

1 <html><head>2 <title>dbtroubleshoot.asp</title>&3 <body>4 <!--#include file="lib_errors.asp"-->5 <%6 on error resume next7 Set Conn = Server.CreateObject("ADODB.Connection")8 conn.open "DSN=student;uid=student;password=magic"9 10 SQLstmt = "INSERT INTO junk (city,state,zip) VALUES ('Rockville','MD','20849')"11 Set RS = Conn.Execute(SQLStmt)12 13 Call ErrorVBScriptReport("Insert Statement")

Page 38: [ebook] Learn ASP

14 Call ErrorADOReport(SQLstmt,conn)15 16 rs.close17 set rs=nothing18 Conn.Close19 set conn=nothing%>20 21 </body></html>

Here is the include file that displays appropriate errors:

1 <%2 SUB ErrorVBScriptReport(parm_msg)3 If err.number=0 then4 exit sub5 end if6 pad="&nbsp;&nbsp;&nbsp;&nbsp;"7 response.write "<b>VBScript Errors Occured!<br>"8 response.write parm_msg & "</b><br>"9 response.write pad & "Error Number= #<b>" & err.number & "</b><br>"10 response.write pad & "Error Desc.= <b>" & err.description & "</b><br>"11 response.write pad & "Help Context= <b>" & err.HelpContext & "</b><br>"12 response.write pad & "Help File Path=<b>" & err.helpfile & "</b><br>"13 response.write pad & "Error Source= <b>" & err.source & "</b><br><hr>"14 END SUB15 16 SUB ErrorADOReport(parm_msg,parm_conn)17 HowManyErrs=parm_conn.errors.count18 IF HowManyErrs=0 then19 exit sub20 END IF21 pad="&nbsp;&nbsp;&nbsp;&nbsp;"22 response.write "<b>ADO Reports these Database Error(s) executing:<br>"23 response.write SQLstmt & "</b><br>"24 for counter= 0 to HowManyErrs-125 errornum=parm_conn.errors(counter).number26 errordesc=parm_conn.errors(counter).description27 response.write pad & "Error#=<b>" & errornum & "</b><br>"28 response.write pad & "Error description=<b>"29 response.write errordesc & "</b><p>"30 next31 END SUB32 %>

There is a set of links to Microsoft ADO knowledge base articles @http://www.asptracker.com/demo/adokb1.aspwhich may prove invaluable.

http://www.learnASP.com/learn/FAQdbUpdate.asp by Charles M. Carroll Page 38

Database listserve for help!

FAQ #1:Operation must use an updateable query. I get this error message when adding or modifying data

Microsoft OLE DB Provider for ODBC Drivers error '80004005'Database Error: [Microsoft][ODBC Microsoft Access Driver] Operation must use an updateable query.

is a very common error message when updating Access databases. Since Access is file based any attempt to update thedatabase by an ASP script can only modify the Access databases if permissions are established correctly.

Go to the parent directory where the database is stored. Click on the folder permissions and set IUSER_xxxxx to 'change'

Page 39: [ebook] Learn ASP

where xxxxx is the machine name. Make sure the file is also set so the ISUSER_xxxx can change the file.

http://www.learnASP.com/learn/FAQdbSinglequote.asp by Charles M. Carroll Page 39

Database listserve for help!

FAQ #2: A user attempted to edit or add data to the database that had a single quote in the name (for exampleBill's Fish Shop or O'Reilly). Now the form gives an error when adding or updating.

This is a very common error message when updating or adding to databases. Let us look at 3 SQL statements:

UPDATE customer FIELDS (Name,City,State,Zip) _ VALUES ('Acme Inc.','Rockville','MD','20849') _ WHERE custid=20works fine!

UPDATE customer FIELDS (Name,City,State,Zip) _ VALUES ('Acme's Store','Rockville','MD','20849') _ WHERE custid=20will fail because it the single ' confuses the SQL parser.

UPDATE customer FIELDS (Name,City,State,Zip) _ VALUES ('Acme''s Store','Rockville','MD','20849') _ WHERE custid=20will succeed because it the single ' was entered as '' which satisfies the SQL parser.

UPDATE customer FIELDS (Name,City,State,Zip) _ VALUES ('Ledos','Pike's Peak','CO','000000') _ WHERE custid=20will fail because it the single ' confuses the SQL parser.

UPDATE customer FIELDS (Name,City,State,Zip) _ VALUES ('Ledos','Pike''s Peak','CO','000000') _ WHERE custid=20will succeed because it the single ' was entered as '' which satisfies the SQL parser.

In your code you may be building your SQL statement from variables, i.e.

co=request("company")cy=request("city")st=request("state")id=request("keycust")mySQL = "UPDATE customer FIELDS ("mySQL = MySQL & "Name,City,State,Zip) "mySQL = MySQL & "VALUES ('" & co & "',"mySQL = MySQL & "'" & cy & "',"mySQL = MySQL & "'" & st & "',"mySQL = MySQL & "'" & zip & "'"mySQL = MySQL & "WHERE keycust=" & id

and this will work fine as long as the user never enter an ' in the data. But to be robust, you should use a built-in function calledreplace that can find characters in a string and replace them with alternate characters. For example the code above could bereplaced with:

co=request("company")cy=request("city")st=request("state")id=request("keycust")co=replace(co,"'","''")

Page 40: [ebook] Learn ASP

cy=replace(cy,"'","''")mySQL = "UPDATE customer FIELDS ("mySQL = MySQL & "Name,City,State,Zip) "mySQL = MySQL & "VALUES ('" & co & "',"mySQL = MySQL & "'" & cy & "',"mySQL = MySQL & "'" & st & "',"mySQL = MySQL & "'" & zip & "'"mySQL = MySQL & "WHERE keycust=" & id

and it would work even if the user input ' in the company or city field because they would be doubled up and acceptable to the SQLparser.

Additional Information:Check MS knowledgebase article Q178070 (HOWTO : Handle Quotes and Pipes in Concatenated SQL Literals) whichsuggests all pipe characters be replaced with chr(124)

The article can be found at http://support.microsoft.com/support/kb/articles/q178/0/70.asp

http://www.learnASP.com/learn/FAQdbLIKE.asp by Charles M. Carroll Page 40

Database listserve for help!

FAQ #3: I have a query utilizing LIKE that works great in Access but produces an error in ASP.

This is a very common error message when querying databases and the person learned to query in Access. Access uses * formultiple character wildcards and ? for individual character wildcards.

Access ASP/ADO

* %? _Let us look at 2 typical Access Query statements:

SELECT * from customer where city LIKE "N*"works fine in Access! produces an error in ASP.

SELECT * from customer where city LIKE "N%"works fine in ASP.

SELECT * from customer where phrase LIKE "N?w"works fine in Access! produces an error in ASP.

SELECT * from customer where phrase LIKE "N_w"works fine in ASP.

http://www.learnASP.com/learn/FAQdbMEMO.asp by Charles M. Carroll Page 41

Database listserve for help!

FAQ #4: My memo fields are not working. I get the error message:Microsoft OLE DB Provider for ODBC Drivers error '80020009'

Page 41: [ebook] Learn ASP

Let us look at a typical problem Query and the solution:

SELECT * from cargo where city LIKE "New York"produces errors if the memo fields are retrieved.

(for the sake of this example the memo fields are marked in redCargoID, CargoName, Comments, Street, City, State,Zip, ShippingNotes and DueDate)

MEMO/BLOBS must be listed last explictly.

SELECT CargoID,CargoName, Street,City, State,Zip,DueDate,ShippingNotes,Commentsfrom cargo where city LIKE "New York"produces no errors since the memo fields are listed last.

Check out http://support.microsoft.com/support/kb/articles/q175/2/39.asp as well for more details.

http://www.learnASP.com/learn/FAQdbSQLSyntax.asp by Charles M. Carroll Page 42

Database listserve for help!

FAQ #5: Syntax Error in Database Statement

90% of the problems submitted to the listserves could be solved by systematically checking your code against these guidelines. Ifyou complete all of these steps, then submit it to the list, but most people will solve their problem without the list!

Step 1: did you write the SQL statement to the browser?....code...conn.execute(SQLstuff)....code...

needs to be converted to:

....code...response.write SQLstuffconn.execute(SQLstuff)....code...

The SQLstatement written to the browser will allow Step 2 and Step 3 to be checked. The code tells you little about thesyntax error until you write what the code assembles.

Step 2: Are the field names a problem?a. Forbidden/cantankerous field names

Do not name a field date. It will create problems.

A query likeselect * from employees where date=#1/17/98#will fail even though it is syntactically correct because date is a forbidden name.

Rename the field, so the query could look like"select * from employees where hiredate=#1/17/98#and you are "out of the woods"

b. Field names with spaces

A field name that has embedded spaces will create problems if you don't surround it with square brackets whenreferencing it in the query.

A query likeselect * from employees where state of residence='MD'will fail even though it is syntactically correct because state of residence is a field with spaces in the name.

Page 42: [ebook] Learn ASP

A query likeselect * from employees where [state of residence]='MD'will succeed because the fieldname is delimited properly.

Step 3: Check for these common Syntax Errors?a. Text Fields get surrounded by ' ' and numeric fields do not!

A query like:select * from employees where city=Rockville and State=MD and yearsresiding>9will fail because the text fields were not delimited properly.

A query like:select * from employees where city='Rockville' and State='MD' and yearsresiding>9succeeds.

b. Date fields get surrounded by # #

A query like:select * from employees where birthdate>1/1/1966will fail because the date fields were not delimited properly.

A query like:select * from employees where birthdate>#1/1/1966#succeeds.

http://www.learnASP.com/learn/dbtroubleshootopen.asp by Charles M. Carroll Page 43

Database Error Trapping: Opening Databaseby Charles Carroll

Many people want to intercept specific errors and replace them with friendly messages. Here is some sample code that catchesmispelled DSNs and bad login/user ids:

1 <html><head>2 <title>dbtroubleshoot.asp</title>&3 <body>4 <%5 on error resume next6 Set Conn = Server.CreateObject("ADODB.Connection")7 my_DSN="DSN=student;uid=student;password=magic2"8 conn.open my_DSN9 Call CheckOpen10 11 Conn.Close12 set conn=nothing13 14 SUB CheckOpen15 If err.number>0 then%>16 <b>VBScript Errors Occured:</b><br>17 Error Number=<%=err.number%><br>18 Error Descr.=<%=err.description%><br>19 Help Context=<%=err.helpcontext%><br>20 Help Path=<%=err.helppath%><br>21 Native Error=<%=err.nativeerror%><br>22 Source=<%=err.source%><br>23 SQLState=<%=err.sqlstate%><P>24 <%else%>25 No VBScript problems occured!<p>26 <%end if27 IF conn.errors.count> 0 then%>28 <b>ADO Reports these Database Error(s):</b><br>

Page 43: [ebook] Learn ASP

29 <%30 maxerrors=conn.errors.count-131 for counter= 0 to maxerrors32 DBErrorNum=conn.errors(counter).number33 DBErrorDesc=conn.errors(counter).description34 SELECT CASE DBErrorNum35 CASE -214746725936 response.write "Problem => <b>Bad DSN</b><br>"37 response.write "DSN => <b>" & my_DSN & "</b><br>"38 CASE -214721784339 response.write "Problem => <b>Bad Login Info</b><br>"40 response.write "DSN => <b>" & my_DSN & "</b><br>"41 exit sub42 CASE ELSE%>43 Error # = <b><%=DBErrorNum%></b><br>44 Error description = <b><%=DBerrorDesc%></b><p>45 <%END SELECT46 next47 else%>48 Everything Went Fine49 <%50 end if51 52 END SUB%>53 </body></html>

http://www.learnASP.com/learn/asptroubles.asp by Charles M. Carroll Page 44

ASP Troubleshooting Resources Part1When your Active Server Page code does not work, we actually manage a listserv you can write to send in your code and have yourcolleagues from around the world on the listserv help you fix it. Warning: One of listservers -- [aspfreeforall] -- is quite noisy (40-50messages a day) with many people helping each other.

People having trouble with ASP code communicating with a specific database should try their questions on one of these lists:

AccessDB2 AS400DbaseFox/Visual FoxProInformixSQLserver 6.5SQLserver 7.xOracle Setup/Can't Connect!OracleParadoxReports/Printing (Crystal, PDF, etc.)RDS (Remote Data Services)SQL: Joins, complex queries, shapingSybase

People having trouble with ASP and does not have code communicating with a specific database can sign up for one of our generallistservers

Beginning - Any ASP questions [aspfreeforall]Intermediate - NO beginner questions [aspnotnewbie]

Page 44: [ebook] Learn ASP

Advanced - tough ASP questions only! [aspadvanced][aspadvanced] Strict RulesInstalling,Upgrading ASP [aspinstall]ASP Database Beginners [aspdatabasefreeforall]ASP Databases Advanced Users [aspdatabases]

http://www.learnASP.com/learn/asptroubles2.asp by Charles M. Carroll Page 45

ASP Troubleshooting Resources (Worldwide)When your Active Server Page code does not work, we actually manage many listserves that provide help and are run entirely innon-English languages. You can write to send in your code and have your colleagues from around the world on the listserv helpyou fix it in your native language.

ArabicBengaliChineseDanishDutchFarsiFinnishFrenchGermanGerman ASP JobsGerman ASP Coffee HouseHebrewHindiIndonesianIcelandicItalianJapaneseKoreanMalayNorweiganPolishPortugeseRussianSpanishSwedishSwedish AdvancedTurkishThaiUrdu

Page 45: [ebook] Learn ASP

http://www.learnASP.com/learn/asptroubles3.asp by Charles M. Carroll Page 46

ASP Troubleshooting Resources Part 3Sometimes your problem is tough and requires multiple mails to resolve and the answers becomes quite complex and/or obscure.Such problems don't get solved well on general lists like [aspfreeforall] or [aspdatabases]. However, we have some lists wherespecialized topics thrive. All the best people hang out there, the archives are devoid of general questions, game is plentiful, and thesun shines and nary a cloud appears. Here is a master list of all the specialized listserves we run. They will NOT FLOOD YOURMAILBOX since the topic scope is so narrow.

Beginners to Intermediate Lists

ASPFreeForAll [aspfreeforall]The worlds noisiest and helpful ASP list -- 20-40 posts per day and any questions are allowed. It is the onlyunmoderated list we run.signup form at http://www.activeserverpages.com/aspfreeforall

ASPDatabaseFreeForAll [aspfreeforall]Noisy, but an ideal place for database beginners. 1/2 the noise of [aspfreeforall] since only database questions areallowed.signup form at http://www.activeserverpages.com/aspdatabasefreeforall

ADSI [aspadsi]beginners and all level of ADSI questions welcomed here.signup form at http://www.activeserverpages.com/aspadsi

Ecommerce w/ASP [ecommerce]This list is to discuss credit cards, HTTPS://, shopping carts and the ASP topics that intersect with commerce.Non-commerce questions will be rejected.signup form at http://www.activeserverpages.com/aspcommerce

Index Server [aspindexserver]Index Server only. No ASP general scripting questions allowed!signup form at http://www.activeserverpages.com/aspindexserver

International/Multilingual ASP [aspinternational]This list is to discuss multilingual websites (including multi-byte character sets, FEPs, translation services, etc.) andnon-English ASP issues, secure and international encryption issues, etc. Questions that don't deal with international ormultilingual issues will be rejected.signup form at http://www.activeserverpages.com/aspinternational

Jscript ASP [jscript]This list is to discuss server Jscript and client Jscript occasionally. Frames would not be out of the question here, as allthe "right" type of people are there to answer.signup form at http://www.activeserverpages.com/aspjscript

PerlScript w/ASP [aspPerlscript]This list is to discuss Perlscript only.signup form at http://www.activeserverpages.com/aspPerlscript

ASP Site Server [aspsiteserver]This list is to discuss Site Server issues only. General ASP questions will be rejected.signup form at http://www.activeserverpages.com/aspsiteserver

Page 46: [ebook] Learn ASP

Component Building (including MTX, MSMQ)

Visual Basic ASP component building [vbcomponents]This list is to discuss Visual Basic component building only. Of course MTX and MSMQ with components is right ontopic too. General ASP scripting questions will be rejected here.signup form at http://www.activeserverpages.com/aspvbcomponents

Delphi ASP component building [aspDelphi]This list is to discuss Delphi component building only. Of course MTX and MSMQ with components is right on topic too.General ASP scripting questions will be rejected here.signup form at http://www.activeserverpages.com/aspdelphi

C++ low-level component building [low-levelcomponents]This list is to discuss C++ component building only. Of course MTX and MSMQ with components is right on topic too.General ASP scripting questions will be rejected here.signup form at http://www.activeserverpages.com/asplowlevelcomponents

VB WebClasses [aspvbwebclasses]This list is to discuss IIS webclasses only. These are specific types of VB6 apps that are optimized to work with ASP.General scripting questions not allowed.signup form at http://www.activeserverpages.com/aspvbwebclasses

Databases

ASP SQL How-To [aspSQLhowto]This list is to discuss complex joins, complex queries, and how to do certain complex tasks involving SQL. It is not atroubleshooting list and broken code questions and questions that are newbie in nature are always rejected.signup form at http://www.activeserverpages.com/aspsqlhowto

ASP Databases [aspdatabases]This list is to discuss database troubleshooting but is not a beginner's lists. Many beginners questions ( ' questions,permissions, how do I edit a database) will be rejected as to not distract from the tough issues being discussed.signup form at http://www.activeserverpages.com/aspdatabases

ASP Reporting from Databases [aspreporting]This list is to discuss reports with tools like PDF, Crystal Reports, Chilisoft Reports, etc.No database questions or ASP questions will be allowed if reports are not part of the topic.signup form at http://www.activeserverpages.com/aspreporting

ASP RDS (Remote Data Services) [aspRDS]This list is to discuss Remote Data Service and how they can be integrated into ASP sites.signup form at http://www.activeserverpages.com/asprds

Databases/Vendor Specific

DB2AS400 [aspdb2as400]Only to discuss drivers, stored procedures, SQL variations, and vendor specific issues concerning ASP pages andcomponents communication with IBM DB2/AS400 databases.signup form at http://www.activeserverpages.com/aspdb2as400

Informix [aspinformix]Only to discuss drivers, stored procedures, SQL variations, and vendor specific issues concerning ASP pages andcomponents communication with Informix databases.signup form at http://www.activeserverpages.com/aspinformix

Oracle [asporacle]Only to discuss drivers, stored procedures, SQL variations, and vendor specific issues concerning ASP pages andcomponents communication with Oracle databases.

Page 47: [ebook] Learn ASP

signup form at http://www.activeserverpages.com/asporacle

Sybase [aspsybase]Only to discuss drivers, stored procedures, SQL variations, and vendor specific issues concerning ASP pages andcomponents communication with Sybase databases.signup form at http://www.activeserverpages.com/aspsybase

SQLserver7 [aspsqlserver7]Only to discuss drivers, stored procedures, SQL variations, and vendor specific issues concerning ASP pages andcomponents communication with SQLServer 7 databases.signup form at http://www.activeserverpages.com/aspsqlserver7

Editors

ASP with Visual Interdev [aspvisualinterdev]This list is to discuss Visual Interdev editor issues only. As long as you are editing your code with Interdev, this is thelist for you!signup form at http://www.activeserverpages.com/aspvisualinterdev

ASP with Drumbeat/Drumbeat 2000 [aspDrumbeat]This list is to discuss Drumbeat issues only. As long as you are editing your code with Drumbeat, this is the list for you!signup form at http://www.activeserverpages.com/aspdrumbeat

ASP with NetObjects Fusion [aspnetobjects]This list is to discuss Netobject editor issues only. As long as you are editing your code with Netobjects, this is the listfor you!signup form at http://www.activeserverpages.com/aspnetobjects

Non-Technical Lists

ASP Jobs [jobs/consult]This list is to post jobs, or indicate your availablity for jobs. Consulting assignments, full time jobs and resumes are theonly topics allowed here; no how-to allowed.signup form at http://www.activeserverpages.com/aspjobs

ASP Gripes [aspgripe]This list is for readers to complain about ASP products they bought and were unhappy with to share their experiences!signup form at http://www.activeserverpages.com/aspgripe

ASP Convention [aspconvention]This list is to discuss the many www.aspconvention.com events that occur throughout the year.signup form at http://www.activeserverpages.com/aspconvention

ASP Training [asptraining]This list is to discuss people who need training and companies who offer training can post their classes here too andinteract with potential customers.signup form at http://www.activeserverpages.com/asptraining

Free Code & Components [aspfreecodecomponents]This list is to offer FREE code and components. No how-to allowed, just send the list the FREE code or componentURLs you are giving away.signup form at http://www.activeserverpages.com/aspfreecodecomponents

Server Admin

Crashed/Hung Servers [aspcrash]Only crashes and hung servers and mysterious error messages are discussed here. No scripting how-to or serveradmin allowed.

Page 48: [ebook] Learn ASP

signup form at http://www.activeserverpages.com/aspcrash

Installing ASP [aspinstall]Only installs, service pack upgradees are allowed here. No scripting how-to allowed.signup form at http://www.activeserverpages.com/aspinstall

Server Admin [aspserver]This list is to discuss IIS, NT, and MMC from a network administrators standpoint as they work with ASP coders.signup form at http://www.activeserverpages.com/aspserver

3rd Party Products

ASPDB Product Support [aspdbmajormicro]This list is to discuss using the ASPDB component. General ASP questions not allowed.signup form at http://www.activeserverpages.com/aspdbmajormicro

ServerObjects.com Support [aspserverobjectscom]This list is to discuss using components from www.serverobjects.com on your site. General ASP questions not allowed.signup form at http://www.activeserverpages.com/aspserverobjectscom

SoftArtisans Product Support [aspsoftartisans]This list is to discuss using components made by www.softartisans.com. General ASP questions not allowed.signup form at http://www.activeserverpages.com/aspsoftartisans

WROX Readers Support [aspwroxreaders]This list is to discuss questions and coding issues arising from reading books published by WROX -- i.e. the code inChapter 13 has this problem etc. If your question didn't originate because of code in a WROX book it will be rejected.signup form at http://www.activeserverpages.com/aspwroxreaders

Technology Specific

LDAP [aspldap]Communicating with LDAP stores by any mechanism (whether using ADSI, APIs, etc.) is the only topic allowed in thislist.signup form at http://www.activeserverpages.com/aspLDAP

Lotus Notes [asplotusnotes]signup form at http://www.activeserverpages.com/asplotusnotes

MAIL from ASP: Outlook, Exchange, CDO, 3rd Party [aspmail]only getting mail out of ASP pages and interface to mail and appointment stores are discussed here.signup form at http://www.activeserverpages.com/aspmail

MSOffice and ASP [aspmsoffice]automating Word,Excel,Powerpoint, Project with ASP is the only topic here.signup form at http://www.activeserverpages.com/aspmsoffice

Advanced Listserves

ASP FastCode [aspFastCode]This list is to discuss speeding up code. Broken code or how-to is not the topic. Basically your code must work, but youwant to make it faster.signup form at http://www.activeserverpages.com/aspfastcode

ASP NotNewbie [aspnotnewbie]This list is for people who don't want to be on a beginners list but are not super-advanced yet. Beginners posts will berejected always.

Page 49: [ebook] Learn ASP

signup form at http://www.activeserverpages.com/aspnotnewbie

ASP Advanced ADSI [aspadvadsi]This list is to discuss the ADSI issues no other list has resolved after much research.signup form at http://www.activeserverpages.com/aspadvadsi

http://www.learnASP.com/learn/versioncheck.asp by Charles M. Carroll Page 47

Version Check by Charles Carroll DRAFTThis checks what software you are using on your server.1 <%@ language=vbscript%>2 <HTML>3 <HEAD>4 <TITLE>versioncheck.asp</TITLE>5 </HEAD>6 <body bgcolor="#FFFFFF">7 <script language=jscript runat=server>8 response.write ("scripting engine=<b>" + ScriptEngine() + "</b><br>");9 response.write ("buildversion=<b>" + ScriptEngineBuildVersion() + "</b><br>");10 response.write ("majorversion=<b>" + ScriptEngineMajorVersion() + "</b><br>");11 response.write ("minorversion=<b>" + ScriptEngineMinorVersion() + "</b><br>");12 </script>13 14 <%15 response.write "<hr><br>"16 response.write "scripting engine=<b>" & scriptengine() & "</b><br>"17 response.write "buildversion=<b>" & scriptenginebuildversion() & "</b><br>"18 response.write "majorversion=<b>" & scriptenginemajorversion() & "</b><br>"19 response.write "minorversion=<b>" & scriptengineminorversion() & "</b><br>"20 21 response.write "<hr><br>"22 set tempconn=server.createobject("adodb.connection")23 response.write "ado version=<b>"24 response.write tempconn.version & "</b><br>"25 set tempconn=nothing26 27 response.write "<hr><br>"28 serversoftware=request.servervariables("server_software")29 response.write "server software=<b>"30 response.write serversoftware & "</b><br>"31 32 Response.Write "Script Timeout = <b>" & Server.ScriptTimeout & " seconds</b><br>"33 Response.Write "Session Timeout = <b>" & Session.Timeout & " minutes</b><br>"34 %>35 36 </BODY></HTML>

http://www.learnASP.com/learn/componentchecker.asp by Charles M. Carroll Page 48

Component Checker by Charles Carrolldetermine what components are on your serverThe script reads the component.ini file we created and reports whether each of the components in that file can be created.

1 <TITLE>componentchecker.asp</TITLE>

Page 50: [ebook] Learn ASP

2 <body bgcolor="#FFFFFF">3 <%4 dim successSTR, FailSTR, checkSTR5 whichfile=server.mappath("component.ini")6 Set fs = CreateObject("Scripting.FileSystemObject")7 Set thisfile = fs.OpenTextFile(whichfile, 1, False)8 9 counter=010 11 do UNTIL thisfile.AtEndOfStream12 counter=counter+113 thisline=thisfile.readline14 attempt=trim(thisline)15 pad="&nbsp;&nbsp;&nbsp;&nbsp;"16 DO WHILE attempt=""17 thisline=thisfile.readline18 attempt=trim(thisline)19 LOOP20 If mid(thisline,1,1)="[" then21 ' ignore22 CheckSTR=CheckSTR & thisline & " "23 lastcategory=category24 category=lcase(thisline)25 oldcategory=mid(category,1,Len(category)-1) 26 category=replace(category,"www.","<a href='http://www.")27 IF instr(category,"href")>0 then28 category=mid(category,2)29 category=category & "'>" & oldcategory & "]</a>"30 END IF31 group= "<b>" & category & " component group</b><br>"32 successcount=033 failcount=034 thisline=thisfile.readline35 attempt=thisline36 end if37 on error resume next38 set tempobject=server.createobject(attempt)39 eol="<br>" & vbcrlf40 whicherr=err.number41 If whicherr=0 then42 if successcount=0 then43 successSTR=successSTR & group44 end if45 vleft="&nbsp;(ver="46 vright=")&nbsp;"47 SELECT CASE lcase(attempt)48 CASE "adodb.connection"49 version= vleft & tempobject.version & vright50 CASE ELSE51 version=""52 END SELECT53 54 successSTR= successSTR & pad & "<b>" & attempt & version & "</b> successfull!" & eol55 successcount=successcount+156 else57 if failcount=0 then58 FailSTR=FailSTR & group59 end if60 IF whicherr=-2147221005 THEN61 msg = " is not registered!"62 ELSE63 msg = " failed. Error #" & whicherr64 END IF65 FailSTR= failSTR & pad & "<b>" & attempt & "</b>" & msg & eol66 failcount=failcount+167 end if68 set tempobject=nothing

Page 51: [ebook] Learn ASP

69 loop70 71 thisfile.Close72 set thisfile=nothing73 set fs=nothing74 75 response.write "Checked: " & checkSTR & "<hr>"76 response.write successSTR & "<hr>"77 response.write failSTR78 %>

This component.ini file contains a list of typical server components, grouped by type. Type is indicated within [ ] codes. Here is thecontents of the current component.ini:

1 [standard]2 mswc.browsertype3 mswc.nextlink4 scripting.dictionary5 scripting.filesystemobject6 7 [ado]8 adodb.recordset9 adodb.connection10 adodb.command11 12 [cdo]13 CDONTS.NewMail14 15 [cyscape]16 cyScape.browserObj17 18 [indexserver]19 ixsso.Query20 ixsso.Util21 22 [Lyris]23 Lyris.LCP24 25 [http://msdn.microsoft.com/scripting]26 Wscript.Shell27 28 [msfreebies]29 iissample.asp2htm30 iissample.contentrotator31 iissample.registry32 iissample.summaryinfos33 iissample.tracer34 mswc.adrotator35 mswc.counters36 mswc.myinfo37 MSWC.PageCounter38 MSWC.PermissionChecker39 mswc.tools40 mswc.loadbalance41 42 [msXML]43 microsoft.XMLHTTP44 microsoft.XMLDOM45 46 [www.aspdb.com]47 ASPdb.Free48 ASPdb.View49 ASPdb.Pro50 ASPdb.EP51 52 [www.serverobjects.com]53 ASPChart.Chart54 AspConv.Expert

Page 52: [ebook] Learn ASP

55 AspDNS.Lookup56 AspFile.FileObj57 AspHTTP.Conn58 AspImage.Image59 AspInet.FTP60 AspMX.Lookup61 AspNNTP.Conn62 AspPager.Pager63 SMTPsvg.Mailer64 65 [www.softartisans.com]66 SoftArtisans.FileUp67 SoftArtisans.SACheck68 SoftArtisans.SASessionPro69 SoftArtisans.FileManager70 EZsite.Calender71 EZsite.CalendarManager72 EZsite.WebNotes73 74 [www.active4.com]75 ActiveLaunch.Control76 ActiveSAR.SearchAndReplace77 ActiveShopper.Cart78 ActiveShopper.BasketItem79 FileTouch.Control80 PCAuthX.Authorizer81 Prt2Disk.Control82 SemClient.Control83 SPrinterPro.Object84 TimeSpan.Control85 WWWPrint.Client86 87 [Zaks Software]88 ZaksPop3.Server89 JavaPop3.Mailer90 91 [www.persits.com]92 Persits.MailSender93 94 [www.oceantek.com]95 ASPL.Login96 97 [www.able-consulting.com]98 ACI.WhoIs99 100 [www.softwing.com]101 Softwing.EventLogReader102 Softwing.OdbcRegTool103 w3info.w3info.1104 InetCtls.Inet.1105 Softwing.AspQPerfCounters106 SQLOLE.SQLServer107 SOFTWING.ASPEventlog108 SOFTWING.ASPtear109 SOFTWING.EDConverter110 SOFTWING.EventLogReader111 SOFTWING.FileCache.1112 SOFTWING.OdbcRegTool113 SOFTWING.LocaleFormatter114 SOFTWING.Profiler115 116 [www.dougdean.com]117 EZsite.EZuploadLite118 119 [www.algonet.se/~jekman]120 lightcom.xBrowser121 lightcom.xContent

Page 53: [ebook] Learn ASP

122 lightcom.xPop3123 lightcom.xSMTP124 lightcom.xTree125 lightcom.xBrowser126 JESoftware.xContent127 JESoftware.xPop3128 JESoftware.xSMTP129 JESoftware.xTree130 131 [tech.dimac.net]132 Socket.TCP133 134 [www.de-info.com]135 checkemail.maccheckemail136 137 [www.pstruh.cz]138 TCPIP.Trace139 TCPIP.DNS140 141 [www.dana-net.com/products/aspcomponents/magicregistry]142 MagicRegistry.Tricks

http://www.learnASP.com/learn/connectioninfo.asp by Charles M. Carroll Page 49

Connection Info by Christophe [email protected] http://www.softwing.com/iisdev

If you want to know what drivers and other vital details are being used for a DSN, here is some code to the rescue.

1 <html><head>2 <title>connectioninfo.asp by Christophe Wille http://www.softwing.com</title>3 </head>4 <!--#include file="lib_connectioninfo.asp"-->5 <body>6 <%7 response.write "<hr>SQL Server Connection"8 Call DSNinfo("DSN=student;uid=student;pwd=magic")9 response.write "<hr>Access Connection Connection"10 theDSN="DRIVER={Microsoft Access Driver (*.mdb)};DBQ="11 theDSN=theDSN & server.mappath("/learn/test/biblio.mdb")12 Call DSNInfo(theDSN)13 %>14 </body>15 </html>

The Include file looks like this:1 <%2 SUB DSNInfo(strDSN)3 Set cnn1 = Server.CreateObject("ADODB.Connection")4 Set rsQuery = Server.CreateObject("ADODB.RecordSet")5 cnn1.open strDSN6 7 response.write "ADO Version: " & cnn1.Version8 response.write "<BR>" & vbcrlf9 response.write strVersionInfo & "DBMS Name: " & cnn1.Properties("DBMS Name")10 response.write "<BR>" & vbcrlf11 response.write "DBMS Version: " & cnn1.Properties("DBMS Version")12 response.write "<BR>" & vbcrlf13 response.write "OLE DB Version: " & cnn1.Properties("OLE DB Version")14 response.write "<BR>" & vbcrlf15 response.write "Provider Name: " & cnn1.Properties("Provider Name")

Page 54: [ebook] Learn ASP

16 response.write "<BR>" & vbcrlf17 response.write "Provider Version: " & cnn1.Properties("Provider Version")18 response.write "<BR>" & vbcrlf19 response.write "Provider Friendly Name: " & cnn1.Properties("Provider Friendly Name")20 response.write "<BR>" & vbcrlf21 22 If 0 = Instr(LCase(cnn1.Properties("Provider Name")),"oledb") then23 ' ### no OLE DB Provider used, therefore :24 response.write "Driver Name: " & cnn1.Properties("Driver Name")25 response.write "<BR>" & vbcrlf26 response.write "Driver Version: " & cnn1.Properties("Driver Version")27 response.write "<BR>" & vbcrlf28 response.write "Driver ODBC Version: " & cnn1.Properties("Driver ODBC Version")29 response.write "<BR><BR>"30 end if31 32 Set rsQuery = nothing33 Set cnn1 = nothing34 35 36 END SUB37 %>

http://www.learnASP.com/learn/PWS.asp by Charles M. Carroll Page 50

Personal Web Server (PWS) by Charles CarrollThe Personal Web Server is a marvellous tool because it lets you develop and test websites

without being connected to the Internet●

without placing your code on the World-Wide-Web or a server until it is tested off-line and totally debugged.●

The address of your personal web server is:

http://127.0.0.1It has other aliases, like http://localhost but it true reliable name is the one above.

http://www.learnASP.com/learn/Form.asp by Charles M. Carroll Page 51

Forms: Introduction (formintro.asp) - Page 52 Forms: Text Box (formtextbox.asp) - Page 53 Forms: Text Area (formtextarea.asp) - Page 54 Forms: Check Box (formcheckbox.asp) - Page 55 Forms: Radio Buttons (formradio.asp) - Page 56 Forms: List Box (formlistbox.asp) - Page 57 Forms: CASE syntax #1 (case.asp) - Page 58 Forms: CASE syntax #2 (case2.asp) - Page 59 Forms: IF syntax #1 (if.asp) - Page 60 Forms: IF syntax #2 (if2.asp) - Page 61 Forms: IF syntax #3 (if3.asp) - Page 62 Forms: IF syntax #4 (if4.asp) - Page 63

Page 55: [ebook] Learn ASP

Forms: For Each Iteration (formforeach.asp) - Page 64 Forms: mailing w/ASPMail (formsendmail.asp) - Page 65 Cookies: Reading Them (cookiesform.asp) - Page 66 Cookies: Writing Them (cookiesformrespond.asp) - Page 67 Cookies: Deleting Them (cookiesforget.asp) - Page 68 Cookies: Simplified by Paul Rigor (cookiesub.asp) - Page 69

http://www.learnASP.com/learn/formintro.asp by Charles M. Carroll Page 52

Forms Introduction by Charles CarrollForms are the primary way that a user feeds information into ASP. A form is a web page that contains tags that cause the browser toshow fields that the user can fill in.

Forms can be HTML files. They only need to be ASP if ASPy type capabilities are needed (session variables, includes).●

The form must pass the variables onto a .asp file to process the form.●

An excellent form tutorial can be found at:http://www.mountaindragon.com/html/forms.htm

Form with GET

<form action="x.asp" name="whatever" method=get> .... <input type=submit> <input type=reset></form>

there is a limit on the number of characters (approximately 4,000 but varies depending on server and browsers involved. ●

The form will show it's parameter in the browser address window, for example:testform.asp?state=md&city=Germantownwould be the URL in the browser, if the state and city field were populated.

An ASP script picks up a form field with:<%whatever=request.querystring("whichfield")%>

Form with POST

<form action="x.asp" name="whatever" method="post"> .... <input type=submit> <input type=reset></form>

It supports many more characters than get (megabytes of data in case of file uploads)●

The form will not show it's parameter in the browser address window, for example:http://whatever.com/testform.aspwould be the only URL in the browser, regardless of how many fields and how much data is passed.

An ASP script picks up the form field with:<%whatever=request.form("whichfield")%>

Tips:Tip #1: If using response.redirect to simulate a GET don't forget to encode:/learn/encode.asp

Tip #2: a text link to post above form would look like this:<a href="javascript:submitform(document.forms['whatever'])">whatever</a>thanks to Remko van der Vossen <[email protected]> for this tip I looked high and low for.

Page 56: [ebook] Learn ASP

http://www.learnASP.com/learn/formtextbox.asp by Charles M. Carroll Page 53

Forms - Text Box (by John Kauffman & Charles Carroll)

<INPUT NAME="NameLast">This will create an input box of a default size and thebrowser will pass the user input to ASP with the label(identifier) of NameLast.

<INPUT NAME="ZipCode" SIZE="10">This is not a limit to the number of characters that canbe entered. Do not use size as a validation techniqueto limit verbose users.

<INPUT NAME="State" MaxLength="2">This controls the maximum number of characters thatcan be entered.

<INPUT NAME="NameLast" VALUE="Bertrand">The name of Bertrand will appear when the page isopened and will re-appear if the form is reset.

1 <html><head>2 <title>FormTextBox.asp</title>3 </head><body bgcolor="#FFFFFF">4 <Form action = "FormTextBoxRespond.asp" method="get">5 Fill Out This Form For Us:<p>6 Last Name -> <Input NAME="NameLast" size ="10"><br>7 Country -> <Input NAME="Country" value="USA" size=10><br>8 State -> <Input NAME="State" MaxLength="2" size=2><br>9 <Input type="submit" value="Give me your data!">10 <hr></form>11 </body></html>

1 <html><head>2 <title>FormTextBoxRespond.asp</title>3 </head><body bgcolor="#FFFFFF">4 <%5 lname=request.querystring("namelast")6 cty=request.querystring("country")7 st=request.querystring("state")8 9 response.write lname & "<br>"10 response.write cty & "<br>"11 response.write st & "<br>"%>12 </body></html>

http://www.learnASP.com/learn/formtextarea.asp by Charles M. Carroll Page 54

Forms - Text Area (by John Kauffman)Multi-line text boxes are created using the TEXTAREA command as follows:

<TEXTAREA NAME="UserComments" ROWS=5 COLS=50>... default text is typed here</TEXTAREA>

Notes: Windows browsers typically provide scroll bars automatically.Although the TEXT tag does not need to be closed, the TEXTAREA must have a </TEXTAREA>The TEXTAREA tag (like all of the user-input objects) must be within the form tags discussed earlier.

1 <html><head>2 <TITLE>formTextArea.asp</TITLE>

Page 57: [ebook] Learn ASP

3 </head><body bgcolor="#FFFFFF">4 <form action="FormTextAreaRespond.asp" method="post">5 <p>TextArea Example</p>6 <p>Please type your special shipping comments:</p> 7 <TEXTAREA NAME="shippingComments" ROWS=5 COLS=50>8 shipping comments go here9 </textarea>10 <p><input type=submit value="send in comments!">11 </form>12 </body></html>

The responder to the form will look like this:

1 <html><head>2 <TITLE>formTextArearespond.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <%5 comm=request.form("shippingcomments")6 response.write comm7 %>8 <hr>9 </body></html>

http://www.learnASP.com/learn/formcheckbox.asp by Charles M. Carroll Page 55

Forms - Check Boxes (by John Kauffman & Charles Carroll)The checkbox object is coded along the same lines as radio buttons, however each checkbox must get its own unique name sincethe state of "checked" or "not checked" will be passed to ASP for each box. Remember that you can set more than one option to bechecked.

1 <html><head>2 <TITLE>FormCheckBox.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <form action="FormCheckBoxRespond.asp" method="post">5 <p>CheckBox Form Example</p>6 <p>How do you want your order confirmed?</p> 7 <input TYPE="checkbox" NAME="USMail">confirmation sent by first class US Postal Service<br>8 <input TYPE="checkbox" NAME="UPS">confirmation sent by UPS overnight letter service<br>9 <input TYPE="checkbox" NAME="EMail" CHECKED>confirmation sent by EMail<br>10 <input TYPE="checkbox" NAME="Fax">confirmation sent by Fax<br>11 <input TYPE="checkbox" NAME="Tel" CHECKED>confirmation made by telephone call<br><br>12 <input type="submit"><input type="reset">13 </form><hr></body></html>

The responder looks like this:

1 <html><head>2 <TITLE>formCheckBoxRespond.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <%5 If request.form("USMail")="on" then6 response.write "<br>We will confirm by US Mail"7 end if8 If request.form("UPS")="on" then9 response.write "<br>We will confirm by UPS"10 end if11 If request.form("EMail")="on" then12 response.write "<br>We will confirm by EMail"13 end if14 If request.form("fax")="on" then15 response.write "<br>We will confirm by fax"

Page 58: [ebook] Learn ASP

16 end if17 If request.form("tel")="on" then18 response.write "<br>We will confirm by tel"19 end if%>20 </body>21 </html>

http://www.learnASP.com/learn/formradio.asp by Charles M. Carroll Page 56

Forms - Radio Buttons (by John Kauffman)All of your user input objects in a form must have their own unique name which will be the label that the browser will assign to themwhen passing the data to ASP. The exceptions are radio buttons. Since only one piece of information will be passed to ASP from aset of radio buttons, they all get the same name. HTML requires that one of the buttons is selected by default, the one indicated bythe CHECKED command. It is important to understand that the browser will send back to ASP the name and the value of the onebutton which is selected by the user. The browser will NOT send back the text which is associated with the button. For the exampleabove, if the user checked on the button with the text New York City, then ASP would receive City=NY.

1 <html><head>2 <TITLE>formRadio.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <form action="FormRadiorespond.asp" method="post">5 <p><b>Radio Buttons </b> example</p>6 <p>Which Regional Office will you be visiting?</p> 7 <input TYPE="radio" NAME="City" VALUE="NY">New York City8 <input TYPE="radio" NAME="City" VALUE="LA">Los Angeles9 <input TYPE="radio" NAME="City" VALUE="SV" CHECKED>Savannah10 <br><input type="submit" value="choose a city">11 </form>12 </body></html>

The responder looks like:

1 <html><head>2 <TITLE>formradiorespond.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <%myCity = request.form("City")5 Select Case ucase(MyCity)6 case "NY"7 response.write "New York meeting is on Jan 3"8 case "LA"9 response.write "LA meeting meeting is on Jan 15"10 case "SV"11 response.write "Savannah meeting is on Jan 20"12 End Select%>13 </body>14 </html>

http://www.learnASP.com/learn/formlistbox.asp by Charles M. Carroll Page 57

Forms - List Boxes (by John Kauffman & Charles Carroll)The listbox object is very popular since it makes data entry easy. They just pull down a list.

1 <html><head>2 <TITLE>FormListBox.asp</TITLE>3 </head><body bgcolor="#FFFFFF">

Page 59: [ebook] Learn ASP

4 <form action="FormListBoxRespond.asp" method="post">5 <SELECT NAME="state">6 <OPTION SELECTED VALUE="md">Maryland</OPTION>7 <OPTION value="dc">District of Columbia</OPTION>8 <OPTION value="va">Virginia</OPTION>9 <OPTION value="whoknows">Somewhere Else!</OPTION>10 </SELECT>11 <input type=submit value="Choose State">12 </form>13 </body></html>

The responder looks like this:

1 <html><head>2 <TITLE>formlistboxrespond.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <%mystate = request.form("state")5 Select Case ucase(mystate)6 case "DC"7 response.write "DC meeting on 15th"8 case "MD"9 response.write "MD meeting on 20th"10 case else11 response.write "No meetings for you to attend!"12 End Select%>13 </body>14 </html>

http://www.learnASP.com/learn/case.asp by Charles M. Carroll Page 58

Select Case (by John Kauffman & Charles Carroll)Using IF-THEN can be cumbersome, prone to programmer errors and slower to execute. A more efficient construct is SELECTCASE. It is optimized for testing one variable against many conditions.

1 <html><head>2 <TITLE>case.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <form action="caserespond.asp" method="get">5 Your First Name<INPUT NAME="FirstName" MaxLength=20><p>6 Your Last Name<INPUT NAME="LastName" MaxLength=20><p>7 <INPUT TYPE=submit><p><INPUT TYPE=reset>8 </form>9 </body></html>

Here is the select case that will determine what the form input means.

1 <html><head>2 <TITLE>caserespond.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <%5 fname=request.querystring("Firstname")6 lname=request.querystring("Lastname")7 %>8 Nice to Meet You <%=fname%> <%=lname%><p>9 <%If fname="" then%>10 Sorry we are not on a first name basis...<p>11 <%end if12 select case lcase(lname)13 case "washington","adams"14 response.write "The first president has same last name<p>"15 case "jefferson"16 response.write "The third president has same last name<p>"

Page 60: [ebook] Learn ASP

17 case "lincoln"18 response.write "The sixteenth president has same last name<p>"19 end select%>20 </body></html>

http://www.learnASP.com/learn/case2.asp by Charles M. Carroll Page 59

Select Case Part2 (by John Kauffman & Charles Carroll)Using IF-THEN can be cumbersome, prone to programmer errors and slower to execute. A more efficient construct is SELECTCASE. It is optimized for testing one variable against many conditions.

1 <html><head>2 <TITLE>case2.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <form action="case2respond.asp" method="get">5 Your First Name<INPUT NAME="FirstName" MaxLength=20><p>6 Your Last Name<INPUT NAME="LastName" MaxLength=20><p>7 Your Title8 <INPUT TYPE="Radio" name="Title" VALUE="employee">Entry Level9 <INPUT TYPE="Radio" name="Title" VALUE="temp" CHECKED>Temporary Employee10 <INPUT TYPE="Radio" name="Title" VALUE="manager">Management Candidate11 <INPUT TYPE="Radio" name="Title" VALUE="executive">Executive12 <INPUT TYPE="Radio" name="Title" VALUE="vice-prez">The Vice President of...13 <INPUT TYPE="Radio" name="Title" VALUE="CEO">The Boss<p>14 <INPUT TYPE=submit><p>15 </form>16 </body></html>

Here is the select case that will determine what the form input means.

1 <html><head>2 <TITLE>case2respond.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <%5 fname=request.querystring("Firstname")6 lname=request.querystring("Lastname")7 title=request.querystring("title")8 response.write "Nice to Hire You " & fname & " " & lname & "<p>"9 Select Case lcase(Title)10 case "employee","temp"11 response.write("The washroom is in the hall")12 case "manager","executive"13 response.write("Here is your key to the Executive washroom")14 case "ceo", "vice-prez"15 response.write("The maid will attend to your private washroom")16 End Select%>17 </body></html>

http://www.learnASP.com/learn/if.asp by Charles M. Carroll Page 60

IF statement (by John Kauffman & Charles Carroll)Very often you must determine what to do next based on user input. This is one of the roles of the IF statement. First we make aform that will ask a user for their first name and last name.

1 <html><head>

Page 61: [ebook] Learn ASP

2 <TITLE>if.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <form action="ifrespond.asp" method=get>5 Your First Name<INPUT NAME="FirstName" MaxLength=20><p>6 Your Last Name<INPUT NAME="LastName" MaxLength=20><p>7 <INPUT TYPE=submit><p><INPUT TYPE=reset>8 </form></body></html>

Now we make a asp file that examines their first name and last name after the form is submitted.

1 <html><head>2 <TITLE>ifrespond.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <%fname=request.querystring("Firstname")5 lname=request.querystring("Lastname")6 If fname="George" and lname="Washington" then%>7 Hi.<p>You must be the first president!8 <%else%>9 Hi!<p>Nice to Meet You10 <%end if%>11 </body></html>

http://www.learnASP.com/learn/if2.asp by Charles M. Carroll Page 61

IF statement Part2 (by John Kauffman & Charles Carroll)Very often you must determine what to do next based on user input. This is one of the roles of the IF statement. First we make aform that will ask a user for their first name and last name.

1 <html><head>2 <TITLE>if2.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <form action="if2respond.asp" method=get>5 Your First Name<INPUT NAME="FirstName" MaxLength=20><p>6 Your Last Name<INPUT NAME="LastName" MaxLength=20><p>7 <INPUT TYPE=submit><p><INPUT TYPE=reset>8 </form></body></html>

Now we make a asp file that examines their first name and last name after the form is submitted. As contrasted to the previousexample this time we are checking multiple conditions utilizing elseif and we are dealing with entries no matter whether they weretyped in upper or lower case.

1 <html><head>2 <TITLE>if2respond.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <%5 fname=lcase(request.querystring("Firstname"))6 lname=lcase(request.querystring("Lastname"))7 If fname="george" and lname="washington" then%>8 Hi.<p>You must be the first president!9 <%elseIf fname="ronald" and lname="reagan" then%>10 Hi.<p>You must be the actor president!11 <%elseIf fname="jimmy" and lname="carter" then%>12 Hi.<p>You must be the peanut farmer president!13 <%elseIf fname="naoko" or fname="charles" then%>14 Hi.<p>Your name reminds me of someone<p>15 but I am not sure who!16 <%else%>17 Hi!<p>Nice to Meet You18 <%end if%>19 </body></html>

Page 62: [ebook] Learn ASP

http://www.learnASP.com/learn/if3.asp by Charles M. Carroll Page 62

IF statement Part3 (by John Kauffman & Charles Carroll)Very often you must determine what to do next based on user input. This is one of the roles of the IF statement. First we make aform that will ask a user for their first name, last name and salary.

1 <html><head>2 <TITLE>if3.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <form action="if3respond.asp" method=get>5 Your First Name<INPUT NAME="FirstName" MaxLength=20><p>6 Your Last Name<INPUT NAME="LastName" MaxLength=20><p>7 Your Salary <INPUT NAME="Salary" MaxLength=7><p>8 <INPUT TYPE=submit><p><INPUT TYPE=reset>9 </form></body></html>

This example shows how IF can deal with ranges and use various other boolean operators.

1 <html><head>2 <TITLE>if3respond.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <%5 fname=request.querystring("Firstname")6 lname=request.querystring("Lastname")7 salary=request.querystring("Salary")8 response.write "Nice to Meet You " & fname & " " & lname & "<p>"9 if salary>100000 then%>10 Would you like to loan me some money?<p>11 <% 12 sstaxMarginal=1513 else14 SSTaxMarginal=1515 end if16 If salary>6700 and salary<30000 then17 SSTaxMarginal=0%>18 Would you like me to loan you some money?<p>19 <%end if20 If salary<6700 then21 SSTaxMarginal=022 end if23 %>24 By the way your marginal tax rate is <%=sstaxmarginal%>25 </body></html>

http://www.learnASP.com/learn/if4.asp by Charles M. Carroll Page 63

If Then Part4 (by John Kauffman & Charles Carroll)Very often you must determine what to do next based on user input. This is one of the roles of the IF statement. First we make aform that will ask a user for their first name, last name and salary.

1 <html><head>2 <TITLE>if4.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <form action="if4respond.asp" method=get>5 Your First Name<INPUT NAME="FirstName" MaxLength=20><p>6 Your Last Name<INPUT NAME="LastName" MaxLength=20><p>

Page 63: [ebook] Learn ASP

7 Your Salary <INPUT NAME="Salary" MaxLength=7><p>8 <INPUT TYPE=submit><p><INPUT TYPE=reset>9 </form></body></html>

This example shows how IF can deal with ranges but this example illustrates the critical factor of ordering. If you were to re-arrangethese IFs they would not accurately report your salary grade.

1 <html><head>2 <TITLE>if4respond.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <%fname=request.querystring("Firstname")5 lname=request.querystring("Lastname")6 salary=request.querystring("Salary")7 response.write "Nice to Meet You " & fname & " " & lname & "<p>"8 if salary>80000 then9 salarygrade=410 end if11 if salary <=80000 then12 salarygrade=313 end if14 If salary <=60000 then15 salarygrade=216 end if17 if salary <=40000 then18 salarygrade=119 end if20 response.write ("Your Salary is $" & salary)21 response.write (", your Grade is " & salarygrade & ".<p>")22 %>23 </body></html>

http://www.learnASP.com/learn/formforeach.asp by Charles M. Carroll Page 64

Forms - For Each/Iteration by Charles CarrollForms with many elements may be easier to process if a FOR EACH construct is used to loop through every value submitted fromthe source form. In this example, there are many checkboxes and instead of many IF statements we replace them with one FOREACH loop.

1 <html><head>2 <TITLE>monthlyForm.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <form action="monthlyFormRespond.asp" method="post">5 <p>CheckBox Form Example</p>6 <p><b>Check Off The Days You Worked</b></p> 7 <%8 my_month=request.querystring("whichmonth")9 ' response.write my_month & "<br>"10 if my_month="" then11 my_date=now()12 else13 my_month=month("1/" & (request.querystring("whichmonth")) & "/1999")14 my_date=dateserial(year(now()),my_month,1)15 end if16 'response.write my_date & "<br>"17 18 If my_month=12 then19 my_day=120 my_month=121 my_year=my_year+122 else23 my_day=1

Page 64: [ebook] Learn ASP

24 my_month=month(my_date)+125 my_year=year(my_date)26 end if27 28 lastdayofmonth=day(DateSerial(Year(my_Date), my_Month,0))29 'response.write lastdayofmonth & "<br>"30 31 for counter=1 to lastdayofmonth%>32 <input TYPE="checkbox" NAME="workingday<%=counter%>">day <%=counter%> Worked?<br>33 <%next%>34 <input type="submit" value="Submit Days Worked">35 </form>36 </body></html>

1 <html><head>2 <TITLE>monthlyFormRespond.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <%5 daysworked=06 for each whatever in request.form7 thisvalue=request.form(whatever)8 If thisvalue="on" then9 daysworked=daysworked+110 end if11 next12 response.write "Thanks for working <b>" & daysworked & "</b> days"13 %>14 </body></html>

http://www.learnASP.com/learn/formsendmail.asp by Charles M. Carroll Page 65

Forms - Sending Results via EMail by Charles CarrollSometimes it makes sense to just email all the form results to someone. But the "mailto:" method used by many Web developers isnot the best way as it has the following serious limitations:

forms sent this way are difficult to read by a human recipient because of the encoded way it is sent●

Not all browsers support mailto (Netscape does, several IE versions before 4.0 do not, many browsers do not)●

The user may have a faulty email configuration that keeps the browser from sending the mail●

Server side mail has none of these limitations. Here is a form that will be sent to you provided you change the variables at the top ofthe code. This example uses ASPmail, which is available for a modest price at: http://www.serverobjects.com

Here is a sample form that will be sent via email:

1 <%2 ' change these to reflect where form should go3 fromName="Whoever"4 fromAddress="[email protected]"5 toName="Charles M. Carroll"6 toAddress="[email protected]"7 subject="form send mail tutorial"8 relay="relay.datareturn.com"9 %>10 <html><head>11 <title>FormToBeMailed.asp</title>12 </head><body bgcolor="#FFFFFF">13 <form action="FormToBeMailedrespond.asp" method="GET">14 Fill Out This Form For Us:<p>15 First Name -&gt; <input NAME="NameFirst" size="10"><br>16 Last Name -&gt; <input NAME="NameLast" size="10"><br>17 Country -&gt; <input NAME="Country" value="USA" size="10"><br>

Page 65: [ebook] Learn ASP

18 State -&gt; <input NAME="State" MaxLength="2" size="2"><br>19 email copy to -&gt; <input NAME="emailcopy" MaxLength="20" size="20"><br>20 21 <input type="submit"><input type="reset">22 23 <% ' do not touch these lines. Needed to send mail! %>24 <input type="hidden" name="mail-from" value="<%=fromName%>">25 <input type="hidden" name="mail-fromAddress" value="<%=fromAddress%>">26 <input type="hidden" name="mail-to" value="<%=ToName%>">27 <input type="hidden" name="mail-toaddress" value="<%=toaddress%>">28 <input type="hidden" name="mail-subject" value="<%=subject%>">29 <input type="hidden" name="mail-relay" value="<%=relay%>">30 </form>31 </body></html>

Here is the generic form responder that can be used with this or any form:1 <html><head>2 <title>serverobjectsmailrespond.asp</title>3 </head><body bgcolor="#FFFFFF">4 <%5 ' ASPMail(tm) from http://www.serverobjects.com6 ' is not part of ASP per se,7 ' but a excellent third party component8 9 my_from=request("mail-fromName")10 my_fromAddress=request("mail-fromaddress")11 my_to=request("mail-toName")12 my_toAddress=request("mail-toaddress")13 my_subject=request("mail-subject")14 my_relay=request("mail-relay")15 16 Set Mailer = Server.CreateObject("SMTPsvg.Mailer")17 Mailer.RemoteHost = my_relay18 19 Mailer.FromName = my_from20 Mailer.FromAddress = my_fromAddress21 Mailer.AddRecipient my_to, my_toaddress22 Mailer.Subject = my_subject23 24 for each whatever in request.querystring25 If instr(whatever,"mail-")=0 then26 Mailer.BodyText = whatever & "=" & vbcrlf27 Mailer.BodyText = request.querystring(whatever) & vbcrlf & vbcrlf28 end if29 next30 31 for each whatever in request.form32 If instr(whatever,"mail-")=0 then33 Mailer.BodyText = whatever & "=" & vbcrlf34 Mailer.BodyText = request.form(whatever) & vbcrlf & vbcrlf35 end if36 next37 38 my_emailcopy=request("emailcopy")39 If my_emailcopy="" then40 else41 Mailer.AddRecipient "form filler",my_emailcopy42 end if43 44 If Mailer.SendMail then45 Msg = "mail sent sucessfully!"46 Else47 Msg = "mail was not sent sucessfully"48 End If49 response.write Msg50 %>

Page 66: [ebook] Learn ASP

51 </body></html>

http://www.learnASP.com/learn/cookiesform.asp by Charles M. Carroll Page 66

Cookies Storing (by Juan Llibre & Charles Carroll)The script below demonstrates how to populate a form from a cookie.

1 <%2 response.buffer=true3 %>4 <html><head>5 <TITLE>cookiesform.asp</TITLE>&6 <body bgcolor="#FFFFFF">7 <%8 ln=Request.Cookies("thatperson")("lastname")9 fn=Request.Cookies("thatperson")("firstname")10 st=Request.Cookies("thatperson")("state")11 %>12 <Form action = "cookiesformrespond.asp">13 Form with Cookies<p>14 Please enter your First Name<p>15 <Input NAME="NameFirst" size ="40" value=<%=fn%>>16 <p>17 Please enter your Last Name<p>18 <Input NAME="NameLast" size ="40" value=<%=ln%>>19 <p>20 Please enter your State abbreviation<p>21 <Input NAME="State" MaxLength="2" value=<%=st%>>22 <Input type=submit></form>23 </body></html>

http://www.learnASP.com/learn/cookiesformrespond.asp by Charles M. Carroll Page 67

Cookies Displaying (by Juan Llibre & Charles Carroll)The script below demonstrates how to store a cookie that was passed in from the form.

1 <%response.buffer=true%>2 <html><head>3 <TITLE>cookiesformrespond.asp</TITLE>&4 <body bgcolor="#FFFFFF">5 <%6 l=request.querystring("namelast")7 f=request.querystring("namefirst")8 st=request.querystring("state")9 cookypath="/learn/test"10 cookydomain=".www.activeserverpages.com"11 cookydie=date+36512 Response.Cookies("thatperson")("lastname") = l13 Response.Cookies("thatperson")("firstname") = f14 Response.Cookies("thatperson")("state") = st15 Response.Cookies("thatperson").Expires = cookydie16 Response.Cookies("thatperson").Domain = cookydomain17 Response.Cookies("thatperson").Path = cookypath18 response.write Request.Cookies("thatperson")("lastname") & "<p>"19 response.write Request.Cookies("thatperson")("firstname") & "<p>"

Page 67: [ebook] Learn ASP

20 response.write Request.Cookies("thatperson")("state") & "<p>"21 %>22 </body></html>

http://www.learnASP.com/learn/cookiesforget.asp by Charles M. Carroll Page 68

Cookies Deleting (by Juan Llibre & Charles Carroll)The script below demonstrates how to remove a cookie.

1 <%response.buffer=true%>2 <html><head>3 <TITLE>cookiesformforget.asp</TITLE>&4 <body bgcolor="#FFFFFF">5 <%6 cookiepath="/learn/test"7 cookiedomain=".www.activeserverpages.com"8 cookiesdie=date-3659 Response.Cookies("thatperson").Expires = cookiesdie10 Response.Cookies("thatperson").Domain = cookiesdomain11 Response.Cookies("thatperson").Path = cookiespath12 response.write "I will not remember you"13 %>14 </body></html>

http://www.learnASP.com/learn/cookiesub.asp by Charles M. Carroll Page 69

Cookies Simplified (by Paul Rigor of http://www.mysticpc.com)

A reader of the site submits this simplified cookie reading, writing and deleting by automatically determing the correct domain andpath info without you having to specify it for each cookie.

1 <%response.buffer=true%>2 <!--#include file="cookielib.asp"-->3 <html><head>4 <TITLE>cookiesub.asp</TITLE>&5 <body bgcolor="#FFFFFF">6 <%7 Call AddCookie("Person", "Firstname", "Robert", 365)8 Call AddCookie("Person", "LastName", "Forward", 365)9 response.write GetCookie("person","firstname")10 response.write GetCookie("person","lastname")11 %>12 </body></html>

Here is the library code that does most of the work:1 <%2 '=======================================================================3 ' CookieLib.asp by Paul Rigor (http://www.mysticpc.com)4 ' online at http://www.activeserverpages.com/learn/cookiesub.asp5 ' copyright 1998 by Paul Rigor6 '7 ' application("cookiedomain") and application("cookiepath") can be8 ' set if firewall precludes accurate server variable9 '10 ' AddCookie(Cname, CKey, CValue, CExpDays)

Page 68: [ebook] Learn ASP

11 ' Example: Call AddCookie("MyCookie", "Cost", "$1.00", 100)12 '13 ' KillCookie(Cname,CKey)14 ' Example: Call KillCookie("MyCookie", "Cost")15 '16 ' GetCookie(Cname,Ckey)17 ' Example: Call GetCookie("MyCookie", "Cost")18 '19 ' Cname = Cookie Name: Required, for cookie name20 ' Ckey = Cookie Key: Optional(empty sting), use if cookie should be a dictionary21 ' Cvalue = Cookie Value: Required, what the cookie should be set to.22 ' CExpDays = Cookie Expiration: number of days cookie is valid, default 36523 Function AddCookie(Cname, CKey, CValue, CExpDays)24 If Cname = "" Then25 Exit Function26 End If27 28 If IsNumeric(CExpDays) = False Then CExpDays = 029 If CExpDays < 1 Then CExpDays = 36530 31 If CValue = "" Then CValue = " "32 33 If CKey <> "" Then34 Response.Cookies(Cname)(CKey) = CValue35 Else36 Response.Cookies(Cname) = CValue37 End If38 39 Response.Cookies(CName).Expires = Date + CExpDays40 Response.Cookies(CName).Domain = GetCookieDomain()41 Response.Cookies(CName).Path = GetCookiePath()42 End Function43 44 Function KillCookie(Cname,CKey)45 If CKey <> "" Then46 Call AddCookie(Cname, Ckey, "", 0)47 Else48 Response.Cookies(Cname).Expires = Date - 36549 Response.Cookies(CName).Domain = GetCookieDomain()50 Response.Cookies(CName).Path = GetCookiePath()51 End If52 End Function53 54 Function GetCookie(Cname, Ckey)55 If CKey <> "" Then56 GetCookie = Request.Cookies(Cname)(Ckey)57 Else58 GetCookie = Request.Cookies(Cname)59 End If60 End Function61 62 Function GetCookieDomain()63 If Application("CookieDomain") <> "" Then64 GetCookieDomain = Application("CookieDomain")65 Else66 GetCookieDomain = Request.ServerVariables("SERVER_NAME")67 End If68 End Function69 70 Function GetCookiePath()71 If Application("CookiePath") <> "" Then72 GetCookiePath = Application("CookiePath")73 Else74 TmpPath = Request.ServerVariables("SCRIPT_NAME")75 TmpPath = Split(TmpPath, "/")76 For PathArryCnt = 0 to Ubound(TmpPath) - 177 GetCookiePath = GetCookiePath & TmpPath(PathArryCnt) & "/"

Page 69: [ebook] Learn ASP

78 Next79 If GetCookiePath = "/" Then GetCookiePath = ""80 End If81 End Function82 %>

http://www.learnASP.com/learn/statemanagement.asp by Charles M. Carroll Page 70

State Management Introduction (stateintro.asp) - Page 71 What are ASP Sessions? (sessionswhat.asp) - Page 72 State Methods: Pros and Cons (stateproscons.asp) - Page 73 Pass Data w/Hidden Fields (hidden.asp) - Page 74 Pass Data w/Cookies (cookies.asp) - Page 75 Pass Data w/Session Vars (statesessions.asp) - Page 76 Pass Data w/ID tied to database (statedb.asp) - Page 77 State Managment Resources (statemore.asp) - Page 78 [aspStateManagement] Listserver (aspstatemanagement.asp) - Page 79

http://www.learnASP.com/learn/stateintro.asp by Charles M. Carroll Page 71

State Management Intro by Charles CarrollNot written yet.

http://www.learnASP.com/learn/sessionswhat.asp by Charles M. Carroll Page 72

What are Sessions?Sessions are a very convenient ASP feature. When someone visits a web page on your site, ASP calls that a "session" andimmediately can differentiate that user from all other users at a site. Anything stored in that user's session can be retrieved andmanipulated from that page and the next pages they visit, and the data will be tied to that user.

Session data is generally attached to one user. When a user visits their first page of your site, that page and every page they visit iscollectively called a session. Any data attached stored in that session object is private to the pages that user is visiting.

The code to store data in a session variable is simple. Here we will allow a user to flip a coin, i.e. flipcoin.asp and count theirsuccesses:

1 <%2 response.write "Coin Tossed!<br>"3 randomize4 randomnum=int(rnd*2)+15 IF randomnum=1 THEN6 session("heads")=session("heads")+17 ELSE8 session("tails")=session("tails")+19 END IF10 response.write "Heads= " & session("heads") & "<br>"11 response.write "Tails= " & session("tails") & "<br>"12 %>

Page 70: [ebook] Learn ASP

Even though there are many people at the site they all have different scores for their "heads" and "tails" count. They each has asession and it co-ordinates and differentiates their values.

A much more practical example could protect access to a page based on a session variable that indicated their security leveldetermined once upon login, see:http://www.learnasp.com/learn/security.asp

Some basic things should be noted:

Session data is stored on the server, not in cookies. No user could examine the session cookie and determinethe contents of any session variables.

A cookie is used to co-ordinate the user's session ID. Once again the cookie contains no data (just the sessionID). This means if the user accepts no cookies, you can't use sessions as described here.

If you absolutely need sessions without client cookies, installing an ISAPI filter named "Cookie Munger" willsolve your problem, but at a performance penalty.

Cookie Munger by Microsoft (FREE)

Cookies are a necessity to maintain ASP session objects. Even though the session objects are physically maintained on the serverthe essential ID that identifies a user session is kept in a cookie. This ISAPI filter can only be applied globally but if applied, it actuallyrewrites any pages sent back to the user so that any URLs in the page will pass back user session info without any cookies involved.Basically (at a performance penalty) it transforms every page sent to the client to encode the session ID as part of the URLs on thepage. So conceptually if you send a page back to the users with 20 URLs each URL gets a session ID "munged"/intermixed in sothat when they click on the URL you have enough info to Identify them without writing a cookie to their machine.[../trash/msfree.asp]%>

http://www.learnASP.com/learn/stateproscons.asp by Charles M. Carroll Page 73

State Management Intro by Charles CarrollNot written yet.

http://www.learnASP.com/learn/hidden.asp by Charles M. Carroll Page 74

Passing Data with Hidden Fields by Charles CarrollThis page demonstrates how to have several pages that are forms yet after all pages are filled out the final form has access to allinputs without session variables.

surveypage1.asp asks the user the first questions:

1 <html><head>2 <TITLE>surveypage1.asp</TITLE>3 </head>4 <body bgcolor="#FFFFFF">5 <form action="surveypage2.asp" method="post">6 First Name<br>7 &nbsp;&nbsp;&nbsp;8 <input type="text" name="first" size="20"><br>9 Last Name<br>10 &nbsp;&nbsp;&nbsp;

Page 71: [ebook] Learn ASP

11 <input type="text" name="last" size="20">12 <p>&nbsp;&nbsp;&nbsp;13 <input type="submit" value="Next Question ->"></p>14 </form>15 </body></html>

surveypage2.asp asks the user the next questions:

1 <html><head>2 <TITLE>surveypage2.asp</TITLE>3 </head>4 <body bgcolor="#FFFFFF">5 <form action="surveypage3.asp" method="post">6 <%7 first=request.form("first")8 last=request.form("last")9 %>10 Hair Color<br>11 &nbsp;&nbsp;&nbsp;12 <input type="text" name="haircolor" size="20"><br>13 Favorite Color<br>14 &nbsp;&nbsp;&nbsp;15 <input type="text" name="favoritecolor" size="20">16 <p>&nbsp;&nbsp;&nbsp;17 <input type="hidden" name="first" value="<%=first%>">18 <input type="hidden" name="last" value="<%=last%>">19 <input type="submit" value="Next Question ->"></p>20 </form>21 </body></html>

surveypage3.asp asks the user yet some more questions:

1 <html><head>2 <TITLE>surveypage2.asp</TITLE>3 </head>4 <body bgcolor="#FFFFFF">5 <%6 first=request.form("first")7 last=request.form("last")8 haircolor=request.form("haircolor")9 favoritecolor=request.form("favoritecolor")10 %>11 <form action="surveypage3respond.asp" method="post">12 Street Address<br>13 &nbsp;&nbsp;&nbsp;14 <input type="text" name="street" size="20">15 <br>16 City<br>17 &nbsp;&nbsp;&nbsp;18 <input type="text" name="city" size="20"><br>19 State<br>20 &nbsp;&nbsp;&nbsp;21 <input type="text" name="state" size="20">22 <br>23 Zip<br>24 &nbsp;&nbsp;&nbsp;25 <input type="text" name="zip" size="20">26 <br>27 &nbsp;&nbsp;&nbsp;28 29 <input type="hidden" name="first" value="<%=first%>">30 <input type="hidden" name="last" value="<%=last%>">31 <input type="hidden" name="haircolor" value="<%=haircolor%>">32 <input type="hidden" name="favoritecolor" value="<%=favoritecolor%>">33 34 <input type="submit" value="Final Step ->">35 </form>36 </body></html>

Page 72: [ebook] Learn ASP

surveypage3respond.asp gathers all the answers and responds:

1 <html><head>2 <TITLE>surveypage3respond.asp</TITLE>3 </head>4 <body bgcolor="#FFFFFF">5 <%6 first=request.form("first")7 last=request.form("last")8 haircolor=request.form("haircolor")9 favoritecolor=request.form("favoritecolor")10 street=request.form("street")11 city=request.form("city")12 state=request.form("state")13 zip=request.form("zip")14 %>15 Thanks for all your information<br>16 We are happy to meet you <%=first%>&nbsp;<%=last%><br>17 We know your hair color is <%=haircolor%><br>18 and your favorite color is <%=favoritecolor%><br>19 and we will ship all items to<br>20 <%=first%>&nbsp;<%=last%><br>21 <%=street%><br>22 <%=city%>&nbsp;<%=state%>&nbsp;<%=zip%>23 </body></html>

http://www.learnASP.com/learn/cookies.asp by Charles M. Carroll Page 75

Passing Data with Cookies by Charles CarrollThis page demonstrates how to have several pages that are forms yet after all pages are filled out the final form has access to allinputs even after the browser is opened and closed. The browser must accept cookies.

surveypage1c.asp asks the user the first questions:

1 <html><head>2 <TITLE>surveypage1.asp</TITLE>3 </head>4 <body bgcolor="#FFFFFF">5 <%6 first=request.cookies("prefs")("first")7 last=request.cookies("prefs")("last")8 %>9 <form action="surveypage2c.asp" method="post">10 First Name<br>11 &nbsp;&nbsp;&nbsp;12 <input type="text" name="first" size="20" value="<%=first%>"><br>13 Last Name<br>14 &nbsp;&nbsp;&nbsp;15 <input type="text" name="last" size="20" value="<%=last%>">16 <p>&nbsp;&nbsp;&nbsp;17 <input type="submit" value="Next Question ->"></p>18 </form>19 <%20 For Each cookie in Response.Cookies21 Response.Cookies(cookie).Expires = now()+36522 Next23 %>24 </body></html>

surveypage2c.asp asks the user the next questions:

Page 73: [ebook] Learn ASP

1 <%response.buffer=true%>2 <html><head>3 <TITLE>surveypage2c.asp</TITLE>4 </head>5 <body bgcolor="#FFFFFF">6 <%7 first=request("first")8 last=request("last")9 haircolor=request.cookies("prefs")("haircolor")10 favoritecolor=request.cookies("prefs")("favoritecolor")11 %>12 <form action="surveypage3c.asp" method="post">13 Hair Color<br>14 &nbsp;&nbsp;&nbsp;15 <input type="text" name="haircolor" size="20" value="<%=haircolor%>"><br>16 Favorite Color<br>17 &nbsp;&nbsp;&nbsp;18 <input type="text" name="favoritecolor" size="20" value="<%=favoritecolor%>">19 <p>20 <%21 response.cookies("prefs")("first")=first22 response.cookies("prefs")("last")=last23 For Each cookie in Response.Cookies24 Response.Cookies(cookie).Expires = now()+36525 Next26 %>27 <input type="submit" value="Next Question ->"></p>28 </form>29 </body></html>

surveypage3c.asp asks the user yet some more questions:

1 <%response.buffer=true%>2 <html><head>3 <TITLE>surveypage3c.asp</TITLE>4 </head>5 <body bgcolor="#FFFFFF">6 <%7 haircolor=request("haircolor")8 favoritecolor=request("favoritecolor")9 street=request.cookies("prefs")("street")10 city=request.cookies("prefs")("city")11 state=request.cookies("prefs")("state")12 zip=request.cookies("prefs")("zip")13 %>14 <form action="surveypage3crespond.asp" method="post">15 Street Address<br>16 &nbsp;&nbsp;&nbsp;17 <input type="text" name="street" size="20" value="<%=street%>">18 <br>19 City<br>20 &nbsp;&nbsp;&nbsp;21 <input type="text" name="city" size="20" value="<%=city%>"><br>22 State<br>23 &nbsp;&nbsp;&nbsp;24 <input type="text" name="state" size="20" value="<%=state%>">25 <br>26 Zip<br>27 &nbsp;&nbsp;&nbsp;28 <input type="text" name="zip" size="20" value="<%=zip%>">29 <br>30 <%31 response.cookies("prefs")("haircolor")=haircolor32 response.cookies("prefs")("favoritecolor")=favoritecolor33 For Each cookie in Response.Cookies34 Response.Cookies(cookie).Expires = now()+36535 Next36 %>

Page 74: [ebook] Learn ASP

37 <input type="submit" value="Final Step ->">38 </form>39 </body></html>

surveypage3crespond.asp gathers all the answers and responds:

1 <%response.buffer=true%>2 <html><head>3 <TITLE>surveypage3respond.asp</TITLE>4 </head>5 <body bgcolor="#FFFFFF">6 <%7 first=request.cookies("prefs")("first")8 last=request.cookies("prefs")("last")9 haircolor=request.cookies("prefs")("haircolor")10 favoritecolor=request.cookies("prefs")("favoritecolor")11 street=request("street")12 city=request("city")13 state=request("state")14 zip=request("zip")15 %>16 Thanks for all your information<br>17 We are happy to meet you <%=first%>&nbsp;<%=last%><br>18 We know your hair color is <%=haircolor%><br>19 and your favorite color is <%=favoritecolor%><br>20 and we will ship all items to<br>21 <%=first%>&nbsp;<%=last%><br>22 <%=street%><br>23 <%=city%>&nbsp;<%=state%>&nbsp;<%=zip%>24 <%25 response.cookies("prefs")("street")=street26 response.cookies("prefs")("city")=city27 response.cookies("prefs")("state")=state28 response.cookies("prefs")("zip")=zip29 For Each cookie in Response.Cookies30 Response.Cookies(cookie).Expires = now()+36531 Next32 %>33 </body></html>

http://www.learnASP.com/learn/statesessions.asp by Charles M. Carroll Page 76

State Management Intro by Charles CarrollNot written yet.

http://www.learnASP.com/learn/statedb.asp by Charles M. Carroll Page 77

State Management Intro by Charles CarrollNot written yet.

http://www.learnASP.com/learn/statemore.asp by Charles M. Carroll Page 78

Page 75: [ebook] Learn ASP

Global.asa, Sessions, Custom Stats ResourcesThe global.asa, application and sesion variables are certainly a more complex and controversial subject than most ASP topics. Othersites and my site has a lot to say on this:

Everything you wanted to know about global.asa but were afraid to ask @http://www.4guysfromrolla.com/webtech/113098-1.shtml

The lowdown on Global.asa, session vars and app. varshttp://www.asp101.com/resources/apps_sessions_gasa.asp

An example of home-brewed stats:http://www.asp101.com/resources/active_users.asp

Steve Smith's Stats examples:

http://www.aspalliance.com/stevesmith/samples/whosoncode.asp

http://www.aspalliance.com/stevesmith/samples/sitestats.asp

http://www.learnASP.com/learn/aspstatemanagement.asp by Charles M. Carroll Page 79

aspstatemanagement Listserver

JOIN, QUIT or Search ARCHIVES:http://www.asplists.com/asplists/aspstatemanagement.asp

Send Listserver Questions [email protected]

Related LinksGlobal.asa Basics @ http://www.learnasp.com/learn/global.aspFREE Dictionary Component that is session/app safe @ http://www.caprockconsulting.com/comsoftware.htmHidden Fields to Pass Data between pages @ http://www.learnasp.com/learn/hidden.aspGlobal.asa Sclability problems @ http://www.learnasp.com/learn/globalproblems.aspSessions: what are they? @ http://www.learnasp.com/learn/sessionswhat.asp4 Ways to Pass data from page to page @ http://www.4guysfromrolla.com/webtech/041399-1.shtmlCache application level Recordset @ http://msdn.microsoft.com/workshop/server/feature/cache.asp

http://www.learnASP.com/learn/database.asp by Charles M. Carroll Page 80

DB: Troubleshooting Part 1 (dbtroubles.asp) - Page 81 DB: Troubleshooting Part 2 (dbtroubles2.asp) - Page 82

Page 76: [ebook] Learn ASP

DB: Displaying Table w/Simple Code (dbsimple.asp) - Page 83 DB: Table Displayed Generically (dbtable.asp) - Page 84 DB: List Box Displayed Generically (dblist.asp) - Page 85 Database to ListBox Online Resources (dblistmore.asp) - Page 86 DB: Generic DB by Eli Robillard (genericdb.asp) - Page 87 DB: More ways To Display Tables (dbtablemore.asp) - Page 88 DB: DSNLess Connections (dbopen.asp) - Page 89 DB: DSN Setup #1 by Rob Martinson (dsn1.asp) - Page 90 DB: DSN Setup #2 by Rob Martinson (dsn2.asp) - Page 91 DB: DSN Setup #3 by Rob Martinson (dsn3.asp) - Page 92 DB: DSN Setup #4 by Rob Martinson (dsn4.asp) - Page 93 DB: DSN Setup #5 by Rob Martinson (dsn5.asp) - Page 94 DB: DSN Setup #6 by Rob Martinson (dsn6.asp) - Page 95 DB: Full Cycle #1 Show/Edit/Update (dbfull1.asp) - Page 96 DB: Full Cycle #2 Show/Edit/Update (dbfull2.asp) - Page 97 DB: Full Cycle #3 Show/Edit/Update (dbfull3.asp) - Page 98 DB: Converting a DB to a Comma-Delimited file (dbconvert.asp) - Page 99 DB: Deleting a Record w/SQL (dbSQLdelete.asp) - Page 100 DB: Access vs. SQL Server (accessSQLserver.asp) - Page 101 DB: Oracle and ASP (oracle.asp) - Page 102

http://www.learnASP.com/learn/dbtroubles.asp by Charles M. Carroll Page 81

Databases Troubleshooting ResourcesWhen your database code does not work, we actually manage a listserv you can write to send in your code and have yourcolleagues from around the world on the listserv help you fix it. People having trouble with ASP code communicating with a specificdatabase should try their questions on one of these lists:

AccessDB2 AS400DbaseFox/Visual FoxProInformixSQLserver 6.5SQLserver 7.xOracle Setup/Can't Connect!OracleParadoxReports/Printing (Crystal, PDF, etc.)RDS (Remote Data Services)SQL: Joins, complex queries, shapingSybase

Page 77: [ebook] Learn ASP

http://www.learnASP.com/learn/dbtroubles2.asp by Charles M. Carroll Page 82

Databases Troubleshooting Resources Part 2The web is replete with many database resources that we think people should read up on.

User entered ' in Field @ http://www.learnasp.com/learn/FAQdbSinglequote.aspError: Operation must use an updatable query @ http://www.learnasp.com/learn/FAQdbUpdate.aspQuery with LIKE Results in Error @ http://www.learnasp.com/learn/FAQdbLIKE.aspRetrieveing Memo Field Results in Error @ http://www.learnasp.com/learn/FAQdbMEMO.aspSyntax Error in SQL statement @ http://www.learnasp.com/learn/FAQdbSQLSyntax.aspBuild a Drilldown DB screen @ http://www.4guysfromrolla.com/webtech/070799-1.shtmlGeneric DB Free Display Tool @ http://www.ofifc.org/Eli/asp/

http://www.learnASP.com/learn/dbsimple.asp by Charles M. Carroll Page 83

Database -- Simple Table Display by Charles CarrollThis page demonstrates the capabilities how to display a table from a SQL statement.

1 <html><head>2 <TITLE>dbsimple.asp</TITLE>3 </head>4 <body bgcolor="#FFFFFF">5 <%6 ' this code opens the database7 myDSN="DSN=Student;uid=student;pwd=magic"8 set conntemp=server.createobject("adodb.connection")9 conntemp.open myDSN10 11 ' this code retrieves the data12 mySQL="select * from publishers where state='NY'"13 set rstemp=conntemp.execute(mySQL)14 15 ' this code detects if data is empty16 If rstemp.eof then17 response.write "No records matched<br>"18 response.write mySQL & "<br>So cannot make table..."19 connection.close20 set connection=nothing21 response.end22 end if23 %>24 <table border=1>25 <%26 ' This code puts fieldnames into column headings27 response.write "<tr>"

Page 78: [ebook] Learn ASP

28 for each whatever in rstemp.fields29 response.write "<td><B>" & whatever.name & "</B></TD>"30 next31 response.write "</tr>"32 33 ' Now lets grab all the records34 DO UNTIL rstemp.eof35 ' put fields into variables36 pubid=rstemp("pubid")37 name=rstemp("name")38 company_name=rstemp("company_name")39 address=rstemp("address")40 city=rstemp("city")41 state=rstemp("state")42 zip=rstemp("zip")43 telephone=rstemp("telephone")44 fax=rstemp("fax")45 comments=rstemp("comments")46 47 ' write the fields to browser48 cellstart="<td align=""top"">"49 response.write "<tr>"50 response.write cellstart & pubid & "</td>"51 response.write cellstart & name & "</td>"52 response.write cellstart & company_name & "</td>" 53 response.write cellstart & address & "</td>"54 response.write cellstart & city & "</td>"55 response.write cellstart & state & "</td>"56 response.write cellstart & zip & "</td>"57 response.write cellstart & telephone & "</td>"58 response.write cellstart & fax & "</td>"59 response.write cellstart & comments & "</td>"60 61 response.write "</tr>"62 rstemp.movenext63 LOOP64 %>65 </table>66 67 <%68 ' Now close and dispose of resources69 rstemp.close70 set rstemp=nothing71 conntemp.close72 set conntemp=nothing73 %>74 </body></html>

http://www.learnASP.com/learn/dbtable.asp by Charles M. Carroll Page 84

Display Table on Web Page by Charles CarrollThis page demonstrates the capabilities how to display a table from a SQL statement. It illustrates not only how to display the table,but also how to detect that no records were returned from a query, and how to detect null and blank values in the data.

1 <html><head>2 <TITLE>dbtable.asp</TITLE>3 </head>4 <body bgcolor="#FFFFFF">5 <%6 ' ASP program that displays a database in table form7 myDSN="DSN=Student;uid=student;pwd=magic"

Page 79: [ebook] Learn ASP

8 mySQL="select * from publishers where state='NY'"9 showblank="&nbsp;"10 shownull="-null-"11 12 set conntemp=server.createobject("adodb.connection")13 conntemp.open myDSN14 set rstemp=conntemp.execute(mySQL)15 If rstemp.eof then16 response.write "No records matched<br>"17 response.write mySQL & "<br>So cannot make table..."18 conntemp.close19 set conntemp=nothing20 response.end21 end if22 %>23 <table border=1><tr>24 25 <% 'Put Headings On The Table of Field Names26 for each whatever in rstemp.fields%>27 <td><b><%=whatever.name%></B></TD>28 <% next %>29 </tr>30 31 <% ' Now lets grab all the records32 DO UNTIL rstemp.eof %>33 <tr>34 <% for each whatever in rstemp.fields35 thisfield=whatever.value36 if isnull(thisfield) then37 thisfield=shownull38 end if39 if trim(thisfield)="" then40 thisfield=showblank41 end if%>42 <td valign=top><%=thisfield%></td>43 <% next %>44 </tr>45 <%rstemp.movenext46 LOOP%>47 </table>48 49 <%50 rstemp.close51 set rstemp=nothing52 conntemp.close53 set conntemp=nothing54 %>55 </body></html>

http://www.learnASP.com/learn/dblist.asp by Charles M. Carroll Page 85

HTML List Box from ColumnThis page demonstrates the capabilities how to display a list box from a SQL statement. This is the simplest possible example. Thescript to display a list from a database is:

1 <html><head>2 <TITLE>dblist.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <%5 myDSN="DSN=Student;uid=student;pwd=magic"6 mySQL="select author from authors where AU_ID<100"

Page 80: [ebook] Learn ASP

7 8 ' displays a database field as a listbox9 set conntemp=server.createobject("adodb.connection")10 conntemp.open myDSN11 set rstemp=conntemp.execute(mySQL)12 if rstemp.eof then13 response.write "no data for<br>"14 response.write mySQL15 conntemp.close16 set conntemp=nothing17 response.end 18 end if19 20 %>21 <form action="dblistrespond.asp" method="post">22 <Select name="authorname">23 <%24 ' Now lets grab all the data25 do until rstemp.eof %>26 <option> <%=RStemp(0)%> </option>27 <%28 rstemp.movenext29 loop30 31 rstemp.close32 set rstemp=nothing33 conntemp.close34 set conntemp=nothing35 %>36 <input type="submit" value="Choose Author">37 </Select></form>38 </body></html>

The form responder dblistrespond.asp is:1 <html><head>2 <TITLE>dblistrespond.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <%5 my_author=request.form("authorname")6 %>7 You choose <%=my_author%><br>Thanks!<br>8 </body></html>

http://www.learnASP.com/learn/dblistmore.asp by Charles M. Carroll Page 86

Database Listbox ResourcesThere are actually many approaches to creating listboxes from databases demonstrated on this site and other sites:

http://www.learnasp.com/learn/subdblist.asp

http://www.learnasp.com/learn/subdblistbest.asp

http://www.siteexperts.com/tips/elements/ts25/page1.asp

http://www.niblack.com/kbase/listbox_create_x.asp

http://www.niblack.com/kbase/listboxmgmt_x.asp

http://www.niblack.com/kbase/listbox_x.asp

And many people like dynamic list boxes where one listbox choice affects the values available in the other listbox:

Page 81: [ebook] Learn ASP

http://www.learnasp.com/learn/listdynamic.asp

http://www.learnasp.com/learn/listdynamicdb.asp

http://www.learnasp.com/learn/listdynamicmore.asp

There are also some alternative approaches to building alternative, gimicky listboxes that are helpful:

http://www.learnasp.com/learn/listdual.asp

http://www.siteexperts.com/tips/elements/ts22/page1.asp

http://n2.neoshop.com/

http://www.learnASP.com/learn/genericdb.asp by Charles M. Carroll Page 87

Generic Database Display Made EasyWhen you want a quick easy generic database display, go on over to:http://www.ofifc.org/Eli/asp/homepage.asp

Here Eli Robillard has done a lot of work for you. You modify one ASP file that specifies your database and query specs and his ASPscripts magically do the rest.

Here is an example where I make a pubs.asp designed to plug into his ASP scripts.

1 <%2 ' Generic interface to the Northwinds Employee table.3 Session("dbGenericPath") = "/learn/test/genericdb/"4 Session("dbExitPage") = "http://www.activeserverpages.com"5 Session("dbTitle") = "Pubs"6 Session("dbType") = "SQL"7 Session("dbConn") = "DSN=student;uid=student;pwd=magic"8 Session("dbRs") = "Publishers"9 Session("dbKey") = 110 Session("dbOrder") = 211 Session("dbRecsPerPage") = 1012 Session("dbFooter") = 113 Session("dbDispList") = "011101000000100010"14 Session("dbDispView") = "111111111111111111"15 Session("dbDispEdit") = "011111111111111111"16 Session("dbSearchFields") = "011100010010001000"17 Session("dbDefault6") = Date()18 Session("dbCombo11") = "LIST, ??, Unknown, CA, Canada, US, United States, DE, Denmark"19 Session("dbDefault17") = 1020 Session("dbWhere") = ""21 Session("dbDebug") = 122 Session("dbCanEdit") = 123 Session("dbCanAdd") = 124 Session("dbCanDelete") = 125 Session("dbConfirmDelete") = 126 Session("dbViewPage") = Request.ServerVariables("PATH_INFO")27 Response.Redirect Session("dbGenericPath") & "GenericList.asp"28 %>

There is even a listserve supporting this great FREE script collection. It is not a general database troubleshooting list, insteadonly questions concerning these wonderful scripts are allowed.

aspgenericdb Listserver

JOIN, QUIT or Search ARCHIVES:

Page 82: [ebook] Learn ASP

http://www.asplists.com/asplists/genericdb.asp

Send Listserver Questions [email protected]

Related LinksGeneric DB Main Page @ http://www.ofifc.org/Eli/asp/

http://www.learnASP.com/learn/dbtablemore.asp by Charles M. Carroll Page 88

Display database table on Web PageMany Approaches by Charles CarrollThere are many ways to display a table on a web page. So many that we feel that a brief description of the variations and someURLs will help. A good programmer knows many ways to tackle the same problem!Paging through arbitrary groups of records (i.e. record __ of __ ) at: /learn/dbtablepaged.asp

Displaying a table without using a DSN, i.e. a DSNLess connection at: /learn/dbopen.asp

Use the faster Getrows function to retrieve a recordset into an array: /learn/dbtablegetrows.asp

Use the lightning fast Getstring function to retrieve a recordset into a string: /learn/dbtablegetstring.asp

Using a very nice generic routine from Eli Robillard at: /learn/genericdb.asp

Use an excellent 3rd party component (ASPDB): http://www.learnasp.com/learn/aspdb.asp

Displaying a Table with many records as quick as possible is documented in depth at: /learn/speedtables.asp /learn/speedtablesall.asp

Displaying a Table using simple subroutines & includes at: /learn/subdbtable.aspDisplaying tables, listboxes and other arbitrary HTML at: /learn/subreusable.asp

http://www.learnASP.com/learn/dbopen.asp by Charles M. Carroll Page 89

DSNless connection by Charles CarrollAny ASP script that needs to connect to a database must open it on the server first.There are several ways:

a system DSNwhich must be setup on the server, see:/learn/dsn1.asp for detailed instructions orhttp://www.aspalliance.com/components/database.asp for components that automate this task.

Page 83: [ebook] Learn ASP

This is the fastest way since all the information resides on the server and need only be validated when the DSN is setup.

a File DSNwhich is not recommended for high concurrency situations since all users would be limited speedwise to how fast the ASII file thatholds the DSN could be accessed.a DSNless connectionwhich requires no server setup, just a carefully constructed connection string as demonstrated below.This is a necessary evil if a DSN is not available and not as fast as a system DSN since the server must validate the connectioninformation each attempt.

The trouble with a File DSN is that every connection.open must:open, read, close an ASCII file (which may cause concurrency problems on a busy site)●

present the data anew to the provider/driver since the ASCII file may have changed since last connection.●

The designers of ASP have seen File DSNs fail on big busy sites because of reason a) so discourage them. System DSNs thay relyon registry keys in memory are much faster.

Microsoft has a knowledge base article at:http://support.microsoft.com/support/kb/articles/q193/3/32.aspwhich explains all the DSNless connection strings.

DSNless connections demand that that you know the name of the file (i.e. file based databases like Access, Paradox, FoxPro, etc.)or the address of the data server (SQLserver for example). Armed with appropriate information you could open a data source withouta DSN!

Note that you must know the actual filepath on the server, i.e. nwind.mdb is not good enough it needs to be"C:\thatserver\account17\nwind.mdb". Fortunately the server.mappath function can turn a filename into the proper fully qualifiedfilename with path on the server.

Here is a sample nwind.asp connecting to an access database named "nwind.mdb" in the root of the web site with a DSNlessconnection.1 <HTML><HEAD>2 <TITLE>nwind.asp</TITLE>3 <body bgcolor="#FFFFFF"></HEAD>4 <%5 accessdb="nwind.mdb"6 myDSN="DRIVER={Microsoft Access Driver (*.mdb)};"7 myDSN=myDSN & "DBQ=" & server.mappath(accessdb)8 mySQL="select * from customers"9 10 call query2table(mySQL,myDSN)11 %>12 <!--#include virtual="/learn/test/lib_dbtable.asp"-->13 </BODY>14 </HTML>15

Here is a sample sqldsn.asp connecting to an access database named "nwind.mdb" in the root of the web site with a DSNlessconnection.1 <HTML><HEAD>2 <TITLE>sqldsn.asp</TITLE>3 <body bgcolor="#FFFFFF"></HEAD>4 <%5 accessdb="nwind.mdb"6 myDSN="DSN=student;uid=student;pwd=magic"7 mySQL="select * from publishers where state='NY'"8 9 call query2table(mySQL,myDSN)10 %>11 <!--#include virtual="/learn/test/lib_dbtable.asp"-->12 </BODY>13 </HTML>14

Here is a sample sqldsnless.asp connecting to an access database named "nwind.mdb" in the root of the web site with a DSNlessconnection.1 <HTML><HEAD>

Page 84: [ebook] Learn ASP

2 <TITLE>sqlDSNless.asp</TITLE>3 <body bgcolor="#FFFFFF"></HEAD>4 <%5 6 mydb="PROVIDER=MSDASQL;DRIVER={SQL Server};"7 mydb=mydb & "SERVER=sql2.datareturn.com;DATABASE=;"8 mydb=mydb & "UID=student;PWD=magic;"9 10 mySQL="select * from publishers where state='NY'"11 12 call query2table(mySQL,mydb)13 %>14 <!--#include virtual="/learn/test/lib_dbtable.asp"-->15 </BODY>16 </HTML>17 18

The Include file lib_dbtable.asp looks like this:1 <%2 sub query2table(inputquery, inputDSN)3 dim conntemp, rstemp4 set conntemp=server.createobject("adodb.connection")5 conntemp.open inputDSN6 set rstemp=conntemp.execute(inputquery)7 howmanyfields=rstemp.fields.count -1%>8 <table border=1><tr>9 <% 'Put Headings On The Table of Field Names10 for i=0 to howmanyfields %>11 <td><b><%=rstemp(i).name%></B></TD>12 <% next %>13 </tr>14 <% ' Now lets grab all the records15 do while not rstemp.eof %>16 <tr>17 <% for i = 0 to howmanyfields18 thisvalue=rstemp(i)19 If isnull(thisvalue) then20 thisvalue="&nbsp;"21 end if%>22 <td valign=top><%=thisvalue%></td>23 <% next %>24 </tr>25 <%rstemp.movenext26 loop%>27 </table>28 <%29 rstemp.close30 set rstemp=nothing31 conntemp.close32 set conntemp=nothing33 end sub%>

http://www.learnASP.com/learn/dsn1.asp by Charles M. Carroll Page 90

Setting up a system DSN on Windows 95/NT©1998, 1999 by Rob Martinson [email protected]

The easiest way to begin learning ASP, is to install Microsoft PWS, and develop locally. To do this, you must also setup a DSN (DataSource Name) on your machine, if you wish to use any of ASP's database access abilities. This tutorial is meant to walk you throughthe process of setting up a system DSN on your Windows machine.

Page 85: [ebook] Learn ASP

The first step, after you have PWS installed, is to open your control panel and select the 32bit ODBC Data SourceAdministrator icon (shown below).

http://www.learnASP.com/learn/dsn2.asp by Charles M. Carroll Page 91

Setting up a system DSN Part 2©1998, 1999 by Rob Martinson [email protected]

Setting up a system DSN on Windows 95/NT

Once the ODBC Data Source Administrator window is open, select the System DSN tab at the top (I'm doing a system DSNbecause that's what I generally use. See here for more info on the differences between system and file DSNs). This will bringyou to a list of System Data Sources that are setup on your machine. It may vary from the list above. From this point, clickthe "Add" button and move on to the next screen.

Page 86: [ebook] Learn ASP

http://www.learnASP.com/learn/dsn3.asp by Charles M. Carroll Page 92

Setting up a system DSN Part 3©1998, 1999 by Rob Martinson [email protected]

I began my development using Microsoft Access as I already had a copy, and it would help me to learnSQL syntax that would later be of use in larger projects. For this reason, I will choose the MS AccessDatabase driver from this screen. If you are setting up a DSN for a different database format, select theassociated driver here.

Page 87: [ebook] Learn ASP

http://www.learnASP.com/learn/dsn4.asp by Charles M. Carroll Page 93

Setting up a system DSN Part 4©1998, 1999 by Rob Martinson [email protected]

Here we will name our DSN. For web development, I generally setup a single DSN (depending on the project of course) and thenjust modify the database as needed. Because of that, I almost always name mine "tables.dsn". Name it whatever you like, justremember the name. From this screen you are also able to setup various options with your DSN including default authorization (clickadvanced), page timeout, database location, etc. For now we will leave the default options and move on to the next screen bychoosing "Ok".

Page 88: [ebook] Learn ASP

http://www.learnASP.com/learn/dsn5.asp by Charles M. Carroll Page 94

Setting up a system DSN Part 5©1998, 1999 by Rob Martinson [email protected]

If we have not specified the location of the database associated with our DSN on the previous screen, we will be prompted todo so now. This is self explanatory I believe.

http://www.learnASP.com/learn/dsn6.asp by Charles M. Carroll Page 95

Setting up a system DSN©1998, 1999 by Rob Martinson [email protected]

That's it! Your System DSN is setup and running. All you need to do now is get ASP to use it (which is pretty easy).

Page 89: [ebook] Learn ASP

http://www.learnASP.com/learn/dbfull1.asp by Charles M. Carroll Page 96

Database Full Cycle #1 --Display Table, Edit Record, Update Record

dbfull1.asp merely displays a table like we have in other examples, except every row of the table has a hyperlink to dbfull2.asp andpasses the ID to that script in a variable called whichID. After the user edits that information and presses submit, dbfull3.asp iscalled. It's task is to gather all input fields and construct a SQL update statement. Here is a source printout of the script that displaysthe table and "starts the ball rolling":

1 <%2 response.buffer=true3 Response.ExpiresAbsolute = Now() - 14 Response.AddHeader "Cache-Control", "private"5 %>6 <html><head>7 <title>authorshow.asp</title>8 <meta http-equiv="pragma" content="no-cache">9 </head><body bgcolor="#FFFFFF">10 <%11 myDSN="DSN=Student;uid=student;pwd=magic"12 mySQL="select * from authors where AU_ID<100 order by author"13 IDfield="AU_ID"14 scriptresponder="authoredit.asp"15 16 set conntemp=server.createobject("adodb.connection")17 conntemp.open myDSN18 set rstemp=conntemp.execute(mySQL)19 howmanyfields=rstemp.fields.count -120 %>21 <table border="1">

Page 90: [ebook] Learn ASP

22 <tr>23 <td valign="top">---</td>24 <% 'Put Headings On The Table of Field Names25 for i=0 to howmanyfields %>26 <td><b><%=rstemp(i).name %></b></td>27 <% next %>28 </tr>29 <% ' Now lets grab all the records30 do while not rstemp.eof %>31 <tr><td valign="top">32 <%my_link=scriptresponder & "?which=" & rstemp(idfield)%>33 <a HREF="<%=my_link%>">Edit</a></td>34 <% for i = 0 to howmanyfields%>35 <td valign="top"><%=rstemp(i)%></td>36 <% next %>37 </tr>38 <%39 rstemp.movenext40 loop41 42 rstemp.close43 set rstemp=nothing44 conntemp.close45 set conntemp=nothing46 %>47 </table></body></html>

http://www.learnASP.com/learn/dbfull2.asp by Charles M. Carroll Page 97

Database Full Cycle #2 --Display Table, Edit Record, Update Record

Here is the script that shows one record based on being linked to from the table

1 <html><head>2 <title>authoredit.asp</title>3 </head><body bgcolor="#FFFFFF">4 <%5 ' My ASP program that given an AU_ID, allows editing a record6 7 myDSN="DSN=Student;uid=student;pwd=magic"8 9 set conntemp=server.createobject("adodb.connection")10 conntemp.open myDSN11 form_ID=request.querystring("which")12 13 sqltemp="select * from authors "14 sqltemp=sqltemp & " where AU_ID=" & form_id15 16 set rstemp=conntemp.execute(sqltemp)17 18 19 form_auID=rstemp("AU_ID")20 form_author=rstemp("Author")21 form_year_born=rstemp("Year_Born")22 23 rstemp.close24 set rstemp=nothing25 conntemp.close26 set conntemp=nothing27 %>28 <body>

Page 91: [ebook] Learn ASP

29 <form name="myauthor" action="authoreditrespond.asp" method="POST">30 31 <input type="hidden" name="id" value="<%=form_auid%>">32 33 <p>Author ID: <%=form_auid%></p>34 35 <p> Author Name:36 <input type="TEXT" name="name" value="<%=form_author%>"></p>37 38 <p> Year Born:39 <input type="TEXT" name="year" value="<%=form_year_born%>"></p>40 41 <p> <input type="SUBMIT"> </p>42 </form>43 </body>

http://www.learnASP.com/learn/dbfull3.asp by Charles M. Carroll Page 98

Database Full Cycle #3 --Display Table, Edit Record, Update Record

Here is the script that updates one record after the submit button is pushed on the previous script.

1 <HTML><HEAD>2 <TITLE>authoreditrespond.asp</TITLE>3 <body bgcolor="#FFFFFF"></HEAD>4 <%5 on error resume next6 form_name=request.form("name")7 form_year=request.form("year")8 form_ID=request.form("ID")9 10 Set Conn = Server.CreateObject("ADODB.Connection")11 conn.open "DSN=Student;uid=student;pwd=magic"12 13 ' change apostrophe to double apostrophe14 form_name=Replace(form_name, "'", "''")15 16 SQLstmt = "UPDATE authors SET "17 SQLStmt = SQLstmt & "Author='" & form_name & "',"18 SQLstmt = SQLstmt & "year_born=" & form_year19 SQLStmt = SQLStmt & " WHERE AU_ID=" & form_id20 21 22 Set RS = Conn.Execute(SQLStmt)23 24 If err.number>0 then25 response.write "VBScript Errors Occured:" & "<P>"26 response.write "Error Number=" & err.number & "<P>"27 response.write "Error Descr.=" & err.description & "<P>"28 response.write "Help Context=" & err.helpcontext & "<P>"29 response.write "Help Path=" & err.helppath & "<P>"30 response.write "Native Error=" & err.nativeerror & "<P>"31 response.write "Source=" & err.source & "<P>"32 response.write "SQLState=" & err.sqlstate & "<P>"33 end if34 IF conn.errors.count> 0 then35 response.write "Database Errors Occured" & "<P>"36 response.write SQLstmt & "<P>"37 for counter= 0 to conn.errors.count38 response.write "Error #" & conn.errors(counter).number & "<P>"39 response.write "Error desc. -> " & conn.errors(counter).description & "<P>"

Page 92: [ebook] Learn ASP

40 next41 else42 response.write "<B>Everything Went Fine. Record is updated now!</b>"43 response.write "<br>" & SQLstmt44 end if45 46 rs.close47 set rs=nothing48 Conn.Close49 set conn=nothing50 %>51 </BODY>52 </HTML>

http://www.learnASP.com/learn/dbconvert.asp by Charles M. Carroll Page 99

Database -- Convert to Comma-Delimited File by Charles CarrollThis page demonstrates the capabilities how to write an ASCII comma-delimited file from a SQL statement.

1 <html><head>2 <TITLE>dbconvert.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <%5 whichname="/upload/tests/authors.txt"6 myDSN="DSN=Student;uid=student;pwd=magic"7 mySQL="select * from authors where au_id<100"8 showblank=""9 shownull="<null>"10 linestart=chr(34)11 lineend=chr(34)12 delimiter=chr(34) & "," & chr(34)13 delimitersub=""14 15 whichFN=server.mappath(whichname)16 17 Set fstemp = server.CreateObject("Scripting.FileSystemObject")18 Set filetemp = fstemp.CreateTextFile(whichFN, true)19 ' true = file can be over-written if it exists20 ' false = file CANNOT be over-written if it exists21 22 set conntemp=server.createobject("adodb.connection")23 conntemp.open myDSN24 set rstemp=conntemp.execute(mySQL)25 26 ' this code detects if data is empty27 If rstemp.eof then28 response.write "No data to convert for SQL statement<br>"29 response.write mySQL & "<br>"30 connection.close31 set connection=nothing32 response.end33 end if34 35 DO UNTIL rstemp.eof36 thisline=linestart37 for each whatever in rstemp.fields38 thisfield=whatever.value39 if isnull(thisfield) then40 thisfield=shownull41 end if42 if trim(thisfield)="" then

Page 93: [ebook] Learn ASP

43 thisfield=showblank44 end if45 thisfield=replace(thisfield,delimiter,delimitersub)46 thisline=thisline & thisfield & delimiter47 next48 tempLen=len(thisline)49 tempLenDelim=len(delimiter)50 thisline=mid(thisline,1,tempLEN-tempLenDelim) & lineend51 filetemp.WriteLine(thisline)52 ' response.write thisline & "<br>"53 rstemp.movenext54 LOOP55 filetemp.Close56 set filetemp=nothing57 set fstemp=nothing58 rstemp.close59 set rstemp=nothing60 conntemp.close61 set conntemp=nothing62 63 64 65 If err.number=0 then66 response.write "File was converted sucessfully!<br>"67 response.write "Converted file is at <a href='"68 response.write whichname & "'>" & whichname & "</a>"69 else70 response.write "VBScript Errors Occured!<br>"71 response.write "Error Number=#<b>" & err.number & "</b><br>"72 response.write "Error Desc. =<b>" & err.description & "</b><br>"73 response.write "Help Path =<b>" & err.helppath & "</b><br>"74 response.write "Native Error=<b>" & err.nativeerror & "</b><br>"75 response.write "Error Source =<b>" & err.source & "</b><br>"76 response.write "SQL State=#<b>" & err.sqlstate & "</b><br>"77 end if78 79 80 %>81 </body></html>

http://www.learnASP.com/learn/dbSQLdelete.asp by Charles M. Carroll Page 100

Database -- Delete Record with SQL statementSQL statements can be used to delete data as well.

Here is a script that will add a bunch of records with the AU_ID of 200:1 <TITLE>dbaddmany.asp</TITLE>2 <body bgcolor="#FFFFFF">3 <HTML>4 <!--#include file="lib_errors.asp"-->5 <%6 on error resume next7 myDSN = "DSN=Student;uid=student;pwd=magic"8 mySQL = "INSERT INTO authors (AU_ID,author,year_born) "9 mySQL = mySQL & "VALUES (200,'Charles M. Carroll',1964)"10 11 Set Conn = Server.CreateObject("ADODB.Connection")12 conn.open myDSN13 14 for counter=1 to 20015 thistask="Task #" & counter & "<br>"

Page 94: [ebook] Learn ASP

16 response.write thistask17 Conn.Execute(mySQL)18 Call ErrorVBScriptReport(thistask)19 Call ErrorADOReport(mySQL,conn)20 next21 Conn.Close22 set conn=nothing23 %>24 </BODY>25 </HTML>

Now here is a script that will delete all the records the above script added:1 <TITLE>dbdeletemany.asp</TITLE>2 <body bgcolor="#FFFFFF">3 <HTML>4 <!--#include file="lib_errors.asp"-->5 <%6 on error resume next7 myDSN = "DSN=Student;uid=student;pwd=magic"8 mySQL = "DELETE FROM authors WHERE au_id=200"9 10 Set Conn = Server.CreateObject("ADODB.Connection")11 conn.open myDSN12 13 Conn.Execute mySQL,howmany14 response.write "The statement " & mySQL & "<b> deleted " & howmany & " records</b><br>"15 Call ErrorVBScriptReport("Deleting...")16 Call ErrorADOReport(mySQL,conn)17 18 Conn.Close19 set conn=nothing20 %>21 </BODY>22 </HTML>

http://www.learnASP.com/learn/accessSQLserver.asp by Charles M. Carroll Page 101

Access vs. SQL Server by Charles CarrollDRAFT -- NOT FINISHED Microsoft Access is a database package that works well on one machine and with some carefulcoding can function well under a light network and concurrency load. It is rare that a website presents a "light" concurrency load.

http://www.learnASP.com/learn/oracle.asp by Charles M. Carroll Page 102

Oracle and Active Server Pages by Charles CarrollDRAFT -- NOT FINISHEDOracle data can be easily incorporated into ASP scripts though all the details can become complex.

If you have integrating Oracle with your ASP sites, we run a listserv/newgroup called [aspOracle] where that is the only topicallowed you can join to get help from your colleagues worldwide.

aspOracle Listserver

Page 95: [ebook] Learn ASP

JOIN, QUIT or Search ARCHIVES:http://www.asplists.com/asplists/oracle.asp

Send Listserver Questions [email protected]

Related LinksThe Hottest Set of Oracle sites/listserves @ http://www.doug.orgHow to Connect/Troubleshoot Oracle Connection by Bret H. Grade @ /learn/FAQOracleconnect.aspHow to Call Oracle Stored Procedure by Surya Rao @ /learn/FAQOraclestoredproc.aspReturning Recordsets via ADO by John Kilgo @ /asplists/asporacleFAQ4.aspKnow any good Oracle Books? @ /asplists/asporacleFAQ2.asp

http://www.learnASP.com/learn/aspdb.asp by Charles M. Carroll Page 103

ASPDB - A Component That Simplifies Databases (aspdb.asp) - Page 1 ASP DB Sample #1: Displaying Data (aspdb1.asp) - Page 2 ASP DB Sample #2: Editing, Adding Data (aspdb2.asp) - Page 3

http://www.learnASP.com/learn/aspdb1.asp by Charles M. Carroll Page 104

ASPDB: Databases with No Work!This page demonstrates the capabilities how the third party component ASPDB from http://www.aspdb.com makes databaseprogramming simple. Here we will show the code to display a gorgeous table of the customers database just be starting thecomponent and setting a few properties:

1 <% response.buffer=true %>2 <HTML>3 <Head><Title>ASPdb1.asp</Title></Head>4 <%5 Set MyDb = Server.CreateObject("ASPdb.Pro")6 MyDb.dbUnit = 10007 MyDb.dbMDB=Server.MapPath("/learn/test/nwind.mdb")8 MyDb.dbColor = "11"9 MyDb.dbGridTableTag = "border=3"10 MyDb.dbMode= "Grid"11 MyDb.dbSQL = "Select * FROM Customers"12 MyDb.dbNavigationItem = "top, bottom, next, prev, filter"13 MyDb.ASPdbPro14 set myDB=nothing15 %>16 </BODY>17 </HTML>18 19

Page 96: [ebook] Learn ASP

Now we will display publishers:

1 <% response.buffer=true %>2 <HTML>3 <Head><Title>ASPdb1.asp</Title></Head>4 <%5 Set MyDb = Server.CreateObject("ASPdb.Pro")6 MyDb.dbUnit = 10007 MyDb.dbMDB=Server.MapPath("/learn/test/biblio.mdb")8 MyDb.dbColor = "11"9 MyDb.dbGridTableTag = "border=3"10 MyDb.dbMode= "Grid"11 MyDb.dbSQL = "Select * FROM Publishers"12 MyDb.dbNavigationItem = "top, bottom, next, prev, filter"13 MyDb.ASPdbPro14 set myDB=nothing15 %>16 </BODY>17 </HTML>18 19

http://www.learnASP.com/learn/aspdb2.asp by Charles M. Carroll Page 105

ASPDB: Database Editing with A Million Options!This page demonstrates the capabilities how the third party component ASPDB from http://www.aspdb.com makes databaseprogramming powerful and removes you worrying about how and rather what it looks like. Here we will show the code to display agorgeous editable table by starting the component and setting dozens of properties:

1 <% response.buffer=true %>2 <HTML>3 <HEAD><title>ASPdb2.asp</title>4 </HEAD>5 <FONT FACE="Arial,Helvetica" Color=Black Size=3>6 7 <%8 Set MyDb = Server.CreateObject("AspDB.Pro")9 MyDb.dbUnit = 110110 B=Request("ASPdbBut_1101") ' this is NOT case sensitive11 L9=Left(B,9)12 UL9=UCASE(L9)13 L12=Left(B,12)14 UL12=UCASE(L12)15 if UL9 <> "ASPDBEDIT" then16 response.write("<CENTER><B>Welcome to the ASP-db&#153; PRO Test Page.</B><P>")17 response.write("For the benefit of others, please do not delete all of the records.Thanks.<P>")18 response.write("<B>Click on the [Add New] button to see how ASP-db can put default valuesin certain fields.")19 20 response.write("<HR WIDTH=66% Size=1>")21 end if22 23 ' Is it an ASPdbEditUpdate? If so, show user the Name in the "current" record.24 THISNAME = Session("ASPdb_1101_Name")25 26 if UL12 = "ASPDBEDITUPD" then27 MSG1 = "<CENTER><FONT SIZE=4 COLOR=Black><B>"28 MSG1 = MSG1 + "Please Update the Information for: " + THISNAME29 MSG1 = MSG1 + "</B></FONT><P>"30 response.write(MSG1)

Page 97: [ebook] Learn ASP

31 end if32 33 if UL12 = "ASPDBEDITDEL" then34 MSG1 = "<CENTER><FONT SIZE=4 COLOR=red><B>"35 MSG1 = MSG1 + "You are about to DELETE all of the Information for: " + THISNAME36 MSG1 = MSG1 + "</B></FONT><P>"37 response.write(MSG1)38 end if39 40 if UL12 = "ASPDBEDITEDI" then41 MSG1 = "<CENTER><FONT SIZE=4 COLOR=red><B>"42 MSG1 = MSG1 + "You are about to EDIT all of the Information for: " + THISNAME43 MSG1 = MSG1 + "</B></FONT><P>"44 response.write(MSG1)45 end if46 47 Mydb.dbMDB = Server.MapPath("Pro-Demo.mdb") ' Has fields: Name, Age, Salary, NetWorth48 49 MyDb.DBColor = "11,auto,white"50 MyDb.dbGridTableTag = "border=3 cellspacing=3 cellpadding=3"51 MyDb.dbFormTableTag = "border=3 cellspacing=3 cellpadding=3"52 MyDb.dbGridDisplayFlds = "Name,Age,Salary,NetWorth"53 MyDb.DbMode = "dual-horiz"54 MyDb.dbGridInc = 1055 MyDb.dbButtonAnchor=false56 MyDb.dbExportFlds = "Name"57 58 Mydb.dbFilterDropFlds = "Name,,People,Name,,,,,Distinct; Salary,,People,Salary,,,,,Distinct"59 60 Mydb.dbEditDropFlds = "Salary,,,9250.75/11000/15000/21000/25000/32000/38000/44000/75000"61 62 Mydb.dbEditFlds = "Name,Age[10],Salary,NetWorth[123]" ' added Name 07-27-9863 MyDb.dbEditUpdateROFlds = "Name" ' ***** NEW!!!!! *****64 65 EP = "TableName=People,BookMarkFlds=0,TableTag=Border=2"66 EP = EP & ",RecordScope=single,CriteriaSize=4x25,EditSemiColon=;"67 Mydb.dbEditParams = EP68 69 MyDb.dbSQL = "Select * from People"70 71 MyDb.dbMagicCell = _72 "1, align=Left , <font size=2 face=ARIAL color=black><I><B>#1#</B></I>;" & _73 "2, align=Center, <font size=2 face=ARIAL color=black> #2#;" & _74 "3, align=right , <font size=2 face=ARIAL color=black>format=[currency];" & _75 "4, align=right , <font size=2 face=ARIAL color=black>format=[currency];"76 77 MyDb.dbImageDir="images/"78 Mydb.dbNavigation="both"79 Mydb.dbNavigationItem="Next, Prev, Gridrow, Filter, add, update, edit, delete"80 Mydb.dbNavigationIcon="std"81 82 MyDb.aspDBPro83 set mydb=nothing84 %>85 86 </HTML>87 88 89 90

http://www.learnASP.com/learn/ado.asp by Charles M. Carroll Page 106

Page 98: [ebook] Learn ASP

Getstring to display database table (dbtablegetstring.asp) - Page 107 Getrows to display database table (dbtablegetrows.asp) - Page 108 Disconnected Recordsets, Display Table (dbtabledisconnected.asp) - Page 109 ADO: Limiting Number of Records (dbmaxrecs.asp) - Page 110 ADO: Paging Records (dbtablepaged.asp) - Page 111 ADO: Count Records in Query (dbcount.asp) - Page 112 ADO: Cursor Types by Phil Paxton (adocursortypes.asp) - Page 113 ADO: Input Form (dbnewrec.asp) - Page 114 ADO: Input Form, added w/SQL (dbnewSQL.asp) - Page 115 ADO: Input Form, Added w/ADO .addnew (dbnewADO.asp) - Page 116 ADO: GetString function (dbgetstring.asp) - Page 117 ADO: Tables within Databases (dbtablelists.asp) - Page 118 ADO: Schemas to access table lists (dbschemas.asp) - Page 119 ADO: Schemas to access All Data (dbschemasall.asp) - Page 120 ADO: SQL Mistakes (dbtroubleshoot2.asp) - Page 121 ADO: Show Table,1 param (db1parm.asp) - Page 122 ADO: Update/edit Record (dbupdate.asp) - Page 123

http://www.learnASP.com/learn/dbtablegetstring.asp by Charles M. Carroll Page 107

Table Database Display via GetString by Charles CarrollThis page demonstrates the capabilities how to display a table from a SQL statement a very fast and scaleable way using arecordset method called GetString. GetString essentially asks the backend database to build a huge string instead of moving thedata as rows and columns. It allows very limited specifications, basically what string to place between each column and row and howto display nulls. Notice the total absence of the traditional EOF loop.

Does this approach matter for small data sets for example 9 rows x 2 columns of data? YES!!!!!!!!

My site has SQLserver scripts that run like lightning. I once needed to fill a 9 item listbox from Access and got 90 sec script timeoutswith movenext. Getstring never timed out. So in a real production situation it makes weak databases feasible and of course reducesthe load on more industrial back-ends so maybe the SQLserver doesn't need as many indexes or RAM upgrades.

This example does require ADO 2.0 or greater which can be downloaded from:http://www.microsoft.com/data

If you are unsure which ADO version your server has now this code will allow you to identify the version on your server:http://www.learnasp.com/learn/versioncheck.asp

1 <TITLE>dbtablegetstring.asp</TITLE>2 <body bgcolor="#FFFFFF">3 <%4 whichDSN="DSN=Student;uid=student;pwd=magic"5 mySQL="select * from publishers where state='NY'"6 7 ' ASP program that displays a database in table form8 set conntemp=server.createobject("adodb.connection")9 conntemp.open whichDSN10 set rstemp=conntemp.execute(mySQL)11 If rstemp.eof then12 response.write "No records matched<br>"13 response.write mySQL & "<br>So cannot make table..."14 rstemp.close15 set rstemp=nothing16 conntemp.close17 set conntemp=nothing

Page 99: [ebook] Learn ASP

18 response.end19 end if20 response.write "<table border='1'><tr>"21 22 'Put Headings On The Table of Field Names23 for each whatever in rstemp.fields24 response.write "<td><b>" & whatever.name & "</B></TD>"25 next26 response.write "</tr><tr><td>"27 response.write rstemp.getstring(,, "</td><td>", "</td></tr><TR><TD>", "-null-")28 response.write "</td></tr></table>"29 30 rstemp.close31 set rstemp=nothing32 conntemp.close33 set conntemp=nothing34 %>35 </body></html>36 37 38 39 40 41 42

http://www.learnASP.com/learn/dbtablegetrows.asp by Charles M. Carroll Page 108

Table Database Display via GetRows by Charles CarrollThis page demonstrates the capabilities how to display a table from a SQL statement a very fast and scaleable way using arecordset method called GetRows. GetRows that move many records and fields into a memory array. Once in the array it isaccessed very fast. If you read the code closely you will notice it can free up the recordset and connection object earlier than thetraditional loop thus freeing up those resources for other scripts.

In terms of why this is faster, read:http://www.learnasp.com/advice/whygetrows.aspto see an in-depth explanation.

http://www.learnasp.com/learn/dbtablegetstring.asprips getrows to shreds speed-wise as the backend transfers one big string instead of a complex array structure but formatting isSOOOOO limited (unless you know Regexps like the back of your hand....)

Since this code relies heavily on arrays you may want to read up on them at:

http://www.learnasp.com/learn/arrays.asp●

http://www.learnasp.com/learn/arrays2.asp●

http://www.learnasp.com/learn/arrays3.asp●

1 <%@enablesessionstate=false%>2 <%response.buffer=true%>3 <html><head>4 <TITLE>dbtablegetrows.asp</TITLE>5 </head>6 <body bgcolor="#FFFFFF">7 <%8 ' displays a database in table form via GetRows9 myDSN="DSN=Student;uid=student;pwd=magic"10 mySQL="select * from publishers where state='NY'"11 showblank="&nbsp;"

Page 100: [ebook] Learn ASP

12 shownull="-null-"13 14 set conntemp=server.createobject("adodb.connection")15 conntemp.open myDSN16 set rstemp=conntemp.execute(mySQL)17 If rstemp.eof then18 response.write "No records matched<br>"19 response.write mySQL & "<br>So cannot make table..."20 rstemp.close21 set rstemp=nothing22 conntemp.close23 set conntemp=nothing24 response.end25 end if26 27 response.write "<table border='1'><tr>"28 'Put Headings On The Table of Field Names29 for each whatever in rstemp.fields30 response.write "<td><b>" & whatever.name & "</B></TD>"31 next32 response.write "</tr>"33 34 ' Now lets grab all the records35 alldata=rstemp.getrows36 rstemp.close37 set rstemp=nothing38 conntemp.close39 set conntemp=nothing40 41 numcols=ubound(alldata,1)42 numrows=ubound(alldata,2)43 FOR rowcounter= 0 TO numrows44 FOR colcounter=0 to numcols45 thisfield=alldata(colcounter,rowcounter)46 if isnull(thisfield) then47 thisfield=shownull48 end if49 if trim(thisfield)="" then50 thisfield=showblank51 end if52 response.write "<td valign=top>"53 response.write thisfield54 response.write "</td>"55 NEXT56 response.write "</tr>" & vbcrlf57 NEXT58 response.write "</table>"59 %>60 </body></html>

http://www.learnASP.com/learn/dbtabledisconnected.asp by Charles M. Carroll Page 109

Display Table and Disconnect Recordset by Charles CarrollThis page demonstrates the capabilities how to display a table from a SQL statement. It illustrates not only how to display the table,but also how to detect that no records were returned from a query, and how to detect null and blank values in the data. This exampledisconnects the recordset so that the data will not be drawn from up to the millisecond database data BUT retrieval will be muchfaster.

1 <%@enablesessionstate=false%>2 <%response.buffer=true%>3 <!--#include virtual="/adovbs.inc"-->

Page 101: [ebook] Learn ASP

4 <html><head>5 <TITLE>dbtabledisconnected.asp</TITLE>6 </head>7 <body bgcolor="#FFFFFF">8 <%9 ' displays a database in table form via GetRows10 myDSN="DSN=Student;uid=student;pwd=magic"11 mySQL="select * from publishers where state='NY'"12 showblank="&nbsp;"13 shownull="-null-"14 15 set conntemp=server.createobject("adodb.connection")16 conntemp.open myDSN17 ' to disconnect a recordset it must be created explicitly18 set rstemp=server.createobject("adodb.recordset")19 rstemp.cursorlocation=aduseclient20 rstemp.open mySQL,conntemp21 ' this line below disconnects the recordset22 set rstemp.activeconnection=nothing23 24 If rstemp.eof then25 response.write "No records matched<br>"26 response.write mySQL & "<br>So cannot make table..."27 rstemp.close28 set rstemp=nothing29 conntemp.close30 set conntemp=nothing31 response.end32 end if33 34 response.write "<table border='1'><tr>"35 'Put Headings On The Table of Field Names36 for each whatever in rstemp.fields37 response.write "<td><b>" & whatever.name & "</B></TD>"38 next39 response.write "</tr>"40 DO UNTIL rstemp.eof41 response.write "<tr>"42 for each whatever in rstemp.fields43 thisfield=whatever.value44 if isnull(thisfield) then45 thisfield=shownull46 end if47 if trim(thisfield)="" then48 thisfield=showblank49 end if50 response.write "<td valign=top>" & thisfield & "</td>"51 next52 response.write "</tr>"53 rstemp.movenext54 LOOP55 response.write "</table>"56 %>57 </body></html>

http://www.learnASP.com/learn/dbmaxrecs.asp by Charles M. Carroll Page 110

ADO Techniques -- The .maxrecords propertyThis page demonstrates the capabilities how to display a table from a SQL statement but limit the output to a specific number ofrecords.

Page 102: [ebook] Learn ASP

1 <html><head>2 <TITLE>dbmaxrecs.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <!--#INCLUDE VIRTUAL="/ADOVBS.INC" -->5 <%6 set rstemp=Server.CreateObject("adodb.Recordset")7 rstemp.maxrecords=158 connectme="DSN=Student;uid=student;pwd=magic"9 rstemp.open "select * from titles", _10 connectme,adopenstatic11 ' table display12 howmanyfields=rstemp.fields.count -113 %>14 <table border=1><tr>15 <%16 for i=0 to howmanyfields %>17 <td><b><%=rstemp(i).name %></B></TD>18 <% next %>19 </tr>20 <%21 do while not rstemp.eof %>22 <tr>23 <% for i = 0 to howmanyfields%>24 <td valign=top><% = rstemp.fields(i).value %>&nbsp;</td>25 <% next %>26 </tr>27 <%28 rstemp.movenext29 loop30 rstemp.close31 set rstemp=nothing32 %>33 </table></body></html>

http://www.learnASP.com/learn/dbtablepaged.asp by Charles M. Carroll Page 111

Paged Table Displays by Charles Carroll & Jeff Emrich

This page demonstrates how to retrieve a recordset divided up into pages, and to only select data from a specified page. It does notin any way store a recordset or connection in memory when the page is not accessed unlike many solutions you will read about. TheADO properties that make this magic possible are .AbsolutePage, .PageCount and .PageSize.

1 <html><head>2 <TITLE>dbtablepaged.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <!--#INCLUDE VIRTUAL="/ADOVBS.INC" -->5 <%6 connectme="DSN=Student;uid=student;pwd=magic"7 sqltemp="select * from publishers"8 9 ' Troubleshooting TIP:10 ' if you use this code and get an error, for example:11 '12 ' ADODB.Recordset error 800a0cb313 '14 ' The operation requested by the application is not15 ' supported by the provider.16 '17 ' You may have a driver that is out of date, see:18 ' http://www.learnasp.com/learn/connectioninfo.asp19 ' for code that will identify what your driver version is20 ' this script works with Access, SQLserver and Oracle

Page 103: [ebook] Learn ASP

21 ' with up-to-date drivers22 23 If aduseclient="" THEN24 ref="http://www.learnasp.com/adovbs.inc"25 response.write "You forgot to include:<br>"26 response.write "/adovbs.inc<br>"27 response.write "Get the file from <a href='" & ref & "'>" & ref & "<br>"28 response.end29 END IF30 31 mypage=request("whichpage")32 If mypage="" then33 mypage=134 end if35 mypagesize=request("pagesize")36 If mypagesize="" then37 mypagesize=1038 end if39 mySQL=request("SQLquery")40 IF mySQL="" THEN41 mySQL=SQLtemp42 END IF43 44 set rstemp=Server.CreateObject("ADODB.Recordset")45 rstemp.cursorlocation=aduseclient46 rstemp.cachesize=547 rstemp.open mySQL,connectme48 rstemp.movefirst49 rstemp.pagesize=mypagesize50 maxpages=cint(rstemp.pagecount)51 maxrecs=cint(rstemp.pagesize)52 rstemp.absolutepage=mypage53 howmanyrecs=054 howmanyfields=rstemp.fields.count -155 response.write "Page " & mypage & " of " & maxpages & "<br>"56 response.write "<table border='1'><tr>"57 58 'Put Headings On The Table of Field Names59 FOR i=0 to howmanyfields60 response.write "<td><b>" & rstemp(i).name & "</b></td>"61 NEXT62 response.write "</tr>"63 64 ' Now loop through the data65 DO UNTIL rstemp.eof OR howmanyrecs>=maxrecs66 response.write "<tr>"67 FOR i = 0 to howmanyfields68 fieldvalue=rstemp(i)69 If isnull(fieldvalue) THEN70 fieldvalue="n/a"71 END IF72 If trim(fieldvalue)="" THEN73 fieldvalue="&nbsp;"74 END IF75 response.write "<td valign='top'>"76 response.write fieldvalue77 response.write "</td>"78 next79 response.write "</tr>"80 rstemp.movenext81 howmanyrecs=howmanyrecs+182 LOOP83 response.write "</table><p>"84 85 ' close, destroy86 rstemp.close87 set rstemp=nothing

Page 104: [ebook] Learn ASP

88 89 ' Now make the page _ of _ hyperlinks90 Call PageNavBar91 92 sub PageNavBar()93 ' Thanks to Jeff Emrich <[email protected]>94 pad=""95 scriptname=request.servervariables("script_name")96 response.write "<table rows='1' cols='1' width='97%'><tr>"97 response.write "<td>"98 response.write "<font size='2' color='black' face='Verdana, Arial,Helvetica,sans-serif'>"99 if (mypage mod 10) = 0 then100 counterstart = mypage - 9101 else102 counterstart = mypage - (mypage mod 10) + 1103 end if104 counterend = counterstart + 9105 if counterend > maxpages then counterend = maxpages106 if counterstart <> 1 then107 ref="<a href='" & scriptname108 ref=ref & "?whichpage=" & 1109 ref=ref & "&pagesize=" & mypagesize110 ref=ref & "&sqlQuery=" & server.URLencode(mySQL)111 ref=ref & "'>First</a>&nbsp;:&nbsp;"112 Response.Write ref113 114 115 ref="<a href='" & scriptname116 ref=ref & "?whichpage=" & (counterstart - 1)117 ref=ref & "&pagesize=" & mypagesize118 ref=ref & "&sqlQuery=" & server.URLencode(mySQL)119 ref=ref & "'>Previous</a>&nbsp;"120 Response.Write ref121 end if122 Response.Write "["123 for counter=counterstart to counterend124 If counter>=10 then125 pad=""126 end if127 if cstr(counter) <> mypage then128 ref="<a href='" & scriptname129 ref=ref & "?whichpage=" & counter130 ref=ref & "&pagesize=" & mypagesize131 ref=ref & "&sqlQuery=" & server.URLencode(mySQL)132 ref=ref & "'>" & pad & counter & "</a>"133 else134 ref="<b>" & pad & counter & "</b>"135 end if136 response.write ref137 if counter <> counterend then response.write " "138 next139 Response.Write "]"140 if counterend <> maxpages then141 ref="&nbsp;<a href='" & scriptname142 ref=ref & "?whichpage=" & (counterend + 1)143 ref=ref & "&pagesize=" & mypagesize144 ref=ref & "&sqlQuery=" & server.URLencode(mySQL)145 ref=ref & "'>Next</a>"146 Response.Write ref147 148 149 ref="&nbsp;:&nbsp;<a href='" & scriptname150 ref=ref & "?whichpage=" & maxpages151 ref=ref & "&pagesize=" & mypagesize152 ref=ref & "&sqlQuery=" & server.URLencode(mySQL)153 ref=ref & "'>Last</a>"

Page 105: [ebook] Learn ASP

154 Response.Write ref155 end if156 response.write "<br></font>"157 response.write "</td>"158 response.write "</table>"159 end sub160 %>161 </body></html>

http://www.learnASP.com/learn/dbcount.asp by Charles M. Carroll Page 112

Count Query/Table Records by Juan Llibre, Charles CarrollThis script counts the records in a database. Many people who attempt to use the .recordcount property have the value -1 returnedto them. In a nutshell, -1 means "I don't know how many records this query/table contains". It happens since the default cursortype isAdOpenforwardonly (see below for explanation of all cursor types).

The critical part here is having a cursor that supports it and including adovbs.inc to define the cursor types. The file adovbs.inc canbe obtained from http://www.learnasp.com/adovbs.inc

Adopenstatic cursor The data is dead. If you retrieve a million records for example at 9:00am and it takes 6 minutes to read the data, at the 6th minuteyou will not be retrieving fresh or recently added data. It is like a snapshot of the data. Recordsets opened this way WILL contain anaccurate recordcount.

Adopenforwardonly cursor (the default) The data is alive but you can only move forward. Attempts to move backward or to specific record numbers will fail.. Recordsetsopened this way WILL NOT contain an accurate recordcount, instead returning -1.

Adopenkeyset cursor The data is alive and any record read will be the most recent data. f you retrieve a million records for example at 9:00am and ittakes 6 minutes to read the data, at the 6th minute you will still be retrieving fresh data but NOT data added or deleted since 9am.Recordsets opened this way WILL NOT contain an accurate recordcount, instead returning -1.

Adopendynamic cursor The data is alive and additions will be noticed. If you retrieve a million records for example at 9:00am and it takes 6 minutes to readthe data, at the 6th minute you will still be retrieving fresh data and records added to the end of the data. Recordsets opened thisway WILL contain an accurate recordcount.

Here is the script that counts the query results:

1 <head><html>2 <TITLE>dbcount.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <!--#INCLUDE VIRTUAL="/ADOVBS.INC" -->5 <%6 ' change these for your site7 connectme="DSN=Student;uid=student;pwd=magic"8 sqltemp="select * from publishers where state='NY'"9 set rstemp=Server.CreateObject("adodb.Recordset")10 rstemp.open sqltemp, connectme, adopenstatic11 howmanyrecs=rstemp.recordcount12 response.write howmanyrecs & " records in<br>" & sqltemp13 rstemp.close14 set rstemp=nothing15 %>16 </body></html>17

It is also important to understand that any situation where you open the database and are able to obtain an accurate record count isby nature slower than opening a database that also has the burden of knowing how many records it has upon demand. Theadditional overhead and limitations of a adopendynamic or adopenstatic cursor may be a poor way to retrieve the data because therecordset even though they count accurately. If you must count AND retrieve, I recommend counting first, closing the recordset and

Page 106: [ebook] Learn ASP

then re-opening the recordset with the best cursor for speed.

http://www.learnASP.com/learn/adocursortypes.asp by Charles M. Carroll Page 113

ADO Cursor Types by Phil Paxton ([email protected])ADO cursor types affects the properties and methods that are available as this table illustrates.

Property Forward-Only Dynamic Keyset StaticAbsolutePage N/A N/A R/W R/W

AbsolutePosition N/A N/A R/W R/WActiveConnection R/W R/W R/W R/W

BOF R/O R/O R/O R/OBookmark N/A N/A R/W R/WCacheSize R/W R/W R/W R/W

CursorLocation R/W R/W R/W R/WCursorType R/W R/W R/W R/WEditMode R/O R/O R/O R/O

EOF R/O R/O R/O R/OFilter R/W R/W R/W R/W

LockType R/W R/W R/W R/WMarshalOptions R/W R/W R/W R/W

MaxRecords R/W R/W R/W R/WPageCount N/A N/A R/O R/OPageSize R/W R/W R/W R/W

RecordCount N/A N/A R/O R/OSource R/W R/W R/W R/WState R/O R/O R/O R/OStatus R/O R/O R/O R/O

Method AddNew Yes Yes Yes Yes

CancelBatch Yes Yes Yes YesCancelUpdate Yes Yes Yes Yes

Clone N/A N/A Yes YesClose Yes Yes Yes YesDelete Yes Yes Yes Yes

GetRows Yes Yes Yes YesMove Yes Yes Yes Yes

MoveFirst Yes Yes Yes YesMoveLast N/A Yes Yes YesMoveNext Yes Yes Yes Yes

MovePrevious N/A Yes Yes YesNextRecordset Yes Yes Yes Yes

Open Yes Yes Yes YesRequery Yes Yes Yes Yes

Page 107: [ebook] Learn ASP

Resync N/A N/A Yes YesSupports Yes Yes Yes YesUpdate Yes Yes Yes Yes

UpdateBatch Yes Yes Yes Yes

Legend:R/W = Read/WriteR/O = Read-OnlyN/A = Not Available or SupportedYes = Available/Supported

http://www.learnASP.com/learn/dbnewrec.asp by Charles M. Carroll Page 114

Database -- Form to Input a New RecordThis page demonstrates the capabilities how to setup a simple form for a new database record. The script:

1 <html><head>2 <title>dbnewrec.asp</title>&3 <body bgcolor="#FFFFFF">4 <% ' My ASP program that allows you to append a record %>5 <form name="myauthor" action="dbnewrecSQL.asp" method="GET">6 <p>Author ID: <input type="TEXT" name="id"></p>7 <p> Author Name: <input type="TEXT" name="name"></p>8 <p> Year Born: <input type="TEXT" name="year"></p>9 <p> <input type="SUBMIT"> </p>10 </form></body></html>

http://www.learnASP.com/learn/dbnewSQL.asp by Charles M. Carroll Page 115

Database -- Add New Record with SQL statementThis page demonstrates the capabilities how to add a record to a database with a SQL statement. To double check it is in thedatabase try: Test This -->/learn/test/db1parm.asp?id=9000

If the script doesn't work when adapting it to YOUR database, see:http://www.activeserverpages.com/learn/dbtroubleshoot.asp to determine what the trouble is.

The script is:1 <TITLE>dbnewrecSQL.asp</TITLE>2 <body bgcolor="#FFFFFF">3 <HTML>4 <%5 'on error resume next6 auname=request.querystring("name")7 auyear=request.querystring("year")8 auID=request.querystring("ID")9 If auid<9000 then10 auid=auid+900011 end if12 Set Conn = Server.CreateObject("ADODB.Connection")13 conn.open "DSN=Student;uid=student;pwd=magic"14 SQLStmt = "INSERT INTO authors (AU_ID,author,year_born) "

Page 108: [ebook] Learn ASP

15 SQLStmt = SQLStmt & "VALUES (" & auid16 SQLStmt = SQLStmt & ",'" & auname & "'"17 SQLStmt = SQLStmt & "," & int(auyear) & ")"18 Set RS = Conn.Execute(SQLStmt)19 set rs=nothing20 If err.number>0 then21 response.write "VBScript Errors Occured:" & "<P>"22 response.write "Error Number=" & err.number & "<P>"23 response.write "Error Descr.=" & err.description & "<P>"24 response.write "Help Context=" & err.helpcontext & "<P>"25 response.write "Help Path=" & err.helppath & "<P>"26 response.write "Native Error=" & err.nativeerror & "<P>"27 response.write "Source=" & err.source & "<P>"28 response.write "SQLState=" & err.sqlstate & "<P>"29 else30 response.write "No VBScript Errors Occured" & "<P>"31 end if32 IF conn.errors.count> 0 then33 response.write "Database Errors Occured" & "<br>"34 response.write "<b>" & SQLstmt & "</b><P>"35 for counter= 0 to conn.errors.count36 response.write "Error #" & conn.errors(counter).number & "<P>"37 response.write "Error desc. -> " & conn.errors(counter).description & "<P>"38 next39 else40 response.write "No Database Errors Occured!" & "<P>"41 end if42 Conn.Close43 set conn=nothing44 %>45 </BODY>46 </HTML>

http://www.learnASP.com/learn/dbnewADO.asp by Charles M. Carroll Page 116

Add New Record with ADOThis page demonstrates the capabilities how to add a record to a database using ADO instead of SQL. The script is:

1 <html><head>2 <title>dbnewrec.asp</title>&3 <body bgcolor="#FFFFFF">4 <% ' My ASP program that allows you to append a record %>5 <form name="myauthor" action="dbnewADOrespond.asp" method="GET">6 <p>Author ID: <input type="TEXT" name="id"></p>7 <p> Author Name: <input type="TEXT" name="name"></p>8 <p> Year Born: <input type="TEXT" name="year"></p>9 <p> <input type="SUBMIT"> </p>10 </form></body></html>

The form responder looks like this:

1 <TITLE>dbnewADO.asp</TITLE>2 <body bgcolor="#FFFFFF">3 <HTML>4 <!--#INCLUDE VIRTUAL="/ADOVBS.INC" -->5 <!--#INCLUDE VIRTUAL="/learn/test/lib_errors.asp" -->6 <%7 on error resume next8 auname=request.querystring("name")9 auyear=request.querystring("year")10 auID=request.querystring("ID")

Page 109: [ebook] Learn ASP

11 If auid<9000 then12 auid=auid+900013 end if14 conn="DSN=Student;uid=student;pwd=magic"15 Set RS = Server.CreateObject("ADODB.Recordset")16 RS.Open "authors",Conn,adopenstatic,adlockoptimistic17 RS.AddNew18 'RS("AU_ID")=auid19 RS("Author") = auname20 RS("Year_Born")= int(auyear)21 RS.Update22 Call ErrorVBscriptReport("Adding Record")23 Call ErrorADOReport("Adding Record",RS.activeconnection)24 RS.Close25 set rs=nothing26 %>27 </BODY>28 </HTML>29 30 31 32

http://www.learnASP.com/learn/dbgetstring.asp by Charles M. Carroll Page 117

Database -- Use GetString to speed code by Charles CarrollThis page demonstrates the capabilities how to use getstring (part of ADO 2.0 or above, if you are not sure what ADO version ison your server, see /learn/versioncheck.asp)

to display a table from a SQL statement with one call●

eliminate multiple response.writes●

eliminate do until eof tests.●

The script to display the table utilizing getstring is:

1 <TITLE>dbtablegetstring.asp</TITLE>2 <body bgcolor="#FFFFFF">3 <%4 whichDSN="DSN=Student;uid=student;pwd=magic"5 mySQL="select * from publishers where state='NY'"6 7 ' ASP program that displays a database in table form8 set conntemp=server.createobject("adodb.connection")9 conntemp.open whichDSN10 set rstemp=conntemp.execute(mySQL)11 If rstemp.eof then12 response.write "No records matched<br>"13 response.write mySQL & "<br>So cannot make table..."14 rstemp.close15 set rstemp=nothing16 conntemp.close17 set conntemp=nothing18 response.end19 end if20 response.write "<table border='1'><tr>"21 22 'Put Headings On The Table of Field Names23 for each whatever in rstemp.fields24 response.write "<td><b>" & whatever.name & "</B></TD>"

Page 110: [ebook] Learn ASP

25 next26 response.write "</tr><tr><td>"27 response.write rstemp.getstring(,, "</td><td>", "</td></tr><TR><TD>", "-null-")28 response.write "</td></tr></table>"29 30 rstemp.close31 set rstemp=nothing32 conntemp.close33 set conntemp=nothing34 %>35 </body></html>36 37 38 39 40 41 42

A similar script to display a list box utilizing getstring is:

1 <!--#INCLUDE VIRTUAL="/ADOVBS.INC" -->2 <html><head>3 <TITLE>dblistgetstring.asp</TITLE>&4 <body bgcolor="#FFFFFF">5 <%6 ' ASP program that displays a database in list form7 myDSN="DSN=Student;uid=student;pwd=magic"8 mySQL="select distinct state from publishers"9 10 set conntemp=server.createobject("adodb.connection")11 conntemp.open "DSN=Student;uid=student;pwd=magic"12 13 ' Const adCmdUnknown, adCmdText, adCmdTable (no) , adCmdStoredProc14 15 set rstemp=server.createobject("adodb.recordset")16 rstemp.open mySQL, conntemp, adopenforwardonly, _17 adlockReadOnly, adCmdUnknown18 19 response.write "<form><select name='state'><option>"20 21 tempSTR=rstemp.getstring(,, "", "</option><option>", "&nbsp;")22 response.write tempSTR23 24 response.write "</select></form>"25 rstemp.close26 set rstemp=nothing27 conntemp.close28 set conntemp=nothing29 %>30 </body></html>

http://www.learnASP.com/learn/dbtablelists.asp by Charles M. Carroll Page 118

Listing Tables within Databases by Charles Carroll DRAFTSQL Server allows you to list tables like this:

1 <HEAD><TITLE>sqlservertablelist.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <%4 whichDSN="DSN=student;uid=student;pwd=magic"

Page 111: [ebook] Learn ASP

5 6 call query2table("select name,type from sysobjects where type='U'", whichDSN)7 %>8 <!--#include virtual="/learn/test/lib_dbtable.asp"-->9 </BODY></HTML>

Access allows you to list tables like this (assuming you allow system objects to be visible within the database onthe Access side):1 <HEAD><TITLE>accesstablelist.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <%4 whichDSN="DRIVER={Microsoft Access Driver (*.mdb)}; "5 whichDSN=whichDSN & "DBQ=" & server.mappath("/learn/test/biblio.mdb")6 call query2table("select * from MsysObjects WHERE type = 1",whichDSN)7 %>8 <!--#include virtual="/learn/test/lib_dbtable.asp"-->9 </BODY></HTML>

The Include file looks like this:1 <%2 sub query2table(inputquery, inputDSN)3 dim conntemp, rstemp4 set conntemp=server.createobject("adodb.connection")5 conntemp.open inputDSN6 set rstemp=conntemp.execute(inputquery)7 howmanyfields=rstemp.fields.count -1%>8 <table border=1><tr>9 <% 'Put Headings On The Table of Field Names10 for i=0 to howmanyfields %>11 <td><b><%=rstemp(i).name%></B></TD>12 <% next %>13 </tr>14 <% ' Now lets grab all the records15 do while not rstemp.eof %>16 <tr>17 <% for i = 0 to howmanyfields18 thisvalue=rstemp(i)19 If isnull(thisvalue) then20 thisvalue="&nbsp;"21 end if%>22 <td valign=top><%=thisvalue%></td>23 <% next %>24 </tr>25 <%rstemp.movenext26 loop%>27 </table>28 <%29 rstemp.close30 set rstemp=nothing31 conntemp.close32 set conntemp=nothing33 end sub%>

http://www.learnASP.com/learn/dbschemas.asp by Charles M. Carroll Page 119

ADO Schemas to list tables & fieldsYou can examine a Schema for the table names and column names and column detail information.

1 <html><head>

Page 112: [ebook] Learn ASP

2 <TITLE>dbschemas.asp</TITLE>3 </head>4 <body bgcolor="#FFFFFF">5 <!--#INCLUDE VIRTUAL="/ADOVBS.INC" -->6 <!--#INCLUDE VIRTUAL="/learn/test/lib_fieldtypes.asp" -->7 <%8 myDSN="DSN=Student;uid=student;pwd=magic"9 10 set conntemp=server.createobject("adodb.connection")11 conntemp.open myDSN12 13 Set rsSchema = conntemp.OpenSchema(adSchemaColumns)14 thistable=""15 pad="&nbsp;&nbsp;&nbsp;"16 DO UNTIL rsSchema.EOF17 prevtable=thistable18 thistable=rsSchema("Table_Name")19 thiscolumn=rsSchema("COLUMN_NAME")20 IF thistable<>prevtable THEN21 response.write "Table=<b>" & thistable & "</b><br>"22 response.write "TABLE_CATALOG=<b>" & rsSchema("TABLE_CATALOG") & "</b><br>"23 response.write "TABLE_SCHEMA=<b>" & rsSchema("TABLE_SCHEMA") & "</b><p>"24 END IF25 response.write "<br>" & pad & "Field=<b>" & thiscolumn & "</b><br>"26 response.write pad & "Type=<b>" & fieldtypename(rsSchema("DATA_TYPE")) & "</b><br>"27 28 29 DIM colschema(27)30 colschema(0)="TABLE_CATALOG"31 colschema(1)="TABLE_SCHEMA"32 colschema(2)="TABLE_NAME"33 colschema(3)="COLUMN_NAME"34 colschema(4)="COLUMN_GUID"35 colschema(5)="COLUMN_PROP_ID"36 colschema(6)="ORDINAL_POSITION"37 colschema(7)="COLUMN_HASDEFAULT"38 colschema(8)="COLUMN_DEFAULT"39 colschema(9)="COLUMN_FLAGS"40 colschema(10)="IS_NULLABLE"41 colschema(11)="DATA_TYPE"42 colschema(12)="TYPE_GUID"43 colschema(13)="CHARACTER_MAXIMUM_LENGTH"44 colschema(14)="CHARACTER_OCTET_LENGTH"45 colschema(15)="NUMERIC_PRECISION"46 colschema(16)="NUMERIC_SCALE"47 colschema(17)="DATETIME_PRECISION"48 colschema(18)="CHARACTER_SET_CATALOG"49 colschema(19)="CHARACTER_SET_SCHEMA"50 colschema(20)="CHARACTER_SET_NAME"51 colschema(21)="COLLATION_CATALOG"52 colschema(22)="COLLATION_SCHEMA"53 colschema(23)="COLLATION_NAME"54 colschema(24)="DOMAIN_NAME"55 colschema(25)="DOMAIN_CATALOG"56 colschema(26)="DOMAIN_SCHEMA"57 colschema(27)="DESCRIPTION"58 59 ON ERROR RESUME NEXT60 FOR counter=4 to 2761 thisColInfoType=colschema(counter)62 thisColInfo=rsSchema(thisColInfoType)63 If err.number<>0 then64 thiscolinfo="-error-"65 err.clear66 END IF67 IF thisColInfo<>"" THEN68 response.write pad & pad & pad & thiscolinfotype

Page 113: [ebook] Learn ASP

69 response.write "=<b>" & thiscolinfo & "</b><br>"70 END IF71 NEXT72 response.flush73 rsSchema.MoveNext74 LOOP75 76 rsSchema.Close77 set rsSchema=nothing78 79 conntemp.close80 set conntemp=nothing81 %>82 </body></html>

Here is the contents of lib_fieldtypes.asp which is included to make this example work:

1 <%2 FUNCTION fieldtypename(parm1)3 SELECT CASE Parm14 CASE 05 fieldtypename="adEmpty"6 CASE 167 fieldtypename="adTinyInt"8 CASE 29 fieldtypename="adSmallInt"10 CASE 311 fieldtypename="adInteger"12 CASE 2013 fieldtypename="adBigInt"14 CASE 1715 fieldtypename="adUnsignedTinyInt"16 CASE 1817 fieldtypename="adUnsignedSmallInt"18 CASE 1919 fieldtypename="adUnsignedInt"20 CASE 2121 fieldtypename="adUnsignedBigInt"22 CASE 423 fieldtypename="adSingle"24 CASE 525 fieldtypename="adDouble"26 CASE 627 fieldtypename="adCurrency"28 CASE 1429 fieldtypename="adDecimal"30 CASE 13131 fieldtypename="adNumeric"32 CASE 1133 fieldtypename="adBoolean"34 CASE 1035 fieldtypename="adError"36 CASE 13237 fieldtypename="adUserDefined"38 CASE 1239 fieldtypename="adVariant"40 CASE 941 fieldtypename="adIDispatch"42 CASE 1343 fieldtypename="adIUnknown"44 CASE 7245 fieldtypename="adGUID"46 CASE 747 fieldtypename="adDate"48 CASE 13349 fieldtypename="adDBDate"50 CASE 13451 fieldtypename="adDBTime"

Page 114: [ebook] Learn ASP

52 CASE 13553 fieldtypename="adDBTimeStamp"54 CASE 855 fieldtypename="adBSTR"56 CASE 12957 fieldtypename="adChar"58 CASE 20059 fieldtypename="adVarChar"60 CASE 20161 fieldtypename="adLongVarChar"62 CASE 13063 fieldtypename="adWChar"64 CASE 20265 fieldtypename="adVarWChar"66 CASE 20367 fieldtypename="adLongVarWChar"68 CASE 12869 fieldtypename="adBinary"70 CASE 20471 fieldtypename="adVarBinary"72 CASE 20573 fieldtypename="adLongVarBinary"74 CASE ELSE75 fieldtypename="Undefined by ADO"76 END SELECT77 END FUNCTION78 %>

http://www.learnASP.com/learn/dbschemasall.asp by Charles M. Carroll Page 120

ADO Schemas/listing tables and fieldsYou can examine a Schema for the table names and column names and column detail information.

1 <html><head>2 <TITLE>dbschemasall.asp</TITLE>3 </head>4 <body bgcolor="#FFFFFF">5 <!--#INCLUDE VIRTUAL="/ADOVBS.INC" -->6 <!--#INCLUDE VIRTUAL="/learn/test/lib_schemas.asp" -->7 <%8 myDSN="DSN=Student;uid=student;pwd=magic"9 10 DIM colschema(30)11 colschema(0)=adSchemaProviderSpecific12 colschema(1)=adSchemaAsserts13 colschema(2)=adSchemaCatalogs14 colschema(3)=adSchemaCharacterSets15 colschema(4)=adSchemaCollations16 colschema(5)=adSchemaColumns17 colschema(6)=adSchemaCheckConstraints18 colschema(7)=adSchemaConstraintColumnUsage19 colschema(8)=adSchemaConstraintTableUsage20 colschema(9)=adSchemaKeyColumnUsage21 colschema(10)=adSchemaReferentialContraints22 colschema(11)=adSchemaTableConstraints23 colschema(12)=adSchemaColumnsDomainUsage24 colschema(13)= adSchemaIndexes25 colschema(14)=adSchemaColumnPrivileges26 colschema(15)=adSchemaTablePrivileges27 colschema(16)=adSchemaUsagePrivileges28 colschema(17)=adSchemaProcedures

Page 115: [ebook] Learn ASP

29 colschema(18)=adSchemaSchemata30 colschema(19)=adSchemaSQLLanguages31 colschema(20)=adSchemaStatistics32 colschema(21)=adSchemaTables33 colschema(22)=adSchemaTranslations34 colschema(23)=adSchemaProviderTypes35 colschema(24)=adSchemaViews36 colschema(25)=adSchemaViewColumnUsage37 colschema(26)=adSchemaViewTableUsage38 colschema(27)=adSchemaProcedureParameters39 colschema(28)=adSchemaForeignKeys40 colschema(29)=adSchemaPrimaryKeys41 colschema(30)=adSchemaProcedureColumns42 43 FOR counter=1 to 3044 thisSchema=colSchema(counter)45 Call Schema2Table(myDSN,thisSchema)46 response.write "<p>"47 NEXT48 %>49 </body></html>

The include file lib_schemas.asp looks like this:

1 <%2 FUNCTION schemaName(parm1)3 SELECT CASE parm14 CASE adSchemaProviderSpecific5 schemaname="adSchemaProviderSpecific"6 CASE adSchemaAsserts7 schemaName="adSchemaAsserts" 8 CASE adSchemaCatalogs9 schemaName="adSchemaCatalogs"10 CASE adSchemaCharacterSets11 schemaName="adSchemaCharacterSets"12 CASE adSchemaCollations13 schemaName="adSchemaCollations"14 CASE adSchemaColumns15 schemaName="adSchemaColumns"16 CASE adSchemaCheckConstraints17 schemaName="adSchemaCheckConstraints"18 CASE adSchemaConstraintColumnUsage19 schemaName="adSchemaConstraintColumnUsage"20 CASE adSchemaConstraintTableUsage21 schemaName="adSchemaConstraintTableUsage"22 CASE adSchemaKeyColumnUsage23 schemaName="adSchemaKeyColumnUsage"24 CASE adSchemaReferentialContraints25 schemaName="adSchemaReferentialContraints"26 CASE adSchemaTableConstraints27 schemaName="adSchemaTableConstraints"28 CASE adSchemaColumnsDomainUsage29 schemaName="adSchemaColumnsDomainUsage"30 CASE adSchemaIndexes31 schemaName="adSchemaIndexes"32 CASE adSchemaColumnPrivileges33 schemaName="adSchemaColumnPrivileges"34 CASE adSchemaTablePrivileges35 schemaName="adSchemaTablePrivileges"36 CASE adSchemaUsagePrivileges37 schemaName="adSchemaUsagePrivileges"38 CASE adSchemaProcedures39 schemaName="adSchemaProcedures"40 CASE adSchemaSchemata41 schemaName="adSchemaSchemata"42 CASE adSchemaSQLLanguages43 schemaName="adSchemaSQLLanguages"44 CASE adSchemaStatistics

Page 116: [ebook] Learn ASP

45 schemaName="adSchemaStatistics"46 CASE adSchemaTables47 schemaName="adSchemaTables"48 CASE adSchemaTranslations49 schemaName="adSchemaTranslations"50 CASE adSchemaProviderTypes51 schemaName="adSchemaProviderTypes"52 CASE adSchemaViews53 schemaName="adSchemaViews"54 CASE adSchemaViewColumnUsage55 schemaName="adSchemaViewColumnUsage"56 CASE adSchemaViewTableUsage57 schemaName="adSchemaViewTableUsage"58 CASE adSchemaProcedureParameters59 schemaName="adSchemaProcedureParameters"60 CASE adSchemaForeignKeys61 schemaName="adSchemaForeignKeys"62 CASE adSchemaPrimaryKeys63 schemaName="adSchemaPrimaryKeys"64 CASE adSchemaProcedureColumns65 schemaName="adSchemaProcedureColumns"66 CASE ELSE67 schemaName="-unknown-"68 END SELECT69 END FUNCTION70 71 SUB Schema2Table(parmDSN, parmSchemaName)72 set conntemp=server.createobject("adodb.connection")73 conntemp.open parmDSN74 75 on error resume next76 set rsSchema=conntemp.OpenSchema(parmSchemaName)77 78 IF err.number=3251 THEN79 response.flush80 response.write "<b>" & SchemaName(parmSchemaName)81 response.write "</b><br> is not supported<br>"82 err.clear83 ELSE84 Call Schema2Table(thisSchema)85 response.write "<P><b>" & schemaName(parmSchemaName) & "</b><br>"86 response.write "<table border=1><tr>"87 'Put Headings On The Table of Field Names88 for each whatever in rsSchema.fields89 response.write "<td><b>" & whatever.name & "</b></td>"90 next91 response.write "</tr>"92 DO UNTIL rsSchema.eof93 response.write "<tr>"94 for each whatever in rsSchema.fields95 thisfield=whatever.value96 if isnull(thisfield) then97 thisfield="&nbsp;"98 end if99 if trim(thisfield)="" then100 thisfield="&nbsp;"101 end if102 response.write "<td valign=top>" & thisfield & "</td>"103 next104 response.write "</tr>"105 rsSchema.MoveNext106 LOOP107 response.write "</table><br>"108 response.flush109 END IF110 111 rsSchema.Close

Page 117: [ebook] Learn ASP

112 set rsSchema=nothing113 114 conntemp.close115 set conntemp=nothing116 END SUB117 %>

http://www.learnASP.com/learn/dbtroubleshoot2.asp by Charles M. Carroll Page 121

Troubleshooting SQL Statements (by Charles Carroll)Now we will show some SQL statements (below) with mistakes and the fixes indicated in red to show how to make the statementswork. The kind of fixes we deploy include:

text fields must have single quotes around the values.●

fields with spaces in their names must be surrounded with []●

set parameters must have commas between them●

Text fields with single quote ' cannot be placed into SQL statements unmodified. Notice how the last example below uses theVBScript replace command to transform a string that may contain embedded ' .Statement with Flaws Improved Statement (fixes in red)

UPDATE mytableSET LocID=0007,Material=131/4 Description=T-shirts ListPrice=35WHERE CusID=97

added space before SETUPDATE mytable SETLocID='0007',Material='13 1/4',Description='T-shirts', [List Price]=35WHERE CusID=97

INSERT INTO authors (AU_ID, author,year_born) VALUES (7000, JoeSmith,1950)

INSERT INTO authors (AU_ID, author,year_born) VALUES (7000, 'JoeSmith',1950)

SELECT * from atable where state = MDandyear born<1955

SELECT * from atable where state = 'MD'andand [year born]<1955

<%key=request.querystring("id")au=request.querystring("author")birthyear=request.querystring("year")SQLstmt="INSERT INTO authors (AU_ID,author, year_born) VALUES ("SQLstmt= SQLstmt & key & ","SQLstmt= SQLstmt & author & ","SQLstmt= SQLstmt & birthyear & ")"%>

<%key=request.querystring("id")au=request.querystring("author")au=Replace(au, "'", "''")birthyear=request.querystring("year")SQLstmt="INSERT INTO authors (AU_ID,author, year_born) VALUES ("SQLstmt= SQLstmt & key & ",'"SQLstmt= SQLstmt & author & "',"SQLstmt= SQLstmt & birthyear & ")"%>

http://www.learnASP.com/learn/db1parm.asp by Charles M. Carroll Page 122

Displaying A Table/User Supplied Query InputThis page demonstrates the capabilities how to display a table from a SQL statement using one input variable from a user. The scriptto display a specified record in the table is:

1 <TITLE>db1parm.asp</TITLE>2 <body bgcolor="#FFFFFF">3 <%

Page 118: [ebook] Learn ASP

4 ' My ASP program that talks to a database5 set conntemp=server.createobject("adodb.connection")6 conntemp.open "DSN=Student;uid=student;pwd=magic"7 p1=request.querystring("ID")8 temp="select * from authors where AU_ID=" & p19 set rstemp=conntemp.execute(temp)10 howmanyfields=rstemp.fields.count -111 %>12 <table border=1>13 <tr>14 <% 'Put Headings On The Table of Field Names15 for i=0 to howmanyfields %>16 <td><b><%=rstemp(i).name %></B></TD>17 <% next %>18 </tr>19 <% ' Now lets grab all the records20 do while not rstemp.eof %>21 <tr>22 <% for i = 0 to howmanyfields%>23 <td valign=top><% = rstemp(i) %></td>24 <% next %>25 </tr>26 <% rstemp.movenext27 loop28 rstemp.close29 set rstemp=nothing30 conntemp.close31 set conntemp=nothing%>32 </table>33 </body>34 </html>

http://www.learnASP.com/learn/dbupdate.asp by Charles M. Carroll Page 123

Database -- Update RecordThis page demonstrates the capabilities to update an existing record in a database with a SQL statement.

It is called like this:Test This -->/learn/test/dbupdate.asp?name=NewPerson&id=9000&year=1901

To double check it is in the database try:Test This -->/learn/test/db1parm.asp?id=9000

Now try:Test This -->/learn/test/dbupdate.asp?name=NewPerson&id=9000&year=1964

to change the "NewPerson" Birthday to 1964 again andTest This -->/learn/test/dbupdate.asp?name=NewPerson&id=9000&year=1901

The script is:1 <TITLE>dbupdate.asp</TITLE>2 <body bgcolor="#FFFFFF">3 <HTML>4 <%5 on error resume next6 auname=request.querystring("name")7 auyear=request.querystring("year")8 auID=request.querystring("ID")9 Set Conn = Server.CreateObject("ADODB.Connection")10 conn.open "DSN=Student;uid=student;pwd=magic"11 SQLstmt = "UPDATE authors "

Page 119: [ebook] Learn ASP

12 SQLStmt = SQLstmt & "SET Author='" & auname & "',"13 SQLstmt = SQLstmt & "year_born=" & auyear14 SQLStmt = SQLStmt & " WHERE AU_ID=" & auid15 Set RS = Conn.Execute(SQLStmt)16 If err.number>0 then17 response.write "VBScript Errors Occured:" & "<P>"18 response.write "Error Number=" & err.number & "<P>"19 response.write "Error Descr.=" & err.description & "<P>"20 response.write "Help Context=" & err.helpcontext & "<P>"21 response.write "Help Path=" & err.helppath & "<P>"22 response.write "Native Error=" & err.nativeerror & "<P>"23 response.write "Source=" & err.source & "<P>"24 response.write "SQLState=" & err.sqlstate & "<P>"25 else26 response.write "No problems occured!" & "<P>"27 end if28 IF conn.errors.count> 0 then29 response.write "Database Errors Occured" & "<P>"30 for counter= 0 to conn.errors.count31 response.write "Error #" & conn.errors(counter).number & "<P>"32 response.write "Error desc. -> " & conn.errors(counter).description & "<P>"33 next34 else35 response.write SQLstmt36 response.write "Everything Went Fine. Author is updated now!" & "<P>"37 end if38 set rstemp=nothing39 Conn.Close40 set conntemp=nothing41 %>42 </BODY>43 </HTML>

http://www.learnASP.com/learn/SQL.asp by Charles M. Carroll Page 124

SQL Troubles (SQLtroubles.asp) - Page 125 SQL: Example Tables (SQLexamples.asp) - Page 126 SQL: Where Clause Basics (SQLwhere.asp) - Page 127 SQL: Where Clause Examples (SQLwhere2.asp) - Page 128 SQL: Search Forms #1 (SQLwhereform1.asp) - Page 129 SQL: Search Forms #2 (SQLwhereform2.asp) - Page 130 SQL: Search Forms #3 (SQLwhereform3.asp) - Page 131 SQL: Search AND/OR Operators (SQLandor.asp) - Page 132 SQL: Search AND/OR Examples (SQLandor2.asp) - Page 133 SQL: COUNT, GROUPBY (SQLcount.asp) - Page 134 SQL: SUM, MIN, AVE, MAX (SQLaggregate.asp) - Page 135 SQL Joins by Aaron Alexander (dbjoin.asp) - Page 136

http://www.learnASP.com/learn/SQLtroubles.asp by Charles M. Carroll Page 125

Page 120: [ebook] Learn ASP

SQL Troubleshooting ResourcesWe also run a listserve for helping you setup complex SQL queries (Joins, multiple ands/ors, etc.)Unlike the list above, it is not a general database troubleshooting list, instead only complex SQL questions are allowed.

aspsqlhowto Listserver

JOIN, QUIT or Search ARCHIVES:http://www.asplists.com/asplists/SQLtroubles.asp

Send Listserver Questions [email protected]

Related LinksJohn Hoffman's SQL Tutorial @ http://w3.one.net/~jhoffman/sqltut.htmSolution Partners Data Shaping Alternatives @ http://www.solpart.com/techcorner/HRS/HRSOverview.aspBook:SQL for Smarties by Joe Celko @ http://www.learnasp.com/books/sqlsmarties.aspBook: SQL Puzzles & Answers by Joe Celko @ http://www.learnasp.com/books/sqlpuzzles.aspData Shaping Basics Part1 @ http://www.4guysfromrolla.com/webtech/092599-1.shtmlData Shaping Basics Part1 @ http://www.4guysfromrolla.com/webtech/100699-2.shtmlStump The SQL Guru @ http://www.4guysfromrolla.com/webtech/sqlguru/4Guys Inner Join Tutorial @ http://www.4guysfromrolla.com/webtech/050599-1.shtmlJoin Tutorial by Aaron Alexander @ http://www.learnasp.com/learn/dbjoin.asp

General Database questions (i.e. code that is broken, non SQL database issues) needs to be sent to our database listserv, see:/learn/dbtroubles.asp

http://www.learnASP.com/learn/SQLexamples.asp by Charles M. Carroll Page 126

Search Database #2 (SQL Where clause examples)For our next examples, knowing the structures of the tables will be helpful.

The authors database has a structure like this:

Au_ID Author Year_Born

The titles database has a structure like this:

Title Year_Published ISBN PubID Description Notes Subject Comments

The Title_Author table looks like this:

ISBN Au_ID

Page 121: [ebook] Learn ASP

The publisher' database has a structure like this:

PubID Name Company_Name Address City State Zip Telephone Fax Comments

http://www.learnASP.com/learn/SQLwhere.asp by Charles M. Carroll Page 127

Search Database #1 (SQL Where clauses)There are several ways to search the data using pure SQL once we review the simple rules of how a WHERE clause works.

Text fields must be enclosed in single quotes, i.e."select * from publishers where state='MD'

Numeric fields need no special characters before and after"select * from publishers where PubID=10"

If you aren't sure how to spell the text field or are looking for sound alikes, LIKE supports %% wildcards"select * from publishers where Name like 'A%%'"

These basic WHERE clause guidelines above are the fundamental building block of searches.

It is also helpful to utilize the equality operators, i.e.

<> not equal

> greater than

< less than

>= greater than OR equal

<= less than or equal

Numeric fields benefit most from the equality operators:"select * from publishers where PubID>10"

http://www.learnASP.com/learn/SQLwhere2.asp by Charles M. Carroll Page 128

SQL Where Examples by Charles CarrollHere are some where statements and their results.

1 <HEAD><TITLE>SQLwhere1.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <%4 call query2table("select * from publishers where name like 'A%%'")5 %>6 <!--#include virtual="/learn/test/subdbtable.inc"-->7 </BODY></HTML>

1 <HEAD><TITLE>SQLwhere2.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <%4 call query2table("select * from titles where Year_Published >= 1994")5 %>6 <!--#include virtual="/learn/test/subdbtable.inc"-->7 </BODY></HTML>

Page 122: [ebook] Learn ASP

1 <HEAD><TITLE>SQLwhere3.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <%4 call query2table("select * from publishers where fax like '212%%'")5 %>6 <!--#include virtual="/learn/test/subdbtable.inc"-->7 </BODY></HTML>

1 <HEAD><TITLE>sqlwhere4.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <%4 call query2table("select * from publishers where state<> 'NY'")5 %>6 <!--#include virtual="/learn/test/subdbtable.inc"-->7 </BODY></HTML>

The Include file looks like this:

1 <%2 sub query2table(inputquery)3 set conntemp=server.createobject("adodb.connection")4 conntemp.open "DSN=Student;uid=student;pwd=magic"5 set rstemp=conntemp.execute(inputquery)6 howmanyfields=rstemp.fields.count -1%>7 <table border=1><tr>8 <% 'Put Headings On The Table of Field Names9 for i=0 to howmanyfields %>10 <td><b><%=rstemp(i).name%></B></TD>11 <% next %>12 </tr>13 <% ' Now lets grab all the records14 do while not rstemp.eof %>15 <tr>16 <% for i = 0 to howmanyfields17 thisvalue=rstemp(i)18 If isnull(thisvalue) then19 thisvalue="&nbsp;"20 end if%>21 <td valign=top><%=thisvalue%></td>22 <% next %>23 </tr>24 <%rstemp.movenext25 loop%>26 </table>27 <%28 rstemp.close29 set rstemp=nothing30 conntemp.close31 set conntemp=nothing32 end sub%>

http://www.learnASP.com/learn/SQLwhereform1.asp by Charles M. Carroll Page 129

Search Database (SQL Where Form examples)In the previous page we introduced the WHERE clause, but now we will see several examples of the WHERE clause in typical forms.This example allows users to choose a city:

1 <HEAD><TITLE>sqlwhereform1.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <Form action = "sqlwhereForm1respond.asp" method=GET>4 Choose A State:<p>

Page 123: [ebook] Learn ASP

5 State: <Input NAME="st" MaxLength="2" size="3"><P>6 <Input type="submit" value="Get Data">&nbsp;<Input type="reset" value="Clear State"></form>7 </BODY></HTML>

1 <HEAD><TITLE>sqlwhereform1respond.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <%4 myDSN="DSN=student;uid=student;pwd=magic"5 6 mystate=request.querystring("st")7 SQLtemp="select * from publishers where state='"8 SQLtemp=SQLtemp & mystate & "'"9 10 call query2table(SQLtemp,myDSN)11 %>12 <!--#include virtual="/learn/test/lib_dbtable.asp"-->13 </BODY></HTML>

The file lib_subdbtable.asp looks like this:

1 <%2 sub query2table(inputquery, inputDSN)3 dim conntemp, rstemp4 set conntemp=server.createobject("adodb.connection")5 conntemp.open inputDSN6 set rstemp=conntemp.execute(inputquery)7 howmanyfields=rstemp.fields.count -1%>8 <table border=1><tr>9 <% 'Put Headings On The Table of Field Names10 for i=0 to howmanyfields %>11 <td><b><%=rstemp(i).name%></B></TD>12 <% next %>13 </tr>14 <% ' Now lets grab all the records15 do while not rstemp.eof %>16 <tr>17 <% for i = 0 to howmanyfields18 thisvalue=rstemp(i)19 If isnull(thisvalue) then20 thisvalue="&nbsp;"21 end if%>22 <td valign=top><%=thisvalue%></td>23 <% next %>24 </tr>25 <%rstemp.movenext26 loop%>27 </table>28 <%29 rstemp.close30 set rstemp=nothing31 conntemp.close32 set conntemp=nothing33 end sub%>

http://www.learnASP.com/learn/SQLwhereform2.asp by Charles M. Carroll Page 130

Search Database (SQL Where Form examples)We will now present a form that allows people to choose a city but also supports inexact searches using LIKE are supported:

1 <HEAD><TITLE>SQLwhereform2.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">

Page 124: [ebook] Learn ASP

3 <Form action = "SQLwhereForm2respond.asp" method=GET>4 Choose A City:<p>5 City: <Input NAME="cy" MaxLength="20" size="23"><P>6 <input TYPE="checkbox" NAME="ExactSearch" CHECKED>Exact Search<P>7 * note if Exact Search is -> NOT CHECKED <-<br>You can use % as a wildcard<p>8 <Input type="submit" value="Get Data">&nbsp;<Input type="reset" value="Clear City"></form>9 </BODY></HTML>

1 <HTML><HEAD>2 <TITLE>sqlwhereform2respond.asp</TITLE>&3 <body bgcolor="#FFFFFF">4 <%5 myDSN="DSN=student;uid=student;pwd=magic"6 mycity=request.querystring("cy")7 myexactsearch=request.querystring("exactsearch")8 SQLtemp="select * from publishers where city"9 If myexactsearch="on" then10 SQLtemp=SQLtemp & " ='"11 Else12 SQLtemp=SQLtemp & " LIKE '"13 End If14 SQLtemp=SQLtemp & mycity & "'"15 'response.write SQLtemp16 call query2table(SQLtemp,myDSN)17 %>18 <!--#include virtual="/learn/test/lib_dbtable.asp"-->19 </BODY></HTML>

The file lib_dbtable.asp looks like this:

1 <%2 sub query2table(inputquery, inputDSN)3 dim conntemp, rstemp4 set conntemp=server.createobject("adodb.connection")5 conntemp.open inputDSN6 set rstemp=conntemp.execute(inputquery)7 howmanyfields=rstemp.fields.count -1%>8 <table border=1><tr>9 <% 'Put Headings On The Table of Field Names10 for i=0 to howmanyfields %>11 <td><b><%=rstemp(i).name%></B></TD>12 <% next %>13 </tr>14 <% ' Now lets grab all the records15 do while not rstemp.eof %>16 <tr>17 <% for i = 0 to howmanyfields18 thisvalue=rstemp(i)19 If isnull(thisvalue) then20 thisvalue="&nbsp;"21 end if%>22 <td valign=top><%=thisvalue%></td>23 <% next %>24 </tr>25 <%rstemp.movenext26 loop%>27 </table>28 <%29 rstemp.close30 set rstemp=nothing31 conntemp.close32 set conntemp=nothing33 end sub%>

Page 125: [ebook] Learn ASP

http://www.learnASP.com/learn/SQLwhereform3.asp by Charles M. Carroll Page 131

Search Database (SQL Where Form #3)Ideally, the perfect "pick a city" example would show people a list of items so they can't choose wrong:

1 <HEAD><TITLE>SQLwhereform3.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <Form action = "SQLwhereForm3respond.asp" method=GET>4 Choose A City:<p>5 City:6 <%7 call query2list("select distinct city from publishers", _8 "cy","DSN=student;uid=student;pwd=magic")9 %>10 <P>11 <Input type="submit" value="Get Data">&nbsp;<Input type="reset" value="Clear City"></form>12 </BODY></HTML>13 <!--#include virtual="/learn/test/lib_dblist.asp"-->

1 <html><head><TITLE>sqlwhereform3respond.asp</TITLE></head>2 <body bgcolor="#FFFFFF">3 <%4 myDSN="DSN=student;uid=student;pwd=magic"5 mycity=request.querystring("cy")6 myexactsearch=request.querystring("exactsearch")7 SQLtemp="select * from publishers where city"8 If myexactsearch="on" then9 SQLtemp=SQLtemp & " ='"10 Else11 SQLtemp=SQLtemp & " LIKE '"12 End If13 SQLtemp=SQLtemp & mycity & "'"14 'response.write SQLtemp15 call query2table(SQLtemp,myDSN)16 %>17 <!--#include virtual="/learn/test/lib_dbtable.asp"-->18 </body></html>

The file lib_dbtable.asp looks like this:

1 <%2 sub query2table(inputquery, inputDSN)3 dim conntemp, rstemp4 set conntemp=server.createobject("adodb.connection")5 conntemp.open inputDSN6 set rstemp=conntemp.execute(inputquery)7 howmanyfields=rstemp.fields.count -1%>8 <table border=1><tr>9 <% 'Put Headings On The Table of Field Names10 for i=0 to howmanyfields %>11 <td><b><%=rstemp(i).name%></B></TD>12 <% next %>13 </tr>14 <% ' Now lets grab all the records15 do while not rstemp.eof %>16 <tr>17 <% for i = 0 to howmanyfields18 thisvalue=rstemp(i)19 If isnull(thisvalue) then20 thisvalue="&nbsp;"21 end if%>22 <td valign=top><%=thisvalue%></td>23 <% next %>

Page 126: [ebook] Learn ASP

24 </tr>25 <%rstemp.movenext26 loop%>27 </table>28 <%29 rstemp.close30 set rstemp=nothing31 conntemp.close32 set conntemp=nothing33 end sub%>

The file lib_dblist.asp looks like this:

1 <%sub query2list(myquery,myname,myDSN)2 dim conntemp, rstemp3 set conntemp=server.createobject("adodb.connection")4 conntemp.open myDSN5 set rstemp=conntemp.execute(myquery)6 %>7 <Select name="<%=myname%>">8 <%9 do while not rstemp.eof10 thisfield=trim(RStemp(0))11 if isnull(thisfield) or thisfield="" then12 ' ignore13 else14 response.write "<option>" & thisfield & "</option>"15 end if16 rstemp.movenext17 loop18 %>19 </select>20 <%rstemp.close21 set rstemp=nothing22 conntemp.close23 set conntemp=nothing24 end sub%>

http://www.learnASP.com/learn/SQLandor.asp by Charles M. Carroll Page 132

SQL OR Search Example by Charles CarrollAND and OR operators expand the power of the WHERE clause and provide a powerful tool to check multiple conditions. The BasicGuidelines are as follows:

If your goal is that several if conditions must ALL BE TRUE to suceed, this is the Role of the AND within a WHERE clause, i.e."select * from publishers where state='MD' and city='Rockville'"select * from authors where Year_Born>1960 and Year_Born<1970'

If several conditions can indivually be true this is the Role of an OR within a WHERE clause, i.e."select * from publishers where state='MD' OR state='NY'

1 <HEAD><TITLE>SQLcities.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <Form action = "SQLcitiesrespond.asp" method="POST">4 Choose City (or Cities):<p>5 <%6 call query2listm("select distinct city from publishers", _7 "cy","DSN=student;uid=student;pwd=magic")8 %>9 <P>10 <Input type="submit" value="Get Data">&nbsp;<Input type="reset" value="Clear City"></form>

Page 127: [ebook] Learn ASP

11 </BODY></HTML>12 <!--#include virtual="/learn/test/lib_dblistm.asp"-->13

The responder looks like this:

1 <HEAD><TITLE>sqlcitiesrespond.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <%4 citycount=request.form("cy").count5 If citycount=0 then%>6 <B>You never choose a city!</b><br>7 <a href="sqlcities.asp">Choose City</a>8 <%9 response.end10 end if11 firstcity=request.form("cy")(1)12 SQLtemp="select * from publishers "13 SQLtemp = SQLtemp & " where city='" & firstcity & "'"14 for counter=2 to citycount15 whichcity=request.form("cy")(counter)16 SQLtemp = SQLtemp & " or city='" & whichcity & "' "17 next18 response.write SQLtemp19 call query2table(SQLtemp,"DSN=student;uid=student;pwd=magic")20 %>21 <!--#include virtual="/learn/test/lib_dbtable.asp"-->22 </BODY></HTML>

The file lib_dbtable.asp looks like this:

1 <%2 sub query2table(inputquery, inputDSN)3 dim conntemp, rstemp4 set conntemp=server.createobject("adodb.connection")5 conntemp.open inputDSN6 set rstemp=conntemp.execute(inputquery)7 howmanyfields=rstemp.fields.count -1%>8 <table border=1><tr>9 <% 'Put Headings On The Table of Field Names10 for i=0 to howmanyfields %>11 <td><b><%=rstemp(i).name%></B></TD>12 <% next %>13 </tr>14 <% ' Now lets grab all the records15 do while not rstemp.eof %>16 <tr>17 <% for i = 0 to howmanyfields18 thisvalue=rstemp(i)19 If isnull(thisvalue) then20 thisvalue="&nbsp;"21 end if%>22 <td valign=top><%=thisvalue%></td>23 <% next %>24 </tr>25 <%rstemp.movenext26 loop%>27 </table>28 <%29 rstemp.close30 set rstemp=nothing31 conntemp.close32 set conntemp=nothing33 end sub%>

The file lib_dblistm.asp looks like this:

1 <%

Page 128: [ebook] Learn ASP

2 SUB query2listm(myquery,myname,myDSN)3 dim conntemp, rstemp4 set conntemp=server.createobject("adodb.connection")5 conntemp.open myDSN6 set rstemp=conntemp.execute(myquery)7 %>8 <Select name="<%=myname%>" multiple>9 <%10 do while not rstemp.eof11 thisfield=trim(RStemp(0))12 if isnull(thisfield) or thisfield="" then13 ' ignore14 else15 response.write "<option>" & thisfield & "</option>"16 end if17 rstemp.movenext18 loop19 %>20 </select>21 <%rstemp.close22 set rstemp=nothing23 conntemp.close24 set conntemp=nothing25 END SUB26 %>

http://www.learnASP.com/learn/SQLandor2.asp by Charles M. Carroll Page 133

SQL And/OR Examples by Charles CarrollHere are some examples of the AND plus OR operators and INLIST in typical ASP scripts.

DRAFT -- NOT READY YET

COMING SOON!

http://www.learnASP.com/learn/SQLcount.asp by Charles M. Carroll Page 134

SQL Count Syntax/ExamplesSQL can count items. There are a few variations on the syntax and some simple rules to remember:

Any field you want to count here is the simplest syntax"select count(*) from publishers where state='NY'

If you count a specific field you must groupby that field or it won't work:"select count(city),city from publishers group by city"

The AS operator allows you to specify a name for the counted field:"select count(city) as howmany,city from publishers group by city"

1 <HEAD><TITLE>SQLcount1.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <%4 call query2table("select count(*) from publishers where state='NY'")5 %>6 <!--#include virtual="/learn/test/subdbtable.inc"-->7 </BODY></HTML>

Page 129: [ebook] Learn ASP

1 <HEAD><TITLE>SQLcount2.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <%4 call query2table("select count(city),city from publishers group by city")5 %>6 <!--#include virtual="/learn/test/subdbtable.inc"-->7 </BODY></HTML>

1 <HEAD><TITLE>SQLcount3.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <%4 call query2table("select count(city) as howmany,city from publishers group by city")5 %>6 <!--#include virtual="/learn/test/subdbtable.inc"-->7 </BODY></HTML>

1 <HEAD><TITLE>SQLcount4.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <%4 call query2table("select count(*),city,state from publishers group by city,state")5 %>6 <!--#include virtual="/learn/test/subdbtable.inc"-->7 </BODY></HTML>

The Include file looks like this:

1 <%2 sub query2table(inputquery)3 set conntemp=server.createobject("adodb.connection")4 conntemp.open "DSN=Student;uid=student;pwd=magic"5 set rstemp=conntemp.execute(inputquery)6 howmanyfields=rstemp.fields.count -1%>7 <table border=1><tr>8 <% 'Put Headings On The Table of Field Names9 for i=0 to howmanyfields %>10 <td><b><%=rstemp(i).name%></B></TD>11 <% next %>12 </tr>13 <% ' Now lets grab all the records14 do while not rstemp.eof %>15 <tr>16 <% for i = 0 to howmanyfields17 thisvalue=rstemp(i)18 If isnull(thisvalue) then19 thisvalue="&nbsp;"20 end if%>21 <td valign=top><%=thisvalue%></td>22 <% next %>23 </tr>24 <%rstemp.movenext25 loop%>26 </table>27 <%28 rstemp.close29 set rstemp=nothing30 conntemp.close31 set conntemp=nothing32 end sub%>

http://www.learnASP.com/learn/SQLaggregate.asp by Charles M. Carroll Page 135

Page 130: [ebook] Learn ASP

SQL Aggregate Syntax/ExamplesSQL can also compute various aggregate items (MIN, MAX, AVERAGE are the most popular).

http://www.learnASP.com/learn/dbjoin.asp by Charles M. Carroll Page 136

Database -- Inner Joins by Aaron AlexanderIn this demonstration I will explain to you how joins between tables work in SQL. I will use the verbose SQL rather than the shortcuts due to thefact that the shortcuts differ between databases.

I would first like to define some terms that I will be using:

Primary Key(PK): This is the unique field in your table that is used to identify each record. (Ex: RecID)

Foreign Key(FK): This is a column that references a primary key of another table. It can have duplicate values.

We have 2 tables defined:

Customer

CustomerID(PK) CustomerName

1 Joe Schmoe

2 Fred Flintstone

Sales

ID(PK) CustomerID(FK) SalesAmount

3 1 $1.00

4 1 $22.00

5 1 $3.00

6 20 $22.00

Inner Joins

When joining two tables there are two ways to do it. The most common way is the inner join.

The inner join will return all data where all joined data exists.

Lets look at this example of an inner-join:

SELECT Customer.CustomerName, Sales.SalesAmount FROM Customer INNER JOIN Sales ON customer.CustomerID =Sales.CustomerID

In our example above, we are selecting all the Customer Names and amount of the sale where the customer numbers exist in both tables. Theresult of the query is this:

CustomerName SalesAmount

Joe Schmoe $1.00

Joe Schmoe $22.00

Joe Schmoe $3.00

Page 131: [ebook] Learn ASP

Note that record ID 6 in the sales table with customer ID of 20 is not in our result. Since that joined data does not exist we do not see the data.

Note: The SQL above can be written a lot simpler, doing it this way will avoid confusion when other tables are added:

SELECT Customer.CustomerName, Sales.SalesAmount FROM Customer , Sales where customer.CustomerID = Sales.CustomerID

Outer Joins

The outer join is useful when we want to return all data from one table, and also return linked data from another, when it exists, but here is wherewe differ from the inner join, we want to return all data from table 1 no matter what.

In our example we want to return all sales, even if there isn’t a valid customer associated with it.

Here is what our SQL will look like:

SELECT Customer.CustomerName, Sales.SalesAmount FROM Customer RIGHT JOIN Sales ON Customer.CustomerID =Sales.CustomerID

Our results will look like this:

CustomerName SalesAmount

Joe Schmoe $1.00

Joe Schmoe $22.00

Joe Schmoe $3.00

$22.00

Notice we did a right join. We chose to select all the data from the right table in our join statement. What would it look like if we changed to this:

SELECT Customer.CustomerName, Sales.SalesAmount FROM Customer LEFT JOIN Sales ON Customer.CustomerID =Sales.CustomerID;

Our results:

CustomerName SalesAmount

Joe Schmoe $1.00

Joe Schmoe $22.00

Joe Schmoe $3.00

Fred Flintstone

The results gave us all the records from the left table (Customer) and the linked data from the right.

As with the inner join there are shortcuts for joins, but that depends on which database you are using. Writing the verbose SQL statement willwork on all databases.

I hope this helps clear things up.

Aaron Alexander

http://www.learnASP.com/learn/authenticate.asp by Charles M. Carroll Page 137

Authenticate: Overview by Kevin Flick (authenticateoverview.asp) - Page 138 Authenticate: Comparison by Kevin Flick (authenticatecomparisons.asp) - Page 139 Authenticate: NT Challenge/Response by Kevin Flick (authenticatentcr.asp) - Page 140 Authenticate: Basic Authentication by Kevin Flick (authenticatebasic.asp) - Page 141

Page 132: [ebook] Learn ASP

Authenticate: Cookies by Kevin Flick (authenticatecookies.asp) - Page 142 Authenticate: Certificates by Kevin Flick (authenticatecertificate.asp) - Page 143 Authenticate: Build Your Own by Kevin Flick (authenticatebuild.asp) - Page 144 Authenticate: Protect Pages via Login #1 (security.asp) - Page 145 Authenticate: Protect Pages via Login #2 (security2.asp) - Page 146 Authenticate: 3rd Party by Kevin Flick (authenticate3rdparty.asp) - Page 147

http://www.learnASP.com/learn/authenticateoverview.asp by Charles M. Carroll Page 138

Authentication Overviewwritten and ©1998, 99 by Kevin Flick www.flicks.com creator of Authentix

What is Authentication?

Let's assume you want to restrict access to selected portions of your website. For example, you might have valuable information,such as real-time stock quotes (like Reuters or Datastream), or you want to charge a monthly fee in order to access your database.In these cases, you want to let people in, but only after checking that visitors have used an authorized username and password.Additionally, you might want to provide access to the bulk of your website for the simple price of a visitor's email address, creating aneffective method for tracking visitors.

Asking a visitor for their username and password (or their credentials) is called Authentication. On the world wide web, the oldestand most widely supported authentication method is Basic Authentication.

What are my choices?

Assuming you have the latest and greatest IIS, you have several choices when working with authentication including:IIS NT Challenge ResponseA good choice if if you are on a Windows Network, you can require the use of IE, and there's no proxy-server between thebrowser and the server.

IIS Basic AuthenticationCan expose your NT usernames and passwords unless all connections are over SSL.

A Basic Authentication filter such as AuthentiXCannot compromise NT accounts. High performance, large numbers of users. Can validate against ODBC or internaldatabase. Many advanced features.

Write your own filterFlexible, but resource intensive to build.

Cookie Based Authentication with ASP pagesOnly protects ASP pages. Can be slow. Requires cookies. Cookie-based systems can be susceptible to spoofing.

Self-Authenticating ISAPI dlls, CGI-scripts using Basic Authentication.Good performance, all content generated though a single URL. Doesn't use conventional directory/file/html format.

Certificate based.Secure, but intimidating for webmasters and surfers alike. Requires SSL.

http://www.learnASP.com/learn/authenticatecomparisons.asp by Charles M.Carroll

Page 139

Page 133: [ebook] Learn ASP

Authentication Comparisonwritten and ©1998, 99 by Kevin Flick www.flicks.com creator of Authentix

Which should I use?

In deciding which type of Authentication to use, it's important to keep the following points in mind:You want the widest possible audience, along with browser and platform independence. (impacts NTCR and cookies)●

Performance is critical. If (as you hope), your site becomes wildly popular, you don't want a dead-slow server (impactsSSL/Certificates, ASP)

Which Type Why use it? Why not use it? How to use it.

IIS NT Challenge ResponseWhy

Why not

How

IIS Basic AuthenticationWhy Why not

How

A Third Party Basic Authentication filterWhy

Why not How

Write your own Basic Authentication filterWhy

Why not

How

Cookie Based Authentication with ASP pagesWhy

Why not

How

Self-authenticating scriptsWhy

Why not

How

Certificate based authentication.Why

Why not

How

http://www.learnASP.com/learn/authenticatentcr.asp by Charles M. Carroll Page 140

Authentication -- NT Challenge/Responsewritten and ©1998, 99 by Kevin Flick www.flicks.com creator of Authentix

Using NT Challenge Response is an obvious choice, and is included as one of the options when you set up each IIS directory.Any directory you want to protect must be on a NTFS partition.

NTFS is the way to go if you are on a Windows Network. For intranets NTCR can be an ideal solution with theseconditions:

all users are on accessible domains●

there aren't too many users●

you can require the use of a compatible browser (Internet Explorer is the only browser which supports NTCR).●

You won't want to use NTFS ifyou want compatibility with browsers other than IE, or older browsers●

you want to protect directories on FAT partitions●

Page 134: [ebook] Learn ASP

you expect (don't we all?) a large number of users.Having a large number of users becomes a problem because this clutters the NT user database and it becomes verydifficult to maintain. It can also impair the speed of the operating system itself! Using the NT user base can also be aproblem because of potential security risks. You are elevating a 'mere' web surfer to the status of a full NT user. Youhave to be careful not inadvertently grant too many permissions.

there's a proxy server involved As documented in the IIS 4 Resource Kit, NTLM will not work through a proxy. Theproblem is that it requires more than 1 round trip to complete authentication and so needs a persistent connection endto end end, from client to origin server. Proxies don't generally work that way.

Definitions

NTCR = NT Challenge Response●

NTLM = NT Lan Manager●

NTFS = NT File System●

How to set up NTCR

In Internet Service Manager (IIS1-3) or the Microsoft Management Console for IIS (IIS4 and up) select the directory youwant to protect. Make sure Basic (Clear Text) is off and Windows NT Challenge Response is on. You can leave AllowAnonymous on.

Create an account for each user you want to provide access, remove the permissions for "IUSR_machinename" from thedirectory, and add permissions for the added users. Alternatively, you could set up a group, permit access to that group, andadd permitted users to the group. Remember, the user will need execute rights if the directory has any ASP, ISAPIextensions, counters, and so on.Note that when the user returns to a non-protected page, they will be prompted for their username and password again, unlessyou have also granted them read-access to non-protected pages. However cancelling the prompt will let them in,disconcerting though this may be.If the user has permission to access the directory but is in a different domain than the IIS machine, the user will have toprepend the domain name, so IIS knows where to look for the password.

Because NTCR uses a token mechanism for verifying users, the password of the currently logged in user is not available toIIS. This will have an impact if you are trying to access a resource which is not on the same machine as IIS, since IIS will notbe able to login using the current user to a machine elsewhere on the LAN. For example if an NTCR protected ASP pagetried to read an Access mdb file on another machine, it would fail. Similarly for SQL Server with Integrated or Mixedsecurity. See Q166029, Q149425.

http://www.learnASP.com/learn/authenticatebasic.asp by Charles M. Carroll Page 141

Authentication - IIS Basic Authenticationwritten and ©1998, 99 by Kevin Flick www.flicks.com creator of Authentix

IIS Basic Authentication is included as an option when you set up each IIS directory. Any directory you want to protect mustbe on a NTFS partition.

IIS Basic Authentication is the way to go if you accept the need for SSL and don't mind paying the performance penalty.You already have a certificate or you don't mind paying for one and setting it up.

You won't want to use IIS Basic Authentication if you are concerned about the security of your NT accounts andperformance. IIS calls LogonUser and ImpersonateLoggedOnUser for each and every request, which is expensive in terms ofCPU cycles.

Page 135: [ebook] Learn ASP

Definitions

SSL = Secure Socket Layer.●

How to set up IIS Basic Authentication

Setting up IIS Basic Authentication is similar to setting up NTCR.

In Internet Service Manager (IIS1-3) or the Microsoft Management Console for IIS (IIS4 and up) select the directoryyou want to protect. Turn on Basic (Clear Text) and turn off Windows NT Challenge Response. It is OK to leaveAllow Anonymous on.

When you select Basic (Clear Text) you will be warned that you Windows NT usernames and passwords will betransmitted without being encrypted. For your NT accounts this is a pretty serious issue. You should only consider thisoption in combination with SSL, which is slow and requires you to buy a certificate from Verisign or Thawte (amongothers).

Create an account for the each user to whom you want to give access, remove the permissions for"IUSR_machinename" from the directory, and add permissions for the users you added.Alternatively you could set up a group, permit access to that group, and add permitted users to that group.Remember the user will need execute rights if the directory has any ASP, ISAPI extensions, counters etc.

http://www.learnASP.com/learn/authenticatecookies.asp by Charles M. Carroll Page 142

Authentication -- Cookie Basedwritten and ©1998, 99 by Kevin Flick www.flicks.com creator of Authentix

You can use the cookie based session variables of Active Server Pages to capture a username and password from a form,validate the username and password, then set a session variable to indicate the user has correctly logged in.

Cookie Based Authentication with ASP pages is the way to go ifYou are happy coding your own solution in VBScript, and you only have a few asp pages to protect.●

You don't mind excluding those who cannot or will not accept cookies.●

You don't have gif/jpeg/pdf or other non-ASP content, so you are not concerned about someone else creatingweb-pages linking directly to your non-ASP protected content.

You won't want Cookie Based Authentication with ASP pages if

You want to protect all content, not just ASP pages.●

You are worried about performance. Any reasonably large amount of Active Server Pages can have a significantdetrimental effect on the performance of your server. The popularity of products such as XBuilder, which generatesstatic html pages from ASP pages for performance reasons (among others), illustrates this point.

Cookie-based systems can be susceptible to spoofing.●

Definitions

ASP = Active Server Pages.●

How to use Cookie Based Authentication with ASP pages

We have a example in this Tutorial on the next pages that implements session based authentication for people who want toimplement this:

http://www.activeserverpages.com/learn/security.asp●

http://www.activeserverpages.com/learn/security2.asp●

Page 136: [ebook] Learn ASP

http://www.learnASP.com/learn/authenticatecertificate.asp by Charles M. Carroll Page 143

Authentication -- Certificate Basedwritten and ©1998, 99 by Kevin Flick www.flicks.com creator of Authentix

Client certificates are an advanced form of authentication, and at this time they are still very much in their infancy with respect tocompatibility and ease of use.

Certificate based authentication is the way to go if :you want a high degree of certainty of the identity of the users accessing your site●

You accept the need for SSL and don't mind paying the performance penalty.●

You already have a certificate or you don't mind paying for one and setting it up.●

You won't want Certificate based authentication if :The process of issuing a client certificate is too complex and intimidating for both you and your users●

You do not want the performance hit of having all protected information exchanged via SSL●

Definitions

SSL = secure socket layer.●

MMC = Microsoft Management Console.●

How to use Certificate based authenticationSince this technology is still maturing, be sure to have the latest version of IIS4 installed on your system.

Obtain a certificate from a certificate issuing authority such as Verisign or Thawte. Refer to the IIS documentation on KeyManager.

Select a directory you want to protect in the MMC●

Click on the Secure Communicatations Edit button on the Directory Security property sheet and use the certificate youobtained. Select both Enable Client Certificates and Require Client Certificate

Enable client certificates for this resource●

Issue client certificates for access to this resource.●

There are several good references to help understand and use Client Certificate technology. Some articles that are recommendedinclude:

"Internet Information Server 4.0 - Security for the Web-Enabled Enterprise" by Nick Evans in the Premier Edition of SecurityAdvisor by Advisor.com publications, and

"Web Project, Digital IDs" by Jon Udell in the March Edition of Byte magazine.●

"Issuing digital certificates with Microsoft Certificate Server" section of the IIS Security White Paper by Microsoft.●

http://www.learnASP.com/learn/authenticatebuild.asp by Charles M. Carroll Page 144

Authentication -- Write your own Filterwritten and ©1998, 99 by Kevin Flick www.flicks.com creator of Authentix

Writing your own Basic Authentication filter is an option if you have the skills, resources and time to do it.

Writing your own Basic Authentication filter is the way to go ifyou have special requirements, and commissioning a custom enhancement to a third party Basic●

Page 137: [ebook] Learn ASP

Authentication filter is not an option.you have the skills, resources and time.●

you want to validate against a specific or proprietary type of datasource, such as flat-file, or your owndatabase.

You won't want to write your own Basic Authentication filter ifyou have a short deadline●

you do not have the skills or resources required●

Basic Authentication is not secure enough for your purposes●

you want all accounts of every type in one userbase, specifically the NT user account database, foradministrative reasons.

a third party tool like AuthentiX meets all your needs●

Definitions

ISAPI = Internet Server Application Programming Interface●

How to write your own Basic Authentication filter

You will need to build a dll that conforms to the ISAPI filter specification and has the following entry points:GetFilterVersion●

HttpFilterProc●

The GetFilterVersion function is the first entry point called by the Internet Information Server. In this function youset the IIS notifications that you want to receive, and any other first time setup tasks.

The HttpFilterProc function is called in response to the notifications set in GetFilterVersion and is where the workof the filter is actually done.

There are several excellent references to help develop an ISAPI filter. Recommended is Que's "Special EditionUsing ISAPI", ISBN 0-7897-0913-9 (to which this writer also contributed).

http://www.learnASP.com/learn/security.asp by Charles M. Carroll Page 145

Custom Security/Authentication #1You can limit access to specific pages in your website using several methods documented athttp://www.activeserverpages.com/learn/authenticate.asp Here we will demonstrate how to use custom authentication and alsocover session and application issues. You can try our authentication example by:

Attempt to access test/securitytestlevel1.asp or test/securitytestlevel2.asp or test/securitylevel3required.aspAll attempts to read those pages should fail.

Now if you login at test/securitylogin.asp. Sample logins that will work because of the database data are:user=chaz, password=chaz, securitylevel=1user=chaz2, password=chaz2, securitylevel=2user=chaz3, password=chaz3, securitylevel=3

You can also try logging out at test/securitylogout.asp which will put you back to square one. No security level will exist then.●

The next page details the source code for all scripts needed to implement our example but here is the list:securitylogin.aspsecurityloginrespond.asp

the login screen where someone can enter username/password and confirmsecurity level. It is a form that submits to securityloginrespond.asp

securitylogout.asp the screen to abandon someone's username/password and security level

Page 138: [ebook] Learn ASP

securitylevel1required.aspsecuritylevel2required.aspsecuritylevel3required.asp

which can be included on individual pages to limit access to people with thatsecurity level, i.e/:<!--#include file="securitylevel1required.asp"-->

securitytestlevel1.aspsecuritytestlevel2.aspsecuritytestlevel3.asp

which demonstrate how security is implemented. These scripts cannot beseen unless you login.

securitynotallowed.asp which anyone attempting to access a page without appropriate security levelis redirected to.

/learn/test/customsecurity.mdbDownload Database

a 3 column Access database: username, password, security level. Sampledata is:user=chaz, password=chaz, securitylevel=1user=chaz2, password=chaz2, securitylevel=2user=chaz3, password=chaz3, securitylevel=3

In a production application, this database would be located OUTSIDEof the web structure (and accessed by DSN) so it could never bedownloaded by a user.

http://www.learnASP.com/learn/security2.asp by Charles M. Carroll Page 146

Custom Security/Authentication #2To implement custom security via a database, we use the following scripts that we will present the source code for:

Here is the securitylogin.asp script:

1 <html><head>2 <title>securitylogin.asp</title>3 </head><body bgcolor="#FFFFFF">4 <form action="securityloginrespond.asp" method="POST">5 Sign In Page:<p>6 Name -&gt; <input NAME="userName" size="20"><br>7 Password -&gt; <input NAME="userPassword" size="20"><br>8 <input type="submit"><input type="reset">9 </form></body></html>

Here is the securityloginrespond.asp script:

1 <html><head>2 <TITLE>securityloginrespond.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <%5 dbname="/learn/test/secret/customsecurity.mdb"6 myname=request.form("username")7 mypassword=request.form("userpassword")8 set conntemp=server.createobject("adodb.connection")9 cnpath="DBQ=" & server.mappath(dbname)10 conntemp.Open "DRIVER={Microsoft Access Driver (*.mdb)}; " & cnpath11 sqltemp="select * from users where user='"12 sqltemp=sqltemp & myname & "'"13 set rstemp=conntemp.execute(SQLTemp)14 If rstemp.eof then%>15 we don't have a user named <%=Myname%> on file!<br>16 Try <A href='securitylogin.asp'>Logging in</a> again17 <%response.end18 end if19 If rstemp("Password")=mypassword then20 session("name")=rstemp("user")21 session("securitylevel")=rstemp("securitylevel")22 response.write "Security Level=" & session("securitylevel")23 else%>24 Password Unrecognized<br>

Page 139: [ebook] Learn ASP

25 Try <A href='securitylogin.asp'>Logging in</a> again26 <%response.end27 end if28 rstemp.close29 conntemp.close30 set rstemp=nothing31 set conntemp=nothing32 %>33 </body></html>

Here is the securitylogout.asp script:

1 <html><head>2 <title>securitylogout.asp</title>&3 <body>4 <%5 session.abandon6 %>7 Logged out Now!!!8 </body>9 </html>

Here is the securitylevel1required.asp script:

1 <%2 response.expires=03 if session("securitylevel")>0 then4 ' nothing to do 5 else6 response.redirect "securityunauthorized.asp"7 end if8 %>

Here is the securityunauthorized.asp script:

1 <html><head>2 <title>unauthorized</title>&3 <body>4 You are unauthorized to read that page!5 </body></html>

Here is the securitytestlevel1.asp script:

1 <!--#include file="securitylevel1required.asp"-->2 <html><head>3 <title>New Page </title>4 <META HTTP-EQUIV="Expires" CONTENT="Tue, 04 Dec 1993 21:29:02 GMT">5 </head><body>6 My level 1 secret is Pretty Hot!!!<br>7 Our president may not be as honest as we believed!8 </body>9 </html>

http://www.learnASP.com/learn/authenticate3rdparty.asp by Charles M. Carroll Page 147

Authentication -- 3rd Party Methodwritten and ©1998, 99 by Kevin Flick www.flicks.com creator of Authentix

You won't want to use a third party Basic Authentication filter if

protecting your premium content directories does not warrant the price of registration.●

Basic Authentication is not secure enough for your purposes●

Page 140: [ebook] Learn ASP

you want all accounts of every type in one userbase, specifically the NT user account database, for administrativereasons.

Authentix, a third party Basic Authentication filter is the way to go if

You want the high performance that a filter offers●

You want to be able to add and modify users from ASP and don't want the ASP pages to have SysAdmin priviledges●

You want browser independence●

You don't want any chance of compromising NT username/password security●

You want to separate your web-users from your NT Accounts●

You are concerned about performance. In addition to the speed associated with filter based solutions, AuthentiX isunique in that it does not impersonate an NT account to grant access, eliminating the CPU-expensive call toLogonUser on every request.

You have directories you want to validate against an ODBC database●

You want to authenticate multiple IIS servers against a single ODBC machine on the LAN.●

You want to use browser based remote administration●

you need to protect all content in a directory: htm, asp, gif, jpg, zip, and so on.●

you want advanced features like

limiting concurrent logins,❍

bandwith, request and login throttling,❍

protect by IP, Domain Name and by referrer❍

AuthentiX is a fast, filter based third party tool for IIS authentication developed by Flicks Software (me).It allows you to protect content directories and individual files by asking for usernames and passwords held separately fromthe Windows NT usernames and passwords, ensuring the the security of your NT accounts.

Definitions

ODBC = Open Database Connectivity.●

How to set up AuthentiX, a third party Basic Authentication filter

Setting up AuthentiX is easy and straighforward.

Download the free evaluation version, unzip it and run setup.exe. Installshield will guide you through the rest of theinstallation process.

Make sure Basic (Clear Text) is off and Allow Anonymous is on. You can leave Windows NT Challenge Response onor off.

Create a user. From the main AuthentiX dialog, click the Users button, then Add. Type a username and password andclick OK. The user will be added to the User List. Click OK.

Create a group. From the main AuthentiX dialog, click the Groups button, then Add. Type a Groupname, click on auser (to highlight it) listed in the Non-Members list box, and click Add. The user will be moved to the Members listbox. Click OK. You should now see the group in the group list. Click OK.

Protect a directory. From the main AuthentiX dialog, click the Access button, then Add. Click the Browse button andselect a directory that is part of your web directories, and that you would like to protect. Click the By Group button andadd the group you created in the previous step. Click OK. You should now see that the group is protecting thatdirectory. Verify that the group is protecting the desired directory and click OK twice

Using a browser, go to the URL that the directory is accessed from using IIS. It should prompt you for your usernameand password.

Type the username and password and you should be granted access.●

You can see how to set up ODBC and other advanced options by downloading the online Windows help file or checking out

Page 141: [ebook] Learn ASP

the online Guided Tour. Because the pace of enhancements and improvements to this product sometimes outstrips thedocumentation, you can find out more by working with the free evaluation download.

http://www.learnASP.com/learn/qualitycode.asp by Charles M. Carroll Page 148

Strings: Core Functions (strings.asp) - Page 149 Strings: SPLIT Function (stringsplit.asp) - Page 150 Strings: REPLACE Function (stringreplace.asp) - Page 151 Strings: JOIN Function (stringjoin.asp) - Page 152 Arrays: Basics (arrays.asp) - Page 153 Arrays: Variable Size (arrays2.asp) - Page 154 Arrays: Best Way To Load (arrays3.asp) - Page 155 Dictionary Objects (dictionary.asp) - Page 156 Subroutine: Working with Dates #1 (subdates.asp) - Page 157 Subroutine: Working with Dates #2 (subdates2.asp) - Page 158 Subroutine: Query2Table (subdbtable.asp) - Page 159 Subroutine: Query2List (subdblist.asp) - Page 160 Subroutine: Highly Reusable (subreusable.asp) - Page 161 Subroutine: List Box w/optional params (subDBlistbest.asp) - Page 162 Subroutine: Abstract HTML by Phil Paxton (libhtml.asp) - Page 163 Function: Working Days (functionworkingdays.asp) - Page 164 New Features in VBScript version5 (vbs5.asp) - Page 165

http://www.learnASP.com/learn/strings.asp by Charles M. Carroll Page 149

String Functions by Charles CarrollString functions are very useful for parsing data from ASCII files, formatting output in complex ways and parsing form input. Thefollowing scripts provides a sample of some crucial VBScript string functions in action. The string functions demonstrated are:

Instr(string,searchstring)returns a numeric position where search string was found

Mid(string,start,length)chops string at a start position for a fixed number of characters.

Mid(string,start)results in a string that has all characters before startpos removed.

Trim(string)removes all spaces from a string.

1 <html><head>2 <title>citystatezip.asp</title>3 </head><body bgcolor="#FFFFFF">4 <Form action = "citystatezipRespond.asp" method="post">5 Enter City <b>,</b> State Zip<p>6 <Input NAME="CSZ" size ="40"><p>7 <Input type="submit" value="Here is my Data!">8 </form>9 </body></html>

Page 142: [ebook] Learn ASP

The user can enter a city, state and Zip, i.e.Rockville, MD 20849San Fransisco, CA xxxxxPike's Peak, CO xxxxxand the program can use these functions to separate the data.

1 <html><head>2 <title>citystateziprespond.asp</title>3 </head><body>4 <%5 alldata=request("csz")6 IF instr(alldata,",")=0 THEN%>7 You need a comma<br>,<br>between city and state!<p>8 <%response.end9 END IF10 11 findcomma=instr(alldata,",")12 city=mid(alldata,1,findcomma-1)13 leftover=trim(mid(alldata,findcomma+1))14 15 findspace=instr(leftover," ")16 state=mid(leftover,1,findspace)17 leftover=mid(leftover,findspace+1)18 19 zip=leftover20 21 response.write "city=" & city & "<br>"22 response.write "state=" & state & "<br>"23 response.write "zip=" & zip & "<br>"24 25 26 %>27 </body></html>

http://www.learnASP.com/learn/stringsplit.asp by Charles M. Carroll Page 150

SPLIT String Function by Charles CarrollThe various string functions can be used interchangeably often. We will write the same script using SPLIT, REPLACE and JOIN todemonstrate all 3 functions and how they often are used for similar tasks. However, your programming situations may be especiallysuited for 1 out of 3 of the functions.

SPLIT(string,delimiter)is a function that returns an array with as many elements as are separated by delimiters within the string.

The user can enter a state or multiple states. We write the program utilizing SPLIT to demonstrate how this can be used.

statesplit.asp

1 <html><head>2 <title>states.asp</title>3 </head><body bgcolor="#FFFFFF">4 <form action="statesplitrespond.asp" method="post">5 Enter State (or many states separated by <b>,<b><p>6 <input NAME="states" size="40"><p>7 <input type="submit" value="Get The Publishers!">8 </form>9 </body></html>

statesplitrespond.asp

Page 143: [ebook] Learn ASP

1 <!--#include virtual="/learn/test/lib_dbtable.asp"-->2 <html><head>3 <title>statesrespond.asp</title>&4 <body>5 <%6 mySQL="select * from publishers " & whereclause7 myDSN="DSN=student;uid=student;pwd=magic"8 public allstates9 tempinput=request("states")10 allstates=split(tempinput,",")11 12 maxcounter=ubound(allstates)13 14 whereclause=" where state='" & allstates(0) & "'"15 FOR counter=1 TO maxcounter16 thisstate=allstates(counter)17 whereclause=whereclause & " OR state='" & thisstate & "'"18 NEXT19 mySQL=mySQL & whereclause20 Call Query2Table(mySQL,myDSN)21 %>22 </body></html>

http://www.learnASP.com/learn/stringreplace.asp by Charles M. Carroll Page 151

Replace String Functions by Charles CarrollThe various string functions can be used interchangeably often. We will write the same script using SPLIT, REPLACE and JOIN todemonstrate all 3 functions and how they often are used for similar tasks. However, your programming situations may be especiallysuited for 1 out of 3 of the functions.

REPLACE(string,oldvalue,newvalue)results in a string that has all occurences of oldvalue replaced with a newvalue.

The user can enter a state or multiple states. We write the program utilizing REPLACE to demonstrate how this function canbe used.

statereplace.asp

1 <html><head>2 <title>statereplace.asp</title>3 </head><body bgcolor="#FFFFFF">4 <form action="statereplacerespond.asp" method="post">5 Enter State (or many states separated by <b>,<b><p>6 <input NAME="states" size="40"><p>7 <input type="submit" value="Get The Publishers!">8 </form>9 </body></html>

statereplacerespond.asp

1 <!--#include virtual="/learn/test/lib_dbtable.asp"-->2 <html><head>3 <title>statesrespond.asp</title>&4 <body>5 <%6 mySQL="select * from publishers " & whereclause7 myDSN="DSN=student;uid=student;pwd=magic"8 9 tempinput=request("states")10 11 whereclause=" where state='" & tempinput

Page 144: [ebook] Learn ASP

12 whereclause=replace(whereclause, ",","' OR state='")13 whereclause=whereclause & "'"14 15 mySQL=mySQL & whereclause16 response.write mySQL17 Call Query2Table(mySQL,myDSN)18 %>19 </body></html>

http://www.learnASP.com/learn/stringjoin.asp by Charles M. Carroll Page 152

JOIN String Functions by Charles CarrollThe various string functions can be used interchangeably often. We will write the same script using SPLIT, REPLACE and JOIN todemonstrate all 3 functions and how they often are used for similar tasks. However, your programming situations may be especiallysuited for 1 out of 3 of the functions.

JOIN(array,delimiter)takes an array and converts it to one string with delimiters.

The user can enter a state or multiple states. We write the program using the JOIN function to demonstrate how this functioncan be used.

statejoin.asp

1 <html><head>2 <title>statejoin.asp</title>3 </head><body bgcolor="#FFFFFF">4 <form action="statejoinrespond.asp" method="post">5 Enter State (or many states separated by <b>,<b><p>6 <input NAME="states" size="40"><p>7 <input type="submit" value="Get The Publishers!">8 </form>9 </body></html>

statejoinrespond.asp

1 <!--#include virtual="/learn/test/lib_dbtable.asp"-->2 <html><head>3 <title>statejoinrespond.asp</title>&4 <body>5 <%6 mySQL="select * from publishers "7 myDSN="DSN=student;uid=student;pwd=magic"8 public allstates9 tempinput=request("states")10 allstates=split(tempinput,",")11 12 whereclause=" where state='" & JOIN(allstates, "' OR state='") & "'"13 14 mySQL=mySQL & whereclause15 response.write mySQL16 Call Query2Table(mySQL,myDSN)17 %>18 </body></html>

http://www.learnASP.com/learn/arrays.asp by Charles M. Carroll Page 153

Page 145: [ebook] Learn ASP

Arrays to store data Part #1 by Charles CarrollHere would be a code sample without arrays:1 <html><head>2 <title>arraysnot.asp</title>3 </head><body bgcolor="#FFFFFF">4 <%5 dim x,y,z6 7 x=78 y=209 z=x+y10 11 response.write z12 %>13 </body></html>

Here is the same example with arrays1 <html><head>2 <title>arrays.asp</title>3 </head><body bgcolor="#FFFFFF">4 <%5 dim allstuff(3)6 7 allstuff(0)=78 allstuff(1)=209 allstuff(2)=allstuff(0)+allstuff(1)10 11 response.write allstuff(2)12 %>13 </body></html>

http://www.activeserverpages.com/learn/subdates.asphas a good example of arrays in a practical context.

http://www.learnASP.com/learn/arrays2.asp by Charles M. Carroll Page 154

Arrays to store data Part #2 by Charles CarrollAssigning an array size with a variable produces a variable unless the Redim command is used.

Method #1: You know the size●

Method #2: the size is in a variable●

1 <html><head>2 <title>arraysredim.asp</title>3 </head><body bgcolor="#FFFFFF">4 <%5 ' this code6 dim a_array(100)7 8 ' this code will fail9 x=10010 dim my_array(x)11 12 %>13 </body></html>

Assigning an array size with a variable produces an error unless the Redim command is used.1 <html><head>

Page 146: [ebook] Learn ASP

2 <title>arraysredimcorrect.asp</title>3 </head><body bgcolor="#FFFFFF">4 <%5 dim my_array()6 x=1007 redim preserve my_array(x)8 my_array(20)="Hi!"9 my_array(40)="How are You"10 11 lowcount=lbound(my_array)12 highcount=ubound(my_array)13 response.write "lowcount=" & lowcount & ";highcount=" & highcount & "<p>"14 for counter=lowcount to highcount15 response.write counter & "&nbsp;&nbsp;&nbsp;"16 response.write my_array(counter) & "<br>"17 next18 19 %>20 </body></html>

http://www.learnASP.com/learn/arrays3.asp by Charles M. Carroll Page 155

Arrays to store data Part 3 by Charles CarrollThere is a code intensive way to load an array and a less intensive one. For example, here is the code intensive one:1 <html><head>2 <title>arraysload.asp</title>3 </head><body bgcolor="#FFFFFF">4 <%5 dim my_months(13)6 7 my_months(0)=""8 my_months(1)="Jan"9 my_months(2)="Feb"10 my_months(3)="Mar"11 my_months(4)="Apr"12 my_months(5)="May"13 my_months(6)="Jun"14 my_months(7)="Jul"15 my_months(8)="Aug"16 my_months(9)="Sep"17 my_months(10)="Oct"18 my_months(11)="Nov"19 my_months(12)="Dec"20 21 lowcount=lbound(my_months)22 highcount=ubound(my_months)23 response.write "lowcount=" & lowcount & ";highcount=" & highcount & "<p>"24 for counter=lowcount to highcount25 response.write my_months(counter) & "<br>"26 next27 %>28 </body></html>

Here is the less code intense one:1 <html><head>2 <title>arraysloadbest.asp</title>3 </head><body bgcolor="#FFFFFF">4 <%5 dim my_months6 7 my_months=array("Jan","Feb","Mar","Apr", _

Page 147: [ebook] Learn ASP

8 "May","Jun","Jul","Aug", _9 "Sep","Oct","Nov","Dec")10 11 ' finally here is how you loop through an array12 lowcount=lbound(my_months)13 highcount=ubound(my_months)14 response.write "lowcount=" & lowcount & ";highcount=" & highcount & "<p>"15 for counter=lowcount to highcount16 response.write my_months(counter) & "<br>"17 next18 %>19 </body></html>

http://www.learnASP.com/learn/dictionary.asp by Charles M. Carroll Page 156

Dictionary objects to store data by Charles CarrollThis is how to create and place items into a dictionary objects and display the contents:

1 <html><head>2 <title>dictionarybasics.asp</title>3 </head><body bgcolor="#FFFFFF">4 <%5 set mysample=server.CreateObject("Scripting.Dictionary")6 7 mysample.Add "haircolor", "brown"8 mysample.add "eyecolor" , "blue"9 mysample.add "dateofbirth", "5/13/64"10 11 for each whatever in mysample12 response.write whatever & "="13 response.write mysample.item(whatever) & "<br>"14 next15 set mysample=nothing16 %>17 </body></html>

This is how to make an array of dictionary objects.

1 <html><head>2 <title>dictionaryarrays.asp</title>3 </head><body bgcolor="#FFFFFF">4 <%5 dim people(3)6 7 Set people(0) = server.CreateObject("Scripting.Dictionary")8 people(0).Add "fname", "Jane"9 people(0).Add "lname", "Doe"10 people(0).Add "haircolor", "brown"11 people(0).add "eyecolor" , "blue"12 people(0).add "dateofbirth", "1/10/60"13 14 Set people(1) = server.CreateObject("Scripting.Dictionary")15 people(1).Add "fname", "Reginald"16 people(1).Add "mname", "Elton"17 people(1).Add "lname", "Dwight"18 people(1).Add "haircolor", "red"19 people(1).add "eyecolor" , "dusty"20 people(1).add "dateofbirth", "1/10/60"21 22 Set people(2) = server.CreateObject("Scripting.Dictionary")23 people(2).Add "fname", "Hitoshi"

Page 148: [ebook] Learn ASP

24 people(2).Add "lname", "Yoshitsugu"25 26 ' print out one item27 for each whatever in people(1)28 response.write whatever & "="29 response.write people(1).item(whatever) & "<br>"30 next31 32 for counter=0 to 233 set people(counter)=nothing34 next35 %>36 </body></html>

The dictionary items can be removed individually unlike array elements. See: http://www.activeserverpages.com/docs -->vbscript docs for all the rest of the details about the dictionary object.

http://www.learnASP.com/learn/subdates.asp by Charles M. Carroll Page 157

Subroutines - Choosing/Validating Dates by Charles CarrollSubroutines can be used to provide handy date entry list boxes.1 <HEAD><TITLE>subdates.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <form action="subdatesrespond.asp">4 Depart:5 <%call showdateform("depart")%>6 <br>7 Arrive:8 <%call showdateform("arrive")%>9 <input type="submit" value="Ready To Travel">10 </form>11 <%12 sub showdateform(mylistname)13 call showmonth(mylistname)14 call showday(mylistname)15 call showyear(mylistname)16 end sub17 %>18 19 <%sub showmonth(listname)%>20 <select name="<%=listname%>month">21 <%22 dim monthname23 monthname=array("Jan","feb","Mar","Apr", _24 "May","Jun","Jul","Aug", _25 "Sep","Oct","Nov","Dec")26 for counter=0 to 11 27 temp=monthname(counter)28 response.write "<option value='" & counter+129 response.write "'>" & temp & "</option>" 30 next%>31 </select>32 <%end sub%>33 34 <%sub showday(listname)%>35 <select name="<%=listname%>day">36 <%for counter=1 to 3137 response.write "<option>" & counter & "</option>" 38 next%>39 </select>40 <%end sub%>41

Page 149: [ebook] Learn ASP

42 <%sub showyear(listname)%>43 <select name="<%=listname%>year">44 <%for counter=1964 to 200545 response.write "<option>" & counter & "</option>" 46 next%>47 </select>48 <%end sub%>49 50 51 </BODY></HTML>

http://www.learnASP.com/learn/subdates2.asp by Charles M. Carroll Page 158

Subroutines - Choosing/Validating Dates #2 by Charles CarrollThe form handler for the previous example could validate and manipulate dates using some built-in VBscript date handling routines,for example:

isdate() to validate a date●

1 <HEAD><TITLE>subdatesrespond.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <%4 dday=request.querystring("departday")5 dmonth=request.querystring("departmonth")6 dyear=request.querystring("departyear")7 departdate=dday & "/" & dmonth & "/" & dyear8 9 aday=request.querystring("arriveday")10 amonth=request.querystring("arrivemonth")11 ayear=request.querystring("arriveyear")12 arrivedate=aday & "/" & amonth & "/" & ayear13 14 If isdate(departdate) then15 response.write "Departure Date is Valid Date<br>"16 else17 response.write "Departure Date is INVALID<br>" 18 end if19 20 If isdate(arrivedate) then21 response.write "Arrival Date is Valid Date<br>"22 else23 response.write "Arrival Date is INVALID<br>" 24 end if25 %>26 </BODY></HTML>

http://www.learnASP.com/learn/subdbtable.asp by Charles M. Carroll Page 159

Query2Table by Charles CarrollSubroutines can save you having to repeat blocks of code. This code illustrates how we can build tables with minimal code in themain script and by including a file with a convenient subroutine.

1 <HEAD><TITLE>subdbtable.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <%4 myDSN="DSN=student;uid=student;pwd=magic"

Page 150: [ebook] Learn ASP

5 mySQL="select * from publishers"6 call query2table(mySQL,myDSN)7 %>8 <!--#include virtual="/learn/test/lib_dbtable.asp"-->9 </BODY></HTML>

1 <HEAD><TITLE>subdbtable2.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <%4 myDSN="DSN=student;uid=student;pwd=magic"5 mySQL="select * from titles"6 call query2table(mySQL,myDSN)7 %>8 <!--#include virtual="/learn/test/lib_dbtable.asp"-->9 </BODY></HTML>

1 <HEAD><TITLE>subdbtable3.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <%4 myDSN="DSN=student;uid=student;pwd=magic"5 mySQL="select * from authors"6 call query2table(mySQL,myDSN)7 %>8 <!--#include virtual="/learn/test/lib_dbtable.asp"-->9 </BODY></HTML>

1 <HEAD><TITLE>subdbtable4.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <%4 myDSN="DSN=student;uid=student;pwd=magic"5 mySQL= "SELECT Publishers.Name, Titles.Title "6 mySQL= mySQL & "FROM Publishers "7 mySQL= mySQL & "INNER JOIN Titles ON Publishers.PubID = Titles.PubID "8 mySQL= mySQL & "order by Name"9 10 call query2table(mySQL,myDSN)11 %>12 <!--#include virtual="/learn/test/lib_dbtable.asp"-->13 </BODY></HTML>

1 <HEAD><TITLE>subdbtable5.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <%4 myDSN="DSN=student;uid=student;pwd=magic"5 mySQL="select * from title_author"6 call query2table(mySQL, myDSN)7 %>8 <!--#include virtual="/learn/test/lib_dbtable.asp"-->9 </BODY></HTML>

1 <HEAD><TITLE>subdbtable6.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <%4 myDSN="DSN=student;uid=student;pwd=magic"5 mySQL="select name,type from sysobjects"6 call query2table(mySQL,myDSN)7 %>8 <!--#include virtual="/learn/test/lib_dbtable.asp"-->9 </BODY></HTML>

The Include file lib_dbtable.asp looks like this:

1 <%2 sub query2table(inputquery, inputDSN)3 dim conntemp, rstemp4 set conntemp=server.createobject("adodb.connection")5 conntemp.open inputDSN6 set rstemp=conntemp.execute(inputquery)

Page 151: [ebook] Learn ASP

7 howmanyfields=rstemp.fields.count -1%>8 <table border=1><tr>9 <% 'Put Headings On The Table of Field Names10 for i=0 to howmanyfields %>11 <td><b><%=rstemp(i).name%></B></TD>12 <% next %>13 </tr>14 <% ' Now lets grab all the records15 do while not rstemp.eof %>16 <tr>17 <% for i = 0 to howmanyfields18 thisvalue=rstemp(i)19 If isnull(thisvalue) then20 thisvalue="&nbsp;"21 end if%>22 <td valign=top><%=thisvalue%></td>23 <% next %>24 </tr>25 <%rstemp.movenext26 loop%>27 </table>28 <%29 rstemp.close30 set rstemp=nothing31 conntemp.close32 set conntemp=nothing33 end sub%>

http://www.learnASP.com/learn/subdblist.asp by Charles M. Carroll Page 160

Subroutines Query2List by Charles CarrollSubroutines can save you having to repeat blocks of code and can optionally be placed in separate files and included when needed,thus making your pages not appear to have lots of code in-line.

1 <html><head>2 <TITLE>subdblist.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <form>5 <%6 theDSN="DSN=student;uid=student;pwd=magic"7 call query2list("select distinct city from publishers","cy",theDSN)8 call query2list("select distinct state from publishers","st",theDSN)9 call query2list("select distinct zip from publishers","zp",theDSN)10 %>11 </form>12 <!--#include virtual="/learn/test/subdblist.inc"-->13 </body></html>

The include file lib_dblist.asp looks like:

1 <%sub query2list(myquery,myname,myDSN)2 dim conntemp, rstemp3 set conntemp=server.createobject("adodb.connection")4 conntemp.open myDSN5 set rstemp=conntemp.execute(myquery)6 %>7 <Select name="<%=myname%>">8 <%9 do while not rstemp.eof10 thisfield=trim(RStemp(0))11 if isnull(thisfield) or thisfield="" then

Page 152: [ebook] Learn ASP

12 ' ignore13 else14 response.write "<option>" & thisfield & "</option>"15 end if16 rstemp.movenext17 loop18 %>19 </select>20 <%rstemp.close21 set rstemp=nothing22 conntemp.close23 set conntemp=nothing24 end sub%>

http://www.learnASP.com/learn/subreusable.asp by Charles M. Carroll Page 161

Subroutines - A "Flexible Approach" by Charles CarrollSubroutines can be very cleverly constructed so that you can use the same routine to power several different tasks instead ofcopying code as the following examples illustrates!

1 <HEAD><TITLE>subreusabledataform.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <!--#include virtual="/learn/test/subflexible.asp"-->4 <%5 call query2entryform("select * from publishers where pubid=16")6 %>7 </BODY></HTML>

1 <HEAD><TITLE>subreusabledatalist.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <!--#include virtual="/learn/test/lib_subflexible.asp"-->4 <%5 call query2list("select distinct state from publishers","thestate")6 call query2list("select distinct city from publishers","thecity")7 call query2list("select distinct zip from publishers","thezip")8 %>9 </BODY></HTML>10

1 <HEAD><TITLE>subreusabledatatable.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <!--#include virtual="/learn/test/subflexible.asp"-->4 <%5 call query2table("select * from publishers")6 %>7 </BODY></HTML>

1 <HEAD><TITLE>subreusableform.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <!--#include virtual="/learn/test/subflexible.asp"-->4 <%5 call query2form("select * from publishers")6 %>7 </BODY></HTML>

The library file lib_subflexible.asp looks like:

1 <%2 dim htmlstart, htmlend3 dim rowstart, rowend4 dim fieldstart, fieldend5 dim namestart, nameend

Page 153: [ebook] Learn ASP

6 dim fieldnames7 fieldnames=false8 9 sub query2list(myquery,listname)10 htmlstart="<select name='" & listname & "'>"11 htmlend="</select>"12 rowstart="<option>"13 rowend="</option>"14 fieldstart=""15 fieldend=""16 call query2html(myquery)17 end sub18 19 sub query2table(myquery)20 htmlstart="<table border=1>"21 htmlend="</table>"22 rowstart="<tr>"23 rowend="</tr>"24 fieldstart="<td valign=top>"25 fieldend="</td>"26 call query2html(myquery)27 end sub28 29 sub query2form(myquery)30 htmlstart=""31 htmlend=""32 rowstart=""33 rowend="<hr>"34 fieldstart=""35 fieldend="<br>"36 fieldnames=true37 namestart=""38 nameend="&nbsp;=&nbsp;"39 call query2html(myquery)40 end sub41 42 sub query2entryform(myquery)43 htmlstart=""44 htmlend=""45 rowstart=""46 rowend=""47 fieldstart="%name%&nbsp;=&nbsp;<input type='text name='%name%' value='"48 fieldend="' size='%size%'><br>"49 fieldnames=false50 namestart=""51 nameend="&nbsp;&nbsp;="52 call query2html(myquery)53 end sub54 55 sub query2html(inputquery)56 set conntemp=server.createobject("adodb.connection")57 conntemp.open "DSN=Student;uid=student;pwd=magic"58 set rstemp=conntemp.execute(inputquery)59 howmanyfields=rstemp.fields.count -160 redim fsa(howmanyfields)61 redim fea(howmanyfields)62 for i = 0 to howmanyfields63 tempstart=replace(fieldstart,"%name%",rstemp(i).name)64 tempend=replace(fieldend,"%name%",rstemp(i).name)65 tempstart=replace(tempstart,"%size%",rstemp(i).actualsize)66 tempend=replace(tempend,"%size%",rstemp(i).actualsize)67 fsa(i)=tempstart68 fea(i)=tempend69 next70 response.write htmlstart & vbcrlf71 counter=072 do until rstemp.eof

Page 154: [ebook] Learn ASP

73 response.write rowstart & vbcrlf74 for i = 0 to howmanyfields75 if fieldnames=true then76 response.write namestart & rstemp(i).name & nameend77 end if78 response.write fsa(i) & rstemp(i) & fea(i) & vbcrlf79 next80 response.write rowend & vbcrlf81 counter=counter+182 rstemp.movenext83 if response.isclientconnected=false then84 exit do85 end if86 loop87 rstemp.close88 set rstemp=nothing89 conntemp.close90 set conntemp=nothing91 response.write htmlend92 end sub93 %>

http://www.learnASP.com/learn/subDBlistbest.asp by Charles M. Carroll Page 162

Subroutines Db2list "Best" Approach by Charles CarrollSubroutines could be considerably more useful if they took optional parameters. Since they don't we can jury rig a system whereby asubroutine is invoked with two parameters: a delimiter and a string. And the string itself contains the various parameters. Thisapproach implements a more optional parameter "like" solution.

1 <html><head>2 <TITLE>subdblistbest.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <form>5 <%call db2list("^","select distinct city from publishers^city^New York")%>6 <%call db2list("^","select distinct state frompublishers^state^NY^table^DSN=student;uid=student;pwd=magic")%>7 <%call db2list("^","select distinct zip from publishers^Zip Code^^table")%>8 </form>9 <!--#include virtual="/learn/test/lib_dblistbest.asp"-->10

The include file lib_dblistbest.asp looks like:

1 <%2 sub db2list(mydelim,myparm)3 4 dim myparameters5 myparameters=SPLIT(myparm,mydelim)6 parmcount=ubound(myparameters)7 myquery=myparameters(0)8 label=myparameters(1)9 default=myparameters(2)10 if parmcount>2 then11 format=lcase(myparameters(3))12 end if13 if parmcount>3 then14 connstring=myparameters(4)15 else16 connstring="DSN=Student;uid=student;pwd=magic"17 end if18

Page 155: [ebook] Learn ASP

19 set conntemp=server.createobject("adodb.connection")20 conntemp.open connstring21 set rstemp=conntemp.execute(myquery)22 If format="table" then%>23 <table width="100%" border="0" cellspacing="1"><td>24 <%end if25 response.write label26 If format="table" then%>27 </td><td>28 <%end if%>29 <Select>30 <option value="<%=default%>" selected><%=default%></option>31 <%32 do while not rstemp.eof %>33 <option><%=RStemp(0)%></option>34 <%35 rstemp.movenext36 loop37 conntemp.close38 %>39 </select>40 <%If format="table" then%>41 </td><tr></table>42 <%end if43 end sub%>44

http://www.learnASP.com/learn/libhtml.asp by Charles M. Carroll Page 163

Library of HTML Commands by Phil Paxton©1999 by Phil Paxton ([email protected])

Subroutines and Functions can be used, for example, to provide a layer of abstraction over HTML.

1 <!--#include virtual="/learn/test/lib_htmlstuff.asp"-->2 <html><head>3 <title>libhtmldemo.asp by Phil Paxton</title>&4 <body>5 <form action="lib_htmldemorespond.asp">6 <%7 Call Form_TextBox("first name","Fname",20,20,"")8 response.write "<br>"9 Call Form_TextBox("Last Name","Lname",20,20,"")10 response.write "<br>"11 Call Form_TextBox("City","cy",20,20,"")12 response.write "<br>"13 Call Form_TextBox("State","st",2,2,"")14 response.write "<br>"15 Call Form_TextBox("Zip Code","zp",10,10,"")16 response.write "<br>"17 Call Form_SubmitButton("Register Me","register")18 %>19 </form>20 </body>21 </html>

The library that enables this (named lib_htmlstuff.asp) looks like:

1 <%2 Sub Display( Text )3 Response.Write( Text )4 End Sub

Page 156: [ebook] Learn ASP

5 6 '----------------------------------------------------------------7 8 Sub HTML( Text )9 Response.Write( Text )10 End Sub11 12 '----------------------------------------------------------------13 14 Sub Test( Text )15 Response.Write( Text )16 End Sub17 18 '----------------------------------------------------------------19 20 Sub Form_HiddenField( Name, Value )21 22 HTML "<INPUT "23 Form_Parm_Type "Hidden"24 Form_Parm_Name Name25 Form_Parm_Value Value26 HTML ">"27 28 End Sub29 30 '----------------------------------------------------------------31 32 Sub Form_Label( Label, Control )33 34 If Len(Label) > 0 Then35 HTML "<label "36 HTML "for=" & Control37 HTML ">"38 HTML "<strong>"39 Display Label40 HTML "</strong>"41 HTML "</label>"42 End If43 44 End Sub45 46 '----------------------------------------------------------------47 48 Sub Form_TextBox( Label, Name, MaxLength, Size, Value )49 50 Form_Label Label, Name51 52 HTML "<input "53 Form_Parm_Type "text"54 Form_Parm_Name Name55 Form_Parm_Size Size56 Form_Parm_ID Name57 Form_Parm_MaxLength MaxLength58 Form_Parm_Value Value59 HTML ">"60 61 End Sub62 63 '----------------------------------------------------------------64 65 Sub Form_Password( Label, Name, MaxLength, Size, Value )66 67 Form_Label Label, Name68 69 HTML "<input "70 Form_Parm_Type "password"71 Form_Parm_Name Name

Page 157: [ebook] Learn ASP

72 Form_Parm_Size Size73 Form_Parm_ID Name74 Form_Parm_MaxLength MaxLength75 Form_Parm_Value Value76 HTML ">"77 78 End Sub79 80 '----------------------------------------------------------------81 82 Sub Form_ScrollingText( Label, Name, Rows, Cols, Value )83 84 Form_Label Label, Name85 86 HTML "<textarea "87 Form_Parm_Name Name88 If Len(Rows) > 0 Then89 HTML "rows=" & Rows & " "90 End If91 If Len(Cols) > 0 Then92 HTML "cols=" & Cols & " "93 End If94 Form_Parm_ID Name95 HTML ">"96 97 If Len(Value) > 0 Then98 Display Value99 End If100 101 HTML "</textarea>"102 103 End Sub104 105 '----------------------------------------------------------------106 107 Sub Form_ResetButton( Name, Value )108 109 HTML "<input "110 Form_Parm_Type "reset"111 Form_Parm_Value Value112 Form_Parm_Name Name113 HTML ">"114 115 End Sub116 117 '----------------------------------------------------------------118 119 Sub Form_CommandButton( Name, Value )120 121 HTML "<input "122 Form_Parm_Type "button"123 Form_Parm_Value Value124 Form_Parm_Name Name125 HTML ">"126 127 End Sub128 129 '----------------------------------------------------------------130 131 Sub Form_SubmitButton( Name, Value )132 HTML "<input "133 Form_Parm_Type "submit"134 Form_Parm_Value Value135 Form_Parm_Name Name136 HTML ">"137 End Sub138

Page 158: [ebook] Learn ASP

139 '----------------------------------------------------------------140 141 Sub Form_RadioButton( Label, Name, Value, Checked )142 143 HTML "<input "144 Form_Parm_Type "radio"145 Form_Parm_Value Value146 Form_Parm_Name Name147 Form_Parm_ID Name & Value148 If Len(Checked) > 0 Then149 If Checked Then150 HTML " checked "151 End If152 End If153 HTML ">"154 155 Form_Label Label, Name & Value156 157 End Sub158 159 '----------------------------------------------------------------160 161 Sub Form_Checkbox( Label, Name, Value, Checked )162 163 Form_Label Label, Name164 165 HTML "<INPUT "166 Form_Parm_Type "checkbox"167 Form_Parm_Name Name168 Form_Parm_Value Value169 If Len( Checked ) > 0 Then170 If Checked = True Then171 HTML " checked "172 End If173 End If174 HTML ">"175 '176 End Sub177 178 '----------------------------------------------------------------179 180 Sub Form_Begin( Action )181 182 HTML "<form "183 HTML "method=post "184 HTML "action =" & Chr(39) & Action & Chr(39) & " "185 HTML ">"186 187 End Sub188 189 '----------------------------------------------------------------190 191 Sub Form_End( Name, Value )192 193 Form_HiddenField Name, Value194 HTML "</FORM>"195 196 End Sub197 198 '----------------------------------------------------------------199 200 Sub Form_Table_Begin( Border, Width )201 HTML "<table "202 If Len(Border) > 0 Then203 HTML "border=" & Chr(39) & Border & Chr(39) & " "204 End If205 Form_Parm_Width Width

Page 159: [ebook] Learn ASP

206 HTML ">"207 End Sub208 209 '----------------------------------------------------------------210 211 Sub Form_Table_End()212 HTML "</table>"213 End Sub214 215 '----------------------------------------------------------------216 217 Sub Form_Table_Row_Begin( Dummy, Align, VAlign )218 HTML "<tr "219 Form_Parm_Align Align220 Form_Parm_VAlign VAlign221 HTML ">"222 End Sub223 224 '----------------------------------------------------------------225 226 Sub Form_Table_Row_End( Dummy )227 HTML "</tr>"228 End Sub229 230 '----------------------------------------------------------------231 232 Sub Form_Table_Cell_Begin( Dummy, Width, Align, VAlign )233 HTML "<td "234 Form_Parm_Width Width235 Form_Parm_Align Align236 Form_Parm_VAlign VAlign237 HTML ">"238 End Sub239 240 '----------------------------------------------------------------241 242 243 Sub Form_Table_Cell_End( Dummy )244 HTML "</td>"245 End Sub246 247 248 '----------------------------------------------------------------249 250 251 Sub Form_ComboBox_Begin( Label, Name, Size, Multiple )252 Form_Label Label, Name253 HTML "<select "254 Form_Parm_Name Name255 Form_Parm_Size Size256 If Len(Multiple) > 0 Then257 If Multiple Then258 HTML " multiple "259 End If260 End If261 HTML ">"262 End Sub263 264 '----------------------------------------------------------------265 266 Sub Form_ComboBox_Item( Value, Selected )267 HTML "<option "268 Form_Parm_Value Value269 If Len(Selected) > 0 Then270 If Selected Then271 HTML " selected "272 End If

Page 160: [ebook] Learn ASP

273 End If274 HTML ">"275 End Sub276 277 '----------------------------------------------------------------278 279 Sub Form_ComboBox_End()280 HTML "</select>"281 End Sub282 283 '----------------------------------------------------------------284 285 Sub Form_Title( Title )286 HTML "<title>"287 Display Title288 HTML "</title>&289 End Sub290 291 292 '----------------------------------------------------------------293 294 Sub Form_Center( Text )295 HTML "<p align=" & Chr(39) & "center" & Chr(39) & ">"296 Display Text297 HTML "</p>"298 End Sub299 300 '----------------------------------------------------------------301 302 Sub Form_Left( Text )303 HTML "<p align=" & Chr(39) & "left" & Chr(39) & ">"304 Display Text305 HTML "</p>"306 End Sub307 308 '----------------------------------------------------------------309 310 Sub Form_Right( Text )311 HTML "<p align=" & Chr(39) & "right" & Chr(39) & ">"312 Display Text313 HTML "</p>"314 End Sub315 316 '----------------------------------------------------------------317 318 Sub Form_Parm_Align( Align )319 If Len(Align) > 0 Then320 Select Case UCase(Align)321 Case "L", "LEFT"322 Display " align=" & Chr(39) & "left" & Chr(39) & " "323 Case "C", "CENTER"324 Display " align=" & Chr(39) & "center" & Chr(39) & " "325 Case "R", "RIGHT"326 Display " align=" & Chr(39) & "right" & Chr(39) & " "327 Case Else328 End Select329 End If330 End Sub331 332 '----------------------------------------------------------------333 334 Sub Form_Parm_VAlign( VAlign )335 If Len(VAlign) > 0 Then336 Select Case UCase(VAlign)337 Case "T", "TOP"338 Display " align=" & Chr(39) & "top" & Chr(39) & " "339 Case "C", "CENTER"

Page 161: [ebook] Learn ASP

340 Display " align=" & Chr(39) & "center" & Chr(39) & " "341 Case "B", "BOTTOM"342 Display " align=" & Chr(39) & "bottom" & Chr(39) & " "343 Case Else344 End Select345 End If346 End Sub347 348 '----------------------------------------------------------------349 350 Sub Form_Parm_Name( Name )351 If Len(Name) > 0 Then352 Display " name=" & Chr(39) & Name & Chr(39) & " "353 End If354 End Sub355 356 '----------------------------------------------------------------357 358 Sub Form_Parm_Value( Value )359 If Len(Value) > 0 Then360 Display " value=" & Chr(39) & Value & Chr(39) & " "361 End If362 End Sub363 364 '----------------------------------------------------------------365 366 Sub Form_Parm_Type( TypeValue )367 If Len(TypeValue) > 0 Then368 Display " type=" & Chr(39) & TypeValue & Chr(39) & " "369 End If370 End Sub371 372 '----------------------------------------------------------------373 374 Sub Form_Parm_Size( Size )375 If Len(Size) > 0 Then376 Display " size=" & Size & " "377 End If378 End Sub379 380 '----------------------------------------------------------------381 382 Sub Form_Parm_ID( ID )383 If Len(ID) > 0 Then384 Display " id=" & Chr(39) & ID & Chr(39) & " "385 End If386 End Sub387 388 '----------------------------------------------------------------389 390 Sub Form_Parm_MaxLength( MaxLength )391 If Len(MaxLength) > 0 Then392 Display " maxlength=" & MaxLength393 End If394 End Sub395 396 '----------------------------------------------------------------397 398 Sub Form_Parm_Length( Length )399 If Len(Length) > 0 Then400 Display " length=" & Length401 End If402 End Sub403 404 '----------------------------------------------------------------405 406 Sub Form_Parm_Width( Width )

Page 162: [ebook] Learn ASP

407 If Len(Width) > 0 Then408 Display " width=" & Width409 End If410 End Sub411 412 '----------------------------------------------------------------413 414 Sub Anchor_Display( TextToDisplay, HRef )415 HTML "<a href=" & Chr(39) & HRef & Chr(39) & ">"416 Display TextToDisplay417 HTML "</a>"418 End Sub419 420 '----------------------------------------------------------------421 422 Sub MenuItem ( TextToDisplay, HRef )423 HTML "<ul>"424 HTML "<li>"425 HTML "<p "426 Form_Parm_Align "Left"427 Form_Parm_VAlign "Bottom"428 HTML ">"429 Anchor_Display TextToDisplay, HRef430 HTML "</p>"431 HTML "</li>"432 HTML "</ul>"433 End Sub434 435 '----------------------------------------------------------------436 437 Function FormatMoney( Amount )438 '439 ' Standard constants from the MS web site but not built440 ' into VBScript's default constants.441 '442 Const TristateTrue = -1443 Const TristateFalse = 0444 Const TristateUseDefault = -2445 '446 If IsNull( Amount ) Then447 FormatMoney = vbNullString448 Else449 FormatMoney = FormatCurrency( Amount, 2, TristateTrue _450 , False, TristateTrue)451 End If452 '453 End Function454 455 '----------------------------------------------------------------456 %>

http://www.learnASP.com/learn/functionworkingdays.asp by Charles M. Carroll Page 164

Functions -- The WorkingDays functionThis page demonstrates how to make a function and display it's results in your page.

1 <title>functionworkingdays.asp</title>2 <body bgcolor="#FFFFFF">3 <%4 response.write "3 working days from today is " & dtaddWorkingDays(now(),3) & "<p>"5 %>

Page 163: [ebook] Learn ASP

6 2 working days from today is <%=dtaddWorkingDays(now(),2)%>7 </body>8 <%Function dtAddWorkingDays(dtStartDate, nDaystoAdd)9 'Adds working days based on a five day week10 11 Dim dtEndDate12 Dim iLoop13 14 'First add whole weeks15 dtEndDate=DateAdd("ww",Int(nDaysToAdd/5),dtStartDate)16 17 'Add any odd days18 For iLoop = 1 To (nDaysToAdd Mod 5)19 dtEndDate=DateAdd("d",1,dtEndDate)20 'If Saturday increment to following Monday21 If WeekDay(dtEndDate)=vbSaturday Then22 'Increment date to following Monday23 dtEndDate=DateAdd("d",2,dtEndDate)24 End If25 Next26 dtAddWorkingDays=dtEndDate27 End Function28 %>

http://www.learnASP.com/learn/vbs5.asp by Charles M. Carroll Page 165

VBScript 5 Highlights by Charles CarrollSubroutines can save you having to repeat blocks of code. This code illustrates how we can build tables with minimal code in themain script and by including a file with a convenient subroutine.

Eval function

1 <html><head>2 <title>vbs5eval.asp</title>3 </head>4 <body>5 <%6 x="2+2*3"7 response.write eval(x)8 %>9 </body>10 </html>

Classes:

1 <html><head>2 <title>vb5classes.asp</title>3 </head>4 <body>5 <%6 ' Create a myCustomer variable7 Dim myCustomer8 ' Create a new instance of the Customer Class9 ' and set the value of myCustomer to be that instance10 set myCustomer = new Customer11 ' Add a new customer12 myCustomer.Add "Charles","Carroll"13 ' Set their Email address14 myCustomer.EmailName = "[email protected]"15 ' Set their credit limit16 myCustomer.CreditLimit = 500017 ' Display the customers fullname

Page 164: [ebook] Learn ASP

18 response.write myCustomer.FullName19 20 Class Customer21 Public FirstName, LastName22 Private nCreditLimit23 Private strEmailName24 Property Get EmailName25 EmailName = strEmailName26 End Property27 Property Let EmailName ( strName)28 StrEmailName = strName29 End Property30 Property Get FullName31 FullName= FirstName & " " & LastName32 End Property33 Property Let CreditLimit ( s )34 if s >= 0 then35 nSalary = s36 End If37 End Property38 Property Get CreditLimit39 Salary = nSalary40 End Property41 Sub Add( First, Last )42 FirstName = First43 LastName = Last44 End Sub45 Function RaiseCreditLimit( Amount )46 nCreditLimit = nCreditLimit + Amount47 RaiseSalary = nSalary48 End Function49 End Class50 %>51 </body>52 </html>

Execute Function:

1 <html><head>2 <title>vbs5execute.asp</title>3 </head>4 <body>5 <%6 S = "Sub Hi" & vbCrLf7 S = S & " Response.write ""Hi""" & vbCrLf8 S = S & "End Sub"9 Execute S10 Call Hi()11 %>12 </body>13 </html>

Regular Expressions

1 <html><head>2 <title>vbs5reg.asp</title>&3 <body>4 <%5 6 address="[email protected]"7 validmail=checkemail(address)8 IF validmail THEN9 response.write address & " is good!"10 ELSE11 response.write address & " is bad!"12 END IF13

Page 165: [ebook] Learn ASP

14 address="sallyaol.com"15 validmail=checkemail(address)16 IF validmail THEN17 response.write address & " is good!"18 ELSE19 response.write address & " is bad!"20 END IF21 22 23 FUNCTION CheckEmail(parmaddress)24 set myRegExp = new RegExp25 ' Set the pattern to check for a word followed by26 ' an @ followed by a word27 myRegExp.pattern = "\w+\@[.\w]+"28 if myRegExp.Test(parmaddress) then29 CheckEmail=True30 else31 CheckEmail=false32 end if33 END FUNCTION34 %>35 </body>36 </html>

With

1 <html><head>2 <title>vbs5with.asp</title>3 </head>4 <body>5 <%6 with response7 .write "Hi<br>"8 .write "how are you doing?<br>"9 .write "see you around"10 end with11 %>12 </body>13 </html>

http://www.learnASP.com/learn/editors.asp by Charles M. Carroll Page 166

Visual Interdev + Admunsen Resources (admunsen.asp) - Page 167 ASPExpress: HOT ASP Editor (aspexpress.asp) - Page 168 Homesite: HTML editor (homesite.asp) - Page 169

http://www.learnASP.com/learn/admunsen.asp by Charles M. Carroll Page 167

Interdev Guru Michael Amundsen is the first place you should go with Interdev questions.

http://www.amundsen.com/vinterdev/join/vi6talk.htm

Page 166: [ebook] Learn ASP

is his awesome Visual Interdev listserve. One of the best in the world.

http://www.amundsen.com/mskb/Default.htmis his knowledge base Assistant.

He offers Interdev Training, see:http://www.amundsen.com/training/default.htm

There is a healthy assortment of FREE stuff there too.

http://www.learnASP.com/learn/aspexpress.asp by Charles M. Carroll Page 168

ASPExpress - ASP EditorThis is a very ASP centric HTML editor. Unlike homesite which claims ASP functionality but doesn't have it, or wizard/DTC basedbeasts like Visual Interdev this tool truly helps you write ASP Code with:

The Connection Assistant●

The Request Assistant●

buttons that make CASE, IF, LOOPs for you●

Browsing for includes●

I personally use it instead of Visual Interdev.

Take a look at the screenshots @http://www.aspexpress.com/screenShots/screenshots.asp

Of course I am biased, because the author is a student of mine (we hold classes, see www.asptraining.com) and whenever I sendhim a dozen items no ASP editor does and I want, within a month or two, a new editor arrives with all the nifty features I dreamed of.

http://www.aspexpress.comis the place to get it. You will be blown away by the phenomenal tools that no other editor has to make ASPy tasks a snap.

http://www.learnASP.com/learn/homesite.asp by Charles M. Carroll Page 169

Homesite - Popular HTML EditorThis is a very popular HTML editor from

http://www.allaire.com/products/homesite/

I don't like it as much as ASPExpress but if you are using it with ASP I recommend checking out:

http://jw.conallen.net/asp4hs/which focuses on how people using Homesite can edit their ASP scripts even easier.

http://www.learnASP.com/learn/speedscale.asp by Charles M. Carroll Page 170

Application Data (sessionsapps.asp) - Page 171

Page 167: [ebook] Learn ASP

Application Data: Worlds Fastest ListBox (speedappdata.asp) - Page 172 Sessions: What are they? (sessionswhat.asp) - Page 173 Sessions: Global.asa Events (global.asp) - Page 174 Session Overview & Myths (sessionoverview.asp) - Page 175 Sessions: Global.asa and Scalability (globalproblems.asp) - Page 176 Global.asa Resources (globalmore.asp) - Page 177 Speed: Server Optimization (speedserver.asp) - Page 178 Speed: Research Online (speedresearch.asp) - Page 179 Time Tasks with Millisecond Accuracy (speedtimer.asp) - Page 180 Speed: Coding Tips (speedtips.asp) - Page 181 Speed: Database Percieved Speed (speedtables.asp) - Page 182 Speed: Database Retrieval Speed (speedtablesall.asp) - Page 183 Speed: OLEDB & ODBC Drivers differences (speedtablesdrivers.asp) - Page 184 Scale: IsClientConnected & Stray Tasks (isclientconnected.asp) - Page 185 Scale: Virtues of Nothing (nothing.asp) - Page 186 Scale: Connection Pooling (dbpooling.asp) - Page 187 Thread Safety Issues (threadsafe.asp) - Page 188 Round-Robin Code Execution (roundrobin.asp) - Page 189 Why Buffer? (whybuffer.asp) - Page 190 Why GetRows or Getstring to get Data (whygetrows.asp) - Page 191 ASP Scalability Listserver (aspscalability.asp) - Page 192

http://www.learnASP.com/learn/sessionsapps.asp by Charles M. Carroll Page 171

Application Variables by Charles CarrollThere are two kinds of data that your program can manipulate that can be used to "remember" data:

Session datawhich is "attached" to a person browsing your site. If the same page is accessed by 12 different users each user may have totallydifferent session values.

Application datawhich is attached to the webserver and is the same no matter which user is accessing the site.

Application values are visible to every user. But since, unlike session data, any web page could change the application's data thereis a potential concurrency issue. The lock and unlock method of the application object eliminate concurrency issues. Once anapplication is locked, no other updates to the application object can occur until the unlock is executed.

One use for an application variable would be to store variables most scripts on a site needed to access or even HTML cached fromdatabases like inThe Worlds Fastest Listbox Example @http://www.learnasp.com/learn/speedappdata.asp

One example I use to illustrate the conceptual use for each type of data would be a website that simulated a casino. Player'sindividual winnings make perfect sense to maintain in session variables. However, the total number of players at each "virtual table"(blackjack, roulette, etc.) would be application data as the would be the same regardless of an individual player's status.

Here is a file called appblackjackarrive.asp that could be included in any script where someone arrived at the blackjack table!

1 <%2 response.write "Welcome to the BlackJack Table<br>"3 application.lock4 application("bjplayers")=application("bjplayers")+15 application.unlock

Page 168: [ebook] Learn ASP

6 response.write "There are " & application("bjplayers") & " players here!<br>"7 %>

Here is a file called appblackjacklook.asp that displays how many people are at the table.

1 <%2 response.write "Over at the BlackJack Table<br>"3 response.write "There are " & application("bjplayers") & " players there!<br>"4 %>

Here is a file called appblackjackleave.asp that could be included in any script where someone left the blackjack table!

1 <%2 response.write "Thanks for playing BlackJack!<br>"3 application.lock4 application("bjplayers")=application("bjplayers")-15 IF application("bjplayers")<0 THEN6 application("bjplayers")=07 END IF8 application.unlock9 response.write "There are " & application("bjplayers") & " players still at the table!<br>"10 %>

http://www.learnASP.com/learn/speedappdata.asp by Charles M. Carroll Page 172

Speed Data Display w/Application Data by Charles CarrollSometimes data (like a HTML list box) is displayed on many pages of a website. In fact, the database generated list box is displayedthousands of times a day, and the database is queried every time, but it is uneccessary. The database it is drawn from is notchanging thousands of times a day.

In the following example any page that displays the listboxes needs to only access the application variables, not hit the database.Very speedy. If the data changes or gains new records, a trigger mechanism could invoke listmake.asp. Here is a demo script thatdisplays the listboxes without requerying the database.

1 <HTML>2 <TITLE>listmakedemo.asp</TITLE>3 <body bgcolor="#FFFFFF">4 </BODY>5 <%6 IF application("citylist")="" OR _7 application("statelist")="" OR _8 application("ziplist")="" THEN%>9 <!--#include virtual="/learn/test/listmake.asp"-->10 <%END IF11 response.write application("citylist") & "<br>"12 response.write application("statelist") & "<br>"13 response.write application("ziplist") & "<br>"14 %>15 </HTML>

The listbox could be placed in an application variable, ala a "generator" script we will call listmake.asp.

1 <HTML>2 <TITLE>listmake.asp</TITLE>3 <body bgcolor="#FFFFFF">4 </BODY>5 <%6 myDSN="DSN=student;uid=student;pwd=magic"7 8 mySQL="select distinct city from publishers"9 application("citylist")=query2htmlist(mySQL,"cities",myDSN)10

Page 169: [ebook] Learn ASP

11 mySQL="select distinct state from publishers"12 application("statelist")=query2htmlist(mySQL,"state",myDSN)13 14 mySQL="select distinct zip from publishers"15 application("ziplist")=query2htmlist(mySQL,"zip",myDSN)16 %>17 </HTML>18 19 <%function query2htmList(myquery,myname,myDSN)20 dim conntemp, rstemp21 set conntemp=server.createobject("adodb.connection")22 conntemp.open myDSN23 set rstemp=conntemp.execute(myquery)24 query2HTMlist="<Select name='" & myname & "'>"25 do until rstemp.eof26 thisfield=trim(RStemp(0))27 if isnull(thisfield) or thisfield="" then28 ' ignore29 else30 query2HTMlist=query2HTMlist & "<option>" & thisfield & "</option>"31 end if32 rstemp.movenext33 loop34 query2HTMlist=query2HTMlist & "</select>"35 rstemp.close36 set rstemp=nothing37 conntemp.close38 set conntemp=nothing39 end function%>

http://www.learnASP.com/learn/sessionswhat.asp by Charles M. Carroll Page 72

What are Sessions?Sessions are a very convenient ASP feature. When someone visits a web page on your site, ASP calls that a "session" andimmediately can differentiate that user from all other users at a site. Anything stored in that user's session can be retrieved andmanipulated from that page and the next pages they visit, and the data will be tied to that user.

Session data is generally attached to one user. When a user visits their first page of your site, that page and every page they visit iscollectively called a session. Any data attached stored in that session object is private to the pages that user is visiting.

The code to store data in a session variable is simple. Here we will allow a user to flip a coin, i.e. flipcoin.asp and count theirsuccesses:

1 <%2 response.write "Coin Tossed!<br>"3 randomize4 randomnum=int(rnd*2)+15 IF randomnum=1 THEN6 session("heads")=session("heads")+17 ELSE8 session("tails")=session("tails")+19 END IF10 response.write "Heads= " & session("heads") & "<br>"11 response.write "Tails= " & session("tails") & "<br>"12 %>

Even though there are many people at the site they all have different scores for their "heads" and "tails" count. They each has asession and it co-ordinates and differentiates their values.

A much more practical example could protect access to a page based on a session variable that indicated their security leveldetermined once upon login, see:http://www.learnasp.com/learn/security.asp

Page 170: [ebook] Learn ASP

Some basic things should be noted:

Session data is stored on the server, not in cookies. No user could examine the session cookie and determinethe contents of any session variables.

A cookie is used to co-ordinate the user's session ID. Once again the cookie contains no data (just the sessionID). This means if the user accepts no cookies, you can't use sessions as described here.

If you absolutely need sessions without client cookies, installing an ISAPI filter named "Cookie Munger" willsolve your problem, but at a performance penalty.

Cookie Munger by Microsoft (FREE)

Cookies are a necessity to maintain ASP session objects. Even though the session objects are physically maintained on the serverthe essential ID that identifies a user session is kept in a cookie. This ISAPI filter can only be applied globally but if applied, it actuallyrewrites any pages sent back to the user so that any URLs in the page will pass back user session info without any cookies involved.Basically (at a performance penalty) it transforms every page sent to the client to encode the session ID as part of the URLs on thepage. So conceptually if you send a page back to the users with 20 URLs each URL gets a session ID "munged"/intermixed in sothat when they click on the URL you have enough info to Identify them without writing a cookie to their machine.[../trash/msfree.asp]%>

http://www.learnASP.com/learn/global.asp by Charles M. Carroll Page 174

Global.asa Events by Charles CarrollThis page demonstrates what a blank global.asa should look like:

1 <script language=vbscript runat=server>2 SUB Application_OnStart3 END SUB4 5 SUB Application_OnEnd6 END SUB7 8 SUB Session_OnStart9 END SUB10 11 SUB Session_OnEnd12 END SUB13 </script>

A global.asa code is divided into four events, or segments:

session_onstartif 100 users hit your website for example, 100 session starts are initiated and the code in this event is fired for each userbefore their first page is fetched and displayed. But those same 100 users can wander all over your site and another sessionstart will not occur as long as they are actively fetching pages

session_onendAny user that does not fetch any page from your site for 20 minutes (can be adjusted in the Registry/IIS3 or themetabase/IIS4) has ended their session. The code you put in this event can not affect the users as they have already left yoursite but it can allow you to place cleanup code or code that dumps for, example, session data into a database.

application_onstartThe webserver starts. dozens to hundreds to thousands of users hit the site. The minute the first user fetches the first file in anapplication directory an application_onstart occurs and never occurs again no matter how many people are visiting. But if awebserver stops and starts and application_onstart fires. But code inside an application_onstart is code that assumes theentire casino is a "blank slate" not a busy place. If for example, application_onstarts fire often this is not a desired behaviorsince it may have the role of bootsrapping an app and setting certain conditions that don't make sense to set while activity is

Page 171: [ebook] Learn ASP

occuring.

application_onendThe web server stops, the application ends.

http://www.learnASP.com/learn/sessionoverview.asp by Charles M. Carroll Page 175

Session Overview & Myths by Charles CarrollSession data is greatly misunderstood. Sessions themselves were a subtle and complex issue, but the subject was confusedconsiderably by bad information people gathered from code others made that misused sessions. It is also confused by anecdotalperformance evidence when a site is small, or the testing is only done within simple stress tests that don't reveal all the speedissues. We will clarify it all now.

A couple analogies may help. A Porsche seems really fast to get anywhere (of course we assume you have 2 passengers) until youhave 3-10 passengers. Then a mini-van will beat it because you have less trips to make. In client-server terms the Porsche doesn'tSCALE WELL for more than 2 passengers. On the other hand, when a group of 100 wants to go to Atlantic city for the weekend werecommend a Tour Bus. However, someone taking a Tour Bus to the grocery store has anecdotal evidence it is not as fast as aPorsche.

Fact #1: When a browser window closes, the session DOES NOT end.

Fact #2: <%session.abandon%> command can end a session.

Fact #3: Another way a session ends is when a user has not visited any page within that site/application with ___ minutes. Thedefault is 20 minutes of inactivity. The following script can show what the settings are on your server:1 <html><head>2 <TITLE>sessionsettings.asp</TITLE>3 </head>4 <body bgcolor="#FFFFFF">5 <%6 response.write "Session Timeout=" & session.timeout & "minutes <br>"7 %>8 </body></html>

Fact #4: Session ids are not guaranteed to be different anytime a new session is generated. If there are 1,000 sessions there will be1,000 unique session ids. But if 200 people loose session (due to timeout or explicit .abandon) and 150 new sessions are begunASP may and will certainly use the same session IDs it was using earlier.

Myth #1: Storing large objects (recordsets, database data, objects) users access in sessions saves memory*.

No. No. No. Since sessions start when users access one page and don't end until 20 minute after they access the last page. Thinkabout it. If 200 news persons a minute hit your site for 5 minutes that is 1,000 sessions and appropriately 1000 x the memoryconsumed for session variables. If 500 people go away, you still have 1000 sessions and 500 users (twice as much memory isconsumed as needed) until the server detects 20 minutes of inactivity for those 500 users who are not on the site.

Application variables (not session variables) can be used this way without wasting memory. They could be to store variables mostscripts on a site needed to access or even HTML cached from databases like in The Worlds Fastest Listbox Example @http://www.learnasp.com/learn/speedappdata.asp

Myth #2: Storing large objects (recordsets, database data, objects) users access in sessions speeds up access.

No. No. No. Objects in sessions have several potential speed barriers depending on their memory model.

Thread local storage is used internally in some objects (notably VB components). This means once you assign such acomponent to a session variable attached to that user all user request must remain on the thread they started on. If they forexample were assigned Thread #3 upon their session start as they access many pages at the site all their activity will remainon thread #3. I nickname this phenomena Thread Locking.

Free-threaded objects have no speed barriers (though as Myth #1 states, you will always have too many in memory if youstore objects as session variables).

Apartment-Threaded objects, notably VB components and the Microsoft Access databas driver which are Single-Threadedapartments (STA) have some performance limits. Simply put, every user request to a STA object must be serialized.

Page 172: [ebook] Learn ASP

Serialization explained: If 100 users hit the site their use of that code is in sequence. If all the users retrieves 10-20 records from adatabase you might notice no effect. But if person 3 retrieves 2,000 records, person 4 retrieving 2 records will occur after the person3 retrieves 2,000 records. OUCH!!!!! Person 4 will think the webserver is very slow only retrieving 2 records.

Free-Threading explained: Users execution is more round-robin like where the webserver does not have to finish each usersrequest before moving to another user. The code may be able to move to User 4 and grab their records and then person 5 and laterfinish person 3's large request.

Threads explained: Your web server spawns threads (4 per CPU is the default in IIS4; it should be adjusted to 20 seehttp://www.learnasp.com/learn/speedserver.asp. If your webserver had for example 4 threads, then 1000 users might be 250 perthread or 700 on one thread and 100 each on the other threads. The latter is a severe imbalance as one thread is overworked (thusslower) while other threads are underworked.

http://www.learnASP.com/learn/globalproblems.asp by Charles M. Carroll Page 176

Global.asa Overkill by Charles CarrollA global.asa file is a used extraneously and quite wastefully, but can be a very useful tool. First let us bring out what is good and badabout it.

Application variables are good. Since there is only one application variable in memory, no matter how many users are on your site,they can be a convenient place to store central information and retrieve it fast. Since there is only one application variable in memoryregardless of the number of users at your site, remember the following characteristics:

Of course Application variables have no dependence on cookies. They are not required at all.●

If a object or variable is accessed concurrently for anything other than reading it's value, this is a potential concurrency issuethat needs to be carefully coded so that no problems arise, i.e.<%application.lock ... modify app object ...application.unlock%>

Session variables (particularly COM objects put in a session variable) can:waste memory because they live for ___ minutes past their last use. ___ depends on your session. timeout, the default is 20minutes. See /learn/nosessionobjects.asp for more details.

waste threads if you put any objects (made with server.createobject) in a session variable. See /learn/buildvbthreads.asp formore details.

limit the code to users accepting cookies which may mean someone who disables cookies may not use that script at all.●

Session Variable ConstraintsSession variables containing simple variables (texts, numbers, dates, NOT COM objects) are not so wasteful as to be prohibitive.BUT remember, if you write any script that depends on session variables you are working under the following assumptions (and ifthese restrictions are fine, then use sessions as much as you need to):

the person browsing your site MUST enable cookies for your script to function.●

If your site is one giant application (i.e. the root folder is marked as an application) the person browsing the site will haveaccess to their session variables in every script BUT if individual folders are marked as applications, all scripts within thatdirectory set session variables that cannot be read from scripts in other folders marked as applications.In other words three folders: \A, \B and \C can set session variables but cannot see each others. If your goal with a session isto attach people to data and use it in many scripts this visibility can be an issue.

the person using the scripts will never gets "switched" to another server in a web farm situation.●

If the task could be accomplished with hidden fields instead of session variables, then those limitations are not in effect -- and mosttasks can.

Good uses of global.asa and session data include:if you place any value in an Application_OnStart event that sets application variables, this is not wasteful and can be quiteuseful.

Page 173: [ebook] Learn ASP

If you place any non-object data in session variables the waste is not excessive.●

Examples of Wasteful Code and Alternatives...Code that is particularly wasteful is code that places database connection info in the global.asa, i.e.

session_onstart session("dbname")="DSN=employees;" session("dbuser")="whoever" session("dbpass")="majic"end sub

and the script that goes with it looks like this:

... code ....set conntemp=server.createobject("adodb.connection")conntemp.open session("dbname") & "uid=" & session("dbuser") & ";pwd=" & session("dbpass")... code ....

Why? Do 700 users hitting that site hit 700 different databases with 700 different userids and passwords at the database level. Just700 wasted session variables...Session variables are the worst way to keep such data; application variables the best or othermechanisms. Unfortunately Visual Interdev grossly misuses sessions and creates this bizzare concept in people's brains.

If for example, 700 users connect to a page using session variables to store DSN info, etc. You have 700 DSN variables in memoryall with the same value. The purpose of sessions is to have separate data for users not the same data replicated for every session.Plus it means the site is unusable to a user not accepting cookies unnecessarily. It is really necessary to require cookies to display adatabase page where the DSN to the database does NOT change over a multi-month/year period?

The better alternatives would be:

Include Files (cheap and easy)lib_connection.asp

<%dbname="DSN=employees;"dbuser="whoever"dbpass="majic"%>

and the script that goes with it looks like this:

<!--#include virtual="/lib_connection.asp"-->... code ....set conntemp=server.createobject("adodb.connection")conntemp.open dbname & "uid=" & dbuser & ";pwd=" & dbpass... code ....

Application Data (involves a COM object, but is memory cheap)application_onstart application("dbname")="DSN=employees;" application("dbuser")="whoever" application("dbpass")="majic"end sub

and the script that goes with it looks like this:

... code ....set conntemp=server.createobject("adodb.connection")conntemp.open application("dbname") & "uid=" & application("dbuser") & ";pwd=" &application("dbpass")... code ....

In both approaches, if 700 users hit the site, no user specific variables are created. The same three variables are available to allusers with no wasted memory.

Page 174: [ebook] Learn ASP

http://www.learnASP.com/learn/globalmore.asp by Charles M. Carroll Page 177

Global.asa, Sessions, Custom Stats ResourcesThe global.asa, application and sesion variables are certainly a more complex and controversial subject than most ASP topics. Othersites and my site has a lot to say on this:

Everything you wanted to know about global.asa but were afraid to ask @http://www.4guysfromrolla.com/webtech/113098-1.shtml

The lowdown on Global.asa, session vars and app. varshttp://www.asp101.com/resources/apps_sessions_gasa.asp

An example of home-brewed stats:http://www.asp101.com/resources/active_users.asp

Steve Smith's Stats examples:

http://www.aspalliance.com/stevesmith/samples/whosoncode.asp

http://www.aspalliance.com/stevesmith/samples/sitestats.asp

http://www.learnASP.com/learn/speedserver.asp by Charles M. Carroll Page 178

Server Optimization by Charles CarrollImproving server performance is not so well documented and many of the articles lean towards vague, not specific tips. Here are ourtips in we hope as concrete a way as possible.

THREAD TIP:Increase threads per processorfrom 4 to 20 for each CPU.

thanks to Smiling Jack for this one:http://www.aspmagazine.com/aspmagazine/issue10kb.asp

seehttp://support.microsoft.com/support/kb/articles/q196/0/16.asp

Implement the ADOFre15.reg file!If you don't use Access, run ADO as FREE THREADED instead of both.

more details at:http://msdn.microsoft.com/workshop/server/components/daciisperf.asp

WARNING: Access or any STA driver will not function well and may corrupt data. Do not make this change if youare running any Access code in the box.

Additional ResearchWe have essentially summarized the information and chosen only the clearest guidelines from the following resources:

Web Application Stress Toolhttp://homer.rte.microsoft.com

Improving the Performance of Data Access Components with IIS 4.0http://msdn.microsoft.com/workshop/server/components/daciisperf.asp

Mike Moore's Tuning IIS

Page 175: [ebook] Learn ASP

http://www.microsoft.com/isn/whitepapers/tuningiis.asp

IIS4 Tuning Parameters for High Volume Siteshttp://msdn.microsoft.com/workshop/server/feature/tune.asp

Hans Hugli's Seminar:Managing Microsoft Internet Information Server 4.0 for Performance @http://www.microsoft.com/Seminar/1033/199811131-01MaxIISPerfor(HH/Portal.htm

Backstage at Microsoft.comhttp://www.microsoft.com/backstage/whitepaper.htm

IIS Research starts @http://www.microsoft.com/technet/iis/default.htm

Much ASP coding tips and advice related to scalability can be found at:http://www.learnasp.com/advice

http://www.learnASP.com/learn/speedresearch.asp by Charles M. Carroll Page 179

Speed Research Resources by Charles CarrollSpeed affects your web consumers very much. It is a big subject that we will cover in-depth in this section but if this advice doesn'thelp you enough you can join [aspfastcode] to get help.

fastcode Listserver

JOIN, QUIT or Search ARCHIVES:http://www.asplists.com/asplists/speedresearch.asp

Send Listserver Questions [email protected]

Related LinksNiblacks Excellent ListBox/DB Speed Page @ http://niblack.com/kbase/listbox_x.aspTiming Tasks to Millisecond accuracy @ http://www.learnasp.com/learn/speedtimer.aspWeb Application Stress Tool @ http://homer.rte.microsoft.comCaprocks FREE Scalable Dictionary Object Replacement @ http://www.caprockconsulting.com/comsoftware.htmStudy up on Performance Counters @ http://msdn.microsoft.com/workshop/server/iis/usingWCAT.aspmonitor PerfCounters from ASP via a nifty component @ http://www.alphasierrapapa.com/IisDev/Components/Speed Percieved Table Display @ http://www.learnasp.com/learn/speedtables.aspSpeeding Table Display - All Techniques @ http://www.learnasp.com/learn/speedtablesall.aspWorlds Fastest ListBox @ http://www.learnasp.com/learn/speedappdata.aspCharles Carroll's ASP Quick Lessons @ http://www.learnasp.com/learn/speedscale.asp

Page 176: [ebook] Learn ASP

http://www.learnASP.com/learn/speedtimer.asp by Charles M. Carroll Page 180

Speed: Measuring Code Speedby Richard A. Lowe [email protected] with help from Jonathan McGuire [email protected] Gregory Lybanon [email protected] Charles Carroll [email protected]

Measuring speed to the millisecond was considered impossible with ASP. People built COM components that wrapped up API calls!So we called a COM component that called an API and then we distorted the measurement with overhead. Scripting has a few tricksup its sleeves yet as Richard demonstrates with the nifty Library implemented in Jscript. We will use it to time retrieving anddisplaying identical data three different ways:

traditional loop and movenext●

one getrows call●

one getstring call●

This method is great for testing optimizations to 1 script but does not show how the script will run when many users aresimultaneously executing it. Tools like the Stress Tester at:http://homer.rte.microsoft.comare great for simulating and recording measurements for multi-user performance.

Here we retrieve data using a traditional loop (/learn/dbtable.asp):

1 <html><head>2 <TITLE>timedbtable.asp</TITLE>3 </head>4 <body bgcolor="#FFFFFF">5 <!--#include file="lib_timethis.asp"-->6 <%7 Set HttpObj = Server.CreateObject("AspHTTP.Conn")8 HttpObj.Url = "http://www.learnasp.com/learn/test/dbtable.asp"9 timeThen = milliDif()10 strResult = HttpObj.GetURL11 timeNow = milliDif()12 SET HTTPobj = nothing13 elapsed=timeNow-timeThen14 msg="<br>Process time in ms: " & elapsed & "<br>" & elapsedpretty(elapsed)15 bodytag="<body bgcolor=""#FFFFFF"">"16 STRresult=replace(STRResult,bodytag,bodytag & msg)17 18 response.write STRresult19 20 %>21 </body></html>

Here we retrieve data by fetching all the data into an array in one "gulp" (/learn/dbtablegetrows.asp):

1 <html><head>2 <TITLE>timedbtablegetrows.asp</TITLE>3 </head>4 <body bgcolor="#FFFFFF">5 <!--#include file="lib_timethis.asp"-->6 <%7 Set HttpObj = Server.CreateObject("AspHTTP.Conn")8 HttpObj.Url = "http://www.learnasp.com/learn/test/dbtablegetrows.asp"9 timeThen = milliDif()10 strResult = HttpObj.GetURL11 timeNow = milliDif()12 SET HTTPobj = nothing13 elapsed=timeNow-timeThen

Page 177: [ebook] Learn ASP

14 msg="<br>Process time in ms: " & elapsed & "<br>" & elapsedpretty(elapsed)15 bodytag="<body bgcolor=""#FFFFFF"">"16 STRresult=replace(STRResult,bodytag,bodytag & msg)17 18 response.write STRresult19 20 %>21 </body></html>

Here we retrieve data by asking the backend to combine the data into a custom string and not even bring fields and rows, justproduce 1 string (/learn/dbtablegetstring.asp):

1 <html><head>2 <TITLE>timedbtablegetstring.asp</TITLE>3 </head>4 <body bgcolor="#FFFFFF">5 <!--#include file="lib_timethis.asp"-->6 <%7 Set HttpObj = Server.CreateObject("AspHTTP.Conn")8 HttpObj.Url = "http://www.learnasp.com/learn/test/dbtablegetstring.asp"9 timeThen = milliDif()10 strResult = HttpObj.GetURL11 timeNow = milliDif()12 SET HTTPobj = nothing13 elapsed=timeNow-timeThen14 msg="<br>Process time in ms: " & elapsed & "<br>" & elapsedpretty(elapsed)15 bodytag="<body bgcolor=""#FFFFFF"">"16 STRresult=replace(STRResult,bodytag,bodytag & msg)17 18 response.write STRresult19 20 %>21 </body></html>

The library that accomplishes this:

1 <SCRIPT LANGUAGE=JScript RUNAT=Server>2 function y2k(number) {3 return (number < 1000) ? number + 1900 : number;4 }5 function milliDif() {6 var d = new Date();7 return d.getTime()8 }9 10 function elapsedpretty(parm1)11 {12 var elapsedsecs = 013 var elapsedmins = 014 15 elapsedsecs=Math.floor(parm1/1000)16 parm1=parm1%100017 18 elapsedmins=Math.floor(elapsedsecs/60)19 elapsedsecs=elapsedsecs%6020 21 22 elapsedpretty=elapsedmins + " minute"23 if(elapsedmins!=1)24 elapsedpretty=elapsedpretty+"s"25 26 elapsedpretty = elapsedpretty+" " + elapsedsecs+" second"27 if(elapsedsecs!=1)28 elapsedpretty=elapsedpretty+"s"29 30 elapsedpretty = elapsedpretty+ " "+parm1+" millisecond"31 if(parm1!=1)32 elapsedpretty=elapsedpretty+"s"

Page 178: [ebook] Learn ASP

33 34 return elapsedpretty;35 } 36 </script>

http://www.learnASP.com/learn/speedtips.asp by Charles M. Carroll Page 181

Speed Tips by Charles CarrollThere are several ways to speed up a given ASP page. These suggestions come from a very exciting listserver we run called[aspfastcode] (http://www.asplists.com/asplists/aspfastcode.asp) . There people submit their working scripts (broken ones are notallowed) that are running too slow and the members help them speed up that sample.

#1 Any page that does not need session can benefit from this directive at the top:<%@ enablesessionstate=false %>

#2 All pages should be buffered see /advice/whybuffer.asp for explanation. Also see /learn/speedtables.asp to see how flushingbuffer and HTML tags can improve percieved speed.

Add this to top:<%response.buffer=true%>

#3 Pages doing database access will improve performance if the following techniques are used Getrows (see /learn/dbtablegetrows.asp and /advice/whygetrows.asp)●

GetString (see /learn/dbtablegetstring.asp) ●

Disconnected recordsets (see /learn/dbtabledisconnected.asp).●

#4 Before just believing any article you read on the web or in an ASP book (many articles are not researched thoroughly) andimplementing code changes TIME THE CODE BEFORE AND AFTER changes. /learn/speedtimer.asp has the needed code that willtime scripts to millisecond accuracy.

#5 Eliminate any code that reads com properties twice, /learn/propertyexpense.asp has some samples of this.

#6 Just say no to VB components and/or recordsets stored at the session level. Several articles explain why:http://www.learnasp.com/advice/dbsessionapp.aspThis is an attempt to settle this issue once and for all with very clear explanations why. This is NOT recommended by manywho have tried and blown up quiet and busy web servers.

http://www.learnasp.com/learn/nosessionobjects.asp●

http://www.learnasp.com/learn/sessionoverview.asphttp://www.learnasp.com/learn/buildvbthreads.asphttp://www.learnasp.com/learn/globalproblems.aspfor earlier and other perspectives on Thread-locking, Serialization and Thread-Local storage.

#7 Cache frequent query results/HTML generated from databases in application variables.http://www.learnasp.com/learn/speedappdata.asp.

#8 Open database connections as late as possible, Close database connections immediately when done. Placing your code a fewlines later could make a huge difference as your scripts run round-robin with other scripts, see /advice/roundrobin.asp for more whysabout this.

#9 Tune your server. At least make the 20 instead of 4 thread tweak (see http://www.learnasp.com/advice/threads.asp). The articlesat /learn/speedserver.asp will tell you everything you need to know about tuning your server.

#10 Don't waste time running scripts if the user hit the "stop" button or went to different page/site. Normally scripts run started by auser run to completion whether the user is there to read output or not running invisibly on server. See: /learn/isclientconnected.asp tosee how to modify your scripts appropriately.

#11 Bite the bullet and master remote scripting so your HTML and ASP scripts can communicate with ASP asynchronously and

Page 179: [ebook] Learn ASP

refresh portions of page without submitting page to server. Remote scripting works in both Netscape and IE; any Javascript capablebrowser. Some remote scripting links and a listserver to get help is at http://www.asplists.com/asplists/aspremotescripting.asp.

http://www.learnASP.com/learn/speedtables.asp by Charles M. Carroll Page 182

Speed/Optimization Example: A Table DisplaySpeeding up your scripts involves many big and small script changes. We have prepared this "before" and "after" example toillustrate the point. This example assumes you truly have to display this many records (for example, a corporate report). Alternatively:

Paging records into page __ of ___ is much faster if this is appropriate(see /learn/dbtablepaged.asp)

Throttling the maximum number of records if it is appropriate(see www.activeserverpages.com/learn/dbmaxrecs.asp)

Side note: If anyone you know believes Access queries are done asynchronously, running a couple of these scripts will prove themwrong. Access queries execute one web user at a time sequentially.

After OptimizationHere is a very fast table display going against an identical huge SQL Server Table:

1 <%response.buffer=true%>2 <HEAD><TITLE>dbtablefast.asp</TITLE></HEAD>3 <HTML><body bgcolor="#FFFFFF">4 <%5 myDSN = "DSN=student;UID=student;pwd=magic"6 7 mySQL="select * from authors order by author"8 call query2table(mySQL,myDSN)9 %>10 <!--#include virtual="/learn/test/lib_dbtablefast.asp"-->11 </BODY></HTML>12 13

Here is the optimized library lib_dbtablefast.asp which achieves this speed:

1 <%2 sub query2table(inputquery, inputDSN)3 dim conntemp, rstemp4 set conntemp=server.createobject("adodb.connection")5 ' 0 seconds means wait forever, default is 156 conntemp.connectiontimeout=07 conntemp.open inputDSN8 set rstemp=conntemp.execute(inputquery)9 howmanyfields=rstemp.fields.count -110 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><colwidth='15%'><tr>"11 response.write tablestart12 for i=0 to howmanyfields %>13 <td><b><%=rstemp(i).name%></B></TD>14 <% next %>15 </tr>16 <% ' Now lets grab all the records17 DO UNTIL rstemp.eof18 counter=counter+119 response.write "<tr>"20 for i = 0 to howmanyfields

Page 180: [ebook] Learn ASP

21 thisvalue=rstemp(i)22 If isnull(thisvalue) then23 thisvalue="&nbsp;"24 end if25 response.write "<td valign=top>" & thisvalue & "</td>" & vbcrlf26 next27 response.write "</tr>"28 rstemp.movenext29 IF counter mod 50=0 THEN30 If response.isclientconnected()=false THEN31 EXIT DO32 END IF33 response.write "</table>" & TableStart34 response.flush 35 END IF36 37 loop%>38 </table>39 <%40 rstemp.close41 set rstemp=nothing42 conntemp.close43 set conntemp=nothing44 end sub%>45

Before OptimizationHere is the original slow script which basically demonstrates techniques that may work if your data and concurrency load is light, butthe script above demonstrates the typical changes made to speed up a script when it becomes needed or you just want to wringevery ounce of speed from your site. This script will probably timeout before it's completion!

1 <HEAD><TITLE>dbtableslow.asp</TITLE></HEAD>2 <HTML><body bgcolor="#FFFFFF">3 <%4 myDSN = "DSN=student;uid=student;pwd=magic"5 6 mySQL= "SELECT * from authors order by Author"7 call query2table(mySQL,myDSN)8 %>9 <!--#include virtual="/learn/test/lib_dbtableslow.asp"-->10 </BODY></HTML>

Here is the original slow library lib_dbtableslow.asp :

1 <%2 sub query2table(inputquery, inputDSN)3 dim conntemp, rstemp4 set conntemp=server.createobject("adodb.connection")5 conntemp.open inputDSN6 set rstemp=conntemp.execute(inputquery)7 howmanyfields=rstemp.fields.count -1%>8 <table border=1><tr>9 <% 'Put Headings On The Table of Field Names10 for i=0 to howmanyfields %>11 <td><b><%=rstemp(i).name%></B></TD>12 <% next %>13 </tr>14 <% ' Now lets grab all the records15 DO UNTIL rstemp.eof and response.isclientconnected()%>16 <tr>17 <% for i = 0 to howmanyfields18 thisvalue=rstemp(i)19 If isnull(thisvalue) then20 thisvalue="&nbsp;"21 end if%>22 <td valign=top><%=thisvalue%></td>23 <% next %>

Page 181: [ebook] Learn ASP

24 </tr>25 <%rstemp.movenext26 loop%>27 </table>28 <%29 rstemp.close30 set rstemp=nothing31 conntemp.close32 set conntemp=nothing33 end sub%>

http://www.learnASP.com/learn/speedtablesall.asp by Charles M. Carroll Page 183

Speed/Optimization: All VariationsFetching records in an optimized way actually has many variations. We will list most of them here, provide code sample and typicaltimings for fetching and displaying records. These timings reveal an interesting behavior. Even if a script reports it ran in say, 7seconds, that refers to the time that script received from the CPU. So that if 7 scripts take 8 seconds each there may be hundreds orthousands of scripts running on the server that are sharing the CPU. User #1 may see a 7 second result in 21 seconds, so their 7second report reflects the time spent on the server/CPU for the script and the fact that 14 seconds of other stuff was executedround-robin with the rest of the scripts, not the time since the script started.

Method: LOOP, .movenext, periodic response.flush

Query took 6 seconds.Query processed 10835 records.Speed =1805.83333333333 records per second

Method: LOOP, .movenext and periodic response.flush commands. String is assembled with & operator and writenperiodically.

Query took 52 seconds.Query processed 10835 records.Speed =208.365384615385 records per second.

Observation: The & operator is VERY expensive! Unbelievably so.

Method: Single GetString command

Query took 4 secondsQuery processed 10837 records.Speed =2709.25 records per second.

Method: GetRows command with no LOOP + movenext but loop through the array with periodic response flushes.

Query took 3 seconds.Query processed 10834 records.Speed =3611.33333333333 records per second.

Note: Getstring often wins in many tests but it depends on many factors. I have seen a straight loop take 18 secs whereGetRows takes 9 seconds and getstring take 4 secs.

Method: GetRows command of a fixed row count (say 500 record clusters for example) with a reponse.flush after eacharray is read!

Query took 3 seconds.Query processed 10782 records.Speed =3594 records per second.

Method: Displaying a portion of the data (say the first 500 records) only.

Query took 7 seconds.Query processed 500 records.Speed =71.4285714285714 records per second.

Page 182: [ebook] Learn ASP

Note: This was recorded as 7 seconds but actually was much faster actually due to speed the browser reported the results.

Now here is the code that was used to gather all the data.

Here is a table display with a simple LOOP:

1 <%response.buffer=true%>2 <HEAD><TITLE>dbtableLoopAll.asp</TITLE></HEAD>3 <HTML><body bgcolor="#FFFFFF">4 <!--#include virtual="/adovbs.inc"-->5 <!--#include virtual="/learn/test/lib_dbtablefastv2.asp"-->6 <%7 server.scripttimeout=2408 optimize=optimize_LoopAll9 10 myDSN = "DSN=student;UID=student;pwd=magic"11 'mySQL="select * from authors order by author "12 mySQL="select * from authors order by author "13 14 Call TimerStart15 call query2table(mySQL,myDSN,optimize,howmany)16 Call TimerEnd17 %>18 </BODY></HTML>

Here is a table display with a simple LOOP assembling a string:

1 <%response.buffer=true%>2 <HEAD><TITLE>dbtableLoopAllstring.asp</TITLE></HEAD>3 <HTML><body bgcolor="#FFFFFF">4 <!--#include virtual="/adovbs.inc"-->5 <!--#include virtual="/learn/test/lib_dbtablefastv2.asp"-->6 <%7 server.scripttimeout=2408 optimize=optimize_LoopAll_string9 10 myDSN = "DSN=student;UID=student;pwd=magic"11 mySQL="select * from authors order by author "12 13 Call TimerStart14 call query2table(mySQL,myDSN,optimize,howmany)15 Call TimerEnd16 %>17 </BODY></HTML>18

Here is a table display with a GetString call and no LOOP:

1 <%response.buffer=true%>2 <HEAD><TITLE>dbtablegetstringall.asp</TITLE></HEAD>3 <HTML><body bgcolor="#FFFFFF">4 <!--#include virtual="/adovbs.inc"-->5 <!--#include virtual="/learn/test/lib_dbtablefastv2.asp"-->6 <%7 server.scripttimeout=2408 optimize=optimize_GetStringAll9 myDSN = "DSN=student;UID=student;pwd=magic"10 mySQL="select * from authors order by author"11 12 Call TimerStart13 call query2table(mySQL,myDSN,optimize,howmany)14 response.write OptimizationName(optimize) & "<br>"15 Call TimerEnd16 %>17 </BODY></HTML>

Here is a table display with a GetString call (buffered):

Page 183: [ebook] Learn ASP

1 <%response.buffer=true%>2 <HEAD><TITLE>dbtablegetstringbuffered.asp</TITLE></HEAD>3 <HTML><body bgcolor="#FFFFFF">4 <!--#include virtual="/adovbs.inc"-->5 <!--#include virtual="/learn/test/lib_dbtablefastv2.asp"-->6 <%7 server.scripttimeout=2408 optimize=optimize_GetStringBuffered9 myDSN = "DSN=student;UID=student;pwd=magic"10 mySQL="select * from authors order by author"11 12 Call TimerStart13 call query2table(mySQL,myDSN,optimize,howmany)14 response.write OptimizationName(optimize) & "<br>"15 Call TimerEnd16 %>17 </BODY></HTML>

Here is a table display with a GetRows call and no LOOP:

1 <%response.buffer=true%>2 <HEAD><TITLE>dbtablegetrowsall.asp</TITLE></HEAD>3 <HTML><body bgcolor="#FFFFFF">4 <!--#include virtual="/adovbs.inc"-->5 <!--#include virtual="/learn/test/lib_dbtablefastv2.asp"-->6 <%7 server.scripttimeout=2408 optimize=optimize_getrowsall9 response.write OptimizationName(optimize) & "<p>"10 11 myDSN = "DSN=student;UID=student;pwd=magic"12 mySQL="select * from authors order by author "13 14 15 call TimerStart16 call query2table(mySQL,myDSN,optimize,howmany)17 call TimerEnd18 19 %>20 </BODY></HTML>

Here is a table display with a GetRows (buffered):

1 <%response.buffer=true%>2 <HEAD><TITLE>dbtableGetRowsBuffered.asp</TITLE></HEAD>3 <HTML><body bgcolor="#FFFFFF">4 <!--#include virtual="/adovbs.inc"-->5 <!--#include virtual="/learn/test/lib_dbtablefastv2.asp"-->6 <%7 server.scripttimeout=2408 optimize=optimize_GetRowsBuffered9 10 myDSN = "DSN=student;UID=student;pwd=magic"11 'mySQL="select * from authors order by author "12 mySQL="select * from authors order by author "13 14 Call TimerStart15 call query2table(mySQL,myDSN,optimize,howmany)16 Call TimerEnd17 %>18 </BODY></HTML>

Here is a table display of a portion of the records:

1 <%response.buffer=true%>2 <HEAD><TITLE>dbtablelimitrows.asp</TITLE></HEAD>3 <HTML><body bgcolor="#FFFFFF">4 <!--#include virtual="/adovbs.inc"-->

Page 184: [ebook] Learn ASP

5 <!--#include virtual="/learn/test/lib_dbtablefastv2.asp"-->6 <%7 server.scripttimeout=2408 optimize=optimize_LimitRows9 myDSN = "DSN=student;UID=student;pwd=magic"10 mySQL="select * from authors order by author"11 12 Call TimerStart13 call query2table(mySQL,myDSN,optimize,howmany)14 response.write OptimizationName(optimize) & "<br>"15 Call TimerEnd16 %>17 </BODY></HTML>

Here is the optimized library lib_dbtablefastv2.asp which achieves this speed:

1 <%2 Const optimize_LoopAll = 13 Const optimize_GetstringAll = 24 Const optimize_GetrowsAll = 35 Const optimize_GetrowsBuffered = 46 Const optimize_GetStringBuffered = 57 Const optimize_LimitRows = 68 Const optimize_LoopAll_String = 79 10 dim optimize_buffersize11 dim optimize_started12 dim optimize_ended13 dim optimize_SQL14 dim optimize_DSN15 dim optimize_howmany16 dim optimize_cursorlocation17 dim optimize_maxrecs18 dim optimize_disconnectRS19 20 optimize_started=021 22 ' performance stuff23 optimize_buffersize=20024 'optimize_cursorlocation=aduseclient25 optimize_maxrecs=50026 optimize_cursorlocation=aduseserver27 optimize_disconnectRS=false28 optimize_stringwrite=false29 30 SUB TimerStart()31 optimize_started=now()32 END SUB33 34 SUB TimerEnd()35 optimize_ended=now()36 elapsed=DateDiff("s", optimize_started, optimize_ended)37 response.write "SQL=<b>" & optimize_SQL & "</b><br>"38 response.write "DSN=<b>" & optimize_DSN & "</b><br>"39 response.write "Query took <b>" & elapsed & " seconds.</b><br>"40 IF optimize_howmany=-1 THEN41 optimize_howmany=querycount(optimize_DSN,optimize_SQL)42 END IF43 response.write "Query processed <b>" & optimize_howmany & " records.</b><br>"44 response.write "Speed =<b>" & optimize_howmany/elapsed & " records per second.</b><br>"45 response.write "Notes:<br>"46 pad="&nbsp;&nbsp;&nbsp;&nbsp;"47 response.write pad & "buffersize=<b>" & optimize_buffersize & "</b><br>"48 IF optimize_cursorlocation=adUseClient THEN49 response.write pad & "cursorlocation=<b>adUseClient</b><br>"50 END IF51 IF optimize_cursorlocation=adUseServer THEN52 response.write pad & "cursorlocation=<b>adUseServer</b><br>"

Page 185: [ebook] Learn ASP

53 END IF54 END SUB55 56 sub query2table(parmQuery, parmDSN,parmMethod,parmcount)57 ' method 1 = standard58 ' method 2 = getrows59 ' method 3 = getstring60 dim howmany61 SELECT CASE parmMethod62 CASE 163 Call loopStandard(parmQuery,parmDSN,howmany)64 CASE 265 Call loopGetString(parmQuery,parmDSN,howmany)66 CASE 367 Call loopGetRows(parmQuery,parmDSN,howmany)68 CASE 469 Call loopGetRowsBuffered(parmQuery,parmDSN,howmany)70 CASE 571 Call loopGetStringBuffered(parmQuery,parmDSN,howmany)72 CASE 673 Call LimitRows(parmQuery,parmDSN,howmany)74 CASE 775 Call loopStandardStringWrite(parmQuery,parmDSN,howmany)76 CASE ELSE77 response.write "1, 2 or 3 are only valid speedmethods"78 END SELECT79 parmcount=howmany80 If optimize_started<>0 THEN81 optimize_DSN=parmDSN82 optimize_SQL=parmquery83 optimize_howmany=parmcount84 END IF85 END SUB86 87 FUNCTION querycount(parmDSN,parmQuery)88 set rstemp=Server.CreateObject("adodb.Recordset")89 rstemp.open parmQuery, parmDSN, adopenstatic90 querycount=rstemp.recordcount91 rstemp.close92 set rstemp=nothing93 END FUNCTION94 95 96 SUB loopstandard(inputquery, inputDSN,inputcount)97 dim conntemp, rstemp98 set conntemp=server.createobject("adodb.connection")99 ' 0 seconds means wait forever, default is 15100 conntemp.connectiontimeout=0101 conntemp.cursorlocation=optimize_cursorlocation102 conntemp.open inputDSN103 set rstemp=conntemp.execute(inputquery)104 IF optimize_disconnectRS=true THEN105 conntemp.close106 END IF107 howmanyfields=rstemp.fields.count -1108 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><colwidth='15%'><tr>"109 response.write tablestart110 for i=0 to howmanyfields %>111 <td><b><%=rstemp(i).name%></B></TD>112 <% next %>113 </tr>114 <% ' Now lets grab all the records115 DO UNTIL rstemp.eof116 counter=counter+1117 response.write "<tr>"118 for i = 0 to howmanyfields

Page 186: [ebook] Learn ASP

119 thisvalue=rstemp(i)120 If isnull(thisvalue) then121 thisvalue="&nbsp;"122 end if123 response.write "<td valign=top>" & thisvalue & "</td>" & vbcrlf124 next125 response.write "</tr>"126 rstemp.movenext127 IF counter mod 50=0 THEN128 If response.isclientconnected()=false THEN129 EXIT DO130 END IF131 response.write "</table>" & TableStart132 END IF133 134 loop%>135 </table>136 <%137 inputcount=counter138 rstemp.close139 set rstemp=nothing140 conntemp.close141 set conntemp=nothing142 END SUB%>143 144 <%SUB loopstandardStringWrite(inputquery, inputDSN,inputcount)145 dim conntemp, rstemp146 set conntemp=server.createobject("adodb.connection")147 ' 0 seconds means wait forever, default is 15148 conntemp.connectiontimeout=0149 conntemp.cursorlocation=optimize_cursorlocation150 conntemp.open inputDSN151 set rstemp=conntemp.execute(inputquery)152 IF optimize_disconnectRS=true THEN153 conntemp.close154 END IF155 howmanyfields=rstemp.fields.count -1156 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><colwidth='15%'><tr>"157 response.write tablestart158 for i=0 to howmanyfields %>159 <td><b><%=rstemp(i).name%></B></TD>160 <% next %>161 </tr>162 <% ' Now lets grab all the records163 tempSTR=""164 DO UNTIL rstemp.eof165 counter=counter+1166 tempSTR=tempSTR & "<tr>"167 for i = 0 to howmanyfields168 thisvalue=rstemp(i)169 If isnull(thisvalue) then170 thisvalue="&nbsp;"171 end if172 tempSTR=tempSTR & "<td valign=top>" & thisvalue & "</td>" & vbcrlf173 next174 tempSTR=tempSTR & "</tr>"175 rstemp.movenext176 IF counter mod 50=0 THEN177 If response.isclientconnected()=false THEN178 EXIT DO179 END IF180 tempSTR=tempSTR & "</table>" & TableStart181 response.write tempSTR182 response.flush183 tempSTR=""184 END IF

Page 187: [ebook] Learn ASP

185 loop%>186 </table>187 <%188 inputcount=counter189 rstemp.close190 set rstemp=nothing191 conntemp.close192 set conntemp=nothing193 END SUB%>194 195 <%SUB loopGetstring(inputquery, inputDSN,inputcount)196 dim conntemp, rstemp197 set conntemp=server.createobject("adodb.connection")198 ' 0 seconds means wait forever, default is 15199 conntemp.connectiontimeout=0200 conntemp.open inputDSN201 set rstemp=conntemp.execute(inputquery)202 howmanyfields=rstemp.fields.count -1203 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><colwidth='15%'><tr>"204 response.write tablestart205 for i=0 to howmanyfields %>206 <td><b><%=rstemp(i).name%></B></TD>207 <% next %>208 </tr>209 <%210 ' Now lets grab all the records211 tempSTR=rstemp.getstring(,, "</td><td>", "</td></tr><TR><TD>", "&nbsp;")212 response.write tempSTR213 response.write "</table>"214 inputcount=-1215 rstemp.close216 set rstemp=nothing217 conntemp.close218 set conntemp=nothing219 END SUB%>220 221 222 <%SUB loopGetstringbuffered(inputquery, inputDSN,inputcount)223 dim conntemp, rstemp224 set conntemp=server.createobject("adodb.connection")225 ' 0 seconds means wait forever, default is 15226 conntemp.connectiontimeout=0227 conntemp.open inputDSN228 set rstemp=conntemp.execute(inputquery)229 howmanyfields=rstemp.fields.count -1230 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><colwidth='15%'><tr>"231 response.write tablestart232 for i=0 to howmanyfields %>233 <td><b><%=rstemp(i).name%></B></TD>234 <% next %>235 </tr>236 <%237 ' Now lets grab all the records238 DO239 tempSTR=rstemp.getstring(,optimize_buffersize, "</td><td>", "</td></tr><TR><TD>","&nbsp;")240 response.write tempSTR241 If response.isclientconnected()=false THEN242 EXIT SUB243 END IF244 response.write "</table>" & TableStart245 LOOP UNTIL rstemp.eof246 response.write "</table>"247 inputcount=-1248 rstemp.close

Page 188: [ebook] Learn ASP

249 set rstemp=nothing250 conntemp.close251 set conntemp=nothing252 END SUB253 254 SUB loopGetRows(inputquery, inputDSN,inputcount)255 dim conntemp, rstemp256 set conntemp=server.createobject("adodb.connection")257 ' 0 seconds means wait forever, default is 15258 conntemp.connectiontimeout=0259 conntemp.open inputDSN260 set rstemp=conntemp.execute(inputquery)261 howmanyfields=rstemp.fields.count -1262 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><colwidth='15%'><tr>"263 response.write tablestart264 for i=0 to howmanyfields %>265 <td><b><%=rstemp(i).name%></B></TD>266 <% next %>267 </tr>268 <%269 ' Now lets grab all the records270 alldata=rstemp.getrows271 numcols=ubound(alldata,1)272 numrows=ubound(alldata,2)273 274 FOR rowcounter= 0 TO numrows275 FOR colcounter=0 to numcols276 response.write "<td valign=top>"277 response.write alldata(colcounter,rowcounter)278 response.write "</td>"279 NEXT280 response.write "</tr>" & vbcrlf281 IF rowcounter mod 50=0 THEN282 If response.isclientconnected()=false THEN283 EXIT FOR284 END IF285 response.write "</table>" & TableStart286 END IF287 NEXT288 response.write "</table>"289 inputcount=numrows290 rstemp.close291 set rstemp=nothing292 conntemp.close293 set conntemp=nothing294 END SUB295 296 SUB loopGetRowsBuffered(inputquery, inputDSN,inputcount)297 dim conntemp, rstemp298 set conntemp=server.createobject("adodb.connection")299 ' 0 seconds means wait forever, default is 15300 conntemp.connectiontimeout=0301 conntemp.open inputDSN302 set rstemp=conntemp.execute(inputquery)303 howmanyfields=rstemp.fields.count -1304 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><colwidth='15%'><tr>"305 response.write tablestart306 for i=0 to howmanyfields %>307 <td><b><%=rstemp(i).name%></B></TD>308 <% next %>309 </tr>310 <%311 ' Now lets grab all the records312 DO313 alldata=rstemp.getrows(optimize_buffersize)

Page 189: [ebook] Learn ASP

314 numcols=ubound(alldata,1)315 numrows=ubound(alldata,2)316 317 FOR rowcounter= 0 TO numrows318 FOR colcounter=0 to numcols319 response.write "<td valign=top>"320 response.write alldata(colcounter,rowcounter)321 response.write "</td>"322 NEXT323 response.write "</tr>" & vbcrlf324 NEXT325 howmany=howmany+numrows326 If response.isclientconnected()=false THEN327 EXIT SUB328 END IF329 response.write "</table>" & TableStart330 LOOP UNTIL rstemp.eof331 response.write "</table>"332 inputcount=howmany333 rstemp.close334 set rstemp=nothing335 conntemp.close336 set conntemp=nothing337 END SUB338 339 SUB LimitRows(inputquery, inputDSN,inputcount)340 set rstemp=Server.CreateObject("adodb.Recordset")341 rstemp.maxrecords=optimize_maxrecs342 'rstemp.open inputquery, inputDSN, adopenforwardonly, adlockReadOnly343 rstemp.open inputquery, inputDSN,adopenstatic344 345 howmanyfields=rstemp.fields.count -1346 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><colwidth='15%'><tr>"347 response.write tablestart348 for i=0 to howmanyfields %>349 <td><b><%=rstemp(i).name%></B></TD>350 <% next %>351 </tr>352 <%353 response.flush354 tempSTR=rstemp.getstring(,, "</td><td>", "</td></tr><TR><TD>", "&nbsp;")355 response.write tempSTR356 response.write "</td></tr></table>"357 358 inputcount=optimize_maxrecs359 rstemp.close360 set rstemp=nothing361 END SUB362 363 FUNCTION optimizationName(parmNum)364 SELECT CASE parmnum365 CASE optimize_LoopAll366 optimizationName="LoopAll"367 CASE optimize_GetstringAll368 optimizationName="GetstringAll"369 CASE optimize_GetrowsAll370 optimizationName="GetrowsAll"371 CASE optimize_GetrowsBuffered372 optimizationName="GetrowsBuffered"373 CASE optimize_GetStringBuffered374 optimizationName="GetStringBuffered"375 CASE optimize_LimitRows376 optimizationName="LimitRows"377 CASE ELSE378 optimizationName="undefined"379 END SELECT

Page 190: [ebook] Learn ASP

380 END FUNCTION381 382 %>383 384 385 386 387 388 389 390 391 392 393 394

http://www.learnASP.com/learn/speedtablesdrivers.asp by Charles M. Carroll Page 184

Speed/Optimization: What about the Driver?Fetching records in an optimized way may have many variations but before you get to the database you interact with a driver. Herewe time the difference between arbitrary drivers. We will benchmark with the simplest method: Fetching and displaying all recordswith a LOOP, .movenext and periodic response.flush commands.

Here is a table display against a SQL server with a OLEDB driver.

1 <%response.buffer=true%>2 <HEAD><TITLE>dbtableSQLoledb.asp</TITLE></HEAD>3 <HTML><body bgcolor="#FFFFFF">4 <!--#include virtual="/adovbs.inc"-->5 <!--#include virtual="/learn/test/lib_dbtablefastv2.asp"-->6 <%7 server.scripttimeout=2408 optimize=optimize_LoopAll9 mySQL="select * from authors where au_id<2000 order by author "10 11 myDSN="PROVIDER=SQLOLEDB;DATA SOURCE=sql2.datareturn.com;"12 myDSN=myDSN & "USER ID=student;PASSWORD=magic;"13 14 Call TimerStart15 call query2table(mySQL,myDSN,optimize,howmany)16 Call TimerEnd17 18 %>19 </BODY></HTML>

Here is a table display against a SQL server with a ODBC driver:

1 <%response.buffer=true%>2 <HEAD><TITLE>dbtableSQLODBC.asp</TITLE></HEAD>3 <HTML><body bgcolor="#FFFFFF">4 <!--#include virtual="/adovbs.inc"-->5 <!--#include virtual="/learn/test/lib_dbtablefastv2.asp"-->6 <%7 server.scripttimeout=2408 9 mySQL="select * from authors where au_id<2000 order by author "10 optimize=optimize_LoopAll11 myDSN="PROVIDER=MSDASQL;DRIVER={SQL Server};"12 myDSN=myDSN & "SERVER=sql2.datareturn.com;UID=student;PWD=magic;"13 14 Call TimerStart15 call query2table(mySQL,myDSN,optimize,howmany)

Page 191: [ebook] Learn ASP

16 Call TimerEnd17 %>18 </BODY></HTML>

Here is the optimized library lib_dbtablefastv2.asp which achieves this speed:

1 <%2 Const optimize_LoopAll = 13 Const optimize_GetstringAll = 24 Const optimize_GetrowsAll = 35 Const optimize_GetrowsBuffered = 46 Const optimize_GetStringBuffered = 57 Const optimize_LimitRows = 68 Const optimize_LoopAll_String = 79 10 dim optimize_buffersize11 dim optimize_started12 dim optimize_ended13 dim optimize_SQL14 dim optimize_DSN15 dim optimize_howmany16 dim optimize_cursorlocation17 dim optimize_maxrecs18 dim optimize_disconnectRS19 20 optimize_started=021 22 ' performance stuff23 optimize_buffersize=20024 'optimize_cursorlocation=aduseclient25 optimize_maxrecs=50026 optimize_cursorlocation=aduseserver27 optimize_disconnectRS=false28 optimize_stringwrite=false29 30 SUB TimerStart()31 optimize_started=now()32 END SUB33 34 SUB TimerEnd()35 optimize_ended=now()36 elapsed=DateDiff("s", optimize_started, optimize_ended)37 response.write "SQL=<b>" & optimize_SQL & "</b><br>"38 response.write "DSN=<b>" & optimize_DSN & "</b><br>"39 response.write "Query took <b>" & elapsed & " seconds.</b><br>"40 IF optimize_howmany=-1 THEN41 optimize_howmany=querycount(optimize_DSN,optimize_SQL)42 END IF43 response.write "Query processed <b>" & optimize_howmany & " records.</b><br>"44 response.write "Speed =<b>" & optimize_howmany/elapsed & " records per second.</b><br>"45 response.write "Notes:<br>"46 pad="&nbsp;&nbsp;&nbsp;&nbsp;"47 response.write pad & "buffersize=<b>" & optimize_buffersize & "</b><br>"48 IF optimize_cursorlocation=adUseClient THEN49 response.write pad & "cursorlocation=<b>adUseClient</b><br>"50 END IF51 IF optimize_cursorlocation=adUseServer THEN52 response.write pad & "cursorlocation=<b>adUseServer</b><br>"53 END IF54 END SUB55 56 sub query2table(parmQuery, parmDSN,parmMethod,parmcount)57 ' method 1 = standard58 ' method 2 = getrows59 ' method 3 = getstring60 dim howmany61 SELECT CASE parmMethod

Page 192: [ebook] Learn ASP

62 CASE 163 Call loopStandard(parmQuery,parmDSN,howmany)64 CASE 265 Call loopGetString(parmQuery,parmDSN,howmany)66 CASE 367 Call loopGetRows(parmQuery,parmDSN,howmany)68 CASE 469 Call loopGetRowsBuffered(parmQuery,parmDSN,howmany)70 CASE 571 Call loopGetStringBuffered(parmQuery,parmDSN,howmany)72 CASE 673 Call LimitRows(parmQuery,parmDSN,howmany)74 CASE 775 Call loopStandardStringWrite(parmQuery,parmDSN,howmany)76 CASE ELSE77 response.write "1, 2 or 3 are only valid speedmethods"78 END SELECT79 parmcount=howmany80 If optimize_started<>0 THEN81 optimize_DSN=parmDSN82 optimize_SQL=parmquery83 optimize_howmany=parmcount84 END IF85 END SUB86 87 FUNCTION querycount(parmDSN,parmQuery)88 set rstemp=Server.CreateObject("adodb.Recordset")89 rstemp.open parmQuery, parmDSN, adopenstatic90 querycount=rstemp.recordcount91 rstemp.close92 set rstemp=nothing93 END FUNCTION94 95 96 SUB loopstandard(inputquery, inputDSN,inputcount)97 dim conntemp, rstemp98 set conntemp=server.createobject("adodb.connection")99 ' 0 seconds means wait forever, default is 15100 conntemp.connectiontimeout=0101 conntemp.cursorlocation=optimize_cursorlocation102 conntemp.open inputDSN103 set rstemp=conntemp.execute(inputquery)104 IF optimize_disconnectRS=true THEN105 conntemp.close106 END IF107 howmanyfields=rstemp.fields.count -1108 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><colwidth='15%'><tr>"109 response.write tablestart110 for i=0 to howmanyfields %>111 <td><b><%=rstemp(i).name%></B></TD>112 <% next %>113 </tr>114 <% ' Now lets grab all the records115 DO UNTIL rstemp.eof116 counter=counter+1117 response.write "<tr>"118 for i = 0 to howmanyfields119 thisvalue=rstemp(i)120 If isnull(thisvalue) then121 thisvalue="&nbsp;"122 end if123 response.write "<td valign=top>" & thisvalue & "</td>" & vbcrlf124 next125 response.write "</tr>"126 rstemp.movenext127 IF counter mod 50=0 THEN

Page 193: [ebook] Learn ASP

128 If response.isclientconnected()=false THEN129 EXIT DO130 END IF131 response.write "</table>" & TableStart132 END IF133 134 loop%>135 </table>136 <%137 inputcount=counter138 rstemp.close139 set rstemp=nothing140 conntemp.close141 set conntemp=nothing142 END SUB%>143 144 <%SUB loopstandardStringWrite(inputquery, inputDSN,inputcount)145 dim conntemp, rstemp146 set conntemp=server.createobject("adodb.connection")147 ' 0 seconds means wait forever, default is 15148 conntemp.connectiontimeout=0149 conntemp.cursorlocation=optimize_cursorlocation150 conntemp.open inputDSN151 set rstemp=conntemp.execute(inputquery)152 IF optimize_disconnectRS=true THEN153 conntemp.close154 END IF155 howmanyfields=rstemp.fields.count -1156 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><colwidth='15%'><tr>"157 response.write tablestart158 for i=0 to howmanyfields %>159 <td><b><%=rstemp(i).name%></B></TD>160 <% next %>161 </tr>162 <% ' Now lets grab all the records163 tempSTR=""164 DO UNTIL rstemp.eof165 counter=counter+1166 tempSTR=tempSTR & "<tr>"167 for i = 0 to howmanyfields168 thisvalue=rstemp(i)169 If isnull(thisvalue) then170 thisvalue="&nbsp;"171 end if172 tempSTR=tempSTR & "<td valign=top>" & thisvalue & "</td>" & vbcrlf173 next174 tempSTR=tempSTR & "</tr>"175 rstemp.movenext176 IF counter mod 50=0 THEN177 If response.isclientconnected()=false THEN178 EXIT DO179 END IF180 tempSTR=tempSTR & "</table>" & TableStart181 response.write tempSTR182 response.flush183 tempSTR=""184 END IF185 loop%>186 </table>187 <%188 inputcount=counter189 rstemp.close190 set rstemp=nothing191 conntemp.close192 set conntemp=nothing193 END SUB%>

Page 194: [ebook] Learn ASP

194 195 <%SUB loopGetstring(inputquery, inputDSN,inputcount)196 dim conntemp, rstemp197 set conntemp=server.createobject("adodb.connection")198 ' 0 seconds means wait forever, default is 15199 conntemp.connectiontimeout=0200 conntemp.open inputDSN201 set rstemp=conntemp.execute(inputquery)202 howmanyfields=rstemp.fields.count -1203 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><colwidth='15%'><tr>"204 response.write tablestart205 for i=0 to howmanyfields %>206 <td><b><%=rstemp(i).name%></B></TD>207 <% next %>208 </tr>209 <%210 ' Now lets grab all the records211 tempSTR=rstemp.getstring(,, "</td><td>", "</td></tr><TR><TD>", "&nbsp;")212 response.write tempSTR213 response.write "</table>"214 inputcount=-1215 rstemp.close216 set rstemp=nothing217 conntemp.close218 set conntemp=nothing219 END SUB%>220 221 222 <%SUB loopGetstringbuffered(inputquery, inputDSN,inputcount)223 dim conntemp, rstemp224 set conntemp=server.createobject("adodb.connection")225 ' 0 seconds means wait forever, default is 15226 conntemp.connectiontimeout=0227 conntemp.open inputDSN228 set rstemp=conntemp.execute(inputquery)229 howmanyfields=rstemp.fields.count -1230 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><colwidth='15%'><tr>"231 response.write tablestart232 for i=0 to howmanyfields %>233 <td><b><%=rstemp(i).name%></B></TD>234 <% next %>235 </tr>236 <%237 ' Now lets grab all the records238 DO239 tempSTR=rstemp.getstring(,optimize_buffersize, "</td><td>", "</td></tr><TR><TD>","&nbsp;")240 response.write tempSTR241 If response.isclientconnected()=false THEN242 EXIT SUB243 END IF244 response.write "</table>" & TableStart245 LOOP UNTIL rstemp.eof246 response.write "</table>"247 inputcount=-1248 rstemp.close249 set rstemp=nothing250 conntemp.close251 set conntemp=nothing252 END SUB253 254 SUB loopGetRows(inputquery, inputDSN,inputcount)255 dim conntemp, rstemp256 set conntemp=server.createobject("adodb.connection")257 ' 0 seconds means wait forever, default is 15

Page 195: [ebook] Learn ASP

258 conntemp.connectiontimeout=0259 conntemp.open inputDSN260 set rstemp=conntemp.execute(inputquery)261 howmanyfields=rstemp.fields.count -1262 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><colwidth='15%'><tr>"263 response.write tablestart264 for i=0 to howmanyfields %>265 <td><b><%=rstemp(i).name%></B></TD>266 <% next %>267 </tr>268 <%269 ' Now lets grab all the records270 alldata=rstemp.getrows271 numcols=ubound(alldata,1)272 numrows=ubound(alldata,2)273 274 FOR rowcounter= 0 TO numrows275 FOR colcounter=0 to numcols276 response.write "<td valign=top>"277 response.write alldata(colcounter,rowcounter)278 response.write "</td>"279 NEXT280 response.write "</tr>" & vbcrlf281 IF rowcounter mod 50=0 THEN282 If response.isclientconnected()=false THEN283 EXIT FOR284 END IF285 response.write "</table>" & TableStart286 END IF287 NEXT288 response.write "</table>"289 inputcount=numrows290 rstemp.close291 set rstemp=nothing292 conntemp.close293 set conntemp=nothing294 END SUB295 296 SUB loopGetRowsBuffered(inputquery, inputDSN,inputcount)297 dim conntemp, rstemp298 set conntemp=server.createobject("adodb.connection")299 ' 0 seconds means wait forever, default is 15300 conntemp.connectiontimeout=0301 conntemp.open inputDSN302 set rstemp=conntemp.execute(inputquery)303 howmanyfields=rstemp.fields.count -1304 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><colwidth='15%'><tr>"305 response.write tablestart306 for i=0 to howmanyfields %>307 <td><b><%=rstemp(i).name%></B></TD>308 <% next %>309 </tr>310 <%311 ' Now lets grab all the records312 DO313 alldata=rstemp.getrows(optimize_buffersize)314 numcols=ubound(alldata,1)315 numrows=ubound(alldata,2)316 317 FOR rowcounter= 0 TO numrows318 FOR colcounter=0 to numcols319 response.write "<td valign=top>"320 response.write alldata(colcounter,rowcounter)321 response.write "</td>"322 NEXT

Page 196: [ebook] Learn ASP

323 response.write "</tr>" & vbcrlf324 NEXT325 howmany=howmany+numrows326 If response.isclientconnected()=false THEN327 EXIT SUB328 END IF329 response.write "</table>" & TableStart330 LOOP UNTIL rstemp.eof331 response.write "</table>"332 inputcount=howmany333 rstemp.close334 set rstemp=nothing335 conntemp.close336 set conntemp=nothing337 END SUB338 339 SUB LimitRows(inputquery, inputDSN,inputcount)340 set rstemp=Server.CreateObject("adodb.Recordset")341 rstemp.maxrecords=optimize_maxrecs342 'rstemp.open inputquery, inputDSN, adopenforwardonly, adlockReadOnly343 rstemp.open inputquery, inputDSN,adopenstatic344 345 howmanyfields=rstemp.fields.count -1346 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><colwidth='15%'><tr>"347 response.write tablestart348 for i=0 to howmanyfields %>349 <td><b><%=rstemp(i).name%></B></TD>350 <% next %>351 </tr>352 <%353 response.flush354 tempSTR=rstemp.getstring(,, "</td><td>", "</td></tr><TR><TD>", "&nbsp;")355 response.write tempSTR356 response.write "</td></tr></table>"357 358 inputcount=optimize_maxrecs359 rstemp.close360 set rstemp=nothing361 END SUB362 363 FUNCTION optimizationName(parmNum)364 SELECT CASE parmnum365 CASE optimize_LoopAll366 optimizationName="LoopAll"367 CASE optimize_GetstringAll368 optimizationName="GetstringAll"369 CASE optimize_GetrowsAll370 optimizationName="GetrowsAll"371 CASE optimize_GetrowsBuffered372 optimizationName="GetrowsBuffered"373 CASE optimize_GetStringBuffered374 optimizationName="GetStringBuffered"375 CASE optimize_LimitRows376 optimizationName="LimitRows"377 CASE ELSE378 optimizationName="undefined"379 END SELECT380 END FUNCTION381 382 %>383 384 385 386 387 388

Page 197: [ebook] Learn ASP

389 390 391 392 393 394

http://www.learnASP.com/learn/isclientconnected.asp by Charles M. Carroll Page 185

IsClientConnected -- eliminating stray tasks by Charles Carrollresponse.IsClientConnected()is available beginning with IIS4 (if you want to see if you have it, see /learn/versioncheck.asp) and can be used within a page todetermine if the user is still fetching that page, i.e.

1 <%server.scripttimeout=202 ' this times out the script in 20 seconds whether done or not%>3 <TITLE>infiniteloop.asp</TITLE>4 <body bgcolor="#FFFFFF">5 <%6 DO7 x=x+18 response.write x & "<br>"9 If x=10000 then10 x=111 end if12 LOOP13 %>14 </body></html>

This loop could tie up the CPU for quite a while, even though the user hit the "stop" button the task would still be"spinning/executing" on the server even though the user was long gone. This is particularly true in databasetasks.1 <%server.scripttimeout=202 ' this times out the script in 20 seconds whether done or3 ' the user hit the STOP button4 %>5 <TITLE>infiniteloopfixed.asp</TITLE>6 <body bgcolor="#FFFFFF">7 <%8 DO9 x=x+110 response.write x & "<br>"11 If x=10000 then12 x=113 end if14 LOOP WHILE response.isclientconnected()15 %>16 </body></html>

this code will stop when user hits the stop button.

I recommend that all loops through database recordsets incorporate this so that they don't execute invisiblywasting CPU and database server resources. So here is a database table listing script that incorporates thisfunctionality:1 <TITLE>dbtableisclientconnected.asp</TITLE>2 <body bgcolor="#FFFFFF">3 <%4 ' ASP program that displays a database in table form

Page 198: [ebook] Learn ASP

5 myDSN="DSN=Student;uid=student;pwd=magic"6 mySQL="select * from publishers"7 8 set conntemp=server.createobject("adodb.connection")9 conntemp.open myDSN10 set rstemp=conntemp.execute(mySQL)11 howmanyfields=rstemp.fields.count -112 %>13 <table border=1><tr>14 <% 'Put Headings On The Table of Field Names15 for i=0 to howmanyfields %>16 <td><b><%=rstemp(i).name %></B></TD>17 <% next %>18 </tr>19 <% ' Now lets grab all the records20 do until (rstemp.eof or response.isclientconnected=false)%>21 <tr>22 <% for i = 0 to howmanyfields%>23 <td valign=top><%=rstemp(i)%></td>24 <% next %>25 </tr>26 <%rstemp.movenext27 loop28 %>29 </table>30 31 <%32 rstemp.close33 set rstemp=nothing34 conntemp.close35 set conntemp=nothing36 %>37 </body></html>

http://www.learnASP.com/learn/nothing.asp by Charles M. Carroll Page 186

The controversy over Nothing by Charles CarrollRule #1: All objects created with SET whatever=server.createobject("whatever")need to be destroyed on that page, i.e.set whatever=nothing

Rule #2: All objects created withSET whatever=server.createobject("whatever")should never be put in a session variable.These two statements are the source of much controversy. I would like to address the veracity of these statements and address thereal truth of this matter and why this truth is important to building high traffic websites.

The session is issue is dealt with in:http://www.learnasp.com/learn/sessionoverview.asphttp://www.learnasp.com/learn/globalproblems.asphttp://www.activeserverpages.com/learn/buildvbthreads.asphttp://www.learnasp.com/learn/nosessionobjects.asp

Scenario #1:

set x=server.createobject("whatever.whatever")....set x=nothing

Page 199: [ebook] Learn ASP

Scenario #2

set x=server.createobject("whatever.whatever")....

In Scenario #1, I can guarantee

the object is cleared from memory●

exactly the line of code where the object is removed from memory●

In Scenario #2, I cannot guarantee:

that the object WAS cleared from memory(I am basing this on a promise in the MS docs, and that the IIS code internally is flawless). IIS is good but if you think it isflawless I would like to ask you to buy some undervalued land in Florida.

when the object was cleaned from memory (the docs do not say when garbage collection occurs)●

I will also state that large ISPs (Innerhost, DataReturn) will guarantee your webserver will come down several times a day or weekwith scenario #2 (depending on how many objects are created throughout the day). With Scenario #1 the webserver stays up withoutincident. This evidence indicates the IIS garbage collection screws up.

http://www.learnASP.com/learn/dbpooling.asp by Charles M. Carroll Page 187

Database Connection Pooling by Charles CarrollConnection pooling takes care of re-using connections.

Lets say Scripta.aspcreates a connection●

process data●

close connection, set to nothing●

and 1,000 users do this simultaneously. It is not quite simultaneous, let us say that what happens when eight users access a scriptand create, close and destroy eight connections.

User Open conn. time Process Start time Close time#1 1:00am .001 1:00am .002 1:00am .012#2 1:00am .002 1:00am .003 1:00am .013#3 1:00am .003 1:00am .004 1:00am .009#4 1:00am .003 1:00am .004 1:00am .015#5 1:00am .007 1:00am .008 1:00am .014#6 1:00am .009 1:00am .010 1:00am .021#7 1:00am .016 1:00am .017 1:00am .028#8 1:00am .017 1:00am .018 1:00am .026

Time - open conns Open conns Pool to be reused Being Re-used1:00am .001 - 1 #1 01:00am .002 - 2 #1, #2 01:00am .010 - 4 #1, #2, #4, #5, #6 #31:00am .013 - 4 #2, #4, #5, #6 #1 #6 using #31:00am .014 - 3 #4, #5, #6 #1, #21:00am .016 - 2 #6, #7 #2, #4 #7 using #11:00am .022 - #7, #8 #1, #3, #4, #5 #8 using #21:00am .027 - #7 #1, #3, #4, #51:00am .029 - #1, #3, #4, #5 waiting

Page 200: [ebook] Learn ASP

Because of connection pooling they will use MUCH less than 1,000 brand new connections as conn.open statements will beprovided with already existing connections invisibly PROVIDING they were closed and thus guaranteed available for re-use.

The pool connections can only be re-used if they are closed. They expire in sixty seconds by default. This is all explained in:http://msdn.microsoft.com/library/techart/pooling2.htm

http://www.learnASP.com/learn/threadsafe.asp by Charles M. Carroll Page 188

Threading Issues by Charles Carroll with some help from George Reilly

All the work done by a webserver is handled by threads. They are the worker bees of the webserver. Any process running on thewebserver runs on a given thread.

Threads can affect ASP in several ways but we will focus on Thread Safety issues here.

A component that is not thread-safe

Leaks memory and/or places locks on resources in subtle-ways and/or does not behave predictably when many objects arerunning round-robin. The registry may have settings that indicate it is safe to be invoked many times from many clients andmarked and FREE threaded or both, the programmer due to inexperience or lack of stress testing did not truly do the locks,synchronization, memory protection, critical section code they thought they did.

behaves unstable when many clients are calling it and it's behavior causes the callers damage since they assume each call issafe and handling parameters correctly, etc.

If they get hit hard and fail in some complex way in some % of their requests, they don't recover gracefully and eat moreresources than normal and/or leave locks on memory, disk, resources, etc. and never release them.

Thread Safety testing on home-grown components can be done with tools like http://webtool.rte.microsoft.com. Thread Safety issuesare more likely to be discovered on multiprocessor machines and that it's vital to stress test components on MP machines to ensurethread safety.

WinInet - Not Thread SafeBasically this a serious limitation in current ASP. I recommend finding vendors who have seriously stress-tested (Soft-Artisanscomes to mind, Serverobjects.com perhaps) their HTTP components. It is almost guaranteed their implementations are not perfectand are serialized in some situations and not as fast as WinInet, but better than WinInet because slower and less complex internallyis better than a faster mess that does systemic damage to the whole process it runs in.

http://support.microsoft.com/support/kb/articles/Q188/9/55.ASPexplains how it could be used in ASP with light load.

http://support.microsoft.com/support/kb/articles/Q183/1/10.ASPhttp://support.microsoft.com/support/kb/articles/Q238/4/25.ASPexplains about Thread-Safe issues.

Other articles can be found by searching forkbWinInet (kbASP can be added to qualify it)

Because XML core functionality is built on WinInet, I am convinced MS will have to replace/fix WinInet in 6-9 months but in themeantime 3rd party is our safest bet.

Page 201: [ebook] Learn ASP

http://support.microsoft.com/support/kb/articles/q237/9/06.asp

There are reasons to believe ASPHTTP from www.serverobjects.com may be thread-safe BUT I don't have any evidence they are orare not. ASP Tear from http://www.alphasierrapapa.com/ComponentCenter/ is built on WinInet so shares its limitations.

Dictionaries - Threading Problems in App or Session VarsThe scripting dictionary is useful but if used at session or application scope can be slow and prohibit scalability in terms ofserialization and resource issues.

A FREE replacement interface compatible component can be found at:http://www.caprockconsulting.com/comsoftware.htm

http://msdn.microsoft.com/workshop/management/planning/msdnchronicles2.aspexplains how Microsoft had difficulty with scalability at session scope on their site.

http://msdn.microsoft.com/library/techart/d4cache.htmdemonstrates a useful page caching technique.

http://support.microsoft.com/support/kb/articles/Q194/8/03.ASPdiscusses using it as application scope object.A WinNT Option Pack 4 Dictionary Glitch

This is only a problem with the original Windows Option Pack. It's fixed in later service packs and Win2K and it's fixedin everything that installs more recent script engines.

Also an important note for people who have installed WinNT Option Pack 4 to run ASP*: /iishelp/iis/htm/core/iisread.htm

The Scripting.Dictionary object is erroneously marked as Both-threaded. It should be marked as Apartment-threaded. To changethis, use the Registry Editor to open the following registry key:HKEY_CLASSES_ROOT\ CLSID \{EE09B103-97E0-11CF-978F-00A02463E06F} \InprocServer32

Change the named value for ThreadingModel to Apartment. If you use the Dictionary object at Application scope without making thischange, corruption of data may occur.

http://www.learnASP.com/learn/roundrobin.asp by Charles M. Carroll Page 189

Server Code Execution Pattern by Charles CarrollA common expression you will hear when shifting paradigms (Flat Earth to Round Earth, Cold-Blooded to Warm Blooded Dinosaurs,Traditional Applications to Web Apps) is that everything you know is wrong. Great.... My next question is "What is the right answerin this environment?". Often they have only learned to get rid of the wrong tactics, but are not so fluent in the new tactics. Here wewill explain the correct things to do.

Page 202: [ebook] Learn ASP

Round-Robin Code ExecutionScripts on a webserver run round-robin. If a script say x.asp is run by 100 people and 50 people are running y.asp then the servermay be running:

Person1 x.asp lines 1-3Person2 x.asp lines 1-3Person1 x.asp lines 4-20Person3 x.asp lines 1-3Person4 x.asp lines 1-3Person2 x.asp lines 4-10Person1 y.asp lines 1-5Person3 x.asp lines 4-6etc.

So if your process opens recordsets a couple of lines before manipulating them this could lead to more open recordsets for the totalwebserver than you think.

<%rs1.openrs2.openrs3.openrs4.open...process rs1...process rs2...process rs3...process rs4rs1.closers2.closers3.closers4.close%>

It is certainly more wasteful than

...rs1.openprocess rs1rs1.close...rs2.open...process rs2rs2.close

rs3.open...process rs3rs4.close

rs4.open..process rs4rs4.close

mostly because of the round-robin effect.

This is one of the many reason Getrows and GetString, can be so durn fast ala:http://www.learnasp.com/learn/dbtablegetrows.asphttp://www.learnasp.com/learn/dbtablegetstring.asp

This is also why disconnected recordets can help an application perform better see:http://www.learnasp.com/learn/dbtabledisconnected.asp

Page 203: [ebook] Learn ASP

http://www.learnASP.com/learn/whybuffer.asp by Charles M. Carroll Page 190

Buffer That Output by Charles Carroll

In my recent advanced class we recently confirmed my fanatical belief in<%response.buffer=true%>and cautious <%response.flush%>something I hammer into every Intro student I teach every day of my class.

We did dozens of millisecond speed tests ala:http://www.learnasp.com/learn/speedtimer.aspreading 500 database records. Every change (Getrows or Getstring, One gulp, or 50 rows at a time, named or numbered fields) wastimed. Many of these suboptimizations reduced a 4 second task to 2 seconds. But the buffer strick got it down to 3/10 of a second!!!!Why?????

Lets tell the waiter story....

A waiter comes to your table in a busy restaurant. There are 5 at your table. He asks what drink person #1 wants and THEN hops toa different table and lets them order 1 drink and then hops to a different table and asks 1 person what their main course is and then adifferent table to ask what dessert another person wants. Then he comes back to your table and asks person #2 what drink theywant. Then hops all over again.

This story is your webserver with <%response.buffer=false%> (the default in IIS4 and IIS3). Though it might seem slower to theadjacent table for him to finish your order, overall it is faster for him to do one at a time.

Also if a script is <%response.buffer=false%>the number of gulps it takes to move 10k is determined by the browser and server in a chaotic very hard to determine fashion...5 gulps of 2k10 gulps of 1k3 gulps of 3k + 1k gulpIt is not efficient.

But if a script is <%response.buffer=true%>==> 1 gulp of 10k <==If 300 people ask for that script, 300 transfers,not 301...3000 transfers depending on many factors.

BUT, lets say you have a page like this:<%response.buffer=true%>... 1k of HTML ...... 20k graphic ...... 45k background sound ...... 4k of HTML ...

Some facts:- The page will serve quicker if many people hit the site. Go back to waiter analogy. 69k in 1 gulp x a couple hundred users is mucheasier than a couple hundred fragmented gulps.

Now the sane man compromises:

<%response.buffer=true%>... 1k of HTML and/or ASP ...

Page 204: [ebook] Learn ASP

<%response.flush%>... 20k graphic ...<response.flush%>... 45k background sound ...... 4k of HTML and/or ASP ...

Now:The user sees some output at the browser for every upon each flush.●

The whole page serves in 3 controlled gulps NO more chaos.●

Control. Not anarchy.●

I once had an overloaded 100% CPU server. I changed registry so all pages were buffer=true. The server then oscillated instead ofstaying pegged at 100%. Proof incarnate. Users were much happier. No money spent no code changes.

http://www.learnASP.com/learn/whygetrows.asp by Charles M. Carroll Page 191

GetRows or GetString... Don't retrieve data any other way!

http://www.learnasp.com/learn/dbtablegetrows.aspshows how to retrieve data fast but doesn't discuss why.

If your data formatting is simple:http://www.learnasp.com/learn/dbtablegetstring.aspcan accomplish even faster results.

Most people write database retrieval code like his:

<%Open DatabaseDo UNTIL eof city=rs("city") st=rs("state") zip=rs("zip") rs.movenext ... process and format data ....LOOPClose database%>

If there are 700 records for example, we have 2,100 database read requests over the wire. Lots of round-trips. Actually I am fudginga little here.... It actually will transfer the data in chunk sizes defined by rstemp.cachesize -- setting it or reading it will determine howmany gulps it is reading many records in. A cachesize for example of 50 would reduce the previous examples trips to the backenddatabse to 14 since when you asked for the first record you got 50. Until the MOVENEXT triggers record 51-101 being retrieved.

A better alternative code approach:

<%Open Databasemyarray=rstemp.GetRowsrstemp.closeset rstemp=nothing

Page 205: [ebook] Learn ASP

close databasemaxcounter=ubound(myarray)For counter=0 to maxcounter city=myarray(counter,1) st=myarray(counter,2) zip=myarray(counter,3)... process/format data ...NEXT%>

One transfer for seven-hundred records. We can close Rs and connection BEFORE formatting or calcing data. Imagine the backendgets to make one transfer. Very efficient.

The main reason that people do MOVENEXT and field at a time because that is what they learned. But let us say 300 people hit mymain page and it read a database; well if I do my reads without getrows or getstrings I may need a much more powerful CPU as thescripts spin, round-robin and save their context and store their data at a low-level to serve all those users simultaneously. On awebserver every millisecond you waste in one script may be multiplied by tens of thousands of users (Amazon.com, Cnn.com) so itbehooves traditional programmers to bite the bullet and throw away one at a time field reads and movenexts.

Notice how my Getrows example can close RS and CN before processing data. Lets say do LOOP and PROCESS/FORMAT in theloop. Well, if the reads take 1.5 seconds and the processing/formatting takes 2.5 seconds the database is open for 4 seconds. WithGetrows the same operation retrieve might take 3/4 second and the rs and cn are closed and back in the pool for others and theformatting is done while someone else uses the connection and whatever READ locks placed on the data rows/chunks aren'taffecting others while formatting is occurring.

Does it matter for small amounts of data?

YES!!!!!!!!

My site has SQLserver scripts that run like lightning. I once needed to fill a 9 item listbox from Access and got 90 sec script timeoutswith movenext. Getstring never timed out. So in a real production situation it makes weak databases feasible and of course reducesthe load on more industrial back-ends so maybe the SQLserver doesn't need as many indexes or RAM upgrades.

http://www.learnASP.com/learn/aspscalability.asp by Charles M. Carroll Page 192

aspscalability Listserver

JOIN, QUIT or Search ARCHIVES:http://www.asplists.com/asplists/aspscalability.asp

Send Listserver Questions [email protected]

Related LinksMicrosoft Enterprise White Paper @ http://www.microsoft.com/NTServer/ntserverenterprise/techdetails/overview/NTSEE.aspL5: A Self Learning Layer-5 Switch @ http://www.research.ibm.com/people/d/debanjan/papers/l5.pdfPerformance Of TCP Splcing For URL-Aware Redirection (requires membership) @ http://www.usenix.org/events/usits99/cohen.htmlWeb switches open e-comm doors at Nettaxi @ http://www.nwfusion.com/archive/1999/82163_12-06-1999.htmlServer Farms, Port Density, Load-Balancing Switch @ http://www.techweb.com/se/directlink.cgi?INW19991018S0017Enterprise Scaling Benchmarks @ http://www.devx.com/upload/free/features/entdev/1999/08aug99/cs0899/cs0899.aspFitch & Mathers Intro @

Page 206: [ebook] Learn ASP

http://www.fmcorp.com/Radware - Excellent Cluster @ http://www.radware.comDevelopmentor Load Balancing @ http://www.develop.com/hp/ewald/lb/loadbalancing.htm-no name- @ http://www.level3.com-no name- @ http://www.timesten.comScalability Resource Kit @ http://www.microsoft.com/siteserver/commerce/DeployAdmin/ResKit.aspPure SSL acceleration @ http://www.ipivot.com/products/products-ca1000.htmlFaster SSL Acceleration, deals with AOL too @ http://www.ipivot.com/products/products-cd8000.htmlEndurance 400 @ http://www.marathontechnologies.com/productinfo/index.htmArrowPoint Mother Nature Profile @ http://www.arrowpoint.com/solutions/profiles/mother_nature.htmlCommerce Accelerator 1000, claims 50X faster SSL @ http://www.ipivot.comCisco's Local Director @ http://www.cisco.com/warp/public/cc/cisco/mkt/scale/locald/Cisco's Distributed Director, multiple data centers @ http://www.cisco.com/warp/public/cc/cisco/mkt/scale/distr/BIG IP by F5 @ http://www.bigIP.comInterview with Mother Nature Lead Engineer @ http://www.internetwk.com/story/INW19990416S0005RSW Load Balance Analyzer @ http://www.rswsoftware.com/products/eload.html

http://www.learnASP.com/learn/webcom.asp by Charles M. Carroll Page 193

Index Server via ADO (indexserver.asp) - Page 194 Commerce and ASP (commerce.asp) - Page 195 Server JavaScript: Resources (javascript.asp) - Page 196 Validation Resources (validationmore.asp) - Page 197 Listboxes: Linked Dynamically w/JavaScript (listdynamic.asp) - Page 198 Dynamic ListBox Online Examples (listdynamicmore.asp) - Page 199 Listboxes: Linked Dynamically from Database w/JavaScript (listdynamicdb.asp) - Page 200 Listboxes: Easy Choices by Bill Wilkinson (listdual.asp) - Page 201 Server Perlscript: Resources (perlscript.asp) - Page 202 Remote Scripting Simple Example (remotescripting.asp) - Page 203 Remote Scripting Microsoft Example (remotescriptingms.asp) - Page 204 RDS: Remote Data Services Intro (rds.asp) - Page 205 RDS Resources by Carl Prothman (prothman.asp) - Page 206 ADSI: Active Directory Services Interface Intro (ADSI.asp) - Page 207

Page 207: [ebook] Learn ASP

MSMQ: Overview (MSMQ.asp) - Page 208 Usability: Resources (usability.asp) - Page 209 Usability: Safe Color Pallete (safecolors.asp) - Page 210

http://www.learnASP.com/learn/indexserver.asp by Charles M. Carroll Page 194

Index Server Access via ADO by Charles CarrollThe script below demonstrates how Index Server can be accessed via ADO to do simple searches.

1 <html><head>2 <title>iskeyword.asp</title>3 </head><body bgcolor="#FFFFFF">4 <Form action = "iskeywordRespond.asp" method="get">5 Choose The Word You Want to Search For::<p>6 Search Word: <Input NAME="Keyword" size ="30"><br>7 <Input type="submit" value="Find The Documents!">8 </form>9 </body></html>

The iskeywordrespond.asp looks like this:

1 <html><head>2 <title>iskeywordrespond.asp</title>3 </head>4 <body>5 <%6 Set objQuery = Server.CreateObject("ixsso.query")7 Set objUtil = Server.CreateObject("ixsso.util")8 my_keyword=request("keyword")9 10 objquery.catalog=""11 objQuery.Query = my_keyword12 objQuery.Columns = "Vpath, DocTitle, Filename, Characterization, Contents,DocKeyWords, Rank"13 objQuery.SortBy = "Rank [d]"14 objQuery.MaxRecords = 5015 objUtil.AddScopeToQuery objQuery, "/", "DEEP"16 17 linebr="<br>" & vbcrlf18 Set rstemp = objQuery.CreateRecordSet("nonsequential")19 DO UNTIL rstemp.eof20 FOR EACH key in rstemp.fields21 keyname=lcase(key.name)22 SELECT CASE keyname23 CASE "vpath"24 response.write "<a href='"25 response.write key26 response.write "'>" & key & "</a>" & linebr27 CASE ELSE28 response.write "<b>" & keyname & ":</b>" & linebr29 response.write key & linebr30 END SELECT31 NEXT32 response.write "<br><hr>"33 rstemp.movenext34 LOOP35 ' clean up36 rstemp.close37 set rstemp=nothing38 Set objQuery = nothing39 Set objUtil = nothing

Page 208: [ebook] Learn ASP

40 %>41 </body>42 </html>

http://www.learnASP.com/learn/commerce.asp by Charles M. Carroll Page 195

ASP CommerceActive Server Pages is commonly used to setup Ecommerce web sites.

We have a pretty thorough list of Ecommerce ASP components at:http://www.activeserverpages.com/components/ecommerce.asp

People having trouble with ASP can sign up for the [ecommerce] listserv:

ecommerce Listserver

JOIN, QUIT or Search ARCHIVES:http://www.asplists.com/asplists/commerce.asp

Send Listserver Questions [email protected]

Related LinksUPS shipping Interface @ http://www.ups.com/bussol/solutions/index.htmlMOD10 Credit Card Validation @ http://www.15seconds.com/issue/970101.htmHow do I setup https://,get a certificate @ http://www.learnasp.com/learn/FAQCommerceCertif.aspI want to process credit cards, where to start? @ http://www.learnasp.com/learn/FAQCommerceCharge.aspWhat ASP Components & Shopping Carts are available? @ http://www.learnasp.com/learn/FAQCommerceCarts.aspBanner Ad Rotation from Database @ http://www.4guysfromrolla.com/webtech/091299-1.shtmlInstall a SSL Certificate @ http://www.4guysfromrolla.com/webtech/062299-1.shtmlE-Commerce Sites built with MS ASP @ http://www.microsoft.com/dns/ecommerce/default.htm

http://www.learnASP.com/learn/javascript.asp by Charles M. Carroll Page 196

Jscript On the Server by Charles CarrollJscript is an alternative language to VBscript that can be used to build ASP pages. It is a language preferred by a small percentageof ASP programmers, but most new programmers use VBScript as it is easier.

If you have using Jscript to program your ASP sites, we run a listserv/newgroup called [Jscript] where that is the only topic allowedyou can join to get help.

Page 209: [ebook] Learn ASP

jscript Listserver

JOIN, QUIT or Search ARCHIVES:http://www.asplists.com/asplists/javascript.asp

Send Listserver Questions [email protected]

Related LinksWise ASP Jscript Column @ http://www.aspalliance.com/wskClosing Jscript Database Connections @ http://www.learnasp.com/learn/FAQJscriptCleanUp.aspJavaScript/Jscript Links @ http://www.learnasp.com/webbuilding/jscript.aspPhil Malones Jscript column @ http://www.aspalliance.com/philmaloneVB functions converted to Jscript @ http://www.4GuysFromRolla.com/webtech/vb2java.shtmlListBox from DB using Jscript @ http://www.aspmagazine.com/aspmagazine/issue10jscript.aspBook: Danny Goodmans Jscript Bible @ http://www.learnasp.com/books/goodmanjscript.aspBook: Oreilly Definitive JavaScript @ http://www.learnasp.com/books/jscriptdefinitive.aspListboxes Dynamically Linked w/Jscript @ http://www.learnasp.com/learn/listdynamic.aspListboxes Dynamically Linked w/Jscript + Database @ http://www.learnasp.com/learn/listdynamicdb.aspListboxes Dynamically Linked - Online Examples @ http://www.learnasp.com/learn/listdynamicmore.asp10 Open Window Techniques @ http://www.builder.com/Programming/JSWinTips/?tag=st.cn.sr1.dirClient Jscript and ASP Mixed @ http://www.clearviewdesign.com/NEWBIE.asp

http://www.learnASP.com/learn/validationmore.asp by Charles M. Carroll Page 197

Validation ResourcesValidation is handled in much more depth at other sites actually. One of my favorite sites www.4guysfromrolla.com has severalvalidation articles that are excellent:

Validate What? Using Regular Expressions to Validate Input http://www.4guysfromrolla.com/webtech/050399-2.shtml

Client-side Form Validation Using JavaScript (contains an extensive library of validation functions)http://www.4guysfromrolla.com/webtech/091998-1.shtml

The Importance of Server-Side Form Validation (explains why server-side form validation is important also)http://www.4guysfromrolla.com/webtech/120199-1.shtml

Email Validation Routines (this article presents code for three ways to validate email: using client-side scripting, using

Page 210: [ebook] Learn ASP

server-side scripting w/VBScript, and using server-side scripting w/JScript)http://www.4guysfromrolla.com/webtech/validateemail.shtml

AspToday.com has also written some great articles on validation.

Advanced Client-Side Form Validation by Steve Smithhttp://www.asptoday.com/articles/19990611.htm

Professional Form Validation by Jay McKinneyhttp://www.asptoday.com/articles/19990303.htm

Advanced Form Validation By Andrea Chiarellihttp://www.asptoday.com/articles/19990708.htm

A Library of regular Expressions for Form Validation By Alexander Nakhimovskhttp://www.asptoday.com/articles/19990629.htm

Persisting Form Control Values with ASP by Alex Homerhttp://www.asptoday.com/articles/19990331.htm

http://www.learnASP.com/learn/listdynamic.asp by Charles M. Carroll Page 198

Dynamic Client Dependent Lists/JScriptSometimes you need a Listbox that changes in response to a value of another listbox. The most effective way is to use client-sideJscript as illustrated below:

1 <HTML>2 <HEAD><TITLE>Dynamic Select Lists</Title></Head>3 <BODY OnLoad="BuildContacts(0);">4 <FORM Name="myForm">5 Salesperson:6 <SELECT Name="SalesNames" OnChange="BuildContacts(this.selectedIndex);">7 <OPTION Value="Jeff">Jeff8 <OPTION Value="Charles">Charles9 <OPTION Value="Rick">Rick10 <OPTION Value="Kevin">Kevin11 </Select>12 <BR><BR>13 Contacts:14 <!-- We want to define at least one option so that the select tag is created15 with the correct dimensions-->16 <SELECT Name="SalesContacts">17 <OPTION Value="">--------18 </Select>19 </Form>20 </Body>21 </Html>22 23 <SCRIPT Language="JavaScript"><!--24 25 //Build arrays for each person's contacts26 Contacts=new Array(4);27 Contacts[0]=new Array(3);28 Contacts[1]=new Array(2);29 Contacts[2]=new Array(5);30 Contacts[3]=new Array(4);31 32 //Charles33 Contacts[0][0]="Bill";34 Contacts[0][1]="Bob";35 Contacts[0][2]="Chuck";36

Page 211: [ebook] Learn ASP

37 //Jeff38 Contacts[1][0]="Vern";39 Contacts[1][1]="Matt";40 41 //Rick42 Contacts[2][0]="Diana";43 Contacts[2][1]="Dave";44 Contacts[2][2]="Todd";45 Contacts[2][3]="Sherry";46 Contacts[2][4]="Sharon";47 48 //Kevin49 Contacts[3][0]="Brian";50 Contacts[3][1]="Trisha";51 Contacts[3][2]="Greg";52 Contacts[3][3]="Troy";53 54 //Call this to build the Contact list for the specified Salesperson55 function BuildContacts(num)56 {57 //Select the first Contact58 document.myForm.SalesContacts.selectedIndex=0;59 60 //For every contact in the array for this person, add a new option61 for(ctr=0;ctr<Contacts[num].length;ctr++)62 {63 document.myForm.SalesContacts.options[ctr]=newOption(Contacts[num][ctr],Contacts[num][ctr]);64 }65 //Set the length of the select list66 document.myForm.SalesContacts.length=Contacts[num].length;67 }68 //--></Script>

http://www.learnASP.com/learn/listdynamicmore.asp by Charles M. Carroll Page 199

Dynamic Lists/JScript ResourcesThere are actually many approaches to creating dynamic lists with Jscript where a change in one listbox affects what options appearin the other listbox that are explained on various websites:

http://www.atgconsulting.com/doublelist.asp

http://www.atgconsulting.com/triplelist.asp

http://webreference.com/dev/menus/

http://www.amerirus.com/tutor.html

http://n2.neoshop.com/ shows how to use remote scripting

http://www.learnASP.com/learn/listdynamicdb.asp by Charles M. Carroll Page 200

Page 212: [ebook] Learn ASP

Dynamic Dependent Lists/JScriptgenerated from Relational Database

This example shows how to tie a relational database together to form dependent list boxes with Client Jscript. We have made ageneric subroutine to handle it, but be warned... The insides of it are one of the most complicated examples on this site.

1 <html><head>2 <title>listdynamicdb.asp</title>&3 <BODY OnLoad="StartMeUp();">4 <FORM Name="myForm">5 <%6 dim query7 myDSN="DSN=Student;uid=student;pwd=magic"8 mySQL= "SELECT Titles.Title, Publishers.Name "9 mySQL= mySQL & "FROM Publishers "10 mySQL= mySQL & "INNER JOIN Titles ON Publishers.PubID = Titles.PubID "11 call listmaker(myDSN, mySQL, _12 pubnames,"publist",booknames,"booklist",_13 pubevent,pubfun, "myForm")14 %>15 Publisher:16 <%response.write pubnames%><br>17 Books:18 <%response.write booknames%><br>19 </Form>20 </Body></Html>21 <SCRIPT Language="JavaScript"><!--22 function StartMeUp()23 {24 alert("All Books are Loaded Now. Thanks for waiting!");25 }26 <%=pubevent%>27 <%=pubfun%>28 --></Script>29 <!--#include file="lib_listdynamicdb.asp"-->

Here is the include file that defines the subroutine that does most of the work:

1 <%2 SUB listmaker(myDSN,query,byref list1, listname1, byref list2, listname2, byref myevent,byref myfun, myform)3 ' Build the INNER JOIN needed first4 set conntemp=server.createobject("adodb.connection")5 conntemp.open myDSN6 set rstemp=conntemp.execute(query)7 list1="<select name=""" & listname1 & """"8 list1=list1 & " OnChange=""Build" & key9 list1=list1 & "(this.selectedIndex);"">"10 list2="<select name=""" & listname2 & """>"11 loopcounter=012 lastvalue=rstemp(0)13 redim tempArray(1)14 thisgroupcount=015 howmanygroups=016 DO UNTIL rstemp.eof17 loopcounter=loopcounter+118 thisvalue=rstemp(0)19 thisvalue2=rstemp(1)20 if thisvalue<>lastvalue then21 tempSTR=key & "[" & howmanygroups & _22 "]=new Array(" & thisgroupcount & ");" & _23 vbcrlf & tempSTR24 thisgroupcount=025 howmanygroups=howmanygroups+126 end if27 if thisgroupcount=0 then28 tempSTR=tempSTR & "// " & thisvalue & vbcrlf

Page 213: [ebook] Learn ASP

29 list1 = list1 & "<option>" & thisvalue & "</option>" & vbcrlf30 end if31 tempSTR=TempSTR & key & "[" & howmanygroups & "][" & thisgroupcount & "]=""" &thisvalue2 & """;" & vbCRLF32 thisgroupcount=thisgroupcount+133 if howmanygroups=0 then34 list2 = list2 & "<option>" & thisvalue2 & "</option>" & vbcrlf35 end if36 lastvalue=thisvalue37 rstemp.movenext38 IF response.isclientconnected=false THEN39 EXIT DO40 END IF41 LOOP42 tempSTR=key & "[" & howmanygroups & _43 "]=new Array(" & thisgroupcount & ");" & _44 vbcrlf & tempSTR45 list1=list1 & "</select>"46 list2=list2 & "</select>"47 myevent=vbcrlf & key & "=new Array(" & howmanygroups+148 myevent=myevent & ");" & vbcrlf & tempSTR49 rstemp.close50 set rstemp=nothing51 conntemp.close52 set conntemp=nothing53 tempSTR =vbcrlf & "function Build" & Key & "(num)" & vbcrlf54 tempSTR =tempSTR & "{" & vbcrlf55 tempSTR =tempSTR & "document." & myForm & "."56 tempSTR =tempSTR & listname2 & ".selectedIndex=0;" & vbcrlf57 tempSTR =tempSTR & "for(ctr=0;ctr<" & key & "[num].length;ctr++)" & vbcrlf58 tempSTR =tempSTR & "{" & vbcrlf59 tempSTR =tempSTR & "document." & myform & "." & listname260 tempSTR =tempSTR & ".options[ctr]=new Option(" & key & "[num][ctr],"61 tempSTR =tempSTR & key & "[num][ctr]);" & vbcrlf62 tempSTR =tempSTR & "}" & vbcrlf63 tempSTR =tempSTR & "document." & myForm & "." & listname264 tempSTR =tempSTR & ".length=" & key & "[num].length;" & vbcrlf65 tempSTR =tempSTR & "}" & vbcrlf66 myfun=tempSTR67 END SUB68 %>

http://www.learnASP.com/learn/listdual.asp by Charles M. Carroll Page 201

Dual List Boxes by Bill Wilkinson ([email protected])

One nice thing to do is allow users to use one list box and another to transfer elements elegantly. It makes for a friendly interface.

1 2 <html>3 <body>4 5 <%6 Dim Available7 Dim Chosen8 If Session("BeenHere") <> "DoneThat" Then9 ' First time to this page!10 '11 ' In "real life" you'd probably populate the12 ' "initialItems" array from a database query,13 ' but for demo purposes we'll do it this way:14 '

Page 214: [ebook] Learn ASP

15 initialItems = Array("Apples","Oranges","Grapes","Berries","Kiwis")16 '17 Set Available = CreateObject("Scripting.Dictionary")18 For i = 0 To UBound( initialItems )19 Available.add initialItems( i ), "no" ' no means not chosen20 Next21 '22 ' save for next time here23 '24 Set Session("Choices") = Available25 '26 ' set the flag so we don't do this again27 '28 Session("BeenHere") = "DoneThat" 29 30 Else ' if BeenHere *DOES* equal "DoneThat"...31 32 '33 ' Been here before...process requests...34 '35 ' First, retrieve what we remembered from before...36 '37 Set Available = Session("Choices")38 '39 ' including any error message?40 '41 Message = Session("Message")42 '43 ' Then decide what to do44 '45 ' We might be here because of "Add" button,46 ' "Remove" button, or just because user hit47 ' "BACK" in the browser.48 '49 50 If Request.Form("AddFromAvailable") = "Add >>" Then 51 ' user asked to add some value(s)52 For i = 1 To Request.Form("ItemsAvailable").Count53 item = Request.Form("ItemsAvailable")(i)54 If item <> "#" Then55 Available(item) = "yes" ' now chosen!56 End If57 Next58 '59 End If60 If Request.Form("RemoveFromChosen") = "<< Remove" Then61 ' user asked to remove some previously chosen values62 For i = 1 To Request.Form("ItemsChosen").Count63 item = Request.Form("ItemsChosen")(i)64 If item <> "#" Then65 Available(item) = "no" ' no longer chosen66 End If67 Next68 '69 End If70 '71 ' save for next time here72 '73 Set Session("Choices") = Available74 75 End If76 77 ' miscellany:78 iCount = Available.count + 179 80 %>81

Page 215: [ebook] Learn ASP

82 <center>83 84 <font Size="+2">85 Dual List Query Demo: Page 186 </font>87 88 <%89 If Left( Message, 1 ) <> "#" Then90 %>91 <p>92 <font Size="+1"><em>93 <strong>Notice:</strong> <% = Message %>94 </em></font>95 <%96 End If97 %>98 99 <p>&nbsp;<p>&nbsp;<p>100 101 <form Name="ModifyLists" Action="listdual.asp" Method="POST">102 103 <table Border="2" CellSpacing="5" CellPadding="5">104 105 <tr>106 <td>Available Items</td>107 <td>&nbsp;</td>108 <td>Items to Look For</td>109 </tr>110 <tr>111 <td> 112 <select Name="ItemsAvailable" Multiple Size="<% = iCount %>" Width="150">113 <%114 aKeys = Available.keys115 For i = 0 To UBound( aKeys )116 item = aKeys( i )117 ' In this demo, we do NOT display already chosen118 ' items in the "available" Select list...but119 ' you could easily eliminate the following120 ' If...Then test and always display all available121 ' choices, if you preferred!122 '123 If Available( item ) = "no" Then124 %>125 <option Value="<% = item %>"><%= item %></option>126 <%127 End If128 Next129 '130 ' Value="#" option is just to give a minimum131 ' width to the Select list when it would132 ' otherwise be empty:133 %>134 <option Value="#">135 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;136 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;137 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;138 </option>139 </select>140 </td>141 142 <td>143 <table Border="0">144 <tr><td>&nbsp;</td></tr>145 <tr><td><input Type="Submit" Name="AddFromAvailable" Value="Add&gt;&gt;"></td></tr>146 <tr><td>&nbsp;</td></tr>147 <tr><td><input Type="Submit" Name="RemoveFromChosen" Value="&lt;&lt;

Page 216: [ebook] Learn ASP

Remove"></td></tr>148 <tr><td>&nbsp;</td></tr>149 </table>150 </td>151 152 <td>153 <select Name="ItemsChosen" Multiple Size="<% = iCount %>" Width="150">154 <%155 chosenCount = 0156 aKeys = Available.keys157 For i = 0 To UBound( aKeys )158 item = aKeys( i )159 '160 ' we only display chosen "yes" items here...161 '162 If Available( item ) = "yes" Then163 chosenCount = chosenCount + 1164 %>165 <option Value="<% = item %>"><%= item %></option>166 <%167 End If168 Next169 %>170 <option Value="#">171 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;172 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;173 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;174 </option>175 </select>176 </td>177 178 </tr>179 180 </table>181 182 </form>183 184 <form Name="ProcessQuery" Action="listdualrespond.asp" Method="POST">185 <center>186 <input Type="Submit" Name="Query" Value="Look in DB">187 </center>188 </form>189 190 <%191 ' Clean up by setting appropriate flags!192 '193 Session("ChosenCount") = chosenCount194 Session("Message") = "#none"195 %>196 197 </body>198 </html>199

Here is the responder script.1 2 <%3 '4 ' Protection: You can't come here until5 ' you have set up the session variable6 ' with the list of choices.7 '8 If Session("BeenHere") <> "DoneThat" Then9 Response.Redirect "DualList.asp"10 End If11 '12 ' We don't try to process queries until

Page 217: [ebook] Learn ASP

13 ' we have at least one item chosen...14 ' Naturally, you could change this to15 ' use some default instead!16 '17 If Session("ChosenCount") = 0 Then18 Session("Message") = "You must place at least one item in the right hand list beforeasking for a query."19 Response.Redirect "DualList.asp"20 End If21 %>22 23 <HTML>24 <BODY>25 26 <CENTER>27 <FONT Size="+2">28 Dual List Query Demo: Page 229 </FONT>30 <P>&nbsp;<P>31 32 This page is a dummy.<br>33 It just shows a list of the items chosen<br>34 on the prior page. In a real application<br>35 presumably these items would be processed<br>36 by some sort of database query.<P>37 38 <P><FONT Size="+1">The List:</FONT><P>39 <OL>40 41 <%42 Set Chosen = Session("Choices")43 aKeys = Chosen.keys44 For i = 0 To UBound( aKeys )45 item = aKeys( i )46 If Chosen( item ) = "yes" Then47 Response.Write "<LI>" & item & vbCrLf48 End If49 Next50 %>51 52 </OL>53 54 </CENTER>55 </BODY>56 </HTML>57 58

http://www.learnASP.com/learn/perlscript.asp by Charles M. Carroll Page 202

PerlScript on the Server by Charles CarrollPerlscript is an alternative server scripting language that is available for FREE from www.activestate.com

It is a language preferred by a small percentage of ASP programmers, but most use VBScript as it is easier.

If you have using Perlscript to program your ASP sites, we run a listserv/newgroup called [Perlscript] where that is the only topicallowed you can join to get help.

aspperlscript Listserver

Page 218: [ebook] Learn ASP

JOIN, QUIT or Search ARCHIVES:http://www.asplists.com/asplists/perlscript.asp

Send Listserver Questions [email protected]

Related LinksActiveState - Perl Suppliers @ http://www.activestate.comTobias Martinsson's Site @ http://www.perlscripters.comMatt's Perl Pages @ http://www.fastnetltd.ndirect.co.uk/Perl/Roth Consulting @ http://www.roth.net/O'Reilly's Perl Conference @ http://conference.oreilly.com/perl3/Perl Reference Sites & Newsgroups @ http://www.activestate.com/reference/related_sites.htm

http://www.learnASP.com/learn/remotescripting.asp by Charles M. Carroll Page 203

Remote Scripting Basics by Charles CarrollRemote Scripting is a magical, infinitely powerful Javascript client library that allows:

Javascript in an HTML or ASP page to call an ASP subroutine on the server to fetch data●

dynamic page construction via Javascript that could be for example fetching database data for a page without reloading thepage.

The main limitations are

the browser must be a 4.x browser●

It doesn't work on IE Mac (thanks to "Brad Rhoads" <[email protected]> for that tip)●

The current version requires 3 files: rs.asp, rs.htm and rsprox.class which can be downloaded fromhttp://msdn.microsoft.com/scripting on the server to work and their exact path must be set in the files (/learn/test/remote/ is the pathin these samples).

Our sample remote1.htm looks like this:

1 <HTML><HEAD><TITLE>remote1.htm</TITLE></HEAD>2 <BODY onload="handleRSExecute()">3 <script language="JavaScript" src="/learn/test/remote/rs.htm"></script>4 <script language="JavaScript">RSEnableRemoteScripting("/learn/test/remote/");</script>5 <h2>Simple Remote Scripting Example</h2>6 <form name="remote1">7 The Test <input type="text" name="test" value="none"><br>8 <SCRIPT LANGUAGE="javascript">9 var serverURL = "remote1.asp";10 11 function myCallBack(co)12 {13 // document.write (co.return_value);14 remote1.test.value=co.return_value;15 }

Page 219: [ebook] Learn ASP

16 17 function handleRSExecute()18 {19 var co = RSExecute(serverURL,"Method3");20 myCallBack(co);21 }22 </SCRIPT>23 </form>24 </HTML>

Our sample remote1.asp looks like this:

1 <%@ LANGUAGE=VBSCRIPT %>2 <% RSDispatch %>3 <!--#INCLUDE VIRTUAL="/learn/test/remote/rs.asp"-->4 <SCRIPT RUNAT=SERVER Language=javascript>5 function Description()6 {7 this.Method1 = Method1;8 this.Method2 = Method2;9 this.Method3 = Method3;10 }11 public_description = new Description();12 13 function Method1()14 {15 return "method1";16 }17 18 function Method2()19 {20 return "method2";21 }22 23 function Method3()24 {25 return "method3";26 }27 28 </script>29 30

http://www.learnASP.com/learn/remotescriptingms.asp by Charles M. Carroll Page 204

Remote Scripting MS SampleMicrosoft created an obtuse, complex to read Remote Scripting sample that demonstrates all it's capabilities we will reproduce herein running form:

remotems.htm looks like this:

1 <HTML>2 <HEAD>3 <TITLE>SIMPLE CLIENT</TITLE>4 </HEAD>5 6 <BODY>7 <script language="JavaScript" src="/learn/test/remote/rs.htm"></script>8 <script language="JavaScript">RSEnableRemoteScripting("/learn/test/remote/");</script>9 10 <h2>Simple Remote Scripting Example</h2>

Page 220: [ebook] Learn ASP

11 12 <br>13 The following buttons invoke remote scripting calls to an ASP server.14 <br>15 <form>16 <br><br><input type=button name=btnRSExecute value="RSExecute Method1"onclick="handleRSExecute()" style="width:250;height:25">17 <br><br><input type=button name=btnRSExecuteAsynch value="RSExecute Method1 (async)"onclick="handleRSExecuteAsync()" style="width:250;height:25">18 <br><br><input type=button name=btnRSGetASPObject value="aspObject = RSGetASPObject"onclick="handleRSGetAspObject()" style="width:250;height:25">19 <br><br><input type=button name=btnASPObject value="aspObject.Method2 (async)"onclick="handleAspObject()" style="width:250;height:25">20 <br><br><input type=button name=btnInvalidCall value="RSExecute Invalid Method3"onclick="handleInvalidCall()" style="width:250;height:25">21 22 <SCRIPT LANGUAGE="javascript">23 24 var serverURL = "remotems.asp";25 var aspObject;26 27 function myCallBack(co)28 {29 alert("CALLBACK\n\n" +30 "status = " + co.status + "\n\n" +31 "message = " + co.message + "\n\n" +32 "context = " + co.context + "\n\n" +33 "data = " + co.data + "\n\n" +34 "return_value = " + co.return_value);35 }36 37 function errorCallBack(co)38 {39 alert("ERROR_CALLBACK\n\n" +40 "status = " + co.status + "\n\n" +41 "message = " + co.message + "\n\n" +42 "context = " + co.context + "\n\n" +43 "data = " + co.data);44 }45 46 function handleRSExecute()47 {48 var co = RSExecute(serverURL,"Method1");49 myCallBack(co); 50 }51 52 function handleRSExecuteAsync()53 {54 RSExecute(serverURL,"Method1",myCallBack,"RSExecute");55 }56 57 function handleRSGetAspObject()58 {59 aspObject = RSGetASPObject(serverURL);60 var msg = "aspObject public_description\n";61 for (name in aspObject)62 msg += " " + name + "\n";63 alert(msg);64 }65 66 function handleAspObject()67 {68 aspObject.Method2(myCallBack,errorCallBack,"aspObject");69 }70 71 function handleInvalidCall()72 {

Page 221: [ebook] Learn ASP

73 var co = RSExecute(serverURL,"Method3",myCallBack,errorCallBack,"Invalid RSExecute");74 }75 76 </SCRIPT>77 78 </form>79 80 81 </BODY>82 </HTML>

remotems.asp looks like this:

1 <%@ LANGUAGE=VBSCRIPT %>2 <% RSDispatch %>3 4 <!--#INCLUDE VIRTUAL="/learn/test/remote/rs.asp"-->5 <SCRIPT RUNAT=SERVER Language=javascript>6 function Description()7 {8 this.Method1 = Method1;9 this.Method2 = Method2;10 }11 public_description = new Description();12 13 14 function Method1()15 {16 return new Date;17 }18 19 function Method2()20 {21 return new Array("blue","red","green","yellow","orange","purple","cyan","magenta");22 }23 24 </SCRIPT>25 26

http://www.learnASP.com/learn/rds.asp by Charles M. Carroll Page 205

Remote Data Services (RDS) by Charles CarrollRDS is limited to IE4 but it's power is astonishing as it transforms ADO into the same kind of technology used by Access and VisualBasic to connect databases to live forms but in a web context.

If you have integrating RDS with your ASP sites, we run a listserv/newgroup called [aspRDS] where that is the only topic allowedyou can join to get help.

asprds Listserver

JOIN, QUIT or Search ARCHIVES:http://www.asplists.com/asplists/rds.asp

Send Listserver Questions [email protected]

Related LinksRDS FAQ by Carl Prothman @

Page 222: [ebook] Learn ASP

http://www.able-consulting.com/RDS_Faq.htmRDS Tutorial @ http://msdn.microsoft.com/library/psdk/dasdk/mdat2n8s.htmRDS Overview @ http://msdn.microsoft.com/library/psdk/dasdk/mdov17z9.htmRDS Developer's Guide @ http://msdn.microsoft.com/library/psdk/dasdk/mdad5lpz.htmADO Sample Applications (includes RDS samples) @ http://msdn.microsoft.com/library/psdk/dasdk/mdas6c1f.htmADO Code Examples (includes RDS examples) @ http://msdn.microsoft.com/library/psdk/dasdk/mdae550z.htmCarl Prothmans RDS Book List @ http://www.able-consulting.com/books_ado.htmOn Creating a Recordset with RDS @ http://www.asptoday.com/articles/19990813.htmRDS Data Factory @ http://www.asptoday.com/articles/19990607.htmRDS & COM @ http://www.asptoday.com/articles/19990326.htmWeb-Based DB Apps using RDS & ASP @ http://www.15seconds.com/issue/980527.htmIntro to RDS @ http://www.aspwatch.com/c/e/e179B1FBB2B7011D3BBF800A0CC3BDC77.aspRemote Data Access & ADO @ http://www.asp101.com/ado/18350701.asp

http://www.learnASP.com/learn/prothman.asp by Charles M. Carroll Page 206

Carl Prothman's RDS Info

http://www.able-consulting.com/tech.htmhas all his technical articles which include

ADO Connection strings @http://www.able-consulting.com/ADO_Conn.htm

ADO FAQ @http://www.able-consulting.com/ADO_Faq.htm

RDS FAQ @ :http://www.able-consulting.com/RDS_Faq.htm

Konwledge Base Links @http://www.able-consulting.com/KB_MDAC.htm

Page 223: [ebook] Learn ASP

http://www.learnASP.com/learn/ADSI.asp by Charles M. Carroll Page 207

ADSI and ASP by Charles CarrollADSI stands for Active Directory Server Interfaceand it basically is a com object to allow ASP (or any language) to interogate and manipulate the types of objects that are managedby servers traditionally: domains, groups, users, passwords, directory listings. It is intended to be an integral part of NT5 and will alsobe extended to communicate with a variety of server architectures (Netscape Servers, Novell servers, LDAP servers) but it isavailable today in beta form for downloading. Here is a up-to-date list of where you can find out about this bleeding edge technology:

http://www.15seconds.com/focus/ADSI.htmhas everything about ADSI you would want to know and is running a well managed, low-noise list-serve devoted to ADSI.

http://www.netfokus.dk/vbadmincode/is a great source for FREE Visual Basic code to manage NT servers that easily adapts to ASP or can be used in a VB/ASPComponent.

ADSI listserv by 15seconds.comto: -> [email protected] (not subject) -> SUBSCRIBE ADSI Your Name

http://www.jfkdesigns.com/default.asp?go=ADSIhas some FREE ADSI scripts

http://www.learnASP.com/learn/MSMQ.asp by Charles M. Carroll Page 208

MSMQ -- Microsoft Message Que Overview by Charles CarrollMicrosoft Message Que is a programming tool that simplifies building client-server applications that can be robust and reliable evenwhen all the components of the architecture are not functioning perfectly 24 x 7. If your code currently requests that another server(be it the database back end or other services) perform a task and that server is down or overloaded, it is imperative that the requestbe eventually serviced or be able to continue without catastrophically failing. It should be able to send a request, and then await ananswer, as opposed to request immediate fullfillment -- something that cannot be accomodated if the service being requested istemporaily unavailable.

Traditional ApproachClient => send request => Server => send result => Client

The traditional approach fails catastrophically if the server is down or the client is down at the instance the communication occurs.And if either fails and restarts, the results are usually not coded for and the task is left inderminately resolved.

MSMQ ApproachClient => send request through MSMQClient => check results through MSMQ

Server => check for requests through MSMQServer => send results through MSMQ

In the MSMQ Approach, whether each side is up or down does not affect the other, though it may introduce delays. There is nodirect communication.

http://www.learnASP.com/learn/usability.asp by Charles M. Carroll Page 209

Page 224: [ebook] Learn ASP

Usability Issues by Charles CarrollUsability is critical when making a sucessfull website. According to Web Guru, Jakob Neilsen, only 10% of the web sites achieve highusability. So people flock to those and spend little time at the 90% that do not.

Jakob Neilsen's site is a treasure trove of usability information at:http://www.useit.com/

Alan Cooper was my favorite guru for building Desktop Applications and much of his wisdom becomes relevant if someone is usingrich client technologies like browser scripting, dynamic HTML, etc. His website can be found at:http://www.cooper.com

http://www.learnASP.com/learn/safecolors.asp by Charles M. Carroll Page 210

Safe Colors by Charles Carroll

The script below demonstrates two things:

how easy it is to mix Jscript and VBscript in the same file●

samples of web safe colors. These colors will appear the same on almost everybody's browser. Other colors may appeardramatically different from browser to browser.

1 <html><head>2 <title>websafe.asp</title>&3 <body>4 <%5 spacer="&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"6 response.write "<strong><font size='2'><table border=1>"7 for counter=1 to 68 safecolor1=websafe(counter)9 for counter2=1 to 610 safecolor2=websafe(counter2)11 for counter3= 1 to 612 safecolor3=websafe(counter3)13 hexcolor=convertToHex(safecolor1,safecolor2,safecolor3)14 response.write "<tr><td>" & hexcolor & "</td>"15 response.write "<td bgcolor='" & hexcolor & "'>"16 response.write "Black Text</td>"17 response.write "<td bgcolor='" & hexcolor & "'>" & spacer & "</td>"18 response.write "<td bgcolor='" & hexcolor & "'><font color='white'>"19 response.write "White Text</td>"20 response.write "<td bgcolor='" & white & "'><font color='" & hexcolor & "'>"21 response.write "Colored Text</font></td></tr>"22 next23 next24 next25 response.write "</strong></font></table>"26 %>27 </body></html>28 <%29 function websafe(mynumber)30 SELECT CASE mynumber31 CASE 132 websafe=033 CASE 234 websafe=5135 CASE 336 websafe=10237 CASE 438 websafe=15339 CASE 5

Page 225: [ebook] Learn ASP

40 websafe=20441 CASE 642 websafe=255 43 END SELECT44 end function45 %>46 47 <script language=jscript runat=server>48 function convertToHex(R, G, B) {49 50 var n = B;51 n += G << 8;52 n += R << 16;53 return convertBase(n);54 }55 56 // turns decimal integer into hexadecimal string57 function convertBase(num) {58 var i = 0; var j = 20;59 var str = "#";60 61 while(j >= 0) {62 i = (num >> j)%16;63 if(i >= 10) {64 if(i == 10) str += "A";65 else if(i == 11) str += "B";66 else if(i == 12) str += "C";67 else if(i == 13) str += "D";68 else if(i == 14) str += "E";69 else str += "F";70 } else71 str += i;72 j -= 4;73 }74 75 return str;76 }77 </script>

http://www.learnASP.com/learn/research.asp by Charles M. Carroll Page 211

Must Buy Component Building Book (bookcomponents.asp) - Page 212 ASP101.com Scripts for your site (asp101.asp) - Page 213 4GuysFromRolla.com Tons of ASP Material (4guysfromrolla.asp) - Page 214 ASPToday.com from WROX (asptoday.asp) - Page 215

http://www.learnASP.com/learn/bookcomponents.asp by Charles M. Carroll Page 212

Page 226: [ebook] Learn ASP

Developing ASP Componentspublished by Oreillywritten by Shelly Powers

OUR SUMMARY:This is THE ASP Book of 1999. Lucid, detailed. Great for beginners, full of substance forexperts. Component building in 3 languages: C++, Java and Visual Basic. MicrosoftTransaction Server covered beautifully as well. Find out why Charles Carroll calls ShellyPowers the component goddess.

BUY IT http://bn.bfast.com/booklink/click?sourceid=10446528&ISBN=1565924460

INFO ONLINEhttp://www.oreilly.com/catalog/devaspcom/http://www.yasd.com

http://www.learnASP.com/learn/asp101.asp by Charles M. Carroll Page 213

ASP101.com: A Script Resource

A site with a lot of nice scripts is www.asp101.com. I will mention some of my favorite scripts here to provide you with a brief tour ofthe site. Look around, you may have totally different tastes; they have dozens of scripts I am not linking to which are quite clever.They also give away prizes as part of contests frequently there.

Calendar @http://www.asp101.com/samples/calendar.asp

Universal Database Viewer @http://www.asp101.com/samples/db_dsn.asp

Shopping Cart @http://www.asp101.com/samples/shopping.asp

Hangman implemented in ASP @http://www.asp101.com/samples/hangman.asp

http://www.learnASP.com/learn/4guysfromrolla.asp by Charles M. Carroll Page 214

4GuysfromRolla.com: Huge, In-depth ASP Articles

A site with some fairly in-depth material is www.4guysfromrolla.com.I will mention some of my favorite articles there that cover topicswe do not touch on. Look around, you may have totally different tastes; they have dozens of scripts I am not linking to which arequite clever. They also give away prizes as part of contests frequently there.

THIS SITE IS HUGE. YOU COULD SPEND WEEKS THERE!!!

Page 227: [ebook] Learn ASP

Master Article Index @http://www.4guysfromrolla.com/webtech/index_asp.shtml

CDO Emails with ASP @http://www.4guysfromrolla.com/webtech/112298-1.shtml

VBScript to JavaScript Function Index @http://www.4guysfromrolla.com/webtech/vb2java.shtml

A VBScrip implementation of QuickSort @http://4guysfromrolla.com/webtech/012799-2.shtml

http://www.learnASP.com/learn/asptoday.asp by Charles M. Carroll Page 215

ASPToday.com - Free Online ASP Magazine by WROX

A site that is new and well, pretty deep is the WROX site www.ASPToday.com. Basically they pour some of the profits from their bestselling ASP books into paying ASP writers to write some fairly in-depth articles.

I will link to some of my favorite articles to give you a feel for the best articles on the site.

Displaying Graphics from a Database @http://www.asptoday.com/default.asp?art=19990524.htm

Scaling VB COM with MTS @http://www.asptoday.com/default.asp?art=19990422.htm

Buffering, Proxies, Objects Moved Messages @http://www.asptoday.com/default.asp?art=19990218.htm

Creating an Editable Grid @http://www.asptoday.com/default.asp?art=19990312.htm

http://www.learnASP.com/learn/advice.asp by Charles M. Carroll Page 216

advice: Cache No More by Phil Paxton (cachenomore.asp) - Page 217 advice:Option Explicit (explicit.asp) - Page 218 advice: Encode with Redirects (encode.asp) - Page 219 advice: Write Your SQL (sqlwrite.asp) - Page 220 advice: Named constants for ADO are better (namedconstants.asp) - Page 221 advice: Clean Up Your Room, I mean Objects (cleanup.asp) - Page 222 advice: Server.MapPath is Good (pathmap.asp) - Page 223 advice: Just Say No to Session COM objects (nosessionobjects.asp) - Page 224 advice: Don't Read COM Properties Twice (propertyexpense.asp) - Page 225 advice: Secure Code and Data (securecode.asp) - Page 226 advice: Encaspulate Code! (encapsulate.asp) - Page 227 advice: CASE reads better than IF (caseisbetter.asp) - Page 228 advice: Error Trapping Strategies (errorstrategies.asp) - Page 229

Page 228: [ebook] Learn ASP

advice: Error Trapping Secrets (errorsecrets.asp) - Page 230 advice: You Should... (shoulds.asp) - Page 231

http://www.learnASP.com/learn/cachenomore.asp by Charles M. Carroll Page 217

Cache No More by Phil Paxton ([email protected])Here are the things dealing with the issue of caching in ASP:

1. Response.Expires = 02. Response.ExpiresAbsolute = Now() - 13. Response.AddHeader "cache-control", "private"4. Response.AddHeader "pragma", "no-cache"5. Adding a "cachebuster" by creating a unique URL.

Notes:#1 is said to expire at 60 seconds, not 0. Also, Khin Zaw (from ActiveServerPages@ and ASPAdvanced@) has postedresearch from time spent with some IIS internals experts revealing this can be a very touchy parameter to rely upon andusually requires a rather "large" negative number or pedantically, that would be a very small number).

#2 (my own creation) says "expire this page 24 hours ago", allowing for time differences, rather than specify a static date.

#3, #4 from an MS KB article. The code is correct but there are some incorrect statements in the article itself.

n.b. some related KB articles include:(INFO: Controlling the Caching of Web Pages with IIS 4.0)(PRB: Browser Doesn't Show Most Recent Versions of htm/asp Files)(How to Use Pragma: No-cache with IIS and IE)

#5 my term, but not my technique. IE 5.0 can defeat #1-#4 used in conjunction but adding #5 will break it. I usually usesomething like "?NoCache=Rnd" after a statement. Bill Wilkinson (of Chili!Soft) has proposed an alternate of?NoCache=Server.URLEncode(Now())".

Another thing to remember: Netscape will continue to cache, even if you turn all caching off. This behavior persisted through4.5 PR1, PR2, and now in the released version of 4.5.

If you fear you might have to deal with caching later, you might want to build contingencies into your app as you go.Retrofitting #5 throughout even a medium-sized app would take a rather sizeable effort. You could retrofit #1-#4 (inclusive)rather quickly with a single pass through the application, but #5 takes a lot of extra effort. And to that end, I don't everResponse.Redirect anywhere in my code except sample code I post to the lists (then again, the only time I useResponse.Write is to the list because I rely on my Utilities-Form.inc library for Display() and HTML()). Everything isRedirect(NewURL) where the Redirect function looks like this:

Function Redirect( NewURL ) ' If Not IsEmpty( NewURL & "" ) Then Dim QuestionMark ' QuestionMark = Instr( NewURL, "?" ) ' If QuestionMark = 0 Then Response.Redirect NewURL & "?" & NoCacheURL() Response.End

Page 229: [ebook] Learn ASP

Else Response.Redirect NEWURL & "&" & NoCacheURL() Response.End End If End If ' End Function

and NoCacheURL looks like this:

Function NoCacheURL() ' On Error Resume Next ' Randomize ' Randomize not needed if you use Now() ' NoCacheURL = "NoCache=" & Server.URLEncode(rnd) ' ' or NoCacheURL = "NoCache=" & Server.URLEncode(Now()) ' per Bill ' End Function

I've learned that I approach things a little differently (sometimes better, sometimes worse, but overall, just differently) andhave gotten used to a bunch of tiny little routines scattered throughout my app with a bunch of #include statements. Some ofthis might seem like overkill, but you have to understand just how pervasive and frustrating caching can be in a scripted appenvironment. Caching is great for pure HTML because it reduces server overhead. But if you do much scripting againstdatabases, or time-based functions, it's not unusual to see rather bizarre things happen. Shopping cart applications willsuddenly "lose" items already purchased; they'll "regain" items previously deleted. Starting a new order with an assigned"OrderID" (to use as a temporary confirmation number for the sake of the user) will suddenly show items from a previousorder. It can be maddening the first time you have to deal with it. And if you don't deal with it head-on in your code, yourusers may be dealing with it for you -- you can turn caching off for your application in IIS [itself], but what if you are behinda firewall or proxy server which does caching for you? Or, if the user has caching turned on in their browser or they could bebehind one or more layers of firewalls or proxy servers, all of which have been sold under the premise of delivering betterperformance through caching? Unless and until you can control every layer of access to your app, telling your server not tocache isn't a solution because requests may not be making it back to said server.

End-user magazines continue to extol the benefits of caching, demonstrating they are still thinking of an HTML-only world.Scripting and caching are rarely synergistic and are almost always like oil & water: both have a purpose, but rarely together.

You're almost always better off to just turn all caching off and take the performance hit than to try & retrofit all of this into anapp which "mysteriously" begins misbehaving.

Should: Ought to, but not necessarily will.

http://www.learnASP.com/learn/explicit.asp by Charles M. Carroll Page 218

ASP Commandment #1: Use Option Explicituse Option Explicit when writing VBScript.<% option explicit%>goes at the top of the script!

Page 230: [ebook] Learn ASP

http://www.learnASP.com/learn/encode.asp by Charles M. Carroll Page 219

ASP Commandment #2: Encode!When dynamically building a URL with your code, the URL may work fine in IE but Netscape presents this ERROR message:

HTTP Error 400

400 Bad Request

Due to malformed syntax, the request could not be understood by the server.The client should not repeat the request without modifications.

Use Server.URLEncode when passing parameters so that characters within the data are encoded properly (spaces replaced with"+", etc.).

This is bad:<%URL="wherever.asp"part1="fname=Joe"part2="&company=Bait Shop"part3="&fax=703-277-2233"response.redirect URL & "?" & part1 & part2 & part3%>

This is good:<%URL="wherever.asp"part1="fname=" & server.URLencode("Joe")part2="&company=" & server.URLencode("Bait Shop")part3="&fax=" & server.URLencode("703-277-2233")response.redirect URL & "?" & part1 & part2 & part3%>

http://www.learnASP.com/learn/sqlwrite.asp by Charles M. Carroll Page 220

ASP Commandment #3: write that SQLCommand #3: use a string variable to build the SQL string so it can be displayed and debugged if there is a problem.

This is bad:set rstemp=conntemp.execute("select * from publishers where state='NY')

This is good:mySQL= ""select * "mySQL= mySQL & "from publishers"mySQL= mySQL & "where state='NY'"response.write mySQLset rstemp=conntemp.execute(mySQL)rstemp.closeset rstemp=nothing

http://www.learnASP.com/learn/namedconstants.asp by Charles M. Carroll Page 221

Page 231: [ebook] Learn ASP

ASP Commandment #4: Named ConstantsCommand #4: use named constants from adovbs.inc instead of numeric constants. (granted, adovbs.inc isn't complete and requiressome add'l tweaking from time-to-time)

This is good:<!--#INCLUDE VIRTUAL="/ADOVBS.INC" --><%connectme="DSN=Student;uid=student;pwd=magic"sqltemp="select * from publishers where state='NY'"set rstemp=Server.CreateObject("adodb.Recordset")rstemp.open sqltemp, connectme, adopenstaticresponse.write rstemp.recordcount & " records in<br>" & sqltemprstemp.closeset rstemp=nothing%>

This is bad:<%connectme="DSN=Student;uid=student;pwd=magic"sqltemp="select * from publishers where state='NY'"set rstemp=Server.CreateObject("adodb.Recordset")rstemp.open sqltemp, connectme, 3response.write rstemp.recordcount & " records in<br>" & sqltemprstemp.closeset rstemp=nothing%>

http://www.learnASP.com/learn/cleanup.asp by Charles M. Carroll Page 222

ASP Commandment #5: Clean Up ObjectsClose each object when done with them. This frees up the "handle" to the resource. This applies to objects that support closemethods, especially connections and recordsets!

Set each object variable to nothing when done with it.this frees up the memory devoted to the resource and/or returns it to the resource pool.

The code sample below makes a list box from a database. Notice the close and set to nothing at the end of the code. NEVER forgetit in your code.

1 <html><head>2 <TITLE>dblist.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <%5 myDSN="DSN=Student;uid=student;pwd=magic"6 mySQL="select author from authors where AU_ID<100"7 8 ' displays a database field as a listbox9 set conntemp=server.createobject("adodb.connection")10 conntemp.open myDSN11 set rstemp=conntemp.execute(mySQL)12 if rstemp.eof then13 response.write "no data for<br>"14 response.write mySQL15 conntemp.close16 set conntemp=nothing17 response.end 18 end if19 20 %>21 <form action="dblistrespond.asp" method="post">

Page 232: [ebook] Learn ASP

22 <Select name="authorname">23 <%24 ' Now lets grab all the data25 do until rstemp.eof %>26 <option> <%=RStemp(0)%> </option>27 <%28 rstemp.movenext29 loop30 31 rstemp.close32 set rstemp=nothing33 conntemp.close34 set conntemp=nothing35 %>36 <input type="submit" value="Choose Author">37 </Select></form>38 </body></html>

http://www.learnASP.com/learn/pathmap.asp by Charles M. Carroll Page 223

ASP Commandment #6: Use Server.MapPathUse Server.MapPath() whenever referring to files stored locally on the server instead of a static path (except in the rare occasionswhere it's necessary).

This is bad:<%whichfile="D:\inetpub\wwwroot\whatever\junk.txt"set fs = CreateObject("Scripting.FileSystemObject")Set thisfile = fs.OpenTextFile(whichfile, 1, False)tempSTR=thisfile.readallresponse.write tempSTRthisfile.Closeset thisfile=nothingset fs=nothing%>

This is good:<%whichfile=server.mappath("\whatever\junk.txt")set fs = CreateObject("Scripting.FileSystemObject")Set thisfile = fs.OpenTextFile(whichfile, 1, False)tempSTR=thisfile.readallresponse.write tempSTRthisfile.Closeset thisfile=nothingset fs=nothing%>

http://www.learnASP.com/learn/nosessionobjects.asp by Charles M. Carroll Page 224

ASP Commandment #7: No COM objects in SessionsDo not store any COM objects in a Session() variable because of memory waste and threading issues. Do not store any COMobjects in an Application() variable unless the reasons are excellent because of concurrent access issues. For even more details:

Read up on thread locking, Serialization and such at●

Page 233: [ebook] Learn ASP

/advice/dbsessionapp.asp Session and application level data basics at/learn/globalproblems.asp.

STA and Memory Model Issues at/learn/buildvbthreads.asp

Memory Waste ScenariosLet us examine a typical usage pattern:

+ 100 people hit your site for a couple of pages and leave+ 100 new people arrive in a couple of minutes+ 200 people arrive after that and leave within a couple of minutes and then+ 50 people arriveScenario 1:object in session_onstart

Scenario 2: objects created/destroyed on a page perpage basis

End Result:450 sessions/objects in memorywith 50 people on your site. And dozens or hundred ofthreads that can't be reclaimed for a while

End Result:50 objects in memorywith 50 people on your site. No unused threads mustbe kept in memory.

Connection pooling or MTX object caching may actually result in more than 50 objects in memory in the Scenario 2 and more than450 objects in Scenario 1 for better performance. Basically set object=nothing may be ignored and the object placed in an "instantready" pool to be used by the next server.createobject request.

http://www.learnASP.com/learn/propertyexpense.asp by Charles M. Carroll Page 225

ASP Commandment #8: Property Reads are ExpensiveDo not fetch any values obtained via ASP/COM more than once. Store them and use the stored values. It speeds up codesignificantly. Typical examples people forget this include recordset values, request.form and request.querystring.

This is bad (3 COM calls where 1 would accomplish same task):<%if rstemp("city")="Dallas" then ' do somethingend ifif rstemp("city")="New York" then ' do somethingend ifif rstemp("city")="New Orleans" then ' do somethingend if%>

This is good:<%thecity=rstemp("city")if thecity="Dallas" then ' do somethingend ifif thecity="New York" then ' do somethingend ifif thecity="New Orleans" then ' do somethingend if%>

Page 234: [ebook] Learn ASP

http://www.learnASP.com/learn/securecode.asp by Charles M. Carroll Page 226

Secure Your Code and DataIn addition to coding, you need to consider security from an ASP coders point of view.This means:

NO .inc ExtensionsDo not name your include files with a .inc extensionname them with a .asp extension.

Be careful where you place .mdb filesDo not place .mdb files inside your web structure where they can be downloaded. Place them in a directory on the machine but notwithin the web site folder structure. Then just establish a system DSN to it.

We have a directory devoted to security links at www.activeserverpages.com/security and actually run a listserv devoted to ASPSecurity Topics:

aspSecurity Listserver

JOIN, QUIT or Search ARCHIVES:http://www.asplists.com/asplists/securecode.asp

Send Listserver Questions [email protected]

Related LinksSecurity Issues from www.learnasp.com @ http://www.learnasp.com/security

http://www.learnASP.com/learn/encapsulate.asp by Charles M. Carroll Page 227

Encapsulate Your Code in Reusable LibrariesYou should create many subroutines and functions and instead of placing them in each page just use the include facility to accessthem. The following scripts are very compact because they call SUBroutines that the include files contain.

Here someone has encapsulated HTML coding into a high level ASP call:

1 <!--#include virtual="/learn/test/lib_htmlstuff.asp"-->2 <html><head>3 <title>libhtmldemo.asp by Phil Paxton</title>&4 <body>5 <form action="lib_htmldemorespond.asp">6 <%7 Call Form_TextBox("first name","Fname",20,20,"")8 response.write "<br>"9 Call Form_TextBox("Last Name","Lname",20,20,"")10 response.write "<br>"11 Call Form_TextBox("City","cy",20,20,"")12 response.write "<br>"13 Call Form_TextBox("State","st",2,2,"")14 response.write "<br>"15 Call Form_TextBox("Zip Code","zp",10,10,"")16 response.write "<br>"17 Call Form_SubmitButton("Register Me","register")18 %>

Page 235: [ebook] Learn ASP

19 </form>20 </body>21 </html>

Here displaying a listbox from a database has been simplified by a subroutine:

1 <html><head>2 <TITLE>subdblist.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <form>5 <%6 theDSN="DSN=student;uid=student;pwd=magic"7 call query2list("select distinct city from publishers","cy",theDSN)8 call query2list("select distinct state from publishers","st",theDSN)9 call query2list("select distinct zip from publishers","zp",theDSN)10 %>11 </form>12 <!--#include virtual="/learn/test/subdblist.inc"-->13 </body></html>

The library files/includes that make all these tasks one step are detailed at:/learn/qualitycode.asp

http://www.learnASP.com/learn/caseisbetter.asp by Charles M. Carroll Page 228

Case is better than IF (for readabilty)Here are two code samples. One is built using IFs and the other with CASE. I think these drive the point home that readability,speed and code flow is clearer with CASEs.

This is the IF example

1 <html><head>2 <title>suffixif.asp</title>3 </head>4 5 <body>6 <%7 ' ok test it8 For i = 1 TO 10009 n = i10 Response.Write n & AddSuffix(n) & ".<BR>"11 NEXT12 %>13 14 </body>15 </html>16 <%17 FUNCTION AddSuffix(num)18 temp=right(num,1)19 If temp= 1 Then20 AddSuffix = AddSuffix & "st"21 ElseIf temp = 2 Then22 AddSuffix = AddSuffix & "nd"23 ElseIf temp = 3 Then24 AddSuffix = AddSuffix & "rd"25 ElseIf temp<11 Then26 AddSuffix = AddSuffix & "th"27 End If28 END FUNCTION29 %>

This is the CASE example:

Page 236: [ebook] Learn ASP

1 <html><head>2 <title>suffixcase.asp by Dwaine Maltais [email protected]</title>3 </head>4 5 <body>6 <%7 ' ok test it8 FOR i = 1 TO 10009 n = i10 Response.Write AddSuffix(n) & "<br>"11 NEXT12 %>13 14 </body>15 </html>16 <%17 Function AddSuffix(num)18 numpart = RIGHT(num,1)19 SELECT CASE numpart20 CASE "1"21 IF InStr(num,"11") THEN22 num = num & "th"23 ELSE24 num = num & "st"25 END IF26 CASE "2"27 IF InStr(num,"12") THEN28 num = num & "th"29 ELSE30 num = num & "nd"31 END IF32 CASE "3"33 IF InStr(num,"13") THEN34 num = num & "th"35 ELSE36 num = num & "rd"37 END IF38 CASE "4"39 num = num & "th"40 CASE ELSE41 num = num & "th"42 END SELECT43 AddSuffix = num44 END FUNCTION45 %>

http://www.learnASP.com/learn/errorstrategies.asp by Charles M. Carroll Page 229

Error Trapping Strategies by Charles CarrollDRAFT - not ready yet!There are several ways to deal with errors. For example:

write errors to custom log●

write errors to IIS log●

email someone when a page error occurs●

place errors in a custom dictionary/collection●

We will provide code for each scenario and discuss the pros and cons of each approach.

Page 237: [ebook] Learn ASP

http://www.learnASP.com/learn/errorsecrets.asp by Charles M. Carroll Page 230

Error Trapping Secrets by Charles CarrollDRAFT - Not Ready yetBlah, Blah, Blah.

http://www.learnASP.com/learn/shoulds.asp by Charles M. Carroll Page 231

ASP Commandments: ShouldsThou should:

specify all of the parameters for their ADO command, connection, and recordset objects so defaults don't rear their ugly headsand give thou an error when thou tries to do something which isn't permitted by a default (e.g. .AddNew after using defaults,creating a read-only recordset, and the inevitable resulting error).

make sure that ASP scripts that are dynamic in nature have caching turned off. Thou shalt find scripts and caching are like oiland water...they mix not well, except on salads. If caching isn't turned off by default, it should be possible to alter a singlevariable in each script file so caching can be switched on/off at will to avoid retrofitting scripts with the code required to breakcaching./learn/cachenomore.asp has up to date guidelines on how to disable script caching.

remember using .Execute to create an ADO recordset will result in a read-only recordset and thou can neither edit theserecords nor add new records.

Use the correct cursortype or a SQL count to determine how many records are in a table or query, instead of a counting loopor a movelast.see /learn/dbcount.asp for an example.

Should: Ought to, but not necessarily will.

http://www.learnASP.com/learn/more.asp by Charles M. Carroll Page 232

Text Files: Reading Them off Server (txtread.asp) - Page 233 Text Files: Writing Them on Server (txtwrite.asp) - Page 234 Text Files: Meyers-Briggs parsing #1 (mb1.asp) - Page 235 Text Files: Meyers-Briggs parsing #2 (mb2.asp) - Page 236 Text Files: Meyers-Briggs parsing #3 (mb3.asp) - Page 237 Content Linker: Prev/Next Page (cl.asp) - Page 238 Content Linker: Table of Contents (cl2.asp) - Page 239 Content Linker: Listbox of contents (cl3.asp) - Page 240 File Objects: Read Directory (fileobjects.asp) - Page 241 File Objects: Display Directory as Links/Graphics (fileobjects2.asp) - Page 242 File Objects: Read Disk Drive by Steven Harper (fileobjects3.asp) - Page 243 File Objects: Show Dir List by Tim Foster (fileobjects4.asp) - Page 244 Graphic Size Detector (graphicdetect.asp) - Page 245

Page 238: [ebook] Learn ASP

http://www.learnASP.com/learn/txtread.asp by Charles M. Carroll Page 233

Text File Reading1 <html><head>2 <TITLE>txtread.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <%5 whichfile=server.mappath("/aspheader.asp")6 7 Set fs = CreateObject("Scripting.FileSystemObject")8 Set thisfile = fs.OpenTextFile(whichfile, 1, False)9 10 counter=011 do while not thisfile.AtEndOfStream12 counter=counter+113 thisline=thisfile.readline14 response.write thisline & "<br>"15 loop16 17 thisfile.Close18 set thisfile=nothing19 set fs=nothing20 %>21 </body></html>

http://www.learnASP.com/learn/txtwrite.asp by Charles M. Carroll Page 234

Text File Writing by Charles CarrollThe following code snippets adds several lines to an ASCII file.

1 <html><head>2 <TITLE>txtwrite.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <%5 whichFN=server.mappath("/upload/tests/tempfile.txt")6 7 ' first, create the file out of thin air8 Set fstemp = server.CreateObject("Scripting.FileSystemObject")9 Set filetemp = fstemp.CreateTextFile(whichFN, true)10 ' true = file can be over-written if it exists11 ' false = file CANNOT be over-written if it exists12 13 filetemp.WriteLine("This is a brand new file!!!!")14 filetemp.writeblanklines(3)15 filetemp.WriteLine("This is the last line of the file we created!")16 filetemp.Close17 18 ' Now open it and add some lines19 forappending =820 set filetemp=fstemp.OpentextFile(whichFN, forappending)21 filetemp.writeline "a line we added later"22 filetemp.writeline "another line we added later..."23 filetemp.close24 25 set filetemp=nothing26 set fstemp=nothing

Page 239: [ebook] Learn ASP

27 28 If err.number=0 then29 response.write "File was appended sucessfully!"30 else31 response.write "VBScript Errors Occured!<br>"32 response.write "Error Number=#<b>" & err.number & "</b><br>"33 response.write "Error Desc. =<b>" & err.description & "</b><br>"34 response.write "Help Path =<b>" & err.helppath & "</b><br>"35 response.write "Native Error=<b>" & err.nativeerror & "</b><br>"36 response.write "Error Source =<b>" & err.source & "</b><br>"37 response.write "SQL State=#<b>" & err.sqlstate & "</b><br>"38 end if39 40 41 %>42 </body></html>

This code displays the file we created:1 <html><head>2 <TITLE>txtwritedisplay.asp</TITLE>3 </head><body bgcolor="#FFFFFF">4 <%5 whichname="tempfile.txt"6 whichdir=Server.Mappath ("/upload/tests/")7 whichFN=whichdir & whichname8 forreading=19 10 Set fs = CreateObject("Scripting.FileSystemObject")11 Set thisfile = fs.OpenTextFile(whichFN, forreading, False)12 counter=013 do while not thisfile.AtEndOfStream14 counter=counter+115 thisline=thisfile.readline16 response.write thisline & "<br>"17 loop18 thisfile.Close19 20 set thisfile=nothing21 set fs=nothing22 23 %>24 </body></html>

http://www.learnASP.com/learn/mb1.asp by Charles M. Carroll Page 235

Reading/Parsing an ASCII File by Charles CarrollLet us say you have an ASCII file of questions that you want to convert to HTML (listing below). The next page will show you thetypical parsing code used for such a task.

1 EI At a party do you - interact with many, including strangers / interact with a few, knownto you2 SN Are you more - realistic than speculative / speculative than realistic3 SN It is worse to - have your "head in the clouds" / be "in a rut"4 TF Are you more impressed by - principles / emotions5 TF Are you more drawn toward the - convincing / touching6 JP Do you prefer to work - to deadlines / just "whatever"7 JP Do you tend to choose - rather carefully / somewhat impulsively8 EI At parties do you - stay late, with increasing energy / leave early, with decreasedenergy9 SN Are you more attracted to - sensible people / imaginative people

Page 240: [ebook] Learn ASP

10 SN Are you more interested in - what is actual / what is possible11 TF In judging others are you more swayed by - laws than circumstances / circumstances thanlaws12 TF In approaching others is your inclination to be - objective / personal13 JP Are you more - punctual / leisurely14 JP Does it bother you more having things - incomplete / completed15 EI In your social groups do you - keep abreast of other's happenings / get behind on thenews16 SN In doing ordinary things are your more likely to - do it the usual way / do it your ownway17 SN Writers should - "say what they mean and mean what they say" / express things more by useof analogy18 TF Which appeals to you more - consistency of thought / harmonious human relationships19 TF Are you more comfortable in making - logical judgments / value judgmants20 JP Do you want things - settled and decided / unsettled and undecided21 JP Would you say you are more - serious and determined / easy-going22 EI In phoning do you - rarely question that it will all be said / rehearse what you'll say23 SN Facts - "speak for themselves" / illustrate principles24 SN Are visinaries - somewhat annoying / rather fascinating25 TF Are you more often - a cool-headed person / a warm-hearted person26 TF Is it worse to be - unjust / merciless27 JP Should one usually let events occur - by careful selection and choice / randomly and bychance28 JP Do you feel better about - having purchased / having the option to buy29 EI In company do you - initiate conversation / wait to be approached30 SN Common sense is - rarely questionable / frequently questionable31 SN Children often do not - make themselves useful enough / exercise their fantasy enough32 TF In making decisions do you feel more comfortable with - standards / feelings33 TF Are you more - firm than gentle / gentle than firm34 JP Which is more admirable - the ability to organize and be methodical / the ability toadapt and make do35 JP Do you put more value on the - definite / open-ended36 EI Does new and non routine interaction with others - stimulate and energize you / tax yourreserves37 SN Are you more frequently - a practical sort of person / a fanciful sort of person38 SN Are you more likely to - see how others are useful / see how others see39 TF Which is more satisfying - to discuss an issue thoroughly / to arrive at agreement on anissue40 TF Which rules you more - your head / your heart41 JP Are you more comfortable with work that is - contracted / done on a casual basis42 JP Do you tend to look for - the orderly / whatever turns up43 EI Do you prefer - many friends with brief contact / a few friends with more lengthy contact44 SN Do you go more by - facts / principles45 SN Are you more interested in -production and distribution / design and research46 TF Which is more of a compliment - "There is a very logical person." / "There is a verysentimental person."47 TF Do you value in yourself more that you are - unwavering / devoted48 JP Do you more often prefer the - final and unalterable statement / tentative andpreliminary statement49 JP Are you more comfortable - after a decision / before a decision50 EI Do you - speak easily and length with strangers / find little to say to strangers51 SN Are you more likely to trust your - experience / hunch52 SN Do you feel - more practical than ingenious / more ingenious than practical53 TF Which person is more to be complimented - one of clear reason / strong feeling54 TF Are you inclined more to be - fair minded / sysmpathetic55 JP Is it preferable mostly to -make sure things are arranged / just let things happen56 JP In relationships should most things to - renegotiable / random and circumstantial57 EI When the phone rings do you - hasten to get to it first / hope someone else will answer58 SN Do you prize more in yourself - a strong sense of reality / a vivid imagination59 SN Are you drawn more to - fundamentals / overtones60 TF Which seems the greater error - to be too passionate / to be too objective61 JP Do you see yourself as basically - the structured and scheduled / the unstructured andunscheduled62 JP Are you a person that is more - routinized than whimsical / whimsical than routinized63 EI Are you inclined to be - easy to approach / somewhat reserved64 SN In writings do you prefer - the more literal / the more figurative65 SN Is it harder for you to - identify with others / utilize others

Page 241: [ebook] Learn ASP

66 TF Which do you wish more for yourself - clarity of reason / strength of compassion67 TF Which is the greater fault - being indiscriminate / being critical68 EI Do you prefer the - planned event / unplanned event69 JP Do you tend to be more - deliberate than spontaneous / spontaneous than deliberate

http://www.learnASP.com/learn/mb2.asp by Charles M. Carroll Page 236

Reading/Parsing an ASCII File #2 by Charles CarrollHere is one implementation of parsing the file and converting it to on-the-fly HTML.

1 <%option explicit%>2 <html>3 4 <head>5 <title>mb.asp</title>6 </head>7 8 <body bgcolor="#FFFFFF">9 10 <form method="post" action="mbrespond.asp">11 <%12 dim answer1, answer213 dim char1, char2, counter14 Dim fs, findslash, findhyphen15 dim rest16 Dim thisfile, thisline17 dim question18 dim whichfile19 whichfile=server.mappath("mb.txt")20 Set fs = CreateObject("Scripting.FileSystemObject")21 Set thisfile = fs.OpenTextFile(whichfile, 1, False)22 counter=023 do while not thisfile.AtEndOfStream24 counter=counter+125 thisline=thisfile.readline26 char1=mid(thisline,1,1)27 char2=mid(thisline,2,1)28 rest=mid(thisline,3)29 30 findhyphen=instr(thisline,"-")31 question=mid(rest,1,findhyphen-2)32 33 rest=mid(rest,findhyphen)34 findslash=instr(rest,"/")35 answer1=mid(rest,1,findslash-1)36 answer2=mid(rest,findslash+1)37 38 'response.write char1 & "<br>"39 'response.write char2 & "<br>"40 'response.write rest & "<p>"41 response.write question & "<br>"42 'response.write answer1 & "<br>"43 'response.write answer2 & "<p>"44 %>45 <p><input TYPE="radio" name="Q<%=counter%>" VALUE="U" CHECKED>Undecided<br>46 <input TYPE="radio" name="Q<%=counter%>" VALUE="<%=char1%>"><%=answer1%><br>47 <input TYPE="radio" name="Q<%=counter%>" VALUE="<%=char2%>"><%=answer2%></p>48 <p><%49 loop50 thisfile.Close51 set fs=nothing

Page 242: [ebook] Learn ASP

52 %> <input type="submit"></p>53 </form>54 </body>55 </html>

http://www.learnASP.com/learn/mb3.asp by Charles M. Carroll Page 237

Reading/Parsing an ASCII File #3 by Charles CarrollHere is one implementation of scoring the HTML file.

1 <%option explicit%>2 <html>3 4 <head>5 <title>mbrespond.asp</title>6 </head>7 <%8 dim key9 dim ecount, icount10 dim scount, ncount11 dim tcount, fcount12 dim jcount, pcount13 dim ucount14 For Each Key in Request.Form15 SELECT CASE request.form(key)16 CASE "E"17 ecount=ecount+118 CASE "I"19 icount=icount+120 CASE "S"21 scount=scount+122 CASE "N"23 ncount=ncount+124 CASE "T"25 tcount=tcount+126 CASE "F"27 fcount=fcount+128 CASE "J"29 jcount=jcount+130 CASE "P"31 pcount=pcount+132 CASE "U"33 ucount=ucount+134 END SELECT35 Next36 Response.write "E=" & ecount & "<br>"37 Response.write "I=" & icount & "<br>"38 Response.write "S=" & scount & "<br>"39 Response.write "N=" & ncount & "<br>"40 Response.write "T=" & tcount & "<br>"41 Response.write "F=" & fcount & "<br>"42 Response.write "J=" & jcount & "<br>"43 Response.write "P=" & pcount & "<br>"44 Response.write "U=" & ucount & "<br>"45 %>46 47 <body bgcolor="#FFFFFF">48 </body>49 </html>

Page 243: [ebook] Learn ASP

http://www.learnASP.com/learn/cl.asp by Charles M. Carroll Page 238

Content Linking Prev/Next1 <%2 Set NL = Server.CreateObject ("MSWC.NextLink")3 tocname="/learn/learn.txt"4 nextref=NL.GetNextURL(tocname)5 nextdes=NL.GetNextDescription(tocname)6 If (NL.GetListIndex (tocname)>1) Then7 prevref=NL.GetPreviousURL(tocname)8 prevdes=NL.GetPreviousDescription(tocname)9 %>10 Prev:<a href="<%=prevref%>"><%=prevdes%></a>&nbsp;&nbsp;Next:11 <% End If %>12 <a href="<%=nextref%>"><%=nextdes%></a>

http://www.learnASP.com/learn/cl2.asp by Charles M. Carroll Page 239

Content Linking TOC1 <TITLE>cl2.asp</TITLE>2 <body bgcolor="#FFFFFF">3 <%4 Set TL = Server.CreateObject ("MSWC.NextLink")5 for i=1 to cint(TL.GetListCount("/learn/learn.txt"))%>6 Description:7 <%=TL.GetNthDescription ("/learn/learn.txt",i)%>,8 (URL=<%=TL.GetNthURL ("/learn/learn.txt",i)%>).9 Page <%=i%>.<p>10 <% next%>11 </body>12 </html>

http://www.learnASP.com/learn/cl3.asp by Charles M. Carroll Page 240

Content Linking List Box by Charles CarrollHere is a script that will turn the Content Linking elements into a pull-down list so people can arbitrarily jump from one topic toanother....

1 <HTML><HEAD><TITLE>cljump.asp</TITLE></HEAD>2 <body bgcolor="#FFFFFF">3 <FORM ACTION="cljumprespond.asp">4 <%5 Set TL = Server.CreateObject ("MSWC.NextLink")6 maxi= cint(TL.GetListCount("/learn/learn.txt"))7 %>8 <SELECT name="whichtopic">9 <OPTION SELECTED VALUE="">Select a Topic...10 <%for i=1 to maxi%>11 <OPTION value=12 <%=TL.GetNthURL("/learn/learn.txt",i)%>

Page 244: [ebook] Learn ASP

13 >14 <%15 desc=TL.GetNthDescription("/learn/learn.txt",i)16 if mid(desc,1,1)="*" then17 desc=mid(desc,2)18 else19 desc="&nbsp;&nbsp;&nbsp;&nbsp;" & desc20 end if21 %>22 <%=desc%>23 <%next%>24 </SELECT>&nbsp;&nbsp;<INPUT VALUE="Jump to Lesson" TYPE=submit></FORM>25 </BODY>26 </HTML>

The script named cljumprespond.asp that implements the jump looks like this:1 <%2 response.redirect request.querystring("whichtopic")3 %>

http://www.learnASP.com/learn/fileobjects.asp by Charles M. Carroll Page 241

FileObjects by Charles CarrollThe file object is in newer versions of VBScript.

1 <html><head>2 <title>fileobjects.asp</title>3 </head><body>4 <%5 mypath="/learn/test"6 7 Set filesystem = CreateObject("Scripting.FileSystemObject")8 Set folder = filesystem.GetFolder(server.mappath(mypath))9 10 Set filecollection = folder.Files11 For Each file in filecollection12 response.write file.name & "<br>"13 Next14 15 set filesystem=nothing16 set folder=nothing17 set filecollection=nothing18 %>19 </body></html>

http://www.learnASP.com/learn/fileobjects2.asp by Charles M. Carroll Page 242

FileObjects Part 2 by Charles CarrollThe file object is in newer versions of VBScript. Here we use it to walk a directory and make links.

1 <html><head>2 <title>fileobjectslinks.asp</title>3 </head><body>4 <%

Page 245: [ebook] Learn ASP

5 dirtowalk="/learn/test"6 Set fs = CreateObject("Scripting.FileSystemObject")7 Set f = fs.GetFolder(server.mappath(dirtowalk))8 Set fc = f.Files9 For Each whatever in fc10 response.write "<A HREF='"11 response.write whatever.name12 response.write "'>"13 response.write whatever.name14 response.write "</A><br>"15 Next16 %>17 </body></html>

Now we will display graphics in a directory.

1 <html><head>2 <title>fileobjectsgraphics.asp</title>3 </head><body>4 <%5 dirtowalk="/images"6 Set fs = CreateObject("Scripting.FileSystemObject")7 Set f = fs.GetFolder(server.mappath(dirtowalk))8 Set fc = f.Files9 For Each whatever in fc10 response.write "<IMG SRC='/images/"11 response.write whatever.name12 response.write "'>"13 response.write whatever.name & "<br>"14 Next15 %>16 </body></html>

http://www.learnASP.com/learn/fileobjects3.asp by Charles M. Carroll Page 243

FileObjects Part 3 by Steven HarperSteven [email protected], Internet Developer

The file object can be used to examine the disk as well as this cript submitted by a site viewer, demonstrates.

1 <html><head>2 <title>fileobjectsinfo.asp</title>3 </head><body>4 <%5 disktoexamine="C:"6 7 set fs = Server.CreateObject("Scripting.FileSystemObject")8 set f = fs.GetDrive(disktoexamine)9 10 Response.Write(" Root Folder : ")11 Response.Write(f.RootFolder)12 Response.Write("<BR>")13 Response.Write(" Type of Drive : ")14 if f.DriveType=2 then15 Response.Write("Fixed")16 end if17 if f.DriveType=1 then18 Response.Write("Removable")19 end if20 Response.Write("<BR>")21 Response.Write(" File System : ")

Page 246: [ebook] Learn ASP

22 Response.Write(f.FileSystem)23 Response.Write("<BR>")24 Response.Write(" Total Size on Server's C: &nbsp;&nbsp;")25 Response.Write(f.TotalSize)26 Response.Write("<BR>")27 Response.Write(" Drive Space on Server's C: ")28 Response.Write(f.freespace)29 Response.Write("<BR>")30 Response.Write(" Serial Number : ")31 Response.Write(f.SerialNumber)32 33 set f=nothing34 set fs=nothing35 36 %>37 </body></html>

http://www.learnASP.com/learn/fileobjects4.asp by Charles M. Carroll Page 244

FileObjects Part 4 by "Tim Foster" [email protected]

The file object examples was modified by one of our readers to support folders and clicking on them to see the contents beneath.Our readers always come up with some nice variations and new examples.

1 <html><head>2 <title>fileobjectsplusdir.asp</title>3 </head><body>4 <%5 additional = request.querystring("pathh")6 folderspec = "/learn/"7 8 if additional & "x" <> "x" then9 additional = additional & "/"10 folderspec = folderspec & additional11 end if12 13 Set fs = CreateObject("Scripting.FileSystemObject")14 Set f = fs.GetFolder(server.mappath(folderspec))15 Set fd = f.subfolders16 17 response.write "<h2>FOLDERS</h2><blockquote>"18 For Each whatever in fd19 response.write "<A HREF='"20 response.write request.servervariables("script_name")21 response.write "?pathh=" & whatever.name22 response.write "'>"23 response.write whatever.name & " - " & whatever.datecreated24 response.write "</A><br>"25 Next26 27 response.write "</blockquote><hr>"28 29 30 response.write "<h2>FILES</h2><blockquote>"31 32 Set fc = f.files33 34 For Each whatever in fc35 response.write "<A HREF='"36 response.write folderspec & whatever.name37 response.write "'>"38 response.write whatever.name & " - " & whatever.datecreated

Page 247: [ebook] Learn ASP

39 response.write "</A><br>"40 Next41 42 response.write "</blockquote><hr>"43 44 45 %>46 </body></html>

http://www.learnASP.com/learn/graphicdetect.asp by Charles M. Carroll Page 245

Detect Graphic Type/Dimensions by Daniel GorroñoDaniel Gorroño Santurtzi [email protected] - Euskal Herria

This ingenious piece of code demonstrates how to read a file using the file system object and extract bytes that contain the heightand width.

1 <!--#include virtual="/learn/test/lib_graphicdetect.asp"-->2 <html><head>3 <TITLE>dbtable.asp</TITLE>4 </head>5 <body bgcolor="#FFFFFF">6 <%7 graphic="images/learnaspiconmain.gif"8 HW = ReadImg(graphic)9 Response.Write graphic & " Dimensions: " & HW(0) & "x" & HW(1) & "<br>"10 response.write "<img src=""/" & graphic & """"11 response.write height=""" & HW(0) & """12 response.write width=""" & HW(0) & "">"13 %>14 </body></html>15

The library that is included is:

1 <%2 Dim HW3 4 Function AscAt(s, n)5 AscAt = Asc(Mid(s, n, 1))6 End Function7 8 Function HexAt(s, n)9 HexAt = Hex(AscAt(s, n))10 End Function11 12 13 Function isJPG(fichero)14 If inStr(uCase(fichero), ".JPG") <> 0 Then15 isJPG = true16 Else17 isJPG = false18 End If19 End Function20 21 22 Function isPNG(fichero)23 If inStr(uCase(fichero), ".PNG") <> 0 Then24 isPNG = true25 Else

Page 248: [ebook] Learn ASP

26 isPNG = false27 End If28 End Function29 30 31 Function isGIF(fichero)32 If inStr(uCase(fichero), ".GIF") <> 0 Then33 isGIF = true34 Else35 isGIF = false36 End If37 End Function38 39 40 Function isBMP(fichero)41 If inStr(uCase(fichero), ".BMP") <> 0 Then42 isBMP = true43 Else44 isBMP = false45 End If46 End Function47 48 49 Function isWMF(fichero)50 If inStr(uCase(fichero), ".WMF") <> 0 Then51 isWMF = true52 Else53 isWMF = false54 End If55 End Function56 57 58 Function isWebImg(f)59 If isGIF(f) Or isJPG(f) Or isPNG(f) Or isBMP(f) Or isWMF(f) Then60 isWebImg = true61 Else62 isWebImg = true63 End If64 End Function65 66 67 Function ReadImg(fichero)68 If isGIF(fichero) Then69 ReadImg = ReadGIF(fichero)70 Else71 If isJPG(fichero) Then72 ReadImg = ReadJPG(fichero)73 Else74 If isPNG(fichero) Then75 ReadImg = ReadPNG(fichero)76 Else77 If isBMP(fichero) Then78 ReadImg = ReadPNG(fichero)79 Else80 If isWMF(fichero) Then81 ReadImg = ReadWMF(fichero)82 Else83 ReadImg = Array(0,0)84 End If85 End If86 End If87 End If88 End If89 End Function90 91 92 Function ReadJPG(fichero)

Page 249: [ebook] Learn ASP

93 Dim fso, ts, s, HW, nbytes94 HW = Array("","")95 Set fso = CreateObject("Scripting.FileSystemObject")96 Set ts = fso.OpenTextFile(Server.MapPath("/" & fichero), 1)97 s = Right(ts.Read(167), 4)98 HW(0) = HexToDec(HexAt(s,3) & HexAt(s,4))99 HW(1) = HexToDec(HexAt(s,1) & HexAt(s,2))100 ts.Close101 ReadJPG = HW102 End Function103 104 105 Function ReadPNG(fichero)106 Dim fso, ts, s, HW, nbytes107 HW = Array("","")108 Set fso = CreateObject("Scripting.FileSystemObject")109 Set ts = fso.OpenTextFile(Server.MapPath("/" & fichero), 1)110 s = Right(ts.Read(24), 8)111 HW(0) = HexToDec(HexAt(s,3) & HexAt(s,4))112 HW(1) = HexToDec(HexAt(s,7) & HexAt(s,8))113 ts.Close114 ReadPNG = HW115 End Function116 117 118 Function ReadGIF(fichero)119 Dim fso, ts, s, HW, nbytes120 HW = Array("","")121 Set fso = CreateObject("Scripting.FileSystemObject")122 Set ts = fso.OpenTextFile(Server.MapPath("/" & fichero), 1)123 s = Right(ts.Read(10), 4)124 HW(0) = HexToDec(HexAt(s,2) & HexAt(s,1))125 HW(1) = HexToDec(HexAt(s,4) & HexAt(s,3))126 ts.Close127 ReadGIF = HW128 End Function129 130 131 Function ReadWMF(fichero)132 Dim fso, ts, s, HW, nbytes133 HW = Array("","")134 Set fso = CreateObject("Scripting.FileSystemObject")135 Set ts = fso.OpenTextFile(Server.MapPath("/" & fichero), 1)136 s = Right(ts.Read(14), 4)137 HW(0) = HexToDec(HexAt(s,2) & HexAt(s,1))138 HW(1) = HexToDec(HexAt(s,4) & HexAt(s,3))139 ts.Close140 ReadWMF = HW141 End Function142 143 144 Function ReadBMP(fichero)145 Dim fso, ts, s, HW, nbytes146 HW = Array("","")147 Set fso = CreateObject("Scripting.FileSystemObject")148 Set ts = fso.OpenTextFile(Server.MapPath("/" & fichero), 1)149 s = Right(ts.Read(24), 8)150 HW(0) = HexToDec(HexAt(s,4) & HexAt(s,3))151 HW(1) = HexToDec(HexAt(s,8) & HexAt(s,7))152 ts.Close153 ReadBMP = HW154 End Function155 156 157 Function isDigit(c)158 If inStr("0123456789", c) <> 0 Then159 isDigit = true

Page 250: [ebook] Learn ASP

160 Else161 isDigit = false162 End If163 End Function164 165 166 Function isHex(c)167 If inStr("0123456789ABCDEFabcdef", c) <> 0 Then168 isHex = true169 Else170 ishex = false171 End If172 End Function173 174 175 Function HexToDec(cadhex)176 Dim n, i, ch, decimal177 decimal = 0178 n = Len(cadhex)179 For i=1 To n180 ch = Mid(cadhex, i, 1)181 If isHex(ch) Then182 decimal = decimal * 16183 If isDigit(c) Then184 decimal = decimal + ch185 Else186 decimal = decimal + Asc(uCase(ch)) - Asc("A")187 End If188 Else189 HexToDec = -1190 End If191 Next192 HexToDec = decimal193 End Function194 %>195

http://www.learnASP.com/learn/buildcomponents.asp by Charles M. Carroll Page 246

VB Components: Simple Component (buildvbsimple.asp) - Page 247 VB Components: Registering Component (buildregister.asp) - Page 248 VB Components: ADO, Run It! (buildvbado.asp) - Page 249 VB Components: ADO, Build It! (buildvbado2.asp) - Page 250 VB Components: VB Warnings/Guidelines (buildvbguidelines.asp) - Page 251 VB Components: General Building Guidelines (buildvb.asp) - Page 252 VB Components: Installation Requirements (buildvb2.asp) - Page 253 VB Components: Threading Models (buildvbthreads.asp) - Page 254

http://www.learnASP.com/learn/buildvbsimple.asp by Charles M. Carroll Page 247

Page 251: [ebook] Learn ASP

Simple VB Component by Charles CarrollThis is a very simple component written in Visual Basic. You can create it by

making a new "Active-X DLL" project●

under the Project; References menu, you must activate the "Microsoft Active Server Pages" library otherwise it won'trecognize the response object and won't compile.

The project name ==> charlescarrollThe class name ==> simplecomponent

Here is the Visual Basic source code for the component:14 ' projectname =charlescarroll15 ' classname =simplecomponent16 Private ASPresponse As response17 Public Sub onstartpage(sc As ScriptingContext)18 Set ASPresponse = sc.response()19 End Sub20 Public Sub hello()21 ASPresponse.Write "Hello"22 End Sub23 Public Sub goodbye()24 ASPresponse.Write "Goodbye"25 End Sub26

Now it is invoked on an ASP page with the following code:1 <html><head>2 <title>simplevb.asp</title>&3 <body bgcolor="#FFFFFF">4 <%5 set parrot=server.createobject("charlescarroll.simplecomponent")6 parrot.hello7 response.write "<br>"8 parrot.goodbye9 %>10 </body></html>

http://www.learnASP.com/learn/buildregister.asp by Charles M. Carroll Page 248

Registering A ComponentThe minimum recommended steps to register your C++/Visual Basic ASP component are:

Copy your component to where your System DLLs are(probably \winnt\system32)

DO NOT leave the component in the original directory!!!! Make sure the .DLL/component is only in the system directory andnowhere else. If regsvr32 is executed and it rgeisters a DLL that is not in the system directory your ASP pages may fail toinstantiate the component with the dreaded message "Active X DLL cannot create object".

from a command promptregsvr32 <your component name>

If you are updating a component (i.e. registering a component that replaces another component) instead:

Copy your component to where your System DLLs are(probably \winnt\system32)

DO NOT leave the component in the original directory!!!! Make sure the .DLL/component is only in the system directory andnowhere else. If regsvr32 is executed and it rgeisters a DLL that is not in the system directory your ASP pages may fail toinstantiate the component with the dreaded message "Active X DLL cannot create object".

from a command prompt●

Page 252: [ebook] Learn ASP

regsvr32 <old component name> -u

from a command promptregsvr32 <your component name>

start and stop web service to purge old component from memory●

http://www.learnASP.com/learn/buildvbado.asp by Charles M. Carroll Page 249

VB Component: DBHelper from Web PageHere is a call to a VB custom component we created:1 <html><head>2 <title>dbhelper.asp</title>&3 <body>4 <%5 set mycomponent=server.createobject("charlescarroll.dbhelperver001")6 mycomponent.connect ="DSN=student;uid=student;pwd=magic"7 mycomponent.query = "select * from publishers"8 mycomponent.maketable9 set mycomponent=nothing10 %>11 </body></html>

http://www.learnASP.com/learn/buildvbado2.asp by Charles M. Carroll Page 250

VB Component: DBHelper by Charles CarrollThis page has the source code to the component. We have specified: project name=charlescarroll class name=dbhelperver001Remember these are the names set in the property window, not neccesarily the filenames.

This example will not compile unless you go to the "Project; References" menu and check/turn on the following libraries:Microsoft "Active Data Objects" object library●

Microsoft "Active Server Pages" object library●

14 ' projectname =charlescarroll15 ' classname =dbhelperver00116 Private ASPresponse As Response17 Private ASPserver As Server18 Private htmlstart, htmlend, rowstart, rowend19 Private fieldstart, fieldend, namestart, nameend20 Public Sub onstartpage(sc As ScriptingContext)21 Set ASPresponse = sc.Response()22 Set ASPserver = sc.Server()23 End Sub24 Public Property Let connect(temp As Variant)25 myconnect = temp26 End Property27 Public Property Get connect() As Variant28 connectme = myconnect29 End Property30 Public Property Get fieldnames() As Variant31 fieldnames = myfieldnames32 End Property33

Page 253: [ebook] Learn ASP

34 Public Property Let fieldnames(temp As Variant)35 myfieldnames = temp36 End Property37 38 Public Property Let query(temp As Variant)39 myquery = temp40 End Property41 Public Property Get query() As Variant42 query = myquery43 End Property44 45 Public Property Let selectdefault(temp As Variant)46 myselectdefault = temp47 End Property48 Public Property Get selectdefault() As Variant49 selectdefault = myselectdefault50 End Property51 Public Property Let selectname(temp As Variant)52 myselectname = temp53 End Property54 Public Property Get selectname() As Variant55 selectname = myselectname56 End Property57 58 Public Sub query2list()59 htmlstart = "<select name='" & selectname & "'>"60 htmlend = "</select>"61 rowstart = "<option>"62 rowend = "</option>"63 fieldstart = ""64 fieldend = ""65 Call query2html66 End Sub67 68 Public Sub query2table()69 htmlstart = "<table border=1>"70 htmlend = "</table>"71 rowstart = "<tr>"72 rowend = "</tr>"73 fieldstart = "<td valign=top>"74 fieldend = "</td>"75 Call query2html76 End Sub77 78 Public Sub query2form()79 htmlstart = ""80 htmlend = ""81 rowstart = ""82 rowend = "<hr>"83 fieldstart = ""84 fieldend = "<br>"85 fieldnames = True86 namestart = ""87 nameend = "&nbsp;=&nbsp;"88 Call query2html89 End Sub90 91 Public Sub query2entryform()92 htmlstart = ""93 htmlend = ""94 rowstart = ""95 rowend = ""96 fieldstart = "%name%&nbsp;=&nbsp;<input type='text name='%name%' value='"97 fieldend = "' size='%size%'><br>"98 fieldnames = False99 namestart = ""100 nameend = "&nbsp;&nbsp;="

Page 254: [ebook] Learn ASP

101 Call query2html102 End Sub103 104 Public Sub CustomDisplay(PARMhtmlstart, PARMhtmlend, PARMrowstart, PARMrowend, _105 PARMfieldstart, PARMfieldend, PARMfieldnames, _106 PARMnamestart, PARMnameend)107 htmlstart = PARMhtmlstart108 htmlend = PARMhtmlend109 rowstart = PARMrowstart110 rowend = PARMrowend111 fieldstart = PARMfieldstart112 fieldend = PARMfieldend113 fieldnames = PARMfieldnames114 namestart = PARMnamestart115 nameend = PARMnameend116 Call query2html117 End Sub118 119 120 Private Sub query2html()121 On Error GoTo Badnews122 attempt = "creating connection"123 Set conntemp = ASPserver.CreateObject("adodb.connection")124 125 attempt = "opening connection"126 conntemp.Open myconnect127 128 attempt = "making recordset"129 Set rstemp = conntemp.Execute(myquery)130 howmanyfields = rstemp.Fields.Count - 1131 ReDim fsa(howmanyfields)132 ReDim fea(howmanyfields)133 For i = 0 To howmanyfields134 tempstart = Replace(fieldstart, "%name%", rstemp(i).Name)135 tempend = Replace(fieldend, "%name%", rstemp(i).Name)136 tempstart = Replace(tempstart, "%size%", rstemp(i).ActualSize)137 tempend = Replace(tempend, "%size%", rstemp(i).ActualSize)138 fsa(i) = myfieldstart139 fea(i) = myfieldend140 Next141 ASPresponse.Write htmlstart & vbCrLf142 Counter = 0143 Do While Not rstemp.EOF144 ASPresponse.Write rowstart & vbCrLf145 For i = 0 To howmanyfields146 If fieldnames = True Then147 ASPresponse.Write namestart & rstemp(i).Name & nameend148 End If149 ASPresponse.Write fsa(i) & rstemp(i) & fea(i) & vbCrLf150 Next151 ASPresponse.Write rowend & vbCrLf152 Counter = Counter + 1153 rstemp.MoveNext154 Loop155 rstemp.Close156 Set rstemp = Nothing157 conntemp.Close158 Set conntemp = Nothing159 ASPresponse.Write htmlend160 Exit Sub161 Badnews:162 temp = "Error: " & attempt & "<br>"163 temp = temp & Err.Description & "<br>"164 temp = temp & Err.Number165 ASPresponse.Write temp166 End Sub167

Page 255: [ebook] Learn ASP

http://www.learnASP.com/learn/buildvbguidelines.asp by Charles M. Carroll Page 251

VB ASP Component Building Guidelines by Charles CarrollComponent written in Visual Basic can be written using programming techniques that will cause them to be unstable in a web serverenvironment. Commands, Functions and Objects that are fine in most standalone or client/server VB programs may not beappropriate in a web server component. We offer the following major guidelines:

Do not use DAO or RDO for data access. Use ADO only. DAO and RDO do not scale to the concurrency issues a websitefaces well.

Do not use traditional file access methods (Open #, Close #). Instead use the scripting FileSystemObject.●

http://www.learnASP.com/learn/buildvb.asp by Charles M. Carroll Page 252

Generic VB Component Building StepsMaking a VB ASP component is easy:

Use File; New Project●

choose Active-X DLL●

You will now be in the editor and there will be a class open●

when you are done, the code to invoke it on a page will look like:set .... = server.createobject("projectname.classname")choose your project plus class names well.

The project name and class name are set with the (name) property. They are NOT in anyway connected to thefilename although you may make the filenames match the project and class names.

If you need to use one of the five built-in ASP objects (collectively called the scripting context) you can add aspecial event to your class called OnStartPage. Anytime your component is created from an ASP script, ASP willcall your OnStartPage if it exists within your class. OnStartPage allows you to assign the built-in ASP objects(response, request, server, application, session) to objects in your code:

Public Function onstartpage(sc As Object) 'Set ... = sc.response() 'set ... = sc.server() 'set ... = sc.Request() 'set ... = sc.application() 'set ... = sc.session()End Function

If needed, you can add this event:●

Public Function onendpage(sc As Object)End Function

http://www.learnASP.com/learn/buildvb2.asp by Charles M. Carroll Page 253

Page 256: [ebook] Learn ASP

VB Components: what you need...To make a VB ASP component you need the following on your machine:

Visual Basic version 4 or version 5 (our instructions only cover version 5 though)●

A installation of "Active Server Pages" which can be obtained by installing IIS or Visual Interdev. This is because "Project;References" must include the "Active Server Pages" libary.

People having trouble building components can sign up for our listserv:

vbcomponents Listserver

JOIN, QUIT or Search ARCHIVES:http://www.asplists.com/asplists/buildvb2.asp

Send Listserver Questions [email protected]

Related LinksI want to build my first VB component! @ http://www.learnasp.com/learn/buildvbsimple.aspI get error overwriting DLL when updating component! @ http://www.learnasp.com/learn/FAQvbDLLoverwrite.aspASP Component Building Book @ Http://www.learnasp.com/books/components.aspBulletProof VB Components by Charles Alexander @ http://www.microsoft.com/mind/0899/aspcomp/aspcomp.htmSafeArrays. Accessing from VB by Shelley Powers @ http://www.yasd.com/devaspcomp/bonus/arrays.htmDuwamish Books Sample @ http://msdn.microsoft.com/library/techart/dw1intro.htmFitch and Mathers Application Sample @ http://msdn.microsoft.com/isapi/msdnlib.idc?theURL=/library/techart/fmstocks_web.htm

http://www.learnASP.com/learn/buildvbthreads.asp by Charles M. Carroll Page 254

VB Component Threading Detailsby Charles Carrollspecial thanks to Jon Flanders, Stephen Martin and Juan Llibre

Component written in Visual Basic are affected by some complex threading isses we will discuss here. The "bible" for all this is:Programming Distributed Applications with COM and Microsoft Visual Basic 6.0by Ted Pattison, Published by Microsoft Press.

Objects created and destroyed at the page level scale very well. Once a session level object is created it is attached to a specific,discrete thread. That thread can never be destroyed until all users assigned to that thread either <%session.abandon%> or theirsession times out. This is the internal workings of the ASP execution environment. Don Box wrote this fascinating detail up a coupleof MSJs ago. Objects created with a session scope, i.e.

set session("whatever")=server.creatobject("whatever.id")

do not scale well and are affected by the threading issues in the following way:You tie the Session down to a particular thread ( instead of ASP being able to use any thread from the thread pool).●

If you place a object marked apartment into the SessionObject you have an object which can only live and be called from the●

Page 257: [ebook] Learn ASP

Single-Threaded Apartment it was created in, ASP must run ALL request for that Session in that STA.If you don't do this (or only place Apartment Neutral Objects in the SessionObject ) ASP will run requests for that session onthe first available thread.

So imagine - you have a four processor machine running IIS/ASP - forty people come into your site, now each of those requests isnow tied to a specific thread, now two requests stop (are not currently making requests) - one more comes in and gets dispatched toone of these two threads that are free, and one of the two that stopped comes back - but another Session is using that thread - thereare now free threads that cannot be used - they are just sitting there doing nothing - while a user is waiting for its thread to be freed.This is just one example of what can go wrong (not to mention the additional work ASP must do to make sure this all workscorrectly). Overall placing object marked Apartment into the SessionObject is a very bad thing. You are way better off instantiating onevery page. You are correct - that you cannot place an Apartment threaded object into the ApplicationObject - which is probablywhat they should have done with the SessionObject as well.

All calls that involve objects conversing must be proxied. The proxy referring to is what the COM runtime creates in an Apartmentwhen that Apartment receives an interface to a COM object which lives in another Apartment.

For example - if you use a COM object which is marked "Free" in the registry - ASP will create that object and it will live in theMulti-Threaded Apartment (MTA), the page which is executing in a Single-Threaded Apartment (STA) will not get direct access to theobject - but will talk to the object through what is called a proxy. The proxy looks just like the interface to the Page (has the samemethods etc), but when the page calls a method, the proxy forwards the method call (parameters, name etc) to a COM providedchannel. This channel calls what is refered to as a stub - which again looks just like the object - but lives in the same Apartment asthe Object (in this case the MTA). Then finally the object gets called and then returns throught the same method. This is 1000xsslower that if the object lived in the same Apartment as the page (because of a thread switch - so switching threads you can see isvery expensive). This is just how COM works.

When a COM object is redesigned to be stateless and run under MTX, objects in the same package are not crossing processboundaries. Different packages are!

Run the scenarios:

Scenario 1: So if for example,+ 100 people hit your site for a couple of pages and leave+ 100 new people arrive in a couple of minutes+ 200 people arrive after that and then+ 50 people=====450 sessions/objects in memory with 50 !!! people on your site. And dozens or hundred of threads that can't be reclaimed for a while

Scenario 2:+ 100 people hit your site for a couple of pages and leave+ 100 new people arrive in a couple of minutes+ 200 people arrive after that and then+ 50 people=====50 objects in memory because you destroyed all objects at the page level. No threads tied up.

If it isn't Apartment Neutral (i.e. aggregates the Free-Threaded Marshaller) - you will tie the session down to that thread - so youhave to ask yourself - is tying my sessions down to a specific thread a major performance hit - and that really depends on how manyusers are hitting your site and how often. In general I think it is a bad thing and should be avoided - unless there is no other way toaccomplish what you want - and there almost always is a way - that isn't too much work and doesn't have any negative side-effects

This is why I have <%@enablesessionstate=false%> and a blank global.asa. If I need an object, I create and destroy it at the pagelevel. for almost every page on my site and with 10,000 sessions a day and 90,000 page views we still serve pages fast and don't getlocked up very often.

http://www.learnASP.com/learn/buildjava.asp by Charles M. Carroll Page 255

javacomponents Listserver

JOIN, QUIT or Search ARCHIVES:http://www.asplists.com/asplists/buildjava.asp

Page 258: [ebook] Learn ASP

Send Listserver Questions [email protected]

Related LinksRobert Zembowicz White Papers @ http://www.robertz.com/Papers/Frank Leahy's Tutorial @ http://www.hotwired.com/webmonkey/99/29/index2a.html?tw=programmingASP Component Building w/Java Book @ Http://www.learnasp.com/books/components.aspJava COM discussion list @ http://discuss.microsoft.com/archives/java-com.html

http://www.learnASP.com/learn/buildc.asp by Charles M. Carroll Page 256

C, C++, ATL ASP Component BuildingBuilding ASP components with C and/or C plus ATL is possible as well. The following links will explain the process and provide somevaluable information on debugging, etc:

Developing ASP Components with ATL by George Reilly:http://www.microsoft.com/workshop/server/asp/comp.aspThis article is superb and concise.

Active Server Components with VS 5.0:http://www.15seconds.com/issue/970422.htm

Developer's Sample at:http://www.microsoft.com/windows/downloads/contents/AdminTools/IISDeveloperSample/default.asp?custarea=bus&site=nts&openmenu=&highlighteditem=

If you have trouble building or running ASP components written in C/C++, we run a listserv/newgroup called [low-levelcomponents]where that is the only topic allowed you can join to get help.

low-levelcomponents Listserver

JOIN, QUIT or Search ARCHIVES:http://www.asplists.com/asplists/buildc.asp

Send Listserver Questions [email protected]

Related LinksAn Incredible High Quality Dcom List @ http://discuss.microsoft.com/archives/dcom.htmlThe Best Collection of COM Articles @ http://www.sellsbrothers.com/tools/Developmentor COM Tutorial @ http://beta.develop.com/com/ASP C++/ATL Component Building Links @ http://www.learnasp.com/learn/buildc.aspASP Component Building Book @ Http://www.learnasp.com/books/components.aspBusy ATL Listserve @

Page 259: [ebook] Learn ASP

http://discuss.microsoft.com/archives/atl.html

http://www.learnASP.com/learn/buildmtx.asp by Charles M. Carroll Page 257

MTS: Overview (buildmtxoverview.asp) - Page 258 MTS: Essentials (buildmtx2.asp) - Page 259 MTS: Transactional ASP pages (buildmtxasp.asp) - Page 260 MTS: Book (booksmtx.asp) - Page 261 MTS: Book (booksmtx2.asp) - Page 262 MTS: Registering Components (buildmtxregister.asp) - Page 263

http://www.learnASP.com/learn/buildmtxoverview.asp by Charles M. Carroll Page 258

MTX and ComponentsMicrosoft Transaction Server (MTX) is a tool included with IIS4 NT Option Pack. It is an essential long term ingredient to scalable,maintainable, reliable websites. It is necessary for commerce or mission critical websites, though it helps improve performance on allwebsites as well.

Without involving MTX, every request to create an instance of a component (ala server.createobject) and destroy the instanceof that component (ala set object=nothing) is sent directly to the component. IIS tends to cache objects so that when youdestroy an instance, IIS probably will not remove it from memory so that the next creation attempt will be instant since it is already inmemory. This is a direct violation of the DCOM rule that when there are zero instances of a component in memory, the componentis automatically removed from memory.

Any MTX aware component is now managed by MTX and the following benefits are available:

MTX is managing the object so that it may unload or load instances as needed to improve performance.●

MTX objects need not run as the "standard ASP User". Components registered with MTX can impersonate a specific user.●

The typical segments of code that would be unique to components managed by MTX would look like this:

Concept CodeCapture Context shared by all MTXmanaged components

private mycntxt as ObjectContextset mycntxt= GetObjectContext()

Tell MTX your component has completedit's task sucessfully mycntxt.SetComplete

Tell MTX your component has notcompleted it's task sucessfully mycntxt.SetAbort

Tell MTX to create an instance of yourcomponent (don't use new, createobject,or server.createobject)

mycntxt.CreateInstance("... objectname ..")

http://www.learnASP.com/learn/buildmtx2.asp by Charles M. Carroll Page 259

Page 260: [ebook] Learn ASP

MTX: Transaction EssentialsTransaction Server is based on established client server paradigms of reliable transaction processing. The concepts are consistentregardless of the transaction engine involved.

The traditional wisdom is that a robust transaction must pass the ACID test or the transaction procesing has flaws:

Atomic: The transaction must execute completely or not at all.

Consistent: The transaction must never leave any participant in an inconsistent state.

Isolated: The effect of all individual transactions must have exactly the same effect whether run serially (in an ordered sequence)or parallel.

Durable: All transactions must store their results on a permanent or durable device before reporting success.

http://www.learnASP.com/learn/buildmtxasp.asp by Charles M. Carroll Page 260

MTX with ASP pages instead of ComponentsASP pages that need to take advantages of transactions can without being forced to move the ASP script into a component. Firstone of the following directives must be placed on the page:

<%@ Transaction = Required %><%@ Transaction = Requires_New %><%@ Transaction = Supported %><%@ Transaction = Not_Supported %>

Of course the ASP page must include code to address both committing and aborting the transaction:

<%SUB OnTransactionCommit() ...END SUB

SUB OnTransactionAbort() ...END SUB%>

http://www.learnASP.com/learn/booksmtx.asp by Charles M. Carroll Page 261

Database Workshop with Microsoft Transaction Server 2.0written by Roger Jennings, Steven D. Grey, Rick A. Lievanopublished by Sams PublishingNo writeup yet.

Coming soon.

BUY http://bn.bfast.com/booklink/click?sourceid=10446528&ISBN=0672311305

Page 261: [ebook] Learn ASP

http://www.learnASP.com/learn/booksmtx2.asp by Charles M. Carroll Page 262

Not Ready Yet. Coming Soon!

http://www.learnASP.com/learn/buildmtxregister.asp by Charles M. Carroll Page 263

Register Components with MTXRegistering a Component with MTX requires that you specify how the component participates (or doesn't participate) in atransaction. The possibilties are:

Requires a Transaction - run within a existing transaction, or if there is no existing transaction, MTX will create one.●

Requires a New Transaction - MTX starts a new transaction each time that component is activated.●

Support Transactions - run within a existing transaction, or if there is no existing transaction, MTX will run the componentwithout a transaction.

Does Not Support Transactions - This component will always run outside of existing transactions.●

http://www.learnASP.com/learn/components.asp by Charles M. Carroll Page 264

ASPMail: Simple Example (serverobjectsmail.asp) - Page 265 Upload: Simple Example (uploadsimple.asp) - Page 266 Upload: Multi-part form (uploadmultipart.asp) - Page 267 Upload: Limit Size (uploadlimitsize.asp) - Page 268 Upload: Many Files (uploadmanyfiles.asp) - Page 269 Perf Counters on ASP page (perfcounters.asp) - Page 270

http://www.learnASP.com/learn/serverobjectsmail.asp by Charles M. Carroll Page 265

ASPMail™ by Server Objectswww.serverobjects.com is a great place to get a variety of components. Here we will give you a simple script utilizinggenusa mail that e-mails me each time you run the page.

http://www.activeserverpages.com/learn/test/serverobjectsmail.aspis the page you can test this at.

1 <html><head>2 <title>serverobjectsmail.asp</title>3 </head><body bgcolor="#FFFFFF">4 <%5 ' ASPMail(tm) from www.serverobjects.com

Page 262: [ebook] Learn ASP

6 ' is not part of ASP per se,7 ' but a third party utility from serverobjects.com8 Set Mailer = Server.CreateObject("SMTPsvg.Mailer")9 Mailer.RemoteHost = "relay.datareturn.com"10 11 Mailer.FromName = "Some Student"12 Mailer.FromAddress = "[email protected]"13 Mailer.AddRecipient "Charles Carroll","[email protected]"14 Mailer.AddBCC "Charles Carroll","[email protected]"15 Mailer.Subject = "ASPMail Tutorial"16 17 Mailer.BodyText = "Hi. Just trying the mail example" & vbCrLf18 Mailer.BodyText = "Line 2"19 Mailer.BodyText = "Line 3"20 If Mailer.SendMail then21 Msg = "mail sent sucessfully!"22 Else23 Msg = "mail was not sent sucessfully"24 End If25 response.write Msg26 %>27 </body></html>

http://www.learnASP.com/learn/uploadsimple.asp by Charles M. Carroll Page 266

Upload File -- Simple Example by David Wihlutilizes file upload component from http://www.softartisans.com

Uploading Files is easy using Active Server Pages and a great Active Server Component called SA-FileUp.

This code sample allows you to use the Browse... button to select a file from your local hard disk. When you press the "Upload File"button, your browser will transmit the file to our web server. You are about to transmit a file from your local hard disk to theActiveServerPages.Com web server. Please do not send confidential information.

As you can see, no additional software was required on your client's computer: no ActiveX controls, no Java, just a simpleHTML 3.2 form. On the server, you need ASP (for IIS version 3 or 4) and SA-FileUp - that's it.

1 <HTML><HEAD>2 <TITLE>uploadsimple.asp by softwareartisans.com</TITLE>3 </HEAD><body bgcolor="#FFFFFF">4 <form enctype="multipart/form-data" method="post" action="uploadsimplerespond.asp">5 <TABLE WIDTH="100%">6 <TR>7 <TD ALIGN="RIGHT" VALIGN="TOP">Filename:</TD>8 9 <TD ALIGN="LEFT"><INPUT TYPE="FILE" NAME="FILE1">10 </TD>11 </TR>12 <TR>13 <TD ALIGN="RIGHT">&nbsp;</TD>14 <TD ALIGN="LEFT"><INPUT TYPE="SUBMIT" NAME="SUB1" VALUE="Upload File"></TD>15 </TR>16 <TR>17 <TD ALIGN="RIGHT">&nbsp;</TD>18 <TD ALIGN="LEFT">19 <B><I><SMALL>Note: if a button labeled "Browse..." does not appear, then your20 browser does not support File Upload. For Internet Explorer 3.02 users, a21 free add-on is available from Microsoft. If you <b>do not see a Browse... button</b>22 <A HREF="http://www.microsoft.com/msdownload/ieplatform/iewin95/iewin95.asp"TARGET="_new">click here to go to Microsoft's Site and get your free file upload add-on</A>.23 Select "Internet Explorer 3.02 File Upload Add-On for Windows 95 & NT".24 </SMALL></I></B>

Page 263: [ebook] Learn ASP

25 </TD>26 </TR>27 </TABLE>28 </form>29 </BODY></HTML>

The responder to the form will look like this:

1 <HTML><HEAD>2 <TITLE>Uploadsimplerespond.asp by softwareartisans.com</TITLE>3 </HEAD><BODY>4 Thank you for uploading your file.<br>5 <% Set upl = Server.CreateObject("SoftArtisans.FileUp")6 upl.Path = Server.Mappath ("/upload") & "/" & "tests"7 upl.SaveAs "upload.tst"%><BR>8 Total Bytes Written: <%=upl.TotalBytes%>9 </BODY></HTML>

Let's walk through the sample and see what is going on.

Look at the definition of the form. When using a form to upload files, the following items must be set:The FORM must have a tag of ENCTYPE="multipart/form-data".1. The <INPUT TYPE="FILE"> must have a tag of NAME= .2.

This tells the browser to transmit the contents of the file when posting the form.

Let's look at the form's processing (formresp.asp). The following line creates an instance of the SA-FileUp object: <% Set upl = Server.CreateObject("SoftArtisans.FileUp") %>

The following line invokes the .SaveAs method and passes the name of the web server's destination file as a parameter. <% upl.SaveAs "C:\temp\upload.out" %><BR>

In two lines you've uploaded a file!

For bonus points, the following line retrieves the TotalBytes property and displays it to the user. Total Bytes Written: <%=upl.TotalBytes%>

What did we learn?To upload files, there must be two elements on the form:

<FORM ENCTYPE="multipart/form-data" ... >❍

<INPUT TYPE="FILE" NAME="f1">❍

To process the form:First create an instance of the SA-FileUp component❍

Second, invoke the .SaveAs method and specify a filename❍

It is possible to retrieve other properties, such as total size of the upload.●

http://www.learnASP.com/learn/uploadmultipart.asp by Charles M. Carroll Page 267

Upload File -- Multi-Part Form by David Wihlutilizes file upload component from http://www.softartisans.com

The previous example is fine if all you want is file uploads. However most people want to capture additional information on the formalong with the file, such as a description.

Normally, you can use ASP's Request.Form object to access these other elements on the form. However when uploading files, youmust change the Encoding Type to "multipart/form-data". The ASP Request.Form object does not understand data transmitted usingthis encoding type.

SA-FileUp provides a Form object that provides identical functionality to the ASP Request.Form object, but can understand theencoding type that is specific to file uploads.

Page 264: [ebook] Learn ASP

1 <HTML><HEAD>2 <TITLE>uploadmultipart.asp by softwareartisans.com</TITLE>3 </HEAD><body bgcolor="#FFFFFF">4 <form enctype="multipart/form-data" method="post" action="uploadmultipartrespond.asp">5 Enter description: <input type="text" name="descrip"><br>6 Enter filename to upload: <input type="file" name="f1"><br>7 <input type="submit">8 </form>9 </BODY></HTML>

The responder to the form will look like this:

1 <HTML><HEAD>2 <TITLE>Uploadmultipartrespond.asp by softwareartisans.com</TITLE>3 </HEAD><BODY>4 Thank you for uploading your file.<br>5 <% Set upl = Server.CreateObject("SoftArtisans.FileUp")6 upl.Path = server.mappath("\upload") & "/tests"7 %>8 <% upl.SaveAs "upload.tst" %><BR>9 Your description is: '<%=upl.Form("descrip")%>'<BR>10 Total Bytes Written: <%=upl.TotalBytes%>11 <%set upl=nothing%>12 </BODY></HTML>

In this case, the definition of the form still uses ENCTYPE="multipart/form-data", but now there is an additionalform element containing a text box. Enter description: <input type="text" name="descrip"><br>

Let's look at the form's processing (mformresp.asp).

There is still the same creation of an instance. However, in this case we are referring to the form elements(description) explicitly by name. <% upl.SaveAs "C:\temp\upload.out" %><BR> Your description is: '<%=upl.Form("descrip")%>'<BR>

Like the Request.Form syntax, we use upl.Form("name-of-the-form-element") to refer to the value of the formelement.

Since there is only a single file element, we do not have to explicitly specify which one we want to save.

You can use this same mechanism to access all of your form elements, whether they be text boxes, radio buttons,checkboxes, selection boxes, etc.

What did we learn?Even if there are multiple form elements, you must still use:

<FORM ENCTYPE="multipart/form-data" ... >❍

ASP's Request.Form object does not understand this encoding type. Instead use, SA-FileUp's Form objectwhich offers identical functionality.

To refer to elements on the form, use the name of the element on the form, i.e. upl.Form("descrip")●

http://www.learnASP.com/learn/uploadlimitsize.asp by Charles M. Carroll Page 268

Page 265: [ebook] Learn ASP

Upload Limit File Size by David Wihlutilizes file upload component from http://www.softartisans.com

The previous example showed how to upload multiple files and access each of their individual properties. Previously we'veseen how to read properties of the file, such as the TotalBytes of the upload.

There are several properties that can be set. One very useful property is called MaxBytes. MaxBytes allows you to set a firmlimit on the size of the uploaded file, ensuring that malicious users do not fill up your server's hard disk with huge files.

When you set the MaxBytes property (before saving the file!), SA-FileUp will write up to the number you specify and thenstop. Any additional data will be discarded. You can set MaxBytes once and it will apply to all files in the current upload,limiting each of them to the value that you specify.

The maximum file size that SA-FileUp can process is 2 GB. If set MaxBytes equal to zero (0), SA-FileUp will revert to thedefault maximum, which is 2 GB.

Time for an example. We'll use the same simple form as in the very first upload:

1 <HTML><HEAD>2 <TITLE>uploadlimitsize.asp by softartisans.com</TITLE>3 </HEAD><body bgcolor="#FFFFFF">4 <form enctype="multipart/form-data" method="post" action="uploadlimitsizerespond.asp">5 Enter a big file to upload: <input type="file" name="f1"><br>6 <input type="submit">7 </form>8 </BODY></HTML>

The responder to the form will look like this:

1 <HTML><HEAD>2 <TITLE>Uploadlimitsizerespond.asp by softartisans.com</TITLE>3 </HEAD><BODY>4 Thank you for uploading your file.<br>5 <% Set upl = Server.CreateObject("SoftArtisans.FileUp") %>6 <% upl.MaxBytes = 1000 '--- limit the upload size to 1000 bytes %>7 The maximum size that you are permitted to upload is <%=upl.MaxBytes%> bytes per file.<br>8 <%9 upl.Path = server.mappath("\upload") & "/tests"10 upl.SaveAs "upload.out"11 %>12 Total Bytes Written: <%=upl.TotalBytes%><br>13 Server Filename: <%=upl.ServerName%><br>14 Total Bytes Transmitted by you: <%=Request.TotalBytes%>15 <%set upl=nothing%>16 </BODY></HTML>

Let's look at the form's processing (formrespmax.asp).

First, the MaxBytes:

<% upl.MaxBytes = 1000 '--- limit the upload size to 1000 bytes %> The maximum size that you are permitted to upload is <%=upl.MaxBytes%> bytesper file.<br>

We are setting MaxBytes as a limit for all files in this upload, even if there is more than one.

MaxBytes is Read/Write property, meaning that it is possible to both set its value and retrieve its value.

If you uploaded a file larger than 1000 bytes, you will have noticed that only the first 1000 bytes were written to disk.

We also added a new property called ServerName. ServerName is the name of file as it is stored on the web server, includingthe full path.

Server Filename: <%=upl.ServerName%><br>

And finally we displayed an ASP intrinsic property that displays the precise total number of bytes transmitted by the browser.

Page 266: [ebook] Learn ASP

Total Bytes Transmitted by you: <%=Request.TotalBytes%>

You may have noticed that the total bytes transmitted by you is larger than your original file's size on disk. This is normal,since the browser must add information such as headers and encoding information. Request.TotalBytes reports the totalincluding the file, encoding information and other form elements that may be present.

What did we learn?

It is possible to limit the size of the upload by using the MaxBytes property.●

Some properties are Read Only such as TotalBytes, and some are Read/Write such as MaxBytes.●

The amount of information transmitted by the browser is always larger than the file because of addition encodinginformation and form elements.

That completes our tutorial for now. Please see our many code samples for other examples of SA-FileUp functionality,including:

Uploading to a Database●

Secure download from the server to the browser●

Saving the upload in binary format●

Manipulating files on the web server.●

Thank you for using our tutorial!

Please visit the Software Artisans' web

http://www.learnASP.com/learn/uploadmanyfiles.asp by Charles M. Carroll Page 269

Upload Many Files by David Wihlutilizes file upload component from http://www.softartisans.com

The previous example showed how to upload a file and capture addition form elements. What if you wanted to transmit multiple fileswith a single form submit?

To add a second (or other file), just add another <INPUT TYPE="FILE"> tag to your form.

Even though the Internet Standard specification for HTTP Upload (RFC 1867) permits wildcarded filenames ("*.doc"), neitherNetscape Navigator or Microsoft Internet Explorer support wildcarded names at this time. When they do, the current version ofSA-FileUp will be able to process wildcarded filenames. For now, it is necessary to have an additional input tag for every file youwant to upload.

1 <HTML><HEAD>2 <TITLE>uploadmanyfiles.asp by softartisans.com</TITLE>3 </HEAD><body bgcolor="#FFFFFF">4 <form enctype="multipart/form-data" method="post" action="uploadmanyfilesrespond.asp">5 Enter first filename: <input type="file" name="f1"><br>6 Enter second filename: <input type="file" name="f2"><br>7 <input type="submit">8 </form>9 </BODY></HTML>

The responder to the form will look like this:

1 <HTML><HEAD>2 <TITLE>Uploadmanyfilesrespond.asp by softartisans.com</TITLE>3 </HEAD><BODY>4 Thank you for uploading your files.<br>5 <% Set upl = Server.CreateObject("SoftArtisans.FileUp")6 upl.Path = server.mappath("\upload") & "/tests"7 %>

Page 267: [ebook] Learn ASP

8 <% upl.Form("f1").SaveAs "upload1.out" %><BR>9 Total Bytes Written for file 1: <%=upl.Form("f1").TotalBytes%>10 <% upl.Form("f2").SaveAs "upload2.out" %><BR>11 Total Bytes Written for file 2: <%=upl.Form("f2").TotalBytes%>12 </BODY></HTML>

Let's look at the form's processing (formmanyfilesrespond.asp).

In this case we are referring to the file elements explicitly by name. <% upl.Form("f1").SaveAs "C:\temp\upload1.out" %><BR> <% upl.Form("f2").SaveAs "C:\temp\upload2.out" %><BR>

Like the upl.Form syntax, we use upl.Form("name-of-the-form-element") to refer to the value of the file.

The older method, upl.SaveAs, would still work, but would refer to the first file element that was found. This isambiguous. So, when uploading multiple files, be explicit and use the .Form("file-element-name") syntax.

All of the methods and properties, such as the TotalBytes are available when using this syntax. For example, Total Bytes Written for file 1: <%=upl.Form("f1").TotalBytes%>

Internally, SA-FileUp has created an instance of another object to represent the uploaded file. This object is calledthe SAFile object. The SAFile object has properties and methods as well. See the Reference Section for details.

What did we learn?If there are multiple file elements on the form, refer to them explicitly by name.●

For each uploaded file, SA-FileUp creates a new SAFile object to represent the uploaded file.●

Great - you've got lots of uploads working.

http://www.learnASP.com/learn/perfcounters.asp by Charles M. Carroll Page 270

Performance Counter monitoring via a Web Pageusing PerfCounter component from www.softwing.com

The following script monitors the officially undocumented error counters that were unofficially documented in:http://www.15seconds.com/Issue/981015.htm.

The following code setup the monitor:1 <html>2 3 <head>4 <title>perfcountersetup.asp</title>5 </head><body>6 <%7 Set objQPerfCnt = CreateObject("Softwing.AspQPerfCounters")8 bResult = objQPerfCnt.OpenQuery()9 bResult = objQPerfCnt.AddCounter("\\.\Active Server Pages\Errors During Script Runtime")10 bResult = objQPerfCnt.CollectQueryData()11 varResult = objQPerfCnt.GetFormattedCounterVal(_12 "\\.\Active Server Pages\Errors During Script Runtime", 0)13 bResult = objQPerfCnt.CloseQuery()14 %>15 </body>16 </html>

The following code displays that monitor:1 <html><head>2 <title>perfcounterswatcherror.asp</title>3 </head><body>

Page 268: [ebook] Learn ASP

4 <%5 ' counters to watch6 Dim arrFriendlyName,arrCounterPath7 arrFriendlyName = Array("Total failed requests","Errors per second (current)",_8 "Runtime errors (total)", "Script compiler errors (total)", _9 "ASP preprocessor errors (total)")10 arrCounterPath = Array("\\.\Active Server Pages\Requests Failed Total", _11 "\\.\Active Server Pages\Errors/Sec", _12 "\\.\Active Server Pages\Errors During Script Runtime",_13 "\\.\Active Server Pages\Errors From Script Compilers", _14 "\\.\Active Server Pages\Errors From ASP Preprocessor")15 Dim objQPerfCnt, bResult, varResult, i16 Set objQPerfCnt = CreateObject("Softwing.AspQPerfCounters")17 bResult = objQPerfCnt.OpenQuery()18 for i = 0 to UBound(arrCounterPath)19 bResult = objQPerfCnt.AddCounter(arrCounterPath(i))20 next21 bResult = objQPerfCnt.CollectQueryData()22 for i=0 to UBound(arrCounterPath)23 varResult = objQPerfCnt.GetFormattedCounterVal(arrCounterPath(i), 0)24 Response.Write "<b>" & arrFriendlyName(i) & "</b>: "25 Response.Write varResult & "<br>" & vbCrLf26 next27 %>28 </body>29 </html>

Questions about this component can be directed to:

aspsoftwing Listserver

JOIN, QUIT or Search ARCHIVES:http://www.asplists.com/asplists/perfcounters.asp

Send Listserver Questions [email protected]

Related Links

http://www.learnASP.com/learn/new.asp by Charles M. Carroll Page 271

New Lessons (new.asp) - Page 1 Global.asa Resources (globalmore.asp) - Page 2 Validation Resources (validationmore.asp) - Page 3 Graphic Size Detector (graphicdetect.asp) - Page 4 Database Display via GetRows (dbtablegetrows.asp) - Page 5 Database Display via GetString (dbtablegetstring.asp) - Page 6 ASPDB - Superb Database Component (aspdb.asp) - Page 7 Date/Time on ASP Pages by Tony Arguelles (datetime.asp) - Page 8 Time Tasks with Millisecond Accuracy (speedtimer.asp) - Page 9 Hidden Fields/Pass Data Among Pages (hidden.asp) - Page 10 Cookies/Pass Data Among Pages (cookies.asp) - Page 11 Remote Scripting Simple Example (remotescripting.asp) - Page 12 Remote Scripting/Microsoft Sample (remotescriptingms.asp) - Page 13 Database to ListBox Online Resources (dblistmore.asp) - Page 14

Page 269: [ebook] Learn ASP

Dynamic ListBox Online Examples (listdynamicmore.asp) - Page 15

http://www.learnASP.com/learn/changed.asp by Charles M. Carroll Page 272

Recently Modified Lessons (changed.asp) - Page 1 Tips to Speed Up Pages (speedtips.asp) - Page 2 Time Tasks to Millisecond (speedtimer.asp) - Page 3 Just say NO to session objects (nosessionobjects.asp) - Page 4 ListBox: Online Resources (dblistmore.asp) - Page 5 Database Tables: Online Resources (dbtablemore.asp) - Page 6 Forms: Introduction (formintro.asp) - Page 7 Server Tuning Resources (speedserver.asp) - Page 8 Print All Pages (printout.asp) - Page 9 TreeView TOC updated (joust.asp) - Page 10

http://www.learnASP.com/learn/newbie.asp by Charles M. Carroll Page 273

Great Beginners Lessons (newbie.asp) - Page 1 Authentication Overview by Kevin Flicks (authenticate.asp) - Page 2 Display, Edit Database Data (dbfull1.asp) - Page 3 Database Display on Web Page (dbtable.asp) - Page 4 Paged (1 of x) Database displays (dbtablepaged.asp) - Page 5 Protecting Pages via Login (security.asp) - Page 6 Count Records Reliably (dbcount.asp) - Page 7 Simple Database Search (SQLwhereform1.asp) - Page 8 Advice for ASP Coding (advice.asp) - Page 9 Including/Reusing Content (inc.asp) - Page 10 Including Files Dynamically (includedynamic.asp) - Page 11 Display ListBox from Database (dblist.asp) - Page 12 Grab Server Variables (server.asp) - Page 13 Detect Browsers (bc.asp) - Page 14 Create, Process Forms (Form.asp) - Page 15 Easy Databases w/FREE GenericDB! (genericdb.asp) - Page 16 Linked Listboxes w/Jscript (listdynamic.asp) - Page 17

http://www.learnASP.com/learn/faqs.asp by Charles M. Carroll Page 274

Commerce: certificates, https:// (FAQCommerceCertif.asp) - Page 275 Commerce: online charging (FAQCommerceCharge.asp) - Page 276 Commerce: components, shopping carts (FAQCommerceCarts.asp) - Page 277

Page 270: [ebook] Learn ASP

Jscript: closing DB Connections (FAQJscriptCleanUp.asp) - Page 278 Jscript: online references (FAQJscriptRefs.asp) - Page 279 Jscript: display databases (FAQJscriptDB.asp) - Page 280 Oracle: I can't connect (FAQOracleconnect.asp) - Page 281 Oracle: Know any good books? (FAQOraclebooks.asp) - Page 282 Oracle: Calling Stored Procs (FAQOraclestoredproc.asp) - Page 283 VB: DLL overwrite problems (FAQvbDLLoverwrite.asp) - Page 284 VB: Recommended books (FAQvbBooks.asp) - Page 285

http://www.learnASP.com/learn/FAQCommerceCertif.asp by Charles M. Carroll Page 275

[aspcommerce] listserv

FAQ #1: How do I setup https:// and get a certificate?Two vendors offer this

www.verisign.com●

www.thawte.com●

http://www.learnASP.com/learn/FAQCommerceCharge.asp by Charles M. Carroll Page 276

[aspcommerce] listserv

FAQ #2: I want to process credit cards on my web site. Where do I start?

Many sites offer credit card processing but here is a list (you can search the archives for opinions and rates, etc.)

www.anacom.com●

www.cybercash.com●

www.charge.com●

ww.swreg.com●

http://www.authorizenet.com/●

http://www.securetrading.co.uk (may do just the UK)●

http://www.worldpay.com●

http://www.merchantservices.com●

http://www.learnASP.com/learn/FAQCommerceCarts.asp by Charles M. Carroll Page 277

[aspcommerce] listserv

FAQ #3: What ASP components and scripts work to charge online?ASPcharge from www.bluesquirell.com●

Page 271: [ebook] Learn ASP

IPCharge from www.gosoftinc.com●

IISCart from http://www.iiscart.com●

PCAuthX used with Tellan's PCAuthorize*Hub at http://www.active4.com/default.asp?PI=PCAUTHX●

www.mercantec.com●

http://www.storefront.net●

http://www1.viaweb.com/softartisans/saxcheck.html●

ActiveShopper at http://www.active4.com●

http://www.learnASP.com/learn/FAQJscriptCleanUp.asp by Charles M. Carroll Page 278

[aspJscript] listserv

FAQ #1: How do I close database connections?

Question: In VBScript, after you would close the recordset and connection objects, you would insure that the objects aredisposed of properly by adding:

rs.closeSet rs = Nothingconn.closeSet conn = Nothing

Can someone tell me if there is an equivalent in JavaScript?

Answer:rs.close;rs=null;conn.close;conn=null;

http://www.learnASP.com/learn/FAQJscriptRefs.asp by Charles M. Carroll Page 279

[aspJscript] listserv

FAQ #2: Is there any online Jscript Tutorials?Scott Kallymer, author of the "Wise ASP" column at:http://www.aspalliance.com/wsk/

Phil Malone offers some "Jscript Tips" at:http://www.aspalliance.com/philmalone

Scott Mitchell offers:http://www.4GuysFromRolla.com/webtech/vb2java.shtml

Page 272: [ebook] Learn ASP

http://www.learnASP.com/learn/FAQJscriptDB.asp by Charles M. Carroll Page 280

[aspJscript] listserv

FAQ #3:How do I connect to a database with Jscript?

There is some sample code to display a listbox from an ASP Database at:http://www.aspmagazine.com/aspmagazine/issue10jscript.asp

http://www.learnASP.com/learn/FAQOracleconnect.asp by Charles M. Carroll Page 281

[asporacle] listserv

FAQ #1: I cannot connect to Oracle via ASP....contributed by Bret H. Grade [email protected]

MCSE, MCP+Internet Senior Consultant,ARIS Corporation Inquire at http://www.aris.com

What do I need for connectivity for Oracle from ASP:This question is a very valid question for most people beginning and experienced with Oracle from within ASP. Because of the variety of thingsthat are needed, there can be many answers to this question. Here are the basics:

SQL*Net needs to be loaded on the machine where IIS resides.●

A "System" DSN (Data Source Name) should be configured on the machine where IIS resides. Or you may use a "DSNless" connection. Aconnection of this type still requires you have the correct ODBC driver. See below.

Your DSN connection consists of an ODBC driver. Here are your most utilized choices:●

Microsoft ODBC Driver for Oracle 2.00.00.6325 (Microsoft supplied driver)●

Microsoft ODBC for Oracle 2.573.3513.00 (Microsoft supplied driver)●

Oracle ODBC Driver 7.x or 8.x (Oracle supplied driver)●

Most people prefer to use the Microsoft ODBC Driver for Oracle 2.0 for the reason that is seems to be more stable than the 2.5driver from MS.

The Oracle ODBC Driver has a variety of incompatibility problems with ASP and it is not recommended to use this driver.

Make sure you’ve tested the DSN before you implement. This will prevent you from having to deal with connectivity problems atthis level while developing.

The TNSNAMES.ORA file needs to have been configured on the machine where IIS resides. This file is located in youORANT\NETWORK (or NET80)\ADMIN\ directory. An Example configuration is provided below:

orcl.world = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (COMMUNITY = tcp.world) (PROTOCOL = TCP) (Host = THE IP ADDRESS OF YOUR HOST OR DNS NAME) (Port = 1521) ) (ADDRESS = (COMMUNITY = tcp.world) (PROTOCOL = TCP) (Host = THE IP ADDRESS OF YOUR HOST OR DNS NAME) (Port = 1526) )

Page 273: [ebook] Learn ASP

) (CONNECT_DATA = (SID = ORCL) ) )

Some things to note are the HOST, CONNECT_DATA, and PORT parameters.

The host is the IP address or DNS name of the machine where the Oracle instance (database) you are trying to connect to resides.●

The CONNECT_DATA string is made up of the Oracle SID. The SID is the name of the Oracle Instance.●

The PORT parameter is defaulted to 1521 and 1526. These are the default installations where the listener listens for requests from themachine where Oracle is installed.

What does a connection string to Oracle look like?Set AUM = Server.CreateObject("ADODB.Connection")

AUM.Open Connect_String(DSN), USERNAME, PASSWORD

How do you configure the Oracle ODBC Driver?To configure the ODBC driver, you will first need to :

open the "ODBC Data Sources" icon in the control panel applet.1.

Once opened, go to the "System DSN" tab and choose add. Select an ODBC driver (See "WHAT DO I NEED FOR CONNECTIVITYFOR ORACLE FROM ASP").

2.

Once selected, you will see the following screen minus everything below connect string. If you want the advanced configuration as shownbelow select options.

3.

* The above example is utilizing the "Microsoft ODBC Driver for Oracle 2.00.00.6325" driver.

I’m getting an error with my SQL statement and I don’t know why!This problem seems to come up quite often. Rest assured, it is not just common to Oracle. Most of the time this problem is because the developerhas not tested the SQL statement in question via a SQL tool (i.e. SQL Plus for Oracle or ISQL in SQL Server). Some of the steps you should takewhen debugging are:

Page 274: [ebook] Learn ASP

ALWAYS run your command through SQL*PLUS if your statement fails. This way you eliminate the fact that it could be a syntaxproblem with Oracle.

If you have successfully tested the statement against the database outside of ASP, make sure your statement is syntactically correct withADO.

Make sure all concatenated statements have the correct spaces in them.●

sqlChk = "SELECT COUNT(NAME)"

sqlChk = sqlChk & " FROM MYAPP_USERS"

sqlChk = sqlChk & " WHERE NAME = UPPER('" & Request.Form("txtUserID") & "')"

* Note: Although eliminating the number of lines for interpretation can optimize your code, some prefer readability to the slightperformance increase.

If you were to look closely, you would notice that the second and third line have a space between the start of the clause and the ".Another method to insure proper spaces between concatenated statements would be to put the space at the end of each line.

Response.Write your sql statement to the screen.●

Make sure that you DO NOT have spaces in your table names.●

I keep getting a TNS error while trying to connect.Check the following:

Insure that you can connect via SQL*PLUS. This will confirm that your TNSNAMES.ORA file is configured properly. If not, check thefollowing:

Verify the instance is running (i.e. Oracle is up).●

Make sure you have a TNSNAMES.ORA entry. See "WHAT DO I NEED FOR CONNECTIVITY FOR ORACLE FROM ASP".●

Check to see that the "TNS listener" service is running on the machine where Oracle resides.●

Check to make sure that you have the correct ODBC driver. See "WHAT DO I NEED FOR CONNECTIVITY FOR ORACLE FROMASP".

If you can connect via SQL*PLUS, check the following:●

Check to make sure that you have the correct ODBC driver. See "WHAT DO I NEED FOR CONNECTIVITY FOR ORACLE FROMASP".

http://www.learnASP.com/learn/FAQOraclebooks.asp by Charles M. Carroll Page 282

[asporacle] listserv

FAQ #2: I need some good books on Oracle. Can you recommend any?

ADO 2.0 Programmers Referencewritten by David Sussman & Alex Homerpublished by WROXbook @http://www.activeserverpages.com/books/wroxadoref.asp

ASP and RDS Database Programmingwritten by Matt Brown, David Sussman, Peter DeBetta, John Pappa, Eric Wilsonpublished by WROX Pressbook @http://www.activeserverpages.com/books/wroxadords.asp

Oracle Programming with Visual Basicwritten by Nick Snowdon, published by Sybex

According to "Bryan P.O'Neil" [email protected]:Not really about ASP... but... this is an excellent book and is a very good all around Oracle text. It includes detailed info on RDO,

Page 275: [ebook] Learn ASP

ODBC Direct, ADO and Oracle Objects for OLE.

http://www.learnASP.com/learn/FAQOraclestoredproc.asp by Charles M. Carroll Page 283

[asporacle] listserv

FAQ #3: How do I call an Oracle Stored Procedureby Surya RaoHOW TO CALL A STORED PROCEDURE FROM AN ASP PAGE:=================================================

Folks, contrary to popular belief there are many waysto call stored procedures from an ASP page. I've triedit with Oracle (the only REAL RDBMS ;-) and it works.

If this bit below, is useful, it can be archived forfuture use by the LISTMASTER, with any changes.

Assume you have a procedure like this one below,and that it has been already created on theOracle database. This procedure doesn't returnanything, but that doesn't change anything!

STEP #1:+++++++++

/******STORED PROCEDURE ON ORACLE DATABASE************//*====================================================*/create or replace procedure test_me is w_count integer;begin insert into TEST values ('Surya was here'); --commit it commit;end;/*****END OF STORED PROCEDURE****/

STEP # 2:+++++++++I assume you have tested it from sql*plus by running thefollowing statements:

/************TEST THE STORED PROCEDURE FROM SQL*PLUS******/SQL> execute test_me

PL/SQL procedure successfully completed.

SQL> /***************END OF TESTING THE STORED PROC************/

STEP# 3:++++++++/*****CALLING A STORED PROCEDURE FROM ASP******************/

1. USING THE CONNECTION OBJECT

You can execute stored procedures which perform Oracle Server sidetasks and return you a recordset. You can only use this method ifyour stored procedure doesn't return any OUTPUT values.

Page 276: [ebook] Learn ASP

<% Set Conn = Server.CreateObject("ADODB.Connection")

Conn.execute "test_me",-1,4%> Note that -1 means no count of total number of records is required. If you want to get the count, substitute count with some integer variable

Note that 4 means it is a stored procedure. By using the actual number -1 and 4, you don't need the server side include ADOVBS.INC ;-)

The above would do the job on the database and return back to you without returning any recordsets.

Alternatively, you could:

<% Set rs = conn.execute("test_me",w_count,4) %>

W_count is the number of records affected. If your stored procedure were to return a query result, it is returned within your recordset (rs). This method is useful with Stored procs which return results of an SQL query

2. USING THE COMMAND OBJECT

<% Set Conn = Server.CreateObject("ADODB.Connection") Set Comm = Server.CreateObject("ADODB.Command")

Set comm.ActiveConnection = conn comm.commandtype=4

'(or use adCmdStoredProc instead of 4, but then you would have to 'include the ADOVBS.INC. Its upto you

comm.commandtext = "test_me"

comm.execute 'or Set rs = comm.execute()%>

STEP# 4+++++++++/************PASSING INPUT/OUTPUT PARAMETERS**************************/<% 'If your stored procedure accepts IN parameters and returns OUT parameters 'here's how to go about it

set param = comm.Parameters param.append comm.createparameter("Input",3,1) param.append comm.createparameter("Output",3,2) 'Note that 3 = adInteger for the datatype 'Note that 1=adParamInput and 2=adParamOutput for parameter direction 'Pass the input value comm("Input") = "...."

OR

set param = comm.createparameter("InPut",3,1) set param = comm.createparameter("OutPut",3,2) comm.parameters.append param 'Pass the input value comm("Input") = "...."

Page 277: [ebook] Learn ASP

'Execute after setting the parameters comm.execute()

'If your stored procedure returns OUT parameters, here's how to get it

Out_1 = comm("Output") 'and so on...

%>

Thats it!

http://www.learnASP.com/learn/FAQvbDLLoverwrite.asp by Charles M. Carroll Page 284

[aspVBComponents] listserv

FAQ #1:I cannot overwrite a DLL I want to update....writeup thanks to Michiel van Otegem <[email protected]>

This happens when the DLL is loaded in memory because it is in use or has been used by an application. The DLL needs to beunloaded before it can be overwritten. The solution depends on the version of Internet Information Server (IIS) and if MicrosoftTransaction Server (MTX) is being used or not.

IIS version 3 (no MTX)In order to unload the DLL, you need to stop the webservice. This can be done through Control Panel->Services or with the InternetService Manager. After the webservice has stopped, the DLL can be overwritten. When the webservice restarts the new DLL is inplace and will be used for subsequent calls.

IIS version 4If the DLL is not registered as an MTX package and the website(s) using the DLL do not run in a separate memory space (checkthis with the Internet Service Manager), the same course of action as with IIS 3 is to be taken. Because of the complexity of thewebservice in IIS 4, the easiest way to shutdown the webservice is through Control Panel->Services.

If the DLL is not registered as an MTX package and the website(s) using the DLL all run in a separate memory space, stoppingthose websites will suffice. The DLL can then be overwritten en the sites can be restarted.

If the DLL is registered as an MTX package, the DLL will be unloaded after the amount of minutes set with the Transaction ServerExplorer for that package, after which you can overwrite the DLL. If the DLL hasn’t been unloaded yet, you can force it to unload withthe Transaction Server Explorer by choosing Shutdown (right click on a package). After the new DLL is in place choose Refresh AllComponents (right click on the computer with the DLL).

There’s a catch however… the new DLL needs to be compiled with binary compatibility with the old DLL. If you don’t do this, youhave to unregister and remove the old DLL, place the new DLL, register it and import it into the right package again.

http://www.learnASP.com/learn/FAQvbBooks.asp by Charles M. Carroll Page 285

[asp VB Components] listserv

FAQ #2: How Do I make my first VB Component?see:

http://www.activeserverpages.com/learn/buildvbsimple.asp●

http://www.activeserverpages.com/learn/buildregister.asp●

That should get you started.

Page 278: [ebook] Learn ASP

http://www.learnASP.com/learn/overview.asp by Charles M. Carroll Page 286

ASP Objects: Built In (aspobjects.asp) - Page 287 ASP Objects: Created when Needed (aspobjects2.asp) - Page 288

http://www.learnASP.com/learn/aspobjects.asp by Charles M. Carroll Page 287

Built-In ASP ObjectsResponse ObjectSend text, data and cookies to the browser and control each stage of transmitting the page. Its methods can be used to send text,data and cookies to the browser and control each stage of transmitting the page.

Server Objectcreate COM objects, some conversion facilities and overall scripting control.

Request ObjectRead submitted form data, cookies and server variables.

Session Objectallows you to attach data to a specific user browsing your site that is isolated and invisible to other users.

Application ObjectAllows you to manipulate global data in your script that will be visible to all users browsing the site or your script code.methods: lock, unlock

http://www.learnASP.com/learn/aspobjects2.asp by Charles M. Carroll Page 288

Other ASP ObjectsSome objects will not be needed for all web pages. Those objects are included with ASP but are created explicity by the page whenneeded so they are not always in memory:

BrowserCap object - this can simplify detecting browsers and aid in writing one page that reacts to all browsers instead ofhaving to write separate pages for each browser.

FileSystem object - this object provides a script with tools to manipulate files and directories.

ADO Objects - The connection, recordsets, command and field objects make programming high concurrency database readsand updates possible.

Dictionary object - provides an alternative to arrays that can be accessed/keyed by names instead of numbers and elementscan be added or removed in any sequence.

Misc. Objects - Content Linker, Permission Checker, Ad Rotator, Page Counter, etc.

Page 279: [ebook] Learn ASP

http://www.learnASP.com/learn/alphaindex.asp by Charles M. Carroll Page 289

A ADO (Active Data Objects) Features ToC (/learn/ado.asp) - Page 106 ASPDB - Displaying A Table (/learn/aspdb1.asp) - Page 104 ASPDB - Editing A Table (/learn/aspdb2.asp) - Page 105 Add Record w/SQL #1 (/learn/dbnewrec.asp) - Page 114 Add Record w/SQL #2 (/learn/dbnewSQL.asp) - Page 115 Add Record with .AddNew Method (/learn/dbnewADO.asp) - Page 116 ADSI: Active Directory Services Interface Intro (/learn/ADSI.asp) - Page 207 Advice For Better Coding! (/learn/advice.asp) - Page 216 Application Data (/learn/sessionsapps.asp) - Page 171 Application Data: Worlds Fastest ListBox (/learn/speedappdata.asp) - Page 172 ASPExpress - HOT ASP Editor (/learn/aspexpress.asp) - Page 168 Authentication/Security TOC (/learn/authenticate.asp) - Page 137 Arrays TOC (/learn/subjectArrays.asp) - Page 0 Arrays: Basics (/learn/arrays.asp) - Page 153 Arrays: Variable Size (/learn/arrays2.asp) - Page 154 Arrays: Best Way To Load (/learn/arrays3.asp) - Page 155 Authentication TOC (/learn/subjectAuthenticate.asp) - Page 0 Authenticate: Overview by Kevin Flick (/learn/authenticateoverview.asp) - Page 138 Authenticate: Comparison by Kevin Flick (/learn/authenticatecomparisons.asp) - Page 139 Authenticate: NT Challenge/Response by Kevin Flick (/learn/authenticatentcr.asp) - Page 140 Authenticate: Basic Authentication by Kevin Flick (/learn/authenticatebasic.asp) - Page 141 Authenticate: Cookies by Kevin Flick (/learn/authenticatecookies.asp) - Page 142 Authenticate: Certificates by Kevin Flick (/learn/authenticatecertificate.asp) - Page 143 Authenticate: Build Your Own by Kevin Flick (/learn/authenticatebuild.asp) - Page 144 Authenticate: Protect Pages via Login #1 (/learn/security.asp) - Page 145 Authenticate: Protect Pages via Login #2 (/learn/security2.asp) - Page 146 Authenticate: 3rd Party by Kevin Flick (/learn/authenticate3rdparty.asp) - Page 147

B Books & Online Resources (/learn/research.asp) - Page 211 Browscap: Basics (/learn/bc.asp) - Page 27 Browscap: Intricate Details (/learn/bcdetails.asp) - Page 28 BrowserHawk: Determing Browser Type (/learn/bhbrowtype.asp) - Page 29 BrowserHawk: older AOL browsers (/learn/bhaol.asp) - Page 30 Browserhawk: MS-Wallet (/learn/bhwallet.asp) - Page 31 BrowserHawk - Reverse DNS lookups (/learn/bhresolveip.asp) - Page 32 BrowserHawk - Frame support (/learn/bhframes.asp) - Page 33

C C++/ATL ASP Component Building (/learn/buildc.asp) - Page 256 CASE syntax #1 (/learn/case.asp) - Page 58 CASE syntax #2 (/learn/case2.asp) - Page 59 Checkbboxes in Forms (/learn/formcheckbox.asp) - Page 55 Content Linker: Prev/Next Page (/learn/cl.asp) - Page 238

Page 280: [ebook] Learn ASP

Content Linker: TOC (/learn/cl2.asp) - Page 239 Content Linker: Listbox of contents (/learn/cl3.asp) - Page 240 Commerce: certificates, https:// (/learn/FAQCommerceCertif.asp) - Page 275 Commerce: online charging (/learn/FAQCommerceCharge.asp) - Page 276 Commerce: components, shopping carts (/learn/FAQCommerceCarts.asp) - Page 277 Converting a DB to a Comma-Delimited file (/learn/dbconvert.asp) - Page 99 Count Records in Query (/learn/dbcount.asp) - Page 112 Cookies: Reading Them (/learn/cookiesform.asp) - Page 66 Cookies: Writing Them (/learn/cookiesformrespond.asp) - Page 67 Cookies: Deleting Them (/learn/cookiesforget.asp) - Page 68 Cookies: Simplified by Paul Rigor (/learn/cookiesub.asp) - Page 69 Cache No More by Phil Paxton (/learn/cachenomore.asp) - Page 217 CASE reads better than IF (/learn/caseisbetter.asp) - Page 228 advice: Close objects, set to Nothing (/learn/cleanup.asp) - Page 222 Commerce and ASP (/learn/commerce.asp) - Page 195 Components from 3rd Party (/learn/components.asp) - Page 264 Component Checker (/learn/componentchecker.asp) - Page 48 Core Ideas TOC (/learn/core.asp) - Page 3 Credits & Instructions (/learn/credits.asp) - Page 2

D Date/Time on ASP Pages by Tony Arguelles (/learn/datetime.asp) - Page 18 Databases TOC (/learn/database.asp) - Page 80 DB: Access vs. SQL Server (/learn/accessSQLserver.asp) - Page 101 DB: Converting a DB to a Comma-Delimited file (/learn/dbconvert.asp) - Page 99 DB: Count Records in Query (/learn/dbcount.asp) - Page 112 DB: Deleting a Record w/SQL (/learn/dbSQLdelete.asp) - Page 100 DB: Cursor Types by Phil Paxton (/learn/adocursortypes.asp) - Page 113 DB: Generic DB by Eli Robillard (/learn/genericdb.asp) - Page 87 DB: GetString function (/learn/dbgetstring.asp) - Page 117 DB: Input Form (/learn/dbnewrec.asp) - Page 114 DB: Input Form, added w/SQL (/learn/dbnewSQL.asp) - Page 115 DB: Input Form, Added w/ADO .addnew (/learn/dbnewADO.asp) - Page 116 DB: Limiting Number of Records (/learn/dbmaxrecs.asp) - Page 110 DB: List Box Display (/learn/dblist.asp) - Page 85 DB: Paging Records (/learn/dbtablepaged.asp) - Page 111 ADO: Schemas to access table lists (/learn/dbschemas.asp) - Page 119 ADO: Schemas to access All Data (/learn/dbschemasall.asp) - Page 120 DB: SQL Mistakes (/learn/dbtroubleshoot2.asp) - Page 121 DB: Table Display w/Simple Code (/learn/dbsimple.asp) - Page 83 DB: Table Display for any Table (/learn/dbtable.asp) - Page 84 DB: Table Display,1 param (/learn/db1parm.asp) - Page 122 DB: Table Listings from Databases (/learn/dbtablelists.asp) - Page 118 DB: Table Display: More ways... (/learn/dbtablemore.asp) - Page 88 DB: Table Show-Edit Record #1 (/learn/dbfull1.asp) - Page 96 DB: Table Show-Edit Record #2 (/learn/dbfull2.asp) - Page 97 DB: Table Show-Edit Record #3 (/learn/dbfull3.asp) - Page 98 DB: Troubleshooting Part 1 (/learn/dbtroubles.asp) - Page 81 DB: Troubleshooting Part 2 (/learn/dbtroubles2.asp) - Page 82

Page 281: [ebook] Learn ASP

DB: Update/Edit Record (/learn/dbupdate.asp) - Page 123 Dictionary Objects (/learn/dictionary.asp) - Page 156 Documentation, free from Microsoft (/learn/docs.asp) - Page 6 DSN: DSNLess Connections (/learn/dbopen.asp) - Page 89 DSN: DSN Setup #1 by Rob Martinson (/learn/dsn1.asp) - Page 90 DSN: DSN Setup #2 by Rob Martinson (/learn/dsn2.asp) - Page 91 DSN: DSN Setup #3 by Rob Martinson (/learn/dsn3.asp) - Page 92 DSN: DSN Setup #4 by Rob Martinson (/learn/dsn4.asp) - Page 93 DSN: DSN Setup #5 by Rob Martinson (/learn/dsn5.asp) - Page 94 DSN: DSN Setup #6 by Rob Martinson (/learn/dsn6.asp) - Page 95

e Editor: ASPExpress - HOT ASP Editor (/learn/aspexpress.asp) - Page 168 Encaspulate Code! (/learn/encapsulate.asp) - Page 227 Encode with Redirects (/learn/encode.asp) - Page 219 advice: Error Trapping Strategies (/learn/errorstrategies.asp) - Page 229 advice: Error Trapping Secrets (/learn/errorsecrets.asp) - Page 230

F File Objects: Read Directory (/learn/fileobjects.asp) - Page 241 File Objects: Display Directory as Links/Graphics (/learn/fileobjects2.asp) - Page 242 File Objects: Read Disk Drive by Steven Harper (/learn/fileobjects3.asp) - Page 243 File Objects: Show Dir List by Tim Foster (/learn/fileobjects4.asp) - Page 244 File Upload: Simple Example (/learn/uploadsimple.asp) - Page 266 File Upload: Multi-part form (/learn/uploadmultipart.asp) - Page 267 File Upload: Limit Size (/learn/uploadlimitsize.asp) - Page 268 File Upload: Many Files (/learn/uploadmanyfiles.asp) - Page 269 Forms/Decisions Table of Contents (/learn/Form.asp) - Page 51 Forms: For Each Iteration (/learn/formforeach.asp) - Page 64 Forms: mailing w/ASPMail (/learn/formsendmail.asp) - Page 65 Format: Numbers #1 (/learn/formatnumbers.asp) - Page 15 Format: Numbers #2 (/learn/formatnumbers2.asp) - Page 16 Format: Dates #1 (/learn/formatdates.asp) - Page 17 Forms: Introduction (/learn/formintro.asp) - Page 52 Forms: Check Box (/learn/formcheckbox.asp) - Page 55 Forms: ListBox (/learn/formlistbox.asp) - Page 57 Form: Listbox Linked Dynamically w/JavaScript (/learn/listdynamic.asp) - Page 198 Form: ListBox Linked Dynamically from Database w/JavaScript (/learn/listdynamicdb.asp) - Page 200 Form: Listboxes Easy Choices by Bill Wilkinson (/learn/listdual.asp) - Page 201 Forms: Radio Buttons (/learn/formradio.asp) - Page 56 Forms: Text Box (/learn/formtextbox.asp) - Page 53 Forms: Text Area (/learn/formtextarea.asp) - Page 54 Frequently Asked Questions (/learn/faqs.asp) - Page 274 Function: Working Days (/learn/functionworkingdays.asp) - Page 164

G Generic DB by Eli Robillard (/learn/genericdb.asp) - Page 87 Getstring method (/learn/dbgetstring.asp) - Page 117 Getstring to display database table (/learn/dbtablegetstring.asp) - Page 107

Page 282: [ebook] Learn ASP

getrows to display database table (/learn/dbtablegetrows.asp) - Page 108 Sessions: Global.asa Events (/learn/global.asp) - Page 174 Global.asa and Scalability (/learn/globalproblems.asp) - Page 176

H HTMLencode / server.htlmencode (/learn/res5.asp) - Page 11 Hidden Fields/Pass Data Between Pages (/learn/hidden.asp) - Page 74 Homesite/HTML Editor w/ASP Support (/learn/homesite.asp) - Page 169

I If reads worse than CASE (/learn/caseisbetter.asp) - Page 228 IF syntax #1 (/learn/if.asp) - Page 60 IF syntax #2 (/learn/if2.asp) - Page 61 IF syntax #3 (/learn/if3.asp) - Page 62 IF syntax #4 (/learn/if4.asp) - Page 63 Include: Basics (/learn/inc.asp) - Page 12 Include: Dynamic FileName (/learn/includedynamic.asp) - Page 13 Include: Sample Exercise (/learn/booksample.asp) - Page 14 Index Server w/ADO (/learn/indexserver.asp) - Page 194 IsClientConnected & Stray Tasks (/learn/isclientconnected.asp) - Page 185

J Java ASP Components Building (/learn/buildjava.asp) - Page 255 Jscript: closing DB Connections (/learn/FAQJscriptCleanUp.asp) - Page 278 Jscript: online references (/learn/FAQJscriptRefs.asp) - Page 279 Jscript: display databases (/learn/FAQJscriptDB.asp) - Page 280 JScript ServerSide: Resources (/learn/javascript.asp) - Page 196 Joins in SQL by Aaron Alexander (/learn/dbjoins.asp) - Page 0

L Loops: DO WHILE/UNTIL #1 (/learn/DoLoop.asp) - Page 19 Loops: Timeouts #2 (/learn/DoLoop2.asp) - Page 20 Loops: Intercepting Timeouts #3 (/learn/DoLoop3.asp) - Page 21 Limiting database Records (/learn/dbmaxrecs.asp) - Page 110 Listbox Display from database (/learn/dblist.asp) - Page 85 Listbox from Database Online Resources (/learn/dblistmore.asp) - Page 86 ListBox in forms (/learn/formlistbox.asp) - Page 57 Listbox linked Dynamically w/JavaScript (/learn/listdynamic.asp) - Page 198 ListBox Linked Dynamically from Database w/JavaScript (/learn/listdynamicdb.asp) - Page 200 Listbox Dynamic Online Examples (/learn/listdynamicmore.asp) - Page 199 Listbox Easy Choices by Bill Wilkinson (/learn/listdual.asp) - Page 201

M Mailing Form w/ASPMail (/learn/formsendmail.asp) - Page 65 Mail: Simple Example (/learn/serverobjectsmail.asp) - Page 265 MSMQ: Overview (/learn/MSMQ.asp) - Page 208 Microsoft Transaction Server (MTS) (/learn/buildmtx.asp) - Page 257 MTS: Overview (/learn/buildmtxoverview.asp) - Page 258 MTS: Essentials (/learn/buildmtx2.asp) - Page 259

Page 283: [ebook] Learn ASP

MTS: Transactional ASP pages (/learn/buildmtxasp.asp) - Page 260 MTS: Books (/learn/booksmtx.asp) - Page 261 MTS: Registering Components (/learn/buildmtxregister.asp) - Page 263

N New Lessons TOC (/learn/new.asp) - Page 271 Nothing and Scalability (/learn/nothing.asp) - Page 186 New Record w/SQL #1 (/learn/dbnewrec.asp) - Page 114 New Record w/SQL #2 (/learn/dbnewSQL.asp) - Page 115 New Record with .AddNew Method (/learn/dbnewADO.asp) - Page 116

O Option Explicit (/learn/explicit.asp) - Page 218 DB: Oracle and ASP (/learn/oracle.asp) - Page 102 Oracle: I can't connect (/learn/FAQOracleconnect.asp) - Page 281 Oracle: Know any good books? (/learn/FAQOraclebooks.asp) - Page 282 Oracle: Calling Stored Procs (/learn/FAQOraclestoredproc.asp) - Page 283

P Paging Records in Database Display (/learn/dbtablepaged.asp) - Page 111 Perf Counters on ASP page (/learn/perfcounters.asp) - Page 270 Perlscript ServerSide: Resources (/learn/perlscript.asp) - Page 202 PWS: Personal Web Server Introduction (/learn/PWS.asp) - Page 50 Prpoerties of COM objects: onl read once (/learn/propertyexpense.asp) - Page 225

Q Quality, Re-Usable Code TOC (/learn/qualitycode.asp) - Page 148

R Radio Buttons in Forms (/learn/formradio.asp) - Page 56 RDS: Remote Data Services Intro (/learn/rds.asp) - Page 205 RDS Resources: RDS Expert Carl Prothman (/learn/prothman.asp) - Page 206 Remote Scripting: Simple Example (/learn/remotescripting.asp) - Page 203 Resource: Must Buy Component Building Book (/learn/bookcomponents.asp) - Page 212 Resource: ASP101.com Scripts for your site (/learn/asp101.asp) - Page 213 Resource: 4GuysFromRolla.com Tons of ASP Material (/learn/4guysfromrolla.asp) - Page 214 Resource: ASPToday.com from WROX (/learn/asptoday.asp) - Page 215 Response: Basics (/learn/res.asp) - Page 7 Response: Buffer Control (/learn/res2.asp) - Page 8 Response: Redirection (/learn/res3.asp) - Page 9 Response: Quotes & Special Characters (/learn/res4.asp) - Page 10 Response: Encoding URLs, HTML (/learn/res5.asp) - Page 11

S Safe Color Pallete (/learn/safecolors.asp) - Page 210 Schemas to access table lists (/learn/dbschemas.asp) - Page 119 Schemas to access All Data (/learn/dbschemasall.asp) - Page 120 Searching a Database Example (/learn/SQLandor.asp) - Page 132 advice: Secure Code and Data (/learn/securecode.asp) - Page 226

Page 284: [ebook] Learn ASP

advice: Server.MapPath is Good (/learn/pathmap.asp) - Page 223 Server Variables: Popular Ones (/learn/server.asp) - Page 22 Server Variables: Domain/Host Name (/learn/server2.asp) - Page 23 Server Variables: Displaying All (/learn/serverall.asp) - Page 24 Sessions: What are they? (/learn/sessionswhat.asp) - Page 72 Session COM objects are wasteful (/learn/nosessionobjects.asp) - Page 224 Speed: Research Online (/learn/speedresearch.asp) - Page 179 Speed: Coding Tips (/learn/speedtips.asp) - Page 181 Speed: Database Percieved Speed (/learn/speedtables.asp) - Page 182 Speed: Database Retrieval Speed (/learn/speedtablesall.asp) - Page 183 Speed: OLEDB & ODBC Drivers differences (/learn/speedtablesdrivers.asp) - Page 184 Speed: Time Tasks w/VB Component by Sunny Yu #1 (/learn/asptime.asp) - Page 306 Speed: Time Tasks w/VB Component by Sunny Yu #2 (/learn/asptimer.asp) - Page 307 Speed, Scalability TOC (/learn/speedscale.asp) - Page 170 Speedup Your Server (/learn/speedserver.asp) - Page 178 SQL statements: Write to Browser (/learn/sqlwrite.asp) - Page 220 SQL Table of Contents (/learn/SQL.asp) - Page 124 SQL Troubles (/learn/SQLtroubles.asp) - Page 125 SQL: Example Tables (/learn/SQLexamples.asp) - Page 126 SQL: Where Clause Basics (/learn/SQLwhere.asp) - Page 127 SQL: Where Clause Examples (/learn/SQLwhere2.asp) - Page 128 SQL: Search Forms #1 (/learn/SQLwhereform1.asp) - Page 129 SQL: Search Forms #2 (/learn/SQLwhereform2.asp) - Page 130 SQL: Search Forms #3 (/learn/SQLwhereform3.asp) - Page 131 SQL: Search AND/OR Operators (/learn/SQLandor.asp) - Page 132 SQL: Search AND/OR Examples (/learn/SQLandor2.asp) - Page 133 SQL: COUNT, GROUPBY (/learn/SQLcount.asp) - Page 134 SQL: SUM, MIN, AVE, MAX (/learn/SQLaggregate.asp) - Page 135 SQL Joins by Aaron Alexander (/learn/dbjoin.asp) - Page 136 Strings: Core Functions (/learn/strings.asp) - Page 149 Strings: SPLIT Function (/learn/stringsplit.asp) - Page 150 Strings: REPLACE Function (/learn/stringreplace.asp) - Page 151 Strings: JOIN Function (/learn/stringjoin.asp) - Page 152 Subroutine: Working with Dates #1 (/learn/subdates.asp) - Page 157 Subroutine: Working with Dates #2 (/learn/subdates2.asp) - Page 158 Subroutine: Query2Table (/learn/subdbtable.asp) - Page 159 Subroutine: Query2List (/learn/subdblist.asp) - Page 160 Subroutine: Highly Reusable (/learn/subreusable.asp) - Page 161 Subroutine: List Box w/optional params (/learn/subDBlistbest.asp) - Page 162 Subroutine: Abstract HTML by Phil Paxton (/learn/libhtml.asp) - Page 163

T Table Display from database w/Simple Code (/learn/dbsimple.asp) - Page 83 Table Display from database (/learn/dbtable.asp) - Page 84 Table Display from database,1 param (/learn/db1parm.asp) - Page 122 Table Listings from Databases (/learn/dbtablelists.asp) - Page 118 TextBoxes in Forms (/learn/formtextbox.asp) - Page 53 TextAreas in Forms (/learn/formtextarea.asp) - Page 54 Text Files: Reading Them off Server (/learn/txtread.asp) - Page 233

Page 285: [ebook] Learn ASP

Text Files: Writing Them on Server (/learn/txtwrite.asp) - Page 234 Text Files: Meyers-Briggs parsing #1 (/learn/mb1.asp) - Page 235 Text Files: Meyers-Briggs parsing #2 (/learn/mb2.asp) - Page 236 Text Files: Meyers-Briggs parsing #3 (/learn/mb3.asp) - Page 237 Time Tasks with Millisecond Accuracy (/learn/speedtimer.asp) - Page 180 Troubleshooting: Basics (/learn/errors1.asp) - Page 35 Troubleshoot: Component Problems (/learn/componentchecker.asp) - Page 48 Troubleshoot: Drivers Versions/Info by Christophe Wille (/learn/connectioninfo.asp) - Page 49 Troubleshoot: Error Msg - Operation must use Updatable Query (/learn/FAQdbUpdate.asp) - Page 38 Troubleshoot: Error Msg - User Entered ' in field (/learn/FAQdbSinglequote.asp) - Page 39 Troubleshoot: Error Msg - LIKE operator * not working (/learn/FAQdbLIKE.asp) - Page 40 Troubleshoot: Error Msg - retrieving MEMO/BLOBs generates error (/learn/FAQdbMEMO.asp) - Page 41 Troubleshoot: Error Msg - Syntax Error in SQL Statement (/learn/FAQdbSQLSyntax.asp) - Page 42 Troubleshoot: List serves to Help! (/learn/asptroubles.asp) - Page 44 Troubleshoot: List serves Worldwide (/learn/asptroubles2.asp) - Page 45 Troubleshoot: List serves Specialized (/learn/asptroubles3.asp) - Page 46 Troubleshoot: Trapping EVERY Error (/learn/dbtablewitherrortrap.asp) - Page 36 Troubleshoot: Trapping Every DB Error (/learn/dbtroubleshoot.asp) - Page 37 Troubleshoot: Trapping Open Connections (/learn/dbtroubleshootopen.asp) - Page 43 Troubleshoot: Version of ASP Sofware (/learn/versioncheck.asp) - Page 47 Troubleshooting, Error Trapping TOC (/learn/troubles.asp) - Page 34

U Usability: Resources (/learn/usability.asp) - Page 209 Usability: Safe Color Pallete (/learn/safecolors.asp) - Page 210

V VB ASP Components Building TOC (/learn/buildcomponents.asp) - Page 246 VB Components: Simple Component (/learn/buildvbsimple.asp) - Page 247 VB Components: Registering Component (/learn/buildregister.asp) - Page 248 VB Components: ADO, Run It! (/learn/buildvbado.asp) - Page 249 VB Components: ADO, Build It! (/learn/buildvbado2.asp) - Page 250 VB Components: VB Warnings/Guidelines (/learn/buildvbguidelines.asp) - Page 251 VB Components: General Building Guidelines (/learn/buildvb.asp) - Page 252 VB Components: Installation Requirements (/learn/buildvb2.asp) - Page 253 VB Components: Threading Models (/learn/buildvbthreads.asp) - Page 254 VB: DLL overwrite problems (/learn/FAQvbDLLoverwrite.asp) - Page 284 VB: Recommended books (/learn/FAQvbBooks.asp) - Page 285 Visual Interdev Resource: VI King Michael Admunsen (/learn/admunsen.asp) - Page 167 VBScript version5 Feature (/learn/vbs5.asp) - Page 165 Version Check of Database Drivers (/learn/connectioninfo.asp) - Page 49 Version Check of Server Software (/learn/versioncheck.asp) - Page 47

http://www.learnASP.com/learn/comingsoon.asp by Charles M. Carroll Page 290

Data Types: VBScript (types.asp) - Page 291

Page 286: [ebook] Learn ASP

Data Types: Conversion (convert.asp) - Page 292 Loops: FOR NEXT #1 (ForNext.asp) - Page 293 Loops: FOR NEXT #2 (ForNext2.asp) - Page 294 Ad Rotator (ad.asp) - Page 295 Content Rotator (cr.asp) - Page 296 DB: Command Object (command.asp) - Page 297 DB: Command Object/Queries (commandquery.asp) - Page 298 DB: Command Object/Create Tables (commandcreate.asp) - Page 299 Reporting: Simple Example (reportsimple.asp) - Page 300 Reporting: Powerful Example (reportpowerful.asp) - Page 301 Dictionaries: Different Approach #1 By Paul Rigor (dictionaryadvanced.asp) - Page 302 Dictionaries: Different Approach #2 by Paul Rigor (dictionaryadvanced2.asp) - Page 303 Validate data (validate.asp) - Page 304 3rd Party: WebJam (webjam.asp) - Page 305 Time Tasks: VB Component by Sunny Yu #1 (asptime.asp) - Page 306 Time Tasks: VB Component by Sunny Yu #2 (asptimer.asp) - Page 307