P. 1
ASP - Learning Guide

ASP - Learning Guide

|Views: 5|Likes:
Published by Fernando

More info:

Published by: Fernando on Jul 06, 2014
Copyright:Traditional Copyright: All rights reserved

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less

12/20/2014

pdf

text

original

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
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
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
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
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
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 255
C++/ATL ASP Component Building (/learn/buildc.asp) - Page 256
Microsoft 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 271
Recently Modified Lessons (/learn/changed.asp) - Page 272
Beginners Lessons (/learn/newbie.asp) - Page 273
Frequently 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
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 289
Coming 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 printed
for any single individual with no restriction. Cannot be reprinted, resold, or commercially made available without the written consent
of 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, Phil
Paxton, Paul Rigor, Christophe Wille, David Wihl and Sunny Yu.
Instructions, Hints, Tips
A complete printout suitable for printing off-line is available @
http://www.learnasp.com/learn/printout.asp
G
All the ASP programs used in this tutorial can be obtained @
http://www.learnasp.com/learn/download.asp
G
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 technical
terms) 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 Pages 1.
FREE and already built into Win2000. 2.
FREE for NT4 if one installs the NT4 Option Pack. Can be downloaded from
http://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 a
very 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 browsers
UNLESS the person making the page uses HTML or browser commands outside of the ASP portions.
5.
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 spending
money; 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, serving
video). 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: Chilisoft
and 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 join
http://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 page
Interprets 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
Microsoft Documentation
There is quite a bit of online documentation that comes with Microsoft Active Server Pages. Our tutorial was written with the express
purpose of being a friendlier, easier to understand set of lessons than the free documentation Microsoft gives you below:
IIS4 Docs
NT4 Option Pak /iishelp
ASP objects reference /iishelp/iis/htm/asp/intr1orp.htm
Ex Air /IISSamples/ExAir/default.asp
Installable Components for ASP /iishelp/iis/htm/asp/comp275c.htm
JScript Language Reference /iishelp/JScript/htm/JStoc.htm
VBScript Language Reference /iishelp/VBScript/htm/VBStoc.htm
Server Side Include Reference /iishelp/iis/htm/asp/iissiref.htm
ASP Quick reference card /iishelp/iis/htm/asp/iiwaref.htm
ASP Tutorial* click here
IIS3 Docs
Roadmap / Official IIS3 Docs /iasdocs/aspdocs/roadmap.asp
IIS3 Code Samples /aspsamp/samples/samples.htm
AdventureWorks /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 Object
The response object is useful, feature rich, and subtle. We are going to focus on it's most fundamental capabilities -- the 20% you will
use 80% of the time. The capabilities we think are vital include:
response.write G
response.write alternate syntax <%= %> which allows ASP simply placed in HTML G
response.end which effectively halts a script in it's tracks. G
response.redirect which transfers control to another page G
Here is a script utilizing response.write to send some information to the browser. It also uses dateadd, a built-in function
documented 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>"
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.end
15 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 Explanation
Response object error 'ASP 0156 : 80004005'
Header Error
whatever.asp, line #
The HTTP headers are already written to the client browser. Any HTTP header modifications must be made before writing page
content.
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 will
do 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 in
midstream" -- it either writes content OR redirects.
<%response.buffer=true%>
which essentially tells the browser don't write anything at all until
a) response.end executes thus stopping the page dead in tracks and sending to browser
b) response.flush executes
c) 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 a
database) people see nothing until the page is completely rendered. In that situation to avoid appearing as the page is dead, an
occassional
response.flush
lets readers see portions of the page being built. We explain why BUFFER=true and flushing is the ideal way to achieve overall
speed @
/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 whatweekday
9 case vbSunday
10 response.redirect "http://www.cnn.com"
11 case vbMonday
12 response.redirect "http://www.activeserverpages.com"
13 case vbTuesday
14 response.redirect "http://www.aspalliance.com"
15 case vbWednesday
16 response.redirect "http://www.aspconvention.com"
17 case vbThursday
18 response.redirect "http://www.aspmagazine.com"
19 case vbFriday
20 response.redirect "http://www.dilbert.com"
21 case vbSaturday
22 response.redirect "http://www.movielink.com"
23 end select
24 %>
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 whatweekday
9 case vbSunday
10 response.redirect "http://www.cnn.com"
11 case vbMonday
12 response.redirect "http://www.activeserverpages.com"
13 case vbTuesday
14 response.redirect "http://www.aspalliance.com"
15 case vbWednesday
16 response.redirect "http://www.aspconvention.com"
17 case vbThursday
18 response.redirect "http://www.aspmagazine.com"
19 case vbFriday
20 response.redirect "http://www.dilbert.com"
21 case vbSaturday
22 response.redirect "http://www.movielink.com"
23 end select
24 %>
25 </body>
26 </html>
.
http://www.learnASP.com/learn/res3.asp by Charles M. Carroll
Page 9
Response Object Part3 - Page Redirection Code
The response object can be used to decide what page to send a user to next. Specifically the response.redirect method will work in
that 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 URL
7 thisURL="http://www.activeserverpages.com"
8 where=Request.QueryString("Wheretogo")
9 Select Case where
10 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 Select
21 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 Carroll
The 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 ways
6 ' depending on what style you personally prefer
7
8 ' Various permutations of writing to the browser
9 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 Carroll
The response object is often used in conjunction with various kinds of codi9ng schemes. No discussion of response would be
complete without a discussion of how to "handle" or "escape" special characters. This sample script demonstrates common
conversion 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 text
6 ' but sometimes some functions must be used to transform
7 ' the text instead of sending as is to the browser
8
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>"
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 Files
The include option is the heart of making efficient ASP files and re-usable chunks. It basically has two forms and now we will present
the 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 the
filename 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 the
file. 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 a
page with many IFs and SELECT CASEs that selectively include files in fact always include the file before the script
begins executing.
http://www.learnASP.com/learn/includedynamic.asp by Charles M. Carroll
Page 13
Include Files Dynamically by Charles Carroll
The 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:
<%
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.readall
26 response.write tempSTR
27 thisfile.Close
28 set thisfile=nothing
29 set fs=nothing
30 END SUB
31 %>
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 Carroll
The Recommend Book Sample Files provides you with several files that when created, prepare you for applying several unrelated
but powerful content management tools in the following pages. The features detailed will include:
Include files that implement pages headers, footers G
sessions and application variables to track users accessing these pages G
the content linker component G
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>
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"-->
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 - Reference
Frequently you want a number to appear in a certain format. The most commands requests are for a set total number of digits and a
set number of digits to the right of the decimal place. Less frequently there is a call for negative amounts displayed in parenthesis or
that 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 meaning
expression the variable holding the raw number
iDigits number of digits to right of decimal point
bleadingDigit
1 for leading zeros
0 for no leading zeros
bParen
1 for parenthesis around negative numbers
0 for no parenthesis around negative numbers
bGroupDigits
1 to display numbers as per regional settings in the Control Panel
0 to over-ride settings in the Control Panel
http://www.learnASP.com/learn/formatnumbers2.asp by Charles M. Carroll
Page 16
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 sample
6 mynumber=123.4567
7 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=.4567
16 response.write mynumber & "<br>"
17 '0 means means no leading zeroes
18 response.write "formatnumber(mynumber,2,0)" & "<br>"
19 response.write formatnumber(mynumber,2,0) & "<hr>"
20 '1 means means pad with leading zeroes
21 'response.write "formatnumber(mynumber,2,1)" & "<br>"
22 'response.write formatnumber(mynumber,2,1) & "<hr>"
23
24 'mynumber=-123.4567
25 'response.write mynumber & "<br>"
26 '0 means means no parentheses for negative numbers
27 '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 numbers
30 '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 dates
5 response.write "<hr>"
6 for counter=0 to 4
7 currentdate=now()
8 response.write "today is..." & "<br>"
9 response.write currentdate & "<P>"
10 select case counter
11 case 0
12 whichformat="vbgeneraldate"
13 case 1
14 whichformat="vblongdate"
15 case 2
16 whichformat="vbshortdate"
17 case 3
18 whichformat="vblongtime"
19 case 4
20 whichformat="vbshorttime"
21 end select
22 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 pages
By Tony Arguelles tony@southbaywebdesigns.com
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 the
date to the home page can create the impression that a site is constantly being updated with new content since each time a visitor
loads 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'll
explain how the function works, teach you how to integrate it into your ASP pages and illustrate the output you'll get depending on
the arguments you pass. I'll round out the tutorial of the FormatDateTime() function by covering a few limitations that it has, which
might 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 of
those 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 Description
date 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 date
and/or time will be displayed on your ASP page.
When specifying the format argument, you can either type the
Visual Basic constant name (name in left column), or the
constant'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
vbGeneralDate 0 This is the default. Not
specifying a value or
specifying 0 will produce a
date in the format of
mm/dd/yy.
If the date expression is Now,
it will also return the time,
after the date, in hh:mm:ss
PM/AM format.
vbLongDate 1 This is my personal favorite
:-) Passing this value will
produce a date in the format
of
weekday, month day, year*
* The year is Y2K compliant
:-).
vbShortDate 2 Passing this value returns a
date formatted just like the
default of 0 (mm/dd/yy).
vbLongTime 3 Passing this value returns the
time in hh:mm:ss PM/AM
format.
vbShortTime 4 Passing this value returns
military time in this format
hh: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 experienced
programmer. For those of you that aren't clear on how all the information in table 1-1 relates to "real world" implementations, let's
take 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 desriptive
format, like this:
<%= FormatDateTime(Date, 1) %>&nbsp;&nbsp;<%= FormatDateTime(Now, 3)%> returns:
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 the
date:
<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 like
to 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 but
trust 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 function
returns is a single string, you can bold, italicize and change the whole date/time by adding HTML or style sheet tags around it, but
you 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'll
cover 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. If
you use the the FormatDateTime() function (or any other date related function) on the server side, the date/time returned will be
whatever 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, then
consider using client side VBScript as an Internet Explorer only solution, or switch to client side JavaScript for a universal browser
solution.
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 to
display 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 handle
that 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 you
have any questions or comments, send me an Email at: tony@southbaywebdesigns.com
http://www.learnASP.com/learn/DoLoop.asp by Charles M. Carroll
Page 19
Do Loop Part #1 by Charles Carroll
To execute a code sequence more than once ASP provides:
DO, LOOP G
WHILE, WEND G
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 Carroll
A 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 DO
7 counter=counter+1
8 response.write counter & "<br>"
9 response.flush
10 LOOP
11 %>
12 </BODY>
13 </HTML>
14
Here is an infinite loop that we explicitly set a timeout for:
1 <%
2 response.buffer=true
3 server.scripttimeout=20
4 %>
5 <TITLE>loop2.asp</TITLE>
6 <body bgcolor="#FFFFFF">
7 <HTML>
8 <%
9 DO
10 counter=counter+1
11 response.write counter & "<br>"
12 response.flush
13 LOOP
14 %>
15 </BODY>
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 transactional
aspect 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 Carroll
The 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=true
4 server.scripttimeout=20
5 %>
6 <HTML>
7 <TITLE>loop3.asp</TITLE>
8 <body bgcolor="#FFFFFF">
9 </BODY>
10 <%
11 DO
12 counter=counter+1
13 response.write counter & "<br>"
14 LOOP
15 response.flush
16 response.write "Script executed without incident"
17 %>
18 </HTML>
19 <%
20 Sub OnTransactionAbort()
21 response.clear
22 Response.Write "The Script Timed Out"
23 end sub
24 %>
loop4.asp succeeds and does not trigger the trap:
1 <%@ TRANSACTION=Required%>
2 <%
3 response.buffer=true
4 server.scripttimeout=40
5 %>
6 <HTML>
7 <TITLE>loop4.asp</TITLE>
8 <body bgcolor="#FFFFFF">
9 </BODY>
10 <%
11 DO UNTIL counter=400
12 counter=counter+1
13 response.write counter & "<br>"
14 LOOP
15 response.flush
16 response.write "Script Exexuted without incident!"
17 %>
18 </HTML>
19 <%
20 Sub OnTransactionAbort()
21 response.clear
22 Response.Write "The Script Timed Out"
23 end sub
24 %>
http://www.learnASP.com/learn/server.asp by Charles M. Carroll
Page 22
Server Variables by Charles Carroll
Available Server Variables are the result of a combination of the browser software and the server software. They are not always
exactly the same on your server and with specific browsers as we document here. Server Variables are retrieved with
request.servervariables("variablename"), for example:
sn=request.servervariables("script_name")
name of script, i.e./learn/server.asp in this case
ref=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 Carroll
Server Variables have many uses. We will show you a popular one here. Web sites are typically attached to an IP address, but
sometimes several domain names may point to the same IP. A clever ASP script could display the same page different ways
depending on which domain name was typed utilizing the HTTP_HOST. Our site, for example has three domain names tied to the
same IP ( activeserverpages.com, asptraining.com, learnasp.com, help.activeserverpages.com ) and the following script will provide
different 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
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 ELSE
20 response.write "Welcome!"
21 END SELECT
22 %>
23 </body></html>
http://www.learnASP.com/learn/serverall.asp by Charles M. Carroll
Page 24
Listing All Server Variables by Charles Carroll
The available Server Variables vary based on the result of a combination of the browser software and the server software. They are
not always exactly the same on your server and with specific browsers as we document here. There is an easy way to obtain a list. If
the 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.servervariables
3 tempvalue=request.servervariables(thing)
4 response.write thing & "=" & tempvalue & "<br>"
5 next
6 %>
Since the above script appears in dozens of books and websites, we wanted to provide you with a better version. This script may
prove useful as it will
list all the available server variables G
skipping the variables ALL_HTTP and ALL-RAW since they are just a "glob" of all the other vars G
place blank variables at the end G
display code to retrieve that variable so you can cut and paste into script G
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>" & vbcrlf
7 quote=chr(34)
8 For Each Key in Request.ServerVariables
9 If instr(Key,"_ALL")+instr(key,"ALL_")=0 then
10 tempvalue=trim(request.servervariables(Key))
11 If len(tempvalue)=0 then
12 BlankVars=BlankVars & Key & ", "
13 Else
14 response.write "request.servervariables(" & quote
15 response.write Key & quote & ") "
16 response.write " =<br><B>" & tempvalue & "</b><p>" & vbcrlf
17 End If
18 end if
19 Next
20 response.write mid(BlankVars,1,len(BlankVars)-2)
21 %>
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 Carroll
This page demonstrates how to use several commands together to serve varying content based on a random number:
RND function G
INT function G
SELECT CASE G
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-6
7 randomize
8 randomnum=int(rnd*6)+1
9 SELECT CASE randomnum
10 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
http://www.learnASP.com/learn/bc.asp by Charles M. Carroll
Page 27
Browser Capabilites
The 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 if
35 set bc=nothing
36 %>
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 minor
release of a browser may be reported as unknown. The technology this DLL uses cannot "guess" that a new browser with
slightly different characteristics is just like the previous one.
G
There are two ways to get a known, reliable browscap.ini. which are explained below. G
Cyscape offer a downloadable latest, greatest BROWSCAP.INI and even offers e-mail subscriptions so you get the latest one sent
to you. Visit http://www.cyscape.com/browscap to pick it up and/or subscribe. You can test in advance whether your browser is
recognized 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 any
browscap 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 browser
definition 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 Version
Often you will want to send content to the client only if you know their browser can support it. You may already
have created pages that are designed to work only in IE and Netscape, version 4 or greater. Or for example you
may have situations where a specific browser type and or version creates a page layout problem. In this lesson
we 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 page
is extremely difficult to read when viewed on WebTV (colors are typically an issue with WebTV due to contrast
and other problems). What are you do to - remove the blue color all together? Change it for a boring share of
grey? Of course not!
The trick here is first finding a alternative color suitable for viewing on WebTV, and only using that color when the
visitor is using a WebTV browser. Otherwise you use your blue font as originally planned. Here's how you would
implement that:
1 <%
2 set bh = server.createobject("cyScape.browserObj")
3 if (bh.browser = "WebTV") then
4 fontColor = "003366" 'a suitable alternate color for WebTV folks only
5 else
6 fontColor = "000066" 'your favorite shade of blue for all folks
7 end if
8 %>
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 highlighted
18 for your convenience. </p>
19 </font>
20 </body>
21 </html>
This technique of testing for a specific browser type is also useful if you have specific tags and scripts that only
work with certain browsers. For example, say you had certain pages that required Netscape or IE versions 4 or
higher. Instead of going through and conditionally including all the v4-only tags, scripts and objects, this example
will show how to use this technique to detect when a browser is not Netscape or IE v4 or higher, and redirect the
user 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") then
4 else
5 response.redirect("PageForNonIEorNNv4.asp")
6 end if
7 set bh = nothing
8 %>
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 keep
this 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 of
superfluous code being sent to the browser... regardless of how insignificant it may seem. This example will show
you 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 the
following link for a few seconds, you will see a tooltip, similar to the kind you see when you hold your mouse over
a button on an application's toolbar. This allows you to include a lot more information in a small space, such as a
navigation 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 which
supports the title element (namely, that it is Internet Explorer AND that it is version 4 or greater). Here is what the
code looks like:
1 <%
2 set bh = server.createobject("cyScape.browserObj")
3 if bh.version>=4 and bh.browser="IE" then
4 %>
5 <a href='x.asp' title=' This is the alternate text. '>
6 <% else %>
7 </a>
8 <a href='x.asp'>
9 <%
10 end if
11 set bh = nothing
12 %>
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. Sometimes
it is worth it to prevent the waste of bandwidth caused by adding elements and features to a page when they can't
be viewed anyway. But more likely then not, you'll use this approach to avoid inconsistencies with layout and
scripting 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.
http://www.learnASP.com/learn/bhaol.asp by Charles M. Carroll
Page 30
Detecting older AOL browsers
Many people ask about how to detect older versions of AOL browsers, particularly AOL version 3.0 and earlier. This is
because 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 the
following 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 is
targeted here specifically to AOL browsers.
1 <%
2 set bh = Server.CreateObject("cyScape.browserObj")
3 if bh.browser = "AOL" and bh.majorver <= 3 then
4 response.redirect "noaol3.asp"
5 end if
6 %>
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 supported
Many developers are chosing to use the Microsoft Wallet for securely taking customer credit card / payment information for
their e-commerce site. The MS Wallet is implemented as a client-side ActiveX control. This means that in order for your
customers 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 (not
even in the latest versions). Therefore if you are implementing the MS Wallet in your site, you'll want to make sure to
provide 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 MS
browser capability component, which frequently misidentifies browsers and ActiveX support in particular. Therefore relying
on 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 the
class string "MSWC.BrowserType" in the CreateObject statements in the scripts to "cyScape.browserObj". This will ensure
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 with
the 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 then
13 response.write "... send MS Wallet control"
14 else
15 response.write "... send alternative code for collecting payment info"
16 end if
17 %></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 names
Have 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 this
information, 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 (or
using someone elses card) over the Internet seems much easier than doing the same in person. This is because it seems easy
to hide behind the anonymous nature of an HTTP connection. What the user may not realize, however, is that based on their
IP address you can likely determine who their their employer or ISP is - and can use that information to track down someone
providing 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 is
possibly that their identify could be determined based on this information. For example, showing someone with dishonest
intentions that you know they are connected through "pop5.erols.net" may make them think twice before entering fraudulent
credit card information. Afterall, it may not prove all that difficult for the authorities to obtain records from their ISP to
determine their identity.
As was mentioned earlier, there are several possible uses for this information. Whatever your reasons may be, BrowserHawk
makes 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
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.ResolveIP
12 if hostname <> "" then
13 response.write hostname
14 else
15 response.write "Unknown"
16 end if
17 %> </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 and
pass 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 <> "" then
16 response.write hostname
17 else
18 response.write "Unknown"
19 end if
20 %> </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 frames
Just about all "modern" browsers today support frames. Unfortunately though there are still several browsers in use today
that do not. Just which ones do and which ones don't? Well, that's a tricky questions - but fortunately we don't need to
concern ourselves with that.
Instead, we simply ask BrowserHawk to determine this for us at run-time, based on the particular browser that a user visits
with. 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 course
is 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 of
their 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 the
frameset 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 if
6 %>
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
http://www.learnASP.com/learn/errors1.asp by Charles M. Carroll
Page 35
Error Trapping #1 by Charles Carroll
Now we will demonstrate how to trap VBScript errors that occur in your scripts with code. The script below runs without incident. All
the syntax in the script is correct.
1 <TITLE>errordivide1.asp</TITLE>
2 <body bgcolor="#FFFFFF">
3 <%
4 ' ASP program that works if numbers are legit
5 x=7
6 y=2
7 z=x/y
8 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" error
the script fails.
1 <TITLE>errordivide2.asp</TITLE>
2 <body bgcolor="#FFFFFF">
3 <%
4 ' ASP program that works if numbers are legit
5 x=7
6 y=2 ' if changed to 0 this will crash
7 z=x/y
8 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 legit
5 on error resume next
6 x=7
7 y=0
8 z=x/y
9 response.write z & "<br>"
10
11 If err.number=0 then
12 response.end
13 end if
14 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
Displaying A Table from Query w/Bells & Whistles
Displaying a table take very little code. A veteran will expand the basic code to deal with many errors that a novice will not have
encountered 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 next
6 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 then
20 response.write "No records matched your query" & "<P>"
21 response.write attempt
22 response.end
23 end if
24
25 attempt="counting fields"
26 howmanyfields=rstemp.fields.count -1
27 Call ErrorVBScriptReport(attempt)
28 Call ErrorADOReport(attempt,conntemp)
29 %>
30 <table border=1>
31 <tr>
32 <% 'Put Headings On The Table of Field Names
33 for i=0 to howmanyfields %>
34 <td><b><%=rstemp(i).name %></B></TD>
35 <% next %>
36 </tr>
37
38 <% ' Now lets grab all the records
39 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.movenext
47 loop
48 rstemp.close
49 set rstemp=nothing
50 conntemp.close
51 set conntemp=nothing
52 %>
53 </table>
54 </BODY>
55 </HTML>
The error trapping library looks like this:
1 <%
2 SUB ErrorVBScriptReport(parm_msg)
3 If err.number=0 then
4 exit sub
5 end if
6 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 SUB
15
16 SUB ErrorADOReport(parm_msg,parm_conn)
17 HowManyErrs=parm_conn.errors.count
18 IF HowManyErrs=0 then
19 exit sub
20 END IF
21 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-1
25 errornum=parm_conn.errors(counter).number
26 errordesc=parm_conn.errors(counter).description
27 response.write pad & "Error#=<b>" & errornum & "</b><br>"
28 response.write pad & "Error description=<b>"
29 response.write errordesc & "</b><p>"
30 next
31 END SUB
32 %>
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 the
following and see if it identifies your problem. There are tons of frightening messages that come up like:
Microsoft OLE DB Provider
for ODBC Drivers error
'80040e07'
[Microsoft][ODBC Microsoft
Access 97 Driver] Data
type mismatch in criteria
expression.
/somewhere/something.asp,
line 12
Error #-2147217900
Error desc. ->
[Microsoft][ODBC SQL
Server Driver][SQL
Server]Line 1: Incorrect
syntax near ','.
Error #-2147217900
Error desc. ->
[Microsoft][ODBC Microsoft
Access 97 Driver] Syntax
error 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 bad
SQL 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 next
7 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")
14 Call ErrorADOReport(SQLstmt,conn)
15
16 rs.close
17 set rs=nothing
18 Conn.Close
19 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 then
4 exit sub
5 end if
6 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 SUB
15
16 SUB ErrorADOReport(parm_msg,parm_conn)
17 HowManyErrs=parm_conn.errors.count
18 IF HowManyErrs=0 then
19 exit sub
20 END IF
21 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-1
25 errornum=parm_conn.errors(counter).number
26 errordesc=parm_conn.errors(counter).description
27 response.write pad & "Error#=<b>" & errornum & "</b><br>"
28 response.write pad & "Error description=<b>"
29 response.write errordesc & "</b><p>"
30 next
31 END SUB
32 %>
There is a set of links to Microsoft ADO knowledge base articles @
http://www.asptracker.com/demo/adokb1.asp
which 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 the
database 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'
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 example
Bill'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=20
works fine!
UPDATE customer FIELDS (Name,City,State,Zip) _
VALUES ('Acme's Store','Rockville','MD','20849') _
WHERE custid=20
will 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=20
will 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=20
will 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=20
will 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 called
replace that can find characters in a string and replace them with alternate characters. For example the code above could be
replaced with:
co=request("company")
cy=request("city")
st=request("state")
id=request("keycust")
co=replace(co,"'","''")
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 SQL
parser.
Additional Information:
Check MS knowledgebase article Q178070 (HOWTO : Handle Quotes and Pipes in Concatenated SQL Literals) which
suggests 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 * for
multiple 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'
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 red
CargoID, 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,Comments
from 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. If
you 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 SQLstuff
conn.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 the
syntax 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 like
select * 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 when
referencing it in the query.
A query like
select * 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.
A query like
select * 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>9
will fail because the text fields were not delimited properly.
A query like:
select * from employees where city='Rockville' and State='MD' and yearsresiding>9
succeeds.
b. Date fields get surrounded by # #
A query like:
select * from employees where birthdate>1/1/1966
will 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 Database
by Charles Carroll
Many people want to intercept specific errors and replace them with friendly messages. Here is some sample code that catches
mispelled DSNs and bad login/user ids:
1 <html><head>
2 <title>dbtroubleshoot.asp</title>&
3 <body>
4 <%
5 on error resume next
6 Set Conn = Server.CreateObject("ADODB.Connection")
7 my_DSN="DSN=student;uid=student;password=magic2"
8 conn.open my_DSN
9 Call CheckOpen
10
11 Conn.Close
12 set conn=nothing
13
14 SUB CheckOpen
15 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 if
27 IF conn.errors.count> 0 then%>
28 <b>ADO Reports these Database Error(s):</b><br>
29 <%
30 maxerrors=conn.errors.count-1
31 for counter= 0 to maxerrors
32 DBErrorNum=conn.errors(counter).number
33 DBErrorDesc=conn.errors(counter).description
34 SELECT CASE DBErrorNum
35 CASE -2147467259
36 response.write "Problem => <b>Bad DSN</b><br>"
37 response.write "DSN => <b>" & my_DSN & "</b><br>"
38 CASE -2147217843
39 response.write "Problem => <b>Bad Login Info</b><br>"
40 response.write "DSN => <b>" & my_DSN & "</b><br>"
41 exit sub
42 CASE ELSE%>
43 Error # = <b><%=DBErrorNum%></b><br>
44 Error description = <b><%=DBerrorDesc%></b><p>
45 <%END SELECT
46 next
47 else%>
48 Everything Went Fine
49 <%
50 end if
51
52 END SUB%>
53 </body></html>
http://www.learnASP.com/learn/asptroubles.asp by Charles M. Carroll
Page 44
ASP Troubleshooting Resources Part1
When your Active Server Page code does not work, we actually manage a listserv you can write to send in your code and have your
colleagues from around the world on the listserv help you fix it. Warning: One of listservers -- [aspfreeforall] -- is quite noisy (40-50
messages 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:
Access
DB2 AS400
Dbase
Fox/Visual FoxPro
Informix
SQLserver 6.5
SQLserver 7.x
Oracle Setup/Can't Connect!
Oracle
Paradox
Reports/Printing (Crystal, PDF, etc.)
RDS (Remote Data Services)
SQL: Joins, complex queries, shaping
Sybase
People having trouble with ASP and does not have code communicating with a specific database can sign up for one of our general
listservers
Beginning - Any ASP questions [aspfreeforall]
Intermediate - NO beginner questions [aspnotnewbie]
Advanced - tough ASP questions only! [aspadvanced]
[aspadvanced] Strict Rules
Installing,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 in
non-English languages. You can write to send in your code and have your colleagues from around the world on the listserv help
you fix it in your native language.
Arabic
Bengali
Chinese
Danish
Dutch
Farsi
Finnish
French
German
German ASP Jobs
German ASP Coffee House
Hebrew
Hindi
Indonesian
Icelandic
Italian
Japanese
Korean
Malay
Norweigan
Polish
Portugese
Russian
Spanish
Swedish
Swedish Advanced
Turkish
Thai
Urdu
http://www.learnASP.com/learn/asptroubles3.asp by Charles M. Carroll
Page 46
ASP Troubleshooting Resources Part 3
Sometimes 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 where
specialized topics thrive. All the best people hang out there, the archives are devoid of general questions, game is plentiful, and the
sun shines and nary a cloud appears. Here is a master list of all the specialized listserves we run. They will NOT FLOOD YOUR
MAILBOX 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 only
unmoderated 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 are
allowed.
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.) and
non-English ASP issues, secure and international encryption issues, etc. Questions that don't deal with international or
multilingual 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 all
the "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
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 on
topic 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 a
troubleshooting 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 and
components 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 and
components 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 and
components communication with Oracle databases.
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 and
components 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 and
components 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 the
list 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 list
for 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 the
only 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 and
interact 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 component
URLs 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 server
admin allowed.
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 in
Chapter 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 this
list.
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 you
want 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 be
rejected always.
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 DRAFT
This 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=nothing
26
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 Carroll
determine what components are on your server
The 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>
2 <body bgcolor="#FFFFFF">
3 <%
4 dim successSTR, FailSTR, checkSTR
5 whichfile=server.mappath("component.ini")
6 Set fs = CreateObject("Scripting.FileSystemObject")
7 Set thisfile = fs.OpenTextFile(whichfile, 1, False)
8
9 counter=0
10
11 do UNTIL thisfile.AtEndOfStream
12 counter=counter+1
13 thisline=thisfile.readline
14 attempt=trim(thisline)
15 pad="&nbsp;&nbsp;&nbsp;&nbsp;"
16 DO WHILE attempt=""
17 thisline=thisfile.readline
18 attempt=trim(thisline)
19 LOOP
20 If mid(thisline,1,1)="[" then
21 ' ignore
22 CheckSTR=CheckSTR & thisline & " "
23 lastcategory=category
24 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 then
28 category=mid(category,2)
29 category=category & "'>" & oldcategory & "]</a>"
30 END IF
31 group= "<b>" & category & " component group</b><br>"
32 successcount=0
33 failcount=0
34 thisline=thisfile.readline
35 attempt=thisline
36 end if
37 on error resume next
38 set tempobject=server.createobject(attempt)
39 eol="<br>" & vbcrlf
40 whicherr=err.number
41 If whicherr=0 then
42 if successcount=0 then
43 successSTR=successSTR & group
44 end if
45 vleft="&nbsp;(ver="
46 vright=")&nbsp;"
47 SELECT CASE lcase(attempt)
48 CASE "adodb.connection"
49 version= vleft & tempobject.version & vright
50 CASE ELSE
51 version=""
52 END SELECT
53
54 successSTR= successSTR & pad & "<b>" & attempt & version & "</b> successfull!" & eol
55 successcount=successcount+1
56 else
57 if failcount=0 then
58 FailSTR=FailSTR & group
59 end if
60 IF whicherr=-2147221005 THEN
61 msg = " is not registered!"
62 ELSE
63 msg = " failed. Error #" & whicherr
64 END IF
65 FailSTR= failSTR & pad & "<b>" & attempt & "</b>" & msg & eol
66 failcount=failcount+1
67 end if
68 set tempobject=nothing
69 loop
70
71 thisfile.Close
72 set thisfile=nothing
73 set fs=nothing
74
75 response.write "Checked: " & checkSTR & "<hr>"
76 response.write successSTR & "<hr>"
77 response.write failSTR
78 %>
This component.ini file contains a list of typical server components, grouped by type. Type is indicated within [ ] codes. Here is the
contents of the current component.ini:
1 [standard]
2 mswc.browsertype
3 mswc.nextlink
4 scripting.dictionary
5 scripting.filesystemobject
6
7 [ado]
8 adodb.recordset
9 adodb.connection
10 adodb.command
11
12 [cdo]
13 CDONTS.NewMail
14
15 [cyscape]
16 cyScape.browserObj
17
18 [indexserver]
19 ixsso.Query
20 ixsso.Util
21
22 [Lyris]
23 Lyris.LCP
24
25 [http://msdn.microsoft.com/scripting]
26 Wscript.Shell
27
28 [msfreebies]
29 iissample.asp2htm
30 iissample.contentrotator
31 iissample.registry
32 iissample.summaryinfos
33 iissample.tracer
34 mswc.adrotator
35 mswc.counters
36 mswc.myinfo
37 MSWC.PageCounter
38 MSWC.PermissionChecker
39 mswc.tools
40 mswc.loadbalance
41
42 [msXML]
43 microsoft.XMLHTTP
44 microsoft.XMLDOM
45
46 [www.aspdb.com]
47 ASPdb.Free
48 ASPdb.View
49 ASPdb.Pro
50 ASPdb.EP
51
52 [www.serverobjects.com]
53 ASPChart.Chart
54 AspConv.Expert
55 AspDNS.Lookup
56 AspFile.FileObj
57 AspHTTP.Conn
58 AspImage.Image
59 AspInet.FTP
60 AspMX.Lookup
61 AspNNTP.Conn
62 AspPager.Pager
63 SMTPsvg.Mailer
64
65 [www.softartisans.com]
66 SoftArtisans.FileUp
67 SoftArtisans.SACheck
68 SoftArtisans.SASessionPro
69 SoftArtisans.FileManager
70 EZsite.Calender
71 EZsite.CalendarManager
72 EZsite.WebNotes
73
74 [www.active4.com]
75 ActiveLaunch.Control
76 ActiveSAR.SearchAndReplace
77 ActiveShopper.Cart
78 ActiveShopper.BasketItem
79 FileTouch.Control
80 PCAuthX.Authorizer
81 Prt2Disk.Control
82 SemClient.Control
83 SPrinterPro.Object
84 TimeSpan.Control
85 WWWPrint.Client
86
87 [Zaks Software]
88 ZaksPop3.Server
89 JavaPop3.Mailer
90
91 [www.persits.com]
92 Persits.MailSender
93
94 [www.oceantek.com]
95 ASPL.Login
96
97 [www.able-consulting.com]
98 ACI.WhoIs
99
100 [www.softwing.com]
101 Softwing.EventLogReader
102 Softwing.OdbcRegTool
103 w3info.w3info.1
104 InetCtls.Inet.1
105 Softwing.AspQPerfCounters
106 SQLOLE.SQLServer
107 SOFTWING.ASPEventlog
108 SOFTWING.ASPtear
109 SOFTWING.EDConverter
110 SOFTWING.EventLogReader
111 SOFTWING.FileCache.1
112 SOFTWING.OdbcRegTool
113 SOFTWING.LocaleFormatter
114 SOFTWING.Profiler
115
116 [www.dougdean.com]
117 EZsite.EZuploadLite
118
119 [www.algonet.se/~jekman]
120 lightcom.xBrowser
121 lightcom.xContent
122 lightcom.xPop3
123 lightcom.xSMTP
124 lightcom.xTree
125 lightcom.xBrowser
126 JESoftware.xContent
127 JESoftware.xPop3
128 JESoftware.xSMTP
129 JESoftware.xTree
130
131 [tech.dimac.net]
132 Socket.TCP
133
134 [www.de-info.com]
135 checkemail.maccheckemail
136
137 [www.pstruh.cz]
138 TCPIP.Trace
139 TCPIP.DNS
140
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 Wille
Christoph.Wille@softwing.com 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 strDSN
6
7 response.write "ADO Version: " & cnn1.Version
8 response.write "<BR>" & vbcrlf
9 response.write strVersionInfo & "DBMS Name: " & cnn1.Properties("DBMS Name")
10 response.write "<BR>" & vbcrlf
11 response.write "DBMS Version: " & cnn1.Properties("DBMS Version")
12 response.write "<BR>" & vbcrlf
13 response.write "OLE DB Version: " & cnn1.Properties("OLE DB Version")
14 response.write "<BR>" & vbcrlf
15 response.write "Provider Name: " & cnn1.Properties("Provider Name")
16 response.write "<BR>" & vbcrlf
17 response.write "Provider Version: " & cnn1.Properties("Provider Version")
18 response.write "<BR>" & vbcrlf
19 response.write "Provider Friendly Name: " & cnn1.Properties("Provider Friendly Name")
20 response.write "<BR>" & vbcrlf
21
22 If 0 = Instr(LCase(cnn1.Properties("Provider Name")),"oledb") then
23 ' ### no OLE DB Provider used, therefore :
24 response.write "Driver Name: " & cnn1.Properties("Driver Name")
25 response.write "<BR>" & vbcrlf
26 response.write "Driver Version: " & cnn1.Properties("Driver Version")
27 response.write "<BR>" & vbcrlf
28 response.write "Driver ODBC Version: " & cnn1.Properties("Driver ODBC Version")
29 response.write "<BR><BR>"
30 end if
31
32 Set rsQuery = nothing
33 Set cnn1 = nothing
34
35
36 END SUB
37 %>
http://www.learnASP.com/learn/PWS.asp by Charles M. Carroll
Page 50
Personal Web Server (PWS) by Charles Carroll
The Personal Web Server is a marvellous tool because it lets you develop and test websites
without being connected to the Internet G
without placing your code on the World-Wide-Web or a server until it is tested off-line and totally debugged. G
The address of your personal web server is:
http://127.0.0.1
It 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
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 Carroll
Forms are the primary way that a user feeds information into ASP. A form is a web page that contains tags that cause the browser to
show 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). G
The form must pass the variables onto a .asp file to process the form. G
An excellent form tutorial can be found at:
http://www.mountaindragon.com/html/forms.htm
G
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. G
The form will show it's parameter in the browser address window, for example:
testform.asp?state=md&city=Germantown
would be the URL in the browser, if the state and city field were populated.
G
An ASP script picks up a form field with:
<%whatever=request.querystring("whichfield")%>
G
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) G
The form will not show it's parameter in the browser address window, for example:
http://whatever.com/testform.asp
would be the only URL in the browser, regardless of how many fields and how much data is passed.
G
An ASP script picks up the form field with:
<%whatever=request.form("whichfield")%>
G
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 <R.vanderVossen@chello.nl> for this tip I looked high and low for.
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 the
browser 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 can
be entered. Do not use size as a validation technique
to limit verbose users.
<INPUT NAME="State" MaxLength="2">
This controls the maximum number of characters that
can be entered.
<INPUT NAME="NameLast" VALUE="Bertrand">
The name of Bertrand will appear when the page is
opened 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>
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 here
9 </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 comm
7 %>
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 since
the state of "checked" or "not checked" will be passed to ASP for each box. Remember that you can set more than one option to be
checked.
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" then
6 response.write "<br>We will confirm by US Mail"
7 end if
8 If request.form("UPS")="on" then
9 response.write "<br>We will confirm by UPS"
10 end if
11 If request.form("EMail")="on" then
12 response.write "<br>We will confirm by EMail"
13 end if
14 If request.form("fax")="on" then
15 response.write "<br>We will confirm by fax"
16 end if
17 If request.form("tel")="on" then
18 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 them
when passing the data to ASP. The exceptions are radio buttons. Since only one piece of information will be passed to ASP from a
set of radio buttons, they all get the same name. HTML requires that one of the buttons is selected by default, the one indicated by
the CHECKED command. It is important to understand that the browser will send back to ASP the name and the value of the one
button which is selected by the user. The browser will NOT send back the text which is associated with the button. For the example
above, 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 City
8 <input TYPE="radio" NAME="City" VALUE="LA">Los Angeles
9 <input TYPE="radio" NAME="City" VALUE="SV" CHECKED>Savannah
10 <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">
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 else
11 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 SELECT
CASE. 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 if
12 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>"
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 SELECT
CASE. 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 Title
8 <INPUT TYPE="Radio" name="Title" VALUE="employee">Entry Level
9 <INPUT TYPE="Radio" name="Title" VALUE="temp" CHECKED>Temporary Employee
10 <INPUT TYPE="Radio" name="Title" VALUE="manager">Management Candidate
11 <INPUT TYPE="Radio" name="Title" VALUE="executive">Executive
12 <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 a
form that will ask a user for their first name and last name.
1 <html><head>
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 You
10 <%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 a
form 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 previous
example this time we are checking multiple conditions utilizing elseif and we are dealing with entries no matter whether they were
typed 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 You
18 <%end if%>
19 </body></html>
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 a
form 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=15
13 else
14 SSTaxMarginal=15
15 end if
16 If salary>6700 and salary<30000 then
17 SSTaxMarginal=0%>
18 Would you like me to loan you some money?<p>
19 <%end if
20 If salary<6700 then
21 SSTaxMarginal=0
22 end if
23 %>
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 a
form 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>
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-arrange
these 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 then
9 salarygrade=4
10 end if
11 if salary <=80000 then
12 salarygrade=3
13 end if
14 If salary <=60000 then
15 salarygrade=2
16 end if
17 if salary <=40000 then
18 salarygrade=1
19 end if
20 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 Carroll
Forms with many elements may be easier to process if a FOR EACH construct is used to loop through every value submitted from
the source form. In this example, there are many checkboxes and instead of many IF statements we replace them with one FOR
EACH 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="" then
11 my_date=now()
12 else
13 my_month=month("1/" & (request.querystring("whichmonth")) & "/1999")
14 my_date=dateserial(year(now()),my_month,1)
15 end if
16 'response.write my_date & "<br>"
17
18 If my_month=12 then
19 my_day=1
20 my_month=1
21 my_year=my_year+1
22 else
23 my_day=1
24 my_month=month(my_date)+1
25 my_year=year(my_date)
26 end if
27
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=0
6 for each whatever in request.form
7 thisvalue=request.form(whatever)
8 If thisvalue="on" then
9 daysworked=daysworked+1
10 end if
11 next
12 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 Carroll
Sometimes it makes sense to just email all the form results to someone. But the "mailto:" method used by many Web developers is
not 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 G
Not all browsers support mailto (Netscape does, several IE versions before 4.0 do not, many browsers do not) G
The user may have a faulty email configuration that keeps the browser from sending the mail G
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 of
the 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 go
3 fromName="Whoever"
4 fromAddress="somestudent@activeserverpages.com"
5 toName="Charles M. Carroll"
6 toAddress="cc@thebestweb.com"
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>
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.com
6 ' is not part of ASP per se,
7 ' but a excellent third party component
8
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_relay
18
19 Mailer.FromName = my_from
20 Mailer.FromAddress = my_fromAddress
21 Mailer.AddRecipient my_to, my_toaddress
22 Mailer.Subject = my_subject
23
24 for each whatever in request.querystring
25 If instr(whatever,"mail-")=0 then
26 Mailer.BodyText = whatever & "=" & vbcrlf
27 Mailer.BodyText = request.querystring(whatever) & vbcrlf & vbcrlf
28 end if
29 next
30
31 for each whatever in request.form
32 If instr(whatever,"mail-")=0 then
33 Mailer.BodyText = whatever & "=" & vbcrlf
34 Mailer.BodyText = request.form(whatever) & vbcrlf & vbcrlf
35 end if
36 next
37
38 my_emailcopy=request("emailcopy")
39 If my_emailcopy="" then
40 else
41 Mailer.AddRecipient "form filler",my_emailcopy
42 end if
43
44 If Mailer.SendMail then
45 Msg = "mail sent sucessfully!"
46 Else
47 Msg = "mail was not sent sucessfully"
48 End If
49 response.write Msg
50 %>
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=true
3 %>
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+365
12 Response.Cookies("thatperson")("lastname") = l
13 Response.Cookies("thatperson")("firstname") = f
14 Response.Cookies("thatperson")("state") = st
15 Response.Cookies("thatperson").Expires = cookydie
16 Response.Cookies("thatperson").Domain = cookydomain
17 Response.Cookies("thatperson").Path = cookypath
18 response.write Request.Cookies("thatperson")("lastname") & "<p>"
19 response.write Request.Cookies("thatperson")("firstname") & "<p>"
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-365
9 Response.Cookies("thatperson").Expires = cookiesdie
10 Response.Cookies("thatperson").Domain = cookiesdomain
11 Response.Cookies("thatperson").Path = cookiespath
12 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 and
path 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.asp
5 ' copyright 1998 by Paul Rigor
6 '
7 ' application("cookiedomain") and application("cookiepath") can be
8 ' set if firewall precludes accurate server variable
9 '
10 ' AddCookie(Cname, CKey, CValue, CExpDays)
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 name
20 ' Ckey = Cookie Key: Optional(empty sting), use if cookie should be a dictionary
21 ' Cvalue = Cookie Value: Required, what the cookie should be set to.
22 ' CExpDays = Cookie Expiration: number of days cookie is valid, default 365
23 Function AddCookie(Cname, CKey, CValue, CExpDays)
24 If Cname = "" Then
25 Exit Function
26 End If
27
28 If IsNumeric(CExpDays) = False Then CExpDays = 0
29 If CExpDays < 1 Then CExpDays = 365
30
31 If CValue = "" Then CValue = " "
32
33 If CKey <> "" Then
34 Response.Cookies(Cname)(CKey) = CValue
35 Else
36 Response.Cookies(Cname) = CValue
37 End If
38
39 Response.Cookies(CName).Expires = Date + CExpDays
40 Response.Cookies(CName).Domain = GetCookieDomain()
41 Response.Cookies(CName).Path = GetCookiePath()
42 End Function
43
44 Function KillCookie(Cname,CKey)
45 If CKey <> "" Then
46 Call AddCookie(Cname, Ckey, "", 0)
47 Else
48 Response.Cookies(Cname).Expires = Date - 365
49 Response.Cookies(CName).Domain = GetCookieDomain()
50 Response.Cookies(CName).Path = GetCookiePath()
51 End If
52 End Function
53
54 Function GetCookie(Cname, Ckey)
55 If CKey <> "" Then
56 GetCookie = Request.Cookies(Cname)(Ckey)
57 Else
58 GetCookie = Request.Cookies(Cname)
59 End If
60 End Function
61
62 Function GetCookieDomain()
63 If Application("CookieDomain") <> "" Then
64 GetCookieDomain = Application("CookieDomain")
65 Else
66 GetCookieDomain = Request.ServerVariables("SERVER_NAME")
67 End If
68 End Function
69
70 Function GetCookiePath()
71 If Application("CookiePath") <> "" Then
72 GetCookiePath = Application("CookiePath")
73 Else
74 TmpPath = Request.ServerVariables("SCRIPT_NAME")
75 TmpPath = Split(TmpPath, "/")
76 For PathArryCnt = 0 to Ubound(TmpPath) - 1
77 GetCookiePath = GetCookiePath & TmpPath(PathArryCnt) & "/"
78 Next
79 If GetCookiePath = "/" Then GetCookiePath = ""
80 End If
81 End Function
82 %>
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 Carroll
Not 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" and
immediately can differentiate that user from all other users at a site. Anything stored in that user's session can be retrieved and
manipulated 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 is
collectively 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 their
successes:
1 <%
2 response.write "Coin Tossed!<br>"
3 randomize
4 randomnum=int(rnd*2)+1
5 IF randomnum=1 THEN
6 session("heads")=session("heads")+1
7 ELSE
8 session("tails")=session("tails")+1
9 END IF
10 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 a
session 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 level
determined 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 determine
the contents of any session variables.
G
A cookie is used to co-ordinate the user's session ID. Once again the cookie contains no data (just the session
ID). This means if the user accepts no cookies, you can't use sessions as described here.
G
If you absolutely need sessions without client cookies, installing an ISAPI filter named "Cookie Munger" will
solve your problem, but at a performance penalty.
G
Cookie Munger by Microsoft (FREE)
Cookies are a necessity to maintain ASP session objects. Even though the session objects are physically maintained on the server
the essential ID that identifies a user session is kept in a cookie. This ISAPI filter can only be applied globally but if applied, it actually
rewrites 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 the
page. So conceptually if you send a page back to the users with 20 URLs each URL gets a session ID "munged"/intermixed in so
that 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 Carroll
Not written yet.
http://www.learnASP.com/learn/hidden.asp by Charles M. Carroll
Page 74
Passing Data with Hidden Fields by Charles Carroll
This page demonstrates how to have several pages that are forms yet after all pages are filled out the final form has access to all
inputs 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;
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>
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 Carroll
This page demonstrates how to have several pages that are forms yet after all pages are filled out the final form has access to all
inputs 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.Cookies
21 Response.Cookies(cookie).Expires = now()+365
22 Next
23 %>
24 </body></html>
surveypage2c.asp asks the user the next questions:
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")=first
22 response.cookies("prefs")("last")=last
23 For Each cookie in Response.Cookies
24 Response.Cookies(cookie).Expires = now()+365
25 Next
26 %>
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")=haircolor
32 response.cookies("prefs")("favoritecolor")=favoritecolor
33 For Each cookie in Response.Cookies
34 Response.Cookies(cookie).Expires = now()+365
35 Next
36 %>
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")=street
26 response.cookies("prefs")("city")=city
27 response.cookies("prefs")("state")=state
28 response.cookies("prefs")("zip")=zip
29 For Each cookie in Response.Cookies
30 Response.Cookies(cookie).Expires = now()+365
31 Next
32 %>
33 </body></html>
http://www.learnASP.com/learn/statesessions.asp by Charles M. Carroll
Page 76
State Management Intro by Charles Carroll
Not written yet.
http://www.learnASP.com/learn/statedb.asp by Charles M. Carroll
Page 77
State Management Intro by Charles Carroll
Not written yet.
http://www.learnASP.com/learn/statemore.asp by Charles M. Carroll
Page 78
Global.asa, Sessions, Custom Stats Resources
The global.asa, application and sesion variables are certainly a more complex and controversial subject than most ASP topics. Other
sites 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. vars
http://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 to
aspstatemanagement@ls.asplists.com
Related Links
Global.asa Basics @
http://www.learnasp.com/learn/global.asp
FREE Dictionary Component that is session/app safe @
http://www.caprockconsulting.com/comsoftware.htm
Hidden Fields to Pass Data between pages @
http://www.learnasp.com/learn/hidden.asp
Global.asa Sclability problems @
http://www.learnasp.com/learn/globalproblems.asp
Sessions: what are they? @
http://www.learnasp.com/learn/sessionswhat.asp
4 Ways to Pass data from page to page @
http://www.4guysfromrolla.com/webtech/041399-1.shtml
Cache 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
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 Resources
When your database code does not work, we actually manage a listserv you can write to send in your code and have your
colleagues from around the world on the listserv help you fix it. People having trouble with ASP code communicating with a specific
database should try their questions on one of these lists:
Access
DB2 AS400
Dbase
Fox/Visual FoxPro
Informix
SQLserver 6.5
SQLserver 7.x
Oracle Setup/Can't Connect!
Oracle
Paradox
Reports/Printing (Crystal, PDF, etc.)
RDS (Remote Data Services)
SQL: Joins, complex queries, shaping
Sybase
http://www.learnASP.com/learn/dbtroubles2.asp by Charles M. Carroll
Page 82
Databases Troubleshooting Resources Part 2
The 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.asp
Error: Operation must use an updatable query @
http://www.learnasp.com/learn/FAQdbUpdate.asp
Query with LIKE Results in Error @
http://www.learnasp.com/learn/FAQdbLIKE.asp
Retrieveing Memo Field Results in Error @
http://www.learnasp.com/learn/FAQdbMEMO.asp
Syntax Error in SQL statement @
http://www.learnasp.com/learn/FAQdbSQLSyntax.asp
Build a Drilldown DB screen @
http://www.4guysfromrolla.com/webtech/070799-1.shtml
Generic 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 Carroll
This 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 database
7 myDSN="DSN=Student;uid=student;pwd=magic"
8 set conntemp=server.createobject("adodb.connection")
9 conntemp.open myDSN
10
11 ' this code retrieves the data
12 mySQL="select * from publishers where state='NY'"
13 set rstemp=conntemp.execute(mySQL)
14
15 ' this code detects if data is empty
16 If rstemp.eof then
17 response.write "No records matched<br>"
18 response.write mySQL & "<br>So cannot make table..."
19 connection.close
20 set connection=nothing
21 response.end
22 end if
23 %>
24 <table border=1>
25 <%
26 ' This code puts fieldnames into column headings
27 response.write "<tr>"
28 for each whatever in rstemp.fields
29 response.write "<td><B>" & whatever.name & "</B></TD>"
30 next
31 response.write "</tr>"
32
33 ' Now lets grab all the records
34 DO UNTIL rstemp.eof
35 ' put fields into variables
36 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 browser
48 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.movenext
63 LOOP
64 %>
65 </table>
66
67 <%
68 ' Now close and dispose of resources
69 rstemp.close
70 set rstemp=nothing
71 conntemp.close
72 set conntemp=nothing
73 %>
74 </body></html>
http://www.learnASP.com/learn/dbtable.asp by Charles M. Carroll
Page 84
Display Table on Web Page by Charles Carroll
This 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 form
7 myDSN="DSN=Student;uid=student;pwd=magic"
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 myDSN
14 set rstemp=conntemp.execute(mySQL)
15 If rstemp.eof then
16 response.write "No records matched<br>"
17 response.write mySQL & "<br>So cannot make table..."
18 conntemp.close
19 set conntemp=nothing
20 response.end
21 end if
22 %>
23 <table border=1><tr>
24
25 <% 'Put Headings On The Table of Field Names
26 for each whatever in rstemp.fields%>
27 <td><b><%=whatever.name%></B></TD>
28 <% next %>
29 </tr>
30
31 <% ' Now lets grab all the records
32 DO UNTIL rstemp.eof %>
33 <tr>
34 <% for each whatever in rstemp.fields
35 thisfield=whatever.value
36 if isnull(thisfield) then
37 thisfield=shownull
38 end if
39 if trim(thisfield)="" then
40 thisfield=showblank
41 end if%>
42 <td valign=top><%=thisfield%></td>
43 <% next %>
44 </tr>
45 <%rstemp.movenext
46 LOOP%>
47 </table>
48
49 <%
50 rstemp.close
51 set rstemp=nothing
52 conntemp.close
53 set conntemp=nothing
54 %>
55 </body></html>
http://www.learnASP.com/learn/dblist.asp by Charles M. Carroll
Page 85
HTML List Box from Column
This page demonstrates the capabilities how to display a list box from a SQL statement. This is the simplest possible example. The
script 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"
7
8 ' displays a database field as a listbox
9 set conntemp=server.createobject("adodb.connection")
10 conntemp.open myDSN
11 set rstemp=conntemp.execute(mySQL)
12 if rstemp.eof then
13 response.write "no data for<br>"
14 response.write mySQL
15 conntemp.close
16 set conntemp=nothing
17 response.end
18 end if
19
20 %>
21 <form action="dblistrespond.asp" method="post">
22 <Select name="authorname">
23 <%
24 ' Now lets grab all the data
25 do until rstemp.eof %>
26 <option> <%=RStemp(0)%> </option>
27 <%
28 rstemp.movenext
29 loop
30
31 rstemp.close
32 set rstemp=nothing
33 conntemp.close
34 set conntemp=nothing
35 %>
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 Resources
There 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:
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 Easy
When 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 ASP
scripts 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") = 1
10 Session("dbOrder") = 2
11 Session("dbRecsPerPage") = 10
12 Session("dbFooter") = 1
13 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") = 10
20 Session("dbWhere") = ""
21 Session("dbDebug") = 1
22 Session("dbCanEdit") = 1
23 Session("dbCanAdd") = 1
24 Session("dbCanDelete") = 1
25 Session("dbConfirmDelete") = 1
26 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, instead
only questions concerning these wonderful scripts are allowed.
aspgenericdb Listserver

JOIN, QUIT or Search ARCHIVES:
http://www.asplists.com/asplists/genericdb.asp
Send Listserver Questions to
aspgenericdb@ls.asplists.com
Related Links
Generic 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 Page
Many Approaches by Charles Carroll
There are many ways to display a table on a web page. So many that we feel that a brief description of the variations and some
URLs 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.asp
Displaying 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 Carroll
Any ASP script that needs to connect to a database must open it on the server first.There are several ways:
a system DSN
which must be setup on the server, see:
/learn/dsn1.asp for detailed instructions or
http://www.aspalliance.com/components/database.asp for components that automate this task.
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 DSN
which is not recommended for high concurrency situations since all users would be limited speedwise to how fast the ASII file that
holds the DSN could be accessed.
a DSNless connection
which 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 connection
information 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) G
present the data anew to the provider/driver since the ASCII file may have changed since last connection. G
The designers of ASP have seen File DSNs fail on big busy sites because of reason a) so discourage them. System DSNs thay rely
on registry keys in memory are much faster.
Microsoft has a knowledge base article at:
http://support.microsoft.com/support/kb/articles/q193/3/32.asp
which 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 without
a 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 qualified
filename 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 DSNless
connection.
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 DSNless
connection.
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 DSNless
connection.
1 <HTML><HEAD>
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, rstemp
4 set conntemp=server.createobject("adodb.connection")
5 conntemp.open inputDSN
6 set rstemp=conntemp.execute(inputquery)
7 howmanyfields=rstemp.fields.count -1%>
8 <table border=1><tr>
9 <% 'Put Headings On The Table of Field Names
10 for i=0 to howmanyfields %>
11 <td><b><%=rstemp(i).name%></B></TD>
12 <% next %>
13 </tr>
14 <% ' Now lets grab all the records
15 do while not rstemp.eof %>
16 <tr>
17 <% for i = 0 to howmanyfields
18 thisvalue=rstemp(i)
19 If isnull(thisvalue) then
20 thisvalue="&nbsp;"
21 end if%>
22 <td valign=top><%=thisvalue%></td>
23 <% next %>
24 </tr>
25 <%rstemp.movenext
26 loop%>
27 </table>
28 <%
29 rstemp.close
30 set rstemp=nothing
31 conntemp.close
32 set conntemp=nothing
33 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 rob.martinson@directionsmag.com
The easiest way to begin learning ASP, is to install Microsoft PWS, and develop locally. To do this, you must also setup a DSN (Data
Source Name) on your machine, if you wish to use any of ASP's database access abilities. This tutorial is meant to walk you through
the process of setting up a system DSN on your Windows machine.

The first step, after you have PWS installed, is to open your control panel and select the 32bit ODBC Data Source
Administrator 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 rob.martinson@directionsmag.com
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 DSN
because that's what I generally use. See here for more info on the differences between system and file DSNs). This will bring
you to a list of System Data Sources that are setup on your machine. It may vary from the list above. From this point, click
the "Add" button and move on to the next screen.
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 rob.martinson@directionsmag.com
I began my development using Microsoft Access as I already had a copy, and it would help me to learn
SQL syntax that would later be of use in larger projects. For this reason, I will choose the MS Access
Database driver from this screen. If you are setting up a DSN for a different database format, select the
associated driver here.
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 rob.martinson@directionsmag.com
Here we will name our DSN. For web development, I generally setup a single DSN (depending on the project of course) and then
just modify the database as needed. Because of that, I almost always name mine "tables.dsn". Name it whatever you like, just
remember the name. From this screen you are also able to setup various options with your DSN including default authorization (click
advanced), page timeout, database location, etc. For now we will leave the default options and move on to the next screen by
choosing "Ok".
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 rob.martinson@directionsmag.com
If we have not specified the location of the database associated with our DSN on the previous screen, we will be prompted to
do 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 rob.martinson@directionsmag.com
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).
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 and
passes the ID to that script in a variable called whichID. After the user edits that information and presses submit, dbfull3.asp is
called. It's task is to gather all input fields and construct a SQL update statement. Here is a source printout of the script that displays
the table and "starts the ball rolling":
1 <%
2 response.buffer=true
3 Response.ExpiresAbsolute = Now() - 1
4 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 myDSN
18 set rstemp=conntemp.execute(mySQL)
19 howmanyfields=rstemp.fields.count -1
20 %>
21 <table border="1">
22 <tr>
23 <td valign="top">---</td>
24 <% 'Put Headings On The Table of Field Names
25 for i=0 to howmanyfields %>
26 <td><b><%=rstemp(i).name %></b></td>
27 <% next %>
28 </tr>
29 <% ' Now lets grab all the records
30 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.movenext
40 loop
41
42 rstemp.close
43 set rstemp=nothing
44 conntemp.close
45 set conntemp=nothing
46 %>
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 record
6
7 myDSN="DSN=Student;uid=student;pwd=magic"
8
9 set conntemp=server.createobject("adodb.connection")
10 conntemp.open myDSN
11 form_ID=request.querystring("which")
12
13 sqltemp="select * from authors "
14 sqltemp=sqltemp & " where AU_ID=" & form_id
15
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.close
24 set rstemp=nothing
25 conntemp.close
26 set conntemp=nothing
27 %>
28 <body>
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 next
6 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 apostrophe
14 form_name=Replace(form_name, "'", "''")
15
16 SQLstmt = "UPDATE authors SET "
17 SQLStmt = SQLstmt & "Author='" & form_name & "',"
18 SQLstmt = SQLstmt & "year_born=" & form_year
19 SQLStmt = SQLStmt & " WHERE AU_ID=" & form_id
20
21
22 Set RS = Conn.Execute(SQLStmt)
23
24 If err.number>0 then
25 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 if
34 IF conn.errors.count> 0 then
35 response.write "Database Errors Occured" & "<P>"
36 response.write SQLstmt & "<P>"
37 for counter= 0 to conn.errors.count
38 response.write "Error #" & conn.errors(counter).number & "<P>"
39 response.write "Error desc. -> " & conn.errors(counter).description & "<P>"
40 next
41 else
42 response.write "<B>Everything Went Fine. Record is updated now!</b>"
43 response.write "<br>" & SQLstmt
44 end if
45
46 rs.close
47 set rs=nothing
48 Conn.Close
49 set conn=nothing
50 %>
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 Carroll
This 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 exists
20 ' false = file CANNOT be over-written if it exists
21
22 set conntemp=server.createobject("adodb.connection")
23 conntemp.open myDSN
24 set rstemp=conntemp.execute(mySQL)
25
26 ' this code detects if data is empty
27 If rstemp.eof then
28 response.write "No data to convert for SQL statement<br>"
29 response.write mySQL & "<br>"
30 connection.close
31 set connection=nothing
32 response.end
33 end if
34
35 DO UNTIL rstemp.eof
36 thisline=linestart
37 for each whatever in rstemp.fields
38 thisfield=whatever.value
39 if isnull(thisfield) then
40 thisfield=shownull
41 end if
42 if trim(thisfield)="" then
43 thisfield=showblank
44 end if
45 thisfield=replace(thisfield,delimiter,delimitersub)
46 thisline=thisline & thisfield & delimiter
47 next
48 tempLen=len(thisline)
49 tempLenDelim=len(delimiter)
50 thisline=mid(thisline,1,tempLEN-tempLenDelim) & lineend
51 filetemp.WriteLine(thisline)
52 ' response.write thisline & "<br>"
53 rstemp.movenext
54 LOOP
55 filetemp.Close
56 set filetemp=nothing
57 set fstemp=nothing
58 rstemp.close
59 set rstemp=nothing
60 conntemp.close
61 set conntemp=nothing
62
63
64
65 If err.number=0 then
66 response.write "File was converted sucessfully!<br>"
67 response.write "Converted file is at <a href='"
68 response.write whichname & "'>" & whichname & "</a>"
69 else
70 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 if
78
79
80 %>
81 </body></html>
http://www.learnASP.com/learn/dbSQLdelete.asp by Charles M. Carroll
Page 100
Database -- Delete Record with SQL statement
SQL 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 next
7 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 myDSN
13
14 for counter=1 to 200
15 thistask="Task #" & counter & "<br>"
16 response.write thistask
17 Conn.Execute(mySQL)
18 Call ErrorVBScriptReport(thistask)
19 Call ErrorADOReport(mySQL,conn)
20 next
21 Conn.Close
22 set conn=nothing
23 %>
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 next
7 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 myDSN
12
13 Conn.Execute mySQL,howmany
14 response.write "The statement " & mySQL & "<b> deleted " & howmany & " records</b><br>"
15 Call ErrorVBScriptReport("Deleting...")
16 Call ErrorADOReport(mySQL,conn)
17
18 Conn.Close
19 set conn=nothing
20 %>
21 </BODY>
22 </HTML>
http://www.learnASP.com/learn/accessSQLserver.asp by Charles M. Carroll
Page 101
Access vs. SQL Server by Charles Carroll
DRAFT -- NOT FINISHED Microsoft Access is a database package that works well on one machine and with some careful
coding 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 Carroll
DRAFT -- NOT FINISHED
Oracle 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 topic
allowed you can join to get help from your colleagues worldwide.
aspOracle Listserver

JOIN, QUIT or Search ARCHIVES:
http://www.asplists.com/asplists/oracle.asp
Send Listserver Questions to
aspOracle@ls.asplists.com
Related Links
The Hottest Set of Oracle sites/listserves @
http://www.doug.org
How to Connect/Troubleshoot Oracle Connection by Bret H. Grade @
/learn/FAQOracleconnect.asp
How to Call Oracle Stored Procedure by Surya Rao @
/learn/FAQOraclestoredproc.asp
Returning Recordsets via ADO by John Kilgo @
/asplists/asporacleFAQ4.asp
Know 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 database
programming simple. Here we will show the code to display a gorgeous table of the customers database just be starting the
component 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 = 1000
7 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.ASPdbPro
14 set myDB=nothing
15 %>
16 </BODY>
17 </HTML>
18
19
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 = 1000
7 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.ASPdbPro
14 set myDB=nothing
15 %>
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 database
programming powerful and removes you worrying about how and rather what it looks like. Here we will show the code to display a
gorgeous 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 = 1101
10 B=Request("ASPdbBut_1101") ' this is NOT case sensitive
11 L9=Left(B,9)
12 UL9=UCASE(L9)
13 L12=Left(B,12)
14 UL12=UCASE(L12)
15 if UL9 <> "ASPDBEDIT" then
16 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 values
in certain fields.")
19
20 response.write("<HR WIDTH=66% Size=1>")
21 end if
22
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" then
27 MSG1 = "<CENTER><FONT SIZE=4 COLOR=Black><B>"
28 MSG1 = MSG1 + "Please Update the Information for: " + THISNAME
29 MSG1 = MSG1 + "</B></FONT><P>"
30 response.write(MSG1)
31 end if
32
33 if UL12 = "ASPDBEDITDEL" then
34 MSG1 = "<CENTER><FONT SIZE=4 COLOR=red><B>"
35 MSG1 = MSG1 + "You are about to DELETE all of the Information for: " + THISNAME
36 MSG1 = MSG1 + "</B></FONT><P>"
37 response.write(MSG1)
38 end if
39
40 if UL12 = "ASPDBEDITEDI" then
41 MSG1 = "<CENTER><FONT SIZE=4 COLOR=red><B>"
42 MSG1 = MSG1 + "You are about to EDIT all of the Information for: " + THISNAME
43 MSG1 = MSG1 + "</B></FONT><P>"
44 response.write(MSG1)
45 end if
46
47 Mydb.dbMDB = Server.MapPath("Pro-Demo.mdb") ' Has fields: Name, Age, Salary, NetWorth
48
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 = 10
55 MyDb.dbButtonAnchor=false
56 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-98
63 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 = EP
68
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.aspDBPro
83 set mydb=nothing
84 %>
85
86 </HTML>
87
88
89
90
http://www.learnASP.com/learn/ado.asp by Charles M. Carroll
Page 106
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 Carroll
This page demonstrates the capabilities how to display a table from a SQL statement a very fast and scaleable way using a
recordset method called GetString. GetString essentially asks the backend database to build a huge string instead of moving the
data as rows and columns. It allows very limited specifications, basically what string to place between each column and row and how
to 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 timeouts
with movenext. Getstring never timed out. So in a real production situation it makes weak databases feasible and of course reduces
the 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 form
8 set conntemp=server.createobject("adodb.connection")
9 conntemp.open whichDSN
10 set rstemp=conntemp.execute(mySQL)
11 If rstemp.eof then
12 response.write "No records matched<br>"
13 response.write mySQL & "<br>So cannot make table..."
14 rstemp.close
15 set rstemp=nothing
16 conntemp.close
17 set conntemp=nothing
18 response.end
19 end if
20 response.write "<table border='1'><tr>"
21
22 'Put Headings On The Table of Field Names
23 for each whatever in rstemp.fields
24 response.write "<td><b>" & whatever.name & "</B></TD>"
25 next
26 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.close
31 set rstemp=nothing
32 conntemp.close
33 set conntemp=nothing
34 %>
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 Carroll
This page demonstrates the capabilities how to display a table from a SQL statement a very fast and scaleable way using a
recordset method called GetRows. GetRows that move many records and fields into a memory array. Once in the array it is
accessed very fast. If you read the code closely you will notice it can free up the recordset and connection object earlier than the
traditional loop thus freeing up those resources for other scripts.
In terms of why this is faster, read:
http://www.learnasp.com/advice/whygetrows.asp
to see an in-depth explanation.
http://www.learnasp.com/learn/dbtablegetstring.asp
rips getrows to shreds speed-wise as the backend transfers one big string instead of a complex array structure but formatting is
SOOOOO 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 G
http://www.learnasp.com/learn/arrays2.asp G
http://www.learnasp.com/learn/arrays3.asp G
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 GetRows
9 myDSN="DSN=Student;uid=student;pwd=magic"
10 mySQL="select * from publishers where state='NY'"
11 showblank="&nbsp;"
12 shownull="-null-"
13
14 set conntemp=server.createobject("adodb.connection")
15 conntemp.open myDSN
16 set rstemp=conntemp.execute(mySQL)
17 If rstemp.eof then
18 response.write "No records matched<br>"
19 response.write mySQL & "<br>So cannot make table..."
20 rstemp.close
21 set rstemp=nothing
22 conntemp.close
23 set conntemp=nothing
24 response.end
25 end if
26
27 response.write "<table border='1'><tr>"
28 'Put Headings On The Table of Field Names
29 for each whatever in rstemp.fields
30 response.write "<td><b>" & whatever.name & "</B></TD>"
31 next
32 response.write "</tr>"
33
34 ' Now lets grab all the records
35 alldata=rstemp.getrows
36 rstemp.close
37 set rstemp=nothing
38 conntemp.close
39 set conntemp=nothing
40
41 numcols=ubound(alldata,1)
42 numrows=ubound(alldata,2)
43 FOR rowcounter= 0 TO numrows
44 FOR colcounter=0 to numcols
45 thisfield=alldata(colcounter,rowcounter)
46 if isnull(thisfield) then
47 thisfield=shownull
48 end if
49 if trim(thisfield)="" then
50 thisfield=showblank
51 end if
52 response.write "<td valign=top>"
53 response.write thisfield
54 response.write "</td>"
55 NEXT
56 response.write "</tr>" & vbcrlf
57 NEXT
58 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 Carroll
This 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 example
disconnects the recordset so that the data will not be drawn from up to the millisecond database data BUT retrieval will be much
faster.
1 <%@enablesessionstate=false%>
2 <%response.buffer=true%>
3 <!--#include virtual="/adovbs.inc"-->
4 <html><head>
5 <TITLE>dbtabledisconnected.asp</TITLE>
6 </head>
7 <body bgcolor="#FFFFFF">
8 <%
9 ' displays a database in table form via GetRows
10 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 myDSN
17 ' to disconnect a recordset it must be created explicitly
18 set rstemp=server.createobject("adodb.recordset")
19 rstemp.cursorlocation=aduseclient
20 rstemp.open mySQL,conntemp
21 ' this line below disconnects the recordset
22 set rstemp.activeconnection=nothing
23
24 If rstemp.eof then
25 response.write "No records matched<br>"
26 response.write mySQL & "<br>So cannot make table..."
27 rstemp.close
28 set rstemp=nothing
29 conntemp.close
30 set conntemp=nothing
31 response.end
32 end if
33
34 response.write "<table border='1'><tr>"
35 'Put Headings On The Table of Field Names
36 for each whatever in rstemp.fields
37 response.write "<td><b>" & whatever.name & "</B></TD>"
38 next
39 response.write "</tr>"
40 DO UNTIL rstemp.eof
41 response.write "<tr>"
42 for each whatever in rstemp.fields
43 thisfield=whatever.value
44 if isnull(thisfield) then
45 thisfield=shownull
46 end if
47 if trim(thisfield)="" then
48 thisfield=showblank
49 end if
50 response.write "<td valign=top>" & thisfield & "</td>"
51 next
52 response.write "</tr>"
53 rstemp.movenext
54 LOOP
55 response.write "</table>"
56 %>
57 </body></html>
http://www.learnASP.com/learn/dbmaxrecs.asp by Charles M. Carroll
Page 110
ADO Techniques -- The .maxrecords property
This page demonstrates the capabilities how to display a table from a SQL statement but limit the output to a specific number of
records.
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=15
8 connectme="DSN=Student;uid=student;pwd=magic"
9 rstemp.open "select * from titles", _
10 connectme,adopenstatic
11 ' table display
12 howmanyfields=rstemp.fields.count -1
13 %>
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.movenext
29 loop
30 rstemp.close
31 set rstemp=nothing
32 %>
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 not
in any way store a recordset or connection in memory when the page is not accessed unlike many solutions you will read about. The
ADO 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 800a0cb3
13 '
14 ' The operation requested by the application is not
15 ' supported by the provider.
16 '
17 ' You may have a driver that is out of date, see:
18 ' http://www.learnasp.com/learn/connectioninfo.asp
19 ' for code that will identify what your driver version is
20 ' this script works with Access, SQLserver and Oracle
21 ' with up-to-date drivers
22
23 If aduseclient="" THEN
24 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.end
29 END IF
30
31 mypage=request("whichpage")
32 If mypage="" then
33 mypage=1
34 end if
35 mypagesize=request("pagesize")
36 If mypagesize="" then
37 mypagesize=10
38 end if
39 mySQL=request("SQLquery")
40 IF mySQL="" THEN
41 mySQL=SQLtemp
42 END IF
43
44 set rstemp=Server.CreateObject("ADODB.Recordset")
45 rstemp.cursorlocation=aduseclient
46 rstemp.cachesize=5
47 rstemp.open mySQL,connectme
48 rstemp.movefirst
49 rstemp.pagesize=mypagesize
50 maxpages=cint(rstemp.pagecount)
51 maxrecs=cint(rstemp.pagesize)
52 rstemp.absolutepage=mypage
53 howmanyrecs=0
54 howmanyfields=rstemp.fields.count -1
55 response.write "Page " & mypage & " of " & maxpages & "<br>"
56 response.write "<table border='1'><tr>"
57
58 'Put Headings On The Table of Field Names
59 FOR i=0 to howmanyfields
60 response.write "<td><b>" & rstemp(i).name & "</b></td>"
61 NEXT
62 response.write "</tr>"
63
64 ' Now loop through the data
65 DO UNTIL rstemp.eof OR howmanyrecs>=maxrecs
66 response.write "<tr>"
67 FOR i = 0 to howmanyfields
68 fieldvalue=rstemp(i)
69 If isnull(fieldvalue) THEN
70 fieldvalue="n/a"
71 END IF
72 If trim(fieldvalue)="" THEN
73 fieldvalue="&nbsp;"
74 END IF
75 response.write "<td valign='top'>"
76 response.write fieldvalue
77 response.write "</td>"
78 next
79 response.write "</tr>"
80 rstemp.movenext
81 howmanyrecs=howmanyrecs+1
82 LOOP
83 response.write "</table><p>"
84
85 ' close, destroy
86 rstemp.close
87 set rstemp=nothing
88
89 ' Now make the page _ of _ hyperlinks
90 Call PageNavBar
91
92 sub PageNavBar()
93 ' Thanks to Jeff Emrich <jeff.emrich@datafuse.com>
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 then
100 counterstart = mypage - 9
101 else
102 counterstart = mypage - (mypage mod 10) + 1
103 end if
104 counterend = counterstart + 9
105 if counterend > maxpages then counterend = maxpages
106 if counterstart <> 1 then
107 ref="<a href='" & scriptname
108 ref=ref & "?whichpage=" & 1
109 ref=ref & "&pagesize=" & mypagesize
110 ref=ref & "&sqlQuery=" & server.URLencode(mySQL)
111 ref=ref & "'>First</a>&nbsp;:&nbsp;"
112 Response.Write ref
113
114
115 ref="<a href='" & scriptname
116 ref=ref & "?whichpage=" & (counterstart - 1)
117 ref=ref & "&pagesize=" & mypagesize
118 ref=ref & "&sqlQuery=" & server.URLencode(mySQL)
119 ref=ref & "'>Previous</a>&nbsp;"
120 Response.Write ref
121 end if
122 Response.Write "["
123 for counter=counterstart to counterend
124 If counter>=10 then
125 pad=""
126 end if
127 if cstr(counter) <> mypage then
128 ref="<a href='" & scriptname
129 ref=ref & "?whichpage=" & counter
130 ref=ref & "&pagesize=" & mypagesize
131 ref=ref & "&sqlQuery=" & server.URLencode(mySQL)
132 ref=ref & "'>" & pad & counter & "</a>"
133 else
134 ref="<b>" & pad & counter & "</b>"
135 end if
136 response.write ref
137 if counter <> counterend then response.write " "
138 next
139 Response.Write "]"
140 if counterend <> maxpages then
141 ref="&nbsp;<a href='" & scriptname
142 ref=ref & "?whichpage=" & (counterend + 1)
143 ref=ref & "&pagesize=" & mypagesize
144 ref=ref & "&sqlQuery=" & server.URLencode(mySQL)
145 ref=ref & "'>Next</a>"
146 Response.Write ref
147
148
149 ref="&nbsp;:&nbsp;<a href='" & scriptname
150 ref=ref & "?whichpage=" & maxpages
151 ref=ref & "&pagesize=" & mypagesize
152 ref=ref & "&sqlQuery=" & server.URLencode(mySQL)
153 ref=ref & "'>Last</a>"
154 Response.Write ref
155 end if
156 response.write "<br></font>"
157 response.write "</td>"
158 response.write "</table>"
159 end sub
160 %>
161 </body></html>
http://www.learnASP.com/learn/dbcount.asp by Charles M. Carroll
Page 112
Count Query/Table Records by Juan Llibre, Charles Carroll
This script counts the records in a database. Many people who attempt to use the .recordcount property have the value -1 returned
to them. In a nutshell, -1 means "I don't know how many records this query/table contains". It happens since the default cursortype is
AdOpenforwardonly (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 can
be 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 minute
you will not be retrieving fresh or recently added data. It is like a snapshot of the data. Recordsets opened this way WILL contain an
accurate 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.. Recordsets
opened 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 it
takes 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 read
the data, at the 6th minute you will still be retrieving fresh data and records added to the end of the data. Recordsets opened this
way 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 site
7 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, adopenstatic
11 howmanyrecs=rstemp.recordcount
12 response.write howmanyrecs & " records in<br>" & sqltemp
13 rstemp.close
14 set rstemp=nothing
15 %>
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 is
by nature slower than opening a database that also has the burden of knowing how many records it has upon demand. The
additional overhead and limitations of a adopendynamic or adopenstatic cursor may be a poor way to retrieve the data because the
recordset even though they count accurately. If you must count AND retrieve, I recommend counting first, closing the recordset and
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 (juggler@iquest.net)
ADO cursor types affects the properties and methods that are available as this table illustrates.
Property Forward-Only Dynamic Keyset Static
AbsolutePage N/A N/A R/W R/W
AbsolutePosition N/A N/A R/W R/W
ActiveConnection R/W R/W R/W R/W
BOF R/O R/O R/O R/O
Bookmark N/A N/A R/W R/W
CacheSize R/W R/W R/W R/W
CursorLocation R/W R/W R/W R/W
CursorType R/W R/W R/W R/W
EditMode R/O R/O R/O R/O
EOF R/O R/O R/O R/O
Filter R/W R/W R/W R/W
LockType R/W R/W R/W R/W
MarshalOptions R/W R/W R/W R/W
MaxRecords R/W R/W R/W R/W
PageCount N/A N/A R/O R/O
PageSize R/W R/W R/W R/W
RecordCount N/A N/A R/O R/O
Source R/W R/W R/W R/W
State R/O R/O R/O R/O
Status R/O R/O R/O R/O
Method
AddNew Yes Yes Yes Yes
CancelBatch Yes Yes Yes Yes
CancelUpdate Yes Yes Yes Yes
Clone N/A N/A Yes Yes
Close Yes Yes Yes Yes
Delete Yes Yes Yes Yes
GetRows Yes Yes Yes Yes
Move Yes Yes Yes Yes
MoveFirst Yes Yes Yes Yes
MoveLast N/A Yes Yes Yes
MoveNext Yes Yes Yes Yes
MovePrevious N/A Yes Yes Yes
NextRecordset Yes Yes Yes Yes
Open Yes Yes Yes Yes
Requery Yes Yes Yes Yes
Resync N/A N/A Yes Yes
Supports Yes Yes Yes Yes
Update Yes Yes Yes Yes
UpdateBatch Yes Yes Yes Yes
Legend:
R/W = Read/Write
R/O = Read-Only
N/A = Not Available or Supported
Yes = Available/Supported
http://www.learnASP.com/learn/dbnewrec.asp by Charles M. Carroll
Page 114
Database -- Form to Input a New Record
This 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 statement
This page demonstrates the capabilities how to add a record to a database with a SQL statement. To double check it is in the
database 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 next
6 auname=request.querystring("name")
7 auyear=request.querystring("year")
8 auID=request.querystring("ID")
9 If auid<9000 then
10 auid=auid+9000
11 end if
12 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) "
15 SQLStmt = SQLStmt & "VALUES (" & auid
16 SQLStmt = SQLStmt & ",'" & auname & "'"
17 SQLStmt = SQLStmt & "," & int(auyear) & ")"
18 Set RS = Conn.Execute(SQLStmt)
19 set rs=nothing
20 If err.number>0 then
21 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 else
30 response.write "No VBScript Errors Occured" & "<P>"
31 end if
32 IF conn.errors.count> 0 then
33 response.write "Database Errors Occured" & "<br>"
34 response.write "<b>" & SQLstmt & "</b><P>"
35 for counter= 0 to conn.errors.count
36 response.write "Error #" & conn.errors(counter).number & "<P>"
37 response.write "Error desc. -> " & conn.errors(counter).description & "<P>"
38 next
39 else
40 response.write "No Database Errors Occured!" & "<P>"
41 end if
42 Conn.Close
43 set conn=nothing
44 %>
45 </BODY>
46 </HTML>
http://www.learnASP.com/learn/dbnewADO.asp by Charles M. Carroll
Page 116
Add New Record with ADO
This 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 next
8 auname=request.querystring("name")
9 auyear=request.querystring("year")
10 auID=request.querystring("ID")
11 If auid<9000 then
12 auid=auid+9000
13 end if
14 conn="DSN=Student;uid=student;pwd=magic"
15 Set RS = Server.CreateObject("ADODB.Recordset")
16 RS.Open "authors",Conn,adopenstatic,adlockoptimistic
17 RS.AddNew
18 'RS("AU_ID")=auid
19 RS("Author") = auname
20 RS("Year_Born")= int(auyear)
21 RS.Update
22 Call ErrorVBscriptReport("Adding Record")
23 Call ErrorADOReport("Adding Record",RS.activeconnection)
24 RS.Close
25 set rs=nothing
26 %>
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 Carroll
This page demonstrates the capabilities how to use getstring (part of ADO 2.0 or above, if you are not sure what ADO version is
on your server, see /learn/versioncheck.asp)
to display a table from a SQL statement with one call G
eliminate multiple response.writes G
eliminate do until eof tests. G
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 form
8 set conntemp=server.createobject("adodb.connection")
9 conntemp.open whichDSN
10 set rstemp=conntemp.execute(mySQL)
11 If rstemp.eof then
12 response.write "No records matched<br>"
13 response.write mySQL & "<br>So cannot make table..."
14 rstemp.close
15 set rstemp=nothing
16 conntemp.close
17 set conntemp=nothing
18 response.end
19 end if
20 response.write "<table border='1'><tr>"
21
22 'Put Headings On The Table of Field Names
23 for each whatever in rstemp.fields
24 response.write "<td><b>" & whatever.name & "</B></TD>"
25 next
26 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.close
31 set rstemp=nothing
32 conntemp.close
33 set conntemp=nothing
34 %>
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 form
7 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) , adCmdStoredProc
14
15 set rstemp=server.createobject("adodb.recordset")
16 rstemp.open mySQL, conntemp, adopenforwardonly, _
17 adlockReadOnly, adCmdUnknown
18
19 response.write "<form><select name='state'><option>"
20
21 tempSTR=rstemp.getstring(,, "", "</option><option>", "&nbsp;")
22 response.write tempSTR
23
24 response.write "</select></form>"
25 rstemp.close
26 set rstemp=nothing
27 conntemp.close
28 set conntemp=nothing
29 %>
30 </body></html>
http://www.learnASP.com/learn/dbtablelists.asp by Charles M. Carroll
Page 118
Listing Tables within Databases by Charles Carroll DRAFT
SQL 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"
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 on
the 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, rstemp
4 set conntemp=server.createobject("adodb.connection")
5 conntemp.open inputDSN
6 set rstemp=conntemp.execute(inputquery)
7 howmanyfields=rstemp.fields.count -1%>
8 <table border=1><tr>
9 <% 'Put Headings On The Table of Field Names
10 for i=0 to howmanyfields %>
11 <td><b><%=rstemp(i).name%></B></TD>
12 <% next %>
13 </tr>
14 <% ' Now lets grab all the records
15 do while not rstemp.eof %>
16 <tr>
17 <% for i = 0 to howmanyfields
18 thisvalue=rstemp(i)
19 If isnull(thisvalue) then
20 thisvalue="&nbsp;"
21 end if%>
22 <td valign=top><%=thisvalue%></td>
23 <% next %>
24 </tr>
25 <%rstemp.movenext
26 loop%>
27 </table>
28 <%
29 rstemp.close
30 set rstemp=nothing
31 conntemp.close
32 set conntemp=nothing
33 end sub%>
http://www.learnASP.com/learn/dbschemas.asp by Charles M. Carroll
Page 119
ADO Schemas to list tables & fields
You can examine a Schema for the table names and column names and column detail information.
1 <html><head>
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 myDSN
12
13 Set rsSchema = conntemp.OpenSchema(adSchemaColumns)
14 thistable=""
15 pad="&nbsp;&nbsp;&nbsp;"
16 DO UNTIL rsSchema.EOF
17 prevtable=thistable
18 thistable=rsSchema("Table_Name")
19 thiscolumn=rsSchema("COLUMN_NAME")
20 IF thistable<>prevtable THEN
21 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 IF
25 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 NEXT
60 FOR counter=4 to 27
61 thisColInfoType=colschema(counter)
62 thisColInfo=rsSchema(thisColInfoType)
63 If err.number<>0 then
64 thiscolinfo="-error-"
65 err.clear
66 END IF
67 IF thisColInfo<>"" THEN
68 response.write pad & pad & pad & thiscolinfotype
69 response.write "=<b>" & thiscolinfo & "</b><br>"
70 END IF
71 NEXT
72 response.flush
73 rsSchema.MoveNext
74 LOOP
75
76 rsSchema.Close
77 set rsSchema=nothing
78
79 conntemp.close
80 set conntemp=nothing
81 %>
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 Parm1
4 CASE 0
5 fieldtypename="adEmpty"
6 CASE 16
7 fieldtypename="adTinyInt"
8 CASE 2
9 fieldtypename="adSmallInt"
10 CASE 3
11 fieldtypename="adInteger"
12 CASE 20
13 fieldtypename="adBigInt"
14 CASE 17
15 fieldtypename="adUnsignedTinyInt"
16 CASE 18
17 fieldtypename="adUnsignedSmallInt"
18 CASE 19
19 fieldtypename="adUnsignedInt"
20 CASE 21
21 fieldtypename="adUnsignedBigInt"
22 CASE 4
23 fieldtypename="adSingle"
24 CASE 5
25 fieldtypename="adDouble"
26 CASE 6
27 fieldtypename="adCurrency"
28 CASE 14
29 fieldtypename="adDecimal"
30 CASE 131
31 fieldtypename="adNumeric"
32 CASE 11
33 fieldtypename="adBoolean"
34 CASE 10
35 fieldtypename="adError"
36 CASE 132
37 fieldtypename="adUserDefined"
38 CASE 12
39 fieldtypename="adVariant"
40 CASE 9
41 fieldtypename="adIDispatch"
42 CASE 13
43 fieldtypename="adIUnknown"
44 CASE 72
45 fieldtypename="adGUID"
46 CASE 7
47 fieldtypename="adDate"
48 CASE 133
49 fieldtypename="adDBDate"
50 CASE 134
51 fieldtypename="adDBTime"
52 CASE 135
53 fieldtypename="adDBTimeStamp"
54 CASE 8
55 fieldtypename="adBSTR"
56 CASE 129
57 fieldtypename="adChar"
58 CASE 200
59 fieldtypename="adVarChar"
60 CASE 201
61 fieldtypename="adLongVarChar"
62 CASE 130
63 fieldtypename="adWChar"
64 CASE 202
65 fieldtypename="adVarWChar"
66 CASE 203
67 fieldtypename="adLongVarWChar"
68 CASE 128
69 fieldtypename="adBinary"
70 CASE 204
71 fieldtypename="adVarBinary"
72 CASE 205
73 fieldtypename="adLongVarBinary"
74 CASE ELSE
75 fieldtypename="Undefined by ADO"
76 END SELECT
77 END FUNCTION
78 %>
http://www.learnASP.com/learn/dbschemasall.asp by Charles M. Carroll
Page 120
ADO Schemas/listing tables and fields
You 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)=adSchemaProviderSpecific
12 colschema(1)=adSchemaAsserts
13 colschema(2)=adSchemaCatalogs
14 colschema(3)=adSchemaCharacterSets
15 colschema(4)=adSchemaCollations
16 colschema(5)=adSchemaColumns
17 colschema(6)=adSchemaCheckConstraints
18 colschema(7)=adSchemaConstraintColumnUsage
19 colschema(8)=adSchemaConstraintTableUsage
20 colschema(9)=adSchemaKeyColumnUsage
21 colschema(10)=adSchemaReferentialContraints
22 colschema(11)=adSchemaTableConstraints
23 colschema(12)=adSchemaColumnsDomainUsage
24 colschema(13)= adSchemaIndexes
25 colschema(14)=adSchemaColumnPrivileges
26 colschema(15)=adSchemaTablePrivileges
27 colschema(16)=adSchemaUsagePrivileges
28 colschema(17)=adSchemaProcedures
29 colschema(18)=adSchemaSchemata
30 colschema(19)=adSchemaSQLLanguages
31 colschema(20)=adSchemaStatistics
32 colschema(21)=adSchemaTables
33 colschema(22)=adSchemaTranslations
34 colschema(23)=adSchemaProviderTypes
35 colschema(24)=adSchemaViews
36 colschema(25)=adSchemaViewColumnUsage
37 colschema(26)=adSchemaViewTableUsage
38 colschema(27)=adSchemaProcedureParameters
39 colschema(28)=adSchemaForeignKeys
40 colschema(29)=adSchemaPrimaryKeys
41 colschema(30)=adSchemaProcedureColumns
42
43 FOR counter=1 to 30
44 thisSchema=colSchema(counter)
45 Call Schema2Table(myDSN,thisSchema)
46 response.write "<p>"
47 NEXT
48 %>
49 </body></html>
The include file lib_schemas.asp looks like this:
1 <%
2 FUNCTION schemaName(parm1)
3 SELECT CASE parm1
4 CASE adSchemaProviderSpecific
5 schemaname="adSchemaProviderSpecific"
6 CASE adSchemaAsserts
7 schemaName="adSchemaAsserts"
8 CASE adSchemaCatalogs
9 schemaName="adSchemaCatalogs"
10 CASE adSchemaCharacterSets
11 schemaName="adSchemaCharacterSets"
12 CASE adSchemaCollations
13 schemaName="adSchemaCollations"
14 CASE adSchemaColumns
15 schemaName="adSchemaColumns"
16 CASE adSchemaCheckConstraints
17 schemaName="adSchemaCheckConstraints"
18 CASE adSchemaConstraintColumnUsage
19 schemaName="adSchemaConstraintColumnUsage"
20 CASE adSchemaConstraintTableUsage
21 schemaName="adSchemaConstraintTableUsage"
22 CASE adSchemaKeyColumnUsage
23 schemaName="adSchemaKeyColumnUsage"
24 CASE adSchemaReferentialContraints
25 schemaName="adSchemaReferentialContraints"
26 CASE adSchemaTableConstraints
27 schemaName="adSchemaTableConstraints"
28 CASE adSchemaColumnsDomainUsage
29 schemaName="adSchemaColumnsDomainUsage"
30 CASE adSchemaIndexes
31 schemaName="adSchemaIndexes"
32 CASE adSchemaColumnPrivileges
33 schemaName="adSchemaColumnPrivileges"
34 CASE adSchemaTablePrivileges
35 schemaName="adSchemaTablePrivileges"
36 CASE adSchemaUsagePrivileges
37 schemaName="adSchemaUsagePrivileges"
38 CASE adSchemaProcedures
39 schemaName="adSchemaProcedures"
40 CASE adSchemaSchemata
41 schemaName="adSchemaSchemata"
42 CASE adSchemaSQLLanguages
43 schemaName="adSchemaSQLLanguages"
44 CASE adSchemaStatistics
45 schemaName="adSchemaStatistics"
46 CASE adSchemaTables
47 schemaName="adSchemaTables"
48 CASE adSchemaTranslations
49 schemaName="adSchemaTranslations"
50 CASE adSchemaProviderTypes
51 schemaName="adSchemaProviderTypes"
52 CASE adSchemaViews
53 schemaName="adSchemaViews"
54 CASE adSchemaViewColumnUsage
55 schemaName="adSchemaViewColumnUsage"
56 CASE adSchemaViewTableUsage
57 schemaName="adSchemaViewTableUsage"
58 CASE adSchemaProcedureParameters
59 schemaName="adSchemaProcedureParameters"
60 CASE adSchemaForeignKeys
61 schemaName="adSchemaForeignKeys"
62 CASE adSchemaPrimaryKeys
63 schemaName="adSchemaPrimaryKeys"
64 CASE adSchemaProcedureColumns
65 schemaName="adSchemaProcedureColumns"
66 CASE ELSE
67 schemaName="-unknown-"
68 END SELECT
69 END FUNCTION
70
71 SUB Schema2Table(parmDSN, parmSchemaName)
72 set conntemp=server.createobject("adodb.connection")
73 conntemp.open parmDSN
74
75 on error resume next
76 set rsSchema=conntemp.OpenSchema(parmSchemaName)
77
78 IF err.number=3251 THEN
79 response.flush
80 response.write "<b>" & SchemaName(parmSchemaName)
81 response.write "</b><br> is not supported<br>"
82 err.clear
83 ELSE
84 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 Names
88 for each whatever in rsSchema.fields
89 response.write "<td><b>" & whatever.name & "</b></td>"
90 next
91 response.write "</tr>"
92 DO UNTIL rsSchema.eof
93 response.write "<tr>"
94 for each whatever in rsSchema.fields
95 thisfield=whatever.value
96 if isnull(thisfield) then
97 thisfield="&nbsp;"
98 end if
99 if trim(thisfield)="" then
100 thisfield="&nbsp;"
101 end if
102 response.write "<td valign=top>" & thisfield & "</td>"
103 next
104 response.write "</tr>"
105 rsSchema.MoveNext
106 LOOP
107 response.write "</table><br>"
108 response.flush
109 END IF
110
111 rsSchema.Close
112 set rsSchema=nothing
113
114 conntemp.close
115 set conntemp=nothing
116 END SUB
117 %>
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 statements
work. The kind of fixes we deploy include:
text fields must have single quotes around the values. G
fields with spaces in their names must be surrounded with [] G
set parameters must have commas between them G
Text fields with single quote ' cannot be placed into SQL statements unmodified. Notice how the last example below uses the
VBScript replace command to transform a string that may contain embedded ' .
Statement with Flaws Improved Statement (fixes in red)
UPDATE mytableSET LocID=0007,Material=13
1/4 Description=T-shirts ListPrice=35
WHERE CusID=97
added space before SET
UPDATE mytable SET
LocID='0007',Material='13 1/4',
Description='T-shirts', [List Price]=35
WHERE CusID=97
INSERT INTO authors (AU_ID, author,
year_born) VALUES (7000, Joe
Smith,1950)
INSERT INTO authors (AU_ID, author,
year_born) VALUES (7000, 'Joe
Smith',1950)
SELECT * from atable where state = MD
and
year born<1955
SELECT * from atable where state = 'MD'
and
and [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 Input
This page demonstrates the capabilities how to display a table from a SQL statement using one input variable from a user. The script
to display a specified record in the table is:
1 <TITLE>db1parm.asp</TITLE>
2 <body bgcolor="#FFFFFF">
3 <%
4 ' My ASP program that talks to a database
5 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=" & p1
9 set rstemp=conntemp.execute(temp)
10 howmanyfields=rstemp.fields.count -1
11 %>
12 <table border=1>
13 <tr>
14 <% 'Put Headings On The Table of Field Names
15 for i=0 to howmanyfields %>
16 <td><b><%=rstemp(i).name %></B></TD>
17 <% next %>
18 </tr>
19 <% ' Now lets grab all the records
20 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.movenext
27 loop
28 rstemp.close
29 set rstemp=nothing
30 conntemp.close
31 set conntemp=nothing%>
32 </table>
33 </body>
34 </html>
http://www.learnASP.com/learn/dbupdate.asp by Charles M. Carroll
Page 123
Database -- Update Record
This 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
G
To double check it is in the database try:
Test This -->/learn/test/db1parm.asp?id=9000
G
Now try:
Test This -->/learn/test/dbupdate.asp?name=NewPerson&id=9000&year=1964
to change the "NewPerson" Birthday to 1964 again and
Test This -->/learn/test/dbupdate.asp?name=NewPerson&id=9000&year=1901
G
The script is:
1 <TITLE>dbupdate.asp</TITLE>
2 <body bgcolor="#FFFFFF">
3 <HTML>
4 <%
5 on error resume next
6 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 "
12 SQLStmt = SQLstmt & "SET Author='" & auname & "',"
13 SQLstmt = SQLstmt & "year_born=" & auyear
14 SQLStmt = SQLStmt & " WHERE AU_ID=" & auid
15 Set RS = Conn.Execute(SQLStmt)
16 If err.number>0 then
17 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 else
26 response.write "No problems occured!" & "<P>"
27 end if
28 IF conn.errors.count> 0 then
29 response.write "Database Errors Occured" & "<P>"
30 for counter= 0 to conn.errors.count
31 response.write "Error #" & conn.errors(counter).number & "<P>"
32 response.write "Error desc. -> " & conn.errors(counter).description & "<P>"
33 next
34 else
35 response.write SQLstmt
36 response.write "Everything Went Fine. Author is updated now!" & "<P>"
37 end if
38 set rstemp=nothing
39 Conn.Close
40 set conntemp=nothing
41 %>
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
SQL Troubleshooting Resources
We 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 to
aspsqlhowto@ls.asplists.com
Related Links
John Hoffman's SQL Tutorial @
http://w3.one.net/~jhoffman/sqltut.htm
Solution Partners Data Shaping Alternatives @
http://www.solpart.com/techcorner/HRS/HRSOverview.asp
Book:SQL for Smarties by Joe Celko @
http://www.learnasp.com/books/sqlsmarties.asp
Book: SQL Puzzles & Answers by Joe Celko @
http://www.learnasp.com/books/sqlpuzzles.asp
Data Shaping Basics Part1 @
http://www.4guysfromrolla.com/webtech/092599-1.shtml
Data Shaping Basics Part1 @
http://www.4guysfromrolla.com/webtech/100699-2.shtml
Stump The SQL Guru @
http://www.4guysfromrolla.com/webtech/sqlguru/
4Guys Inner Join Tutorial @
http://www.4guysfromrolla.com/webtech/050599-1.shtml
Join 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
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'
G
Numeric fields need no special characters before and after
"select * from publishers where PubID=10"
G
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%%'"
G
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"
G
http://www.learnASP.com/learn/SQLwhere2.asp by Charles M. Carroll
Page 128
SQL Where Examples by Charles Carroll
Here 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>
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 Names
9 for i=0 to howmanyfields %>
10 <td><b><%=rstemp(i).name%></B></TD>
11 <% next %>
12 </tr>
13 <% ' Now lets grab all the records
14 do while not rstemp.eof %>
15 <tr>
16 <% for i = 0 to howmanyfields
17 thisvalue=rstemp(i)
18 If isnull(thisvalue) then
19 thisvalue="&nbsp;"
20 end if%>
21 <td valign=top><%=thisvalue%></td>
22 <% next %>
23 </tr>
24 <%rstemp.movenext
25 loop%>
26 </table>
27 <%
28 rstemp.close
29 set rstemp=nothing
30 conntemp.close
31 set conntemp=nothing
32 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>
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, rstemp
4 set conntemp=server.createobject("adodb.connection")
5 conntemp.open inputDSN
6 set rstemp=conntemp.execute(inputquery)
7 howmanyfields=rstemp.fields.count -1%>
8 <table border=1><tr>
9 <% 'Put Headings On The Table of Field Names
10 for i=0 to howmanyfields %>
11 <td><b><%=rstemp(i).name%></B></TD>
12 <% next %>
13 </tr>
14 <% ' Now lets grab all the records
15 do while not rstemp.eof %>
16 <tr>
17 <% for i = 0 to howmanyfields
18 thisvalue=rstemp(i)
19 If isnull(thisvalue) then
20 thisvalue="&nbsp;"
21 end if%>
22 <td valign=top><%=thisvalue%></td>
23 <% next %>
24 </tr>
25 <%rstemp.movenext
26 loop%>
27 </table>
28 <%
29 rstemp.close
30 set rstemp=nothing
31 conntemp.close
32 set conntemp=nothing
33 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">
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" then
10 SQLtemp=SQLtemp & " ='"
11 Else
12 SQLtemp=SQLtemp & " LIKE '"
13 End If
14 SQLtemp=SQLtemp & mycity & "'"
15 'response.write SQLtemp
16 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, rstemp
4 set conntemp=server.createobject("adodb.connection")
5 conntemp.open inputDSN
6 set rstemp=conntemp.execute(inputquery)
7 howmanyfields=rstemp.fields.count -1%>
8 <table border=1><tr>
9 <% 'Put Headings On The Table of Field Names
10 for i=0 to howmanyfields %>
11 <td><b><%=rstemp(i).name%></B></TD>
12 <% next %>
13 </tr>
14 <% ' Now lets grab all the records
15 do while not rstemp.eof %>
16 <tr>
17 <% for i = 0 to howmanyfields
18 thisvalue=rstemp(i)
19 If isnull(thisvalue) then
20 thisvalue="&nbsp;"
21 end if%>
22 <td valign=top><%=thisvalue%></td>
23 <% next %>
24 </tr>
25 <%rstemp.movenext
26 loop%>
27 </table>
28 <%
29 rstemp.close
30 set rstemp=nothing
31 conntemp.close
32 set conntemp=nothing
33 end sub%>
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" then
9 SQLtemp=SQLtemp & " ='"
10 Else
11 SQLtemp=SQLtemp & " LIKE '"
12 End If
13 SQLtemp=SQLtemp & mycity & "'"
14 'response.write SQLtemp
15 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, rstemp
4 set conntemp=server.createobject("adodb.connection")
5 conntemp.open inputDSN
6 set rstemp=conntemp.execute(inputquery)
7 howmanyfields=rstemp.fields.count -1%>
8 <table border=1><tr>
9 <% 'Put Headings On The Table of Field Names
10 for i=0 to howmanyfields %>
11 <td><b><%=rstemp(i).name%></B></TD>
12 <% next %>
13 </tr>
14 <% ' Now lets grab all the records
15 do while not rstemp.eof %>
16 <tr>
17 <% for i = 0 to howmanyfields
18 thisvalue=rstemp(i)
19 If isnull(thisvalue) then
20 thisvalue="&nbsp;"
21 end if%>
22 <td valign=top><%=thisvalue%></td>
23 <% next %>
24 </tr>
25 <%rstemp.movenext
26 loop%>
27 </table>
28 <%
29 rstemp.close
30 set rstemp=nothing
31 conntemp.close
32 set conntemp=nothing
33 end sub%>
The file lib_dblist.asp looks like this:
1 <%sub query2list(myquery,myname,myDSN)
2 dim conntemp, rstemp
3 set conntemp=server.createobject("adodb.connection")
4 conntemp.open myDSN
5 set rstemp=conntemp.execute(myquery)
6 %>
7 <Select name="<%=myname%>">
8 <%
9 do while not rstemp.eof
10 thisfield=trim(RStemp(0))
11 if isnull(thisfield) or thisfield="" then
12 ' ignore
13 else
14 response.write "<option>" & thisfield & "</option>"
15 end if
16 rstemp.movenext
17 loop
18 %>
19 </select>
20 <%rstemp.close
21 set rstemp=nothing
22 conntemp.close
23 set conntemp=nothing
24 end sub%>
http://www.learnASP.com/learn/SQLandor.asp by Charles M. Carroll
Page 132
SQL OR Search Example by Charles Carroll
AND and OR operators expand the power of the WHERE clause and provide a powerful tool to check multiple conditions. The Basic
Guidelines 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>
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").count
5 If citycount=0 then%>
6 <B>You never choose a city!</b><br>
7 <a href="sqlcities.asp">Choose City</a>
8 <%
9 response.end
10 end if
11 firstcity=request.form("cy")(1)
12 SQLtemp="select * from publishers "
13 SQLtemp = SQLtemp & " where city='" & firstcity & "'"
14 for counter=2 to citycount
15 whichcity=request.form("cy")(counter)
16 SQLtemp = SQLtemp & " or city='" & whichcity & "' "
17 next
18 response.write SQLtemp
19 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, rstemp
4 set conntemp=server.createobject("adodb.connection")
5 conntemp.open inputDSN
6 set rstemp=conntemp.execute(inputquery)
7 howmanyfields=rstemp.fields.count -1%>
8 <table border=1><tr>
9 <% 'Put Headings On The Table of Field Names
10 for i=0 to howmanyfields %>
11 <td><b><%=rstemp(i).name%></B></TD>
12 <% next %>
13 </tr>
14 <% ' Now lets grab all the records
15 do while not rstemp.eof %>
16 <tr>
17 <% for i = 0 to howmanyfields
18 thisvalue=rstemp(i)
19 If isnull(thisvalue) then
20 thisvalue="&nbsp;"
21 end if%>
22 <td valign=top><%=thisvalue%></td>
23 <% next %>
24 </tr>
25 <%rstemp.movenext
26 loop%>
27 </table>
28 <%
29 rstemp.close
30 set rstemp=nothing
31 conntemp.close
32 set conntemp=nothing
33 end sub%>
The file lib_dblistm.asp looks like this:
1 <%
2 SUB query2listm(myquery,myname,myDSN)
3 dim conntemp, rstemp
4 set conntemp=server.createobject("adodb.connection")
5 conntemp.open myDSN
6 set rstemp=conntemp.execute(myquery)
7 %>
8 <Select name="<%=myname%>" multiple>
9 <%
10 do while not rstemp.eof
11 thisfield=trim(RStemp(0))
12 if isnull(thisfield) or thisfield="" then
13 ' ignore
14 else
15 response.write "<option>" & thisfield & "</option>"
16 end if
17 rstemp.movenext
18 loop
19 %>
20 </select>
21 <%rstemp.close
22 set rstemp=nothing
23 conntemp.close
24 set conntemp=nothing
25 END SUB
26 %>
http://www.learnASP.com/learn/SQLandor2.asp by Charles M. Carroll
Page 133
SQL And/OR Examples by Charles Carroll
Here 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/Examples
SQL 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'
G
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"
G
The AS operator allows you to specify a name for the counted field:
"select count(city) as howmany,city from publishers group by city"
G
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>
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 Names
9 for i=0 to howmanyfields %>
10 <td><b><%=rstemp(i).name%></B></TD>
11 <% next %>
12 </tr>
13 <% ' Now lets grab all the records
14 do while not rstemp.eof %>
15 <tr>
16 <% for i = 0 to howmanyfields
17 thisvalue=rstemp(i)
18 If isnull(thisvalue) then
19 thisvalue="&nbsp;"
20 end if%>
21 <td valign=top><%=thisvalue%></td>
22 <% next %>
23 </tr>
24 <%rstemp.movenext
25 loop%>
26 </table>
27 <%
28 rstemp.close
29 set rstemp=nothing
30 conntemp.close
31 set conntemp=nothing
32 end sub%>
http://www.learnASP.com/learn/SQLaggregate.asp by Charles M. Carroll
Page 135
SQL Aggregate Syntax/Examples
SQL 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 Alexander
In 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 the
fact 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. The
result of the query is this:
CustomerName SalesAmount
Joe Schmoe $1.00
Joe Schmoe $22.00
Joe Schmoe $3.00

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 where
we 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 will
work 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
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 Overview
written 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 an
effective method for tracking visitors.
Asking a visitor for their username and password (or their credentials) is called Authentication. On the world wide web, the oldest
and 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 Response
A good choice if if you are on a Windows Network, you can require the use of IE, and there's no proxy-server between the
browser and the server.
G
IIS Basic Authentication
Can expose your NT usernames and passwords unless all connections are over SSL.
G
A Basic Authentication filter such as AuthentiX
Cannot compromise NT accounts. High performance, large numbers of users. Can validate against ODBC or internal
database. Many advanced features.
G
Write your own filter
Flexible, but resource intensive to build.
G
Cookie Based Authentication with ASP pages
Only protects ASP pages. Can be slow. Requires cookies. Cookie-based systems can be susceptible to spoofing.
G
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.
G
Certificate based.
Secure, but intimidating for webmasters and surfers alike. Requires SSL.
G
http://www.learnASP.com/learn/authenticatecomparisons.asp by Charles M.
Carroll
Page 139
Authentication Comparison
written 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) G
Performance is critical. If (as you hope), your site becomes wildly popular, you don't want a dead-slow server (impacts
SSL/Certificates, ASP)
G
Which Type Why use it? Why not use it? How to use it.
IIS NT Challenge Response
Why

Why not

How

IIS Basic Authentication
Why
Why not

How

A Third Party Basic Authentication filter
Why

Why not How
Write your own Basic Authentication filter
Why

Why not

How

Cookie Based Authentication with ASP pages
Why

Why not

How

Self-authenticating scripts
Why

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/Response
written 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 these
conditions:
all users are on accessible domains G
there aren't too many users G
you can require the use of a compatible browser (Internet Explorer is the only browser which supports NTCR). G
You won't want to use NTFS if
you want compatibility with browsers other than IE, or older browsers G
you want to protect directories on FAT partitions G
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 very
difficult to maintain. It can also impair the speed of the operating system itself! Using the NT user base can also be a
problem because of potential security risks. You are elevating a 'mere' web surfer to the status of a full NT user. You
have to be careful not inadvertently grant too many permissions.
G
there's a proxy server involved As documented in the IIS 4 Resource Kit, NTLM will not work through a proxy. The
problem is that it requires more than 1 round trip to complete authentication and so needs a persistent connection end
to end end, from client to origin server. Proxies don't generally work that way.
G
Definitions
NTCR = NT Challenge Response G
NTLM = NT Lan Manager G
NTFS = NT File System G
How to set up NTCR
In Internet Service Manager (IIS1-3) or the Microsoft Management Console for IIS (IIS4 and up) select the directory you
want to protect. Make sure Basic (Clear Text) is off and Windows NT Challenge Response is on. You can leave Allow
Anonymous on.
Create an account for each user you want to provide access, remove the permissions for "IUSR_machinename" from the
directory, and add permissions for the added users. Alternatively, you could set up a group, permit access to that group, and
add permitted users to the group. Remember, the user will need execute rights if the directory has any ASP, ISAPI
extensions, 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, unless
you 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 to
prepend 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 to
IIS. 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 not
be able to login using the current user to a machine elsewhere on the LAN. For example if an NTCR protected ASP page
tried to read an Access mdb file on another machine, it would fail. Similarly for SQL Server with Integrated or Mixed
security. See Q166029, Q149425.
http://www.learnASP.com/learn/authenticatebasic.asp by Charles M. Carroll
Page 141
Authentication - IIS Basic Authentication
written 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 must
be 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 and
performance. IIS calls LogonUser and ImpersonateLoggedOnUser for each and every request, which is expensive in terms of
CPU cycles.
Definitions
SSL = Secure Socket Layer. G
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 directory
you want to protect. Turn on Basic (Clear Text) and turn off Windows NT Challenge Response. It is OK to leave
Allow Anonymous on.
G
When you select Basic (Clear Text) you will be warned that you Windows NT usernames and passwords will be
transmitted without being encrypted. For your NT accounts this is a pretty serious issue. You should only consider this
option in combination with SSL, which is slow and requires you to buy a certificate from Verisign or Thawte (among
others).
G
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.
G
http://www.learnASP.com/learn/authenticatecookies.asp by Charles M. Carroll
Page 142
Authentication -- Cookie Based
written 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 if
You are happy coding your own solution in VBScript, and you only have a few asp pages to protect. G
You don't mind excluding those who cannot or will not accept cookies. G
You don't have gif/jpeg/pdf or other non-ASP content, so you are not concerned about someone else creating
web-pages linking directly to your non-ASP protected content.
G
You won't want Cookie Based Authentication with ASP pages if
You want to protect all content, not just ASP pages. G
You are worried about performance. Any reasonably large amount of Active Server Pages can have a significant
detrimental effect on the performance of your server. The popularity of products such as XBuilder, which generates
static html pages from ASP pages for performance reasons (among others), illustrates this point.
G
Cookie-based systems can be susceptible to spoofing. G
Definitions
ASP = Active Server Pages. G
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 to
implement this:
http://www.activeserverpages.com/learn/security.asp G
http://www.activeserverpages.com/learn/security2.asp G
http://www.learnASP.com/learn/authenticatecertificate.asp by Charles M. Carroll
Page 143
Authentication -- Certificate Based
written 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 to
compatibility 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 G
You accept the need for SSL and don't mind paying the performance penalty. G
You already have a certificate or you don't mind paying for one and setting it up. G
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 G
You do not want the performance hit of having all protected information exchanged via SSL G
Definitions
SSL = secure socket layer. G
MMC = Microsoft Management Console. G
How to use Certificate based authentication
Since 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 Key
Manager.
G
Select a directory you want to protect in the MMC G
Click on the Secure Communicatations Edit button on the Directory Security property sheet and use the certificate you
obtained. Select both Enable Client Certificates and Require Client Certificate
G
Enable client certificates for this resource G
Issue client certificates for access to this resource. G
There are several good references to help understand and use Client Certificate technology. Some articles that are recommended
include:
"Internet Information Server 4.0 - Security for the Web-Enabled Enterprise" by Nick Evans in the Premier Edition of Security
Advisor by Advisor.com publications, and
G
"Web Project, Digital IDs" by Jon Udell in the March Edition of Byte magazine. G
"Issuing digital certificates with Microsoft Certificate Server" section of the IIS Security White Paper by Microsoft. G
http://www.learnASP.com/learn/authenticatebuild.asp by Charles M. Carroll
Page 144
Authentication -- Write your own Filter
written 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 if
you have special requirements, and commissioning a custom enhancement to a third party Basic G
Authentication filter is not an option.
you have the skills, resources and time. G
you want to validate against a specific or proprietary type of datasource, such as flat-file, or your own
database.
G
You won't want to write your own Basic Authentication filter if
you have a short deadline G
you do not have the skills or resources required G
Basic Authentication is not secure enough for your purposes G
you want all accounts of every type in one userbase, specifically the NT user account database, for
administrative reasons.
G
a third party tool like AuthentiX meets all your needs G
Definitions
ISAPI = Internet Server Application Programming Interface G
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 G
HttpFilterProc G
The GetFilterVersion function is the first entry point called by the Internet Information Server. In this function you
set 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 work
of the filter is actually done.
There are several excellent references to help develop an ISAPI filter. Recommended is Que's "Special Edition
Using 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 #1
You can limit access to specific pages in your website using several methods documented at
http://www.activeserverpages.com/learn/authenticate.asp Here we will demonstrate how to use custom authentication and also
cover session and application issues. You can try our authentication example by:
Attempt to access test/securitytestlevel1.asp or test/securitytestlevel2.asp or test/securitylevel3required.asp
All attempts to read those pages should fail.
G
Now if you login at test/securitylogin.asp. Sample logins that will work because of the database data are:
user=chaz, password=chaz, securitylevel=1
user=chaz2, password=chaz2, securitylevel=2
user=chaz3, password=chaz3, securitylevel=3
G
You can also try logging out at test/securitylogout.asp which will put you back to square one. No security level will exist then. G
The next page details the source code for all scripts needed to implement our example but here is the list:
securitylogin.asp
securityloginrespond.asp
the login screen where someone can enter username/password and confirm
security level. It is a form that submits to securityloginrespond.asp
securitylogout.asp the screen to abandon someone's username/password and security level
securitylevel1required.asp
securitylevel2required.asp
securitylevel3required.asp
which can be included on individual pages to limit access to people with that
security level, i.e/:
<!--#include file="securitylevel1required.asp"-->
securitytestlevel1.asp
securitytestlevel2.asp
securitytestlevel3.asp
which demonstrate how security is implemented. These scripts cannot be
seen unless you login.
securitynotallowed.asp
which anyone attempting to access a page without appropriate security level
is redirected to.
/learn/test/customsecurity.mdb
Download Database
a 3 column Access database: username, password, security level. Sample
data is:
user=chaz, password=chaz, securitylevel=1
user=chaz2, password=chaz2, securitylevel=2
user=chaz3, password=chaz3, securitylevel=3
In a production application, this database would be located OUTSIDE
of the web structure (and accessed by DSN) so it could never be
downloaded by a user.
http://www.learnASP.com/learn/security2.asp by Charles M. Carroll
Page 146
Custom Security/Authentication #2
To 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)}; " & cnpath
11 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> again
17 <%response.end
18 end if
19 If rstemp("Password")=mypassword then
20 session("name")=rstemp("user")
21 session("securitylevel")=rstemp("securitylevel")
22 response.write "Security Level=" & session("securitylevel")
23 else%>
24 Password Unrecognized<br>
25 Try <A href='securitylogin.asp'>Logging in</a> again
26 <%response.end
27 end if
28 rstemp.close
29 conntemp.close
30 set rstemp=nothing
31 set conntemp=nothing
32 %>
33 </body></html>
Here is the securitylogout.asp script:
1 <html><head>
2 <title>securitylogout.asp</title>&
3 <body>
4 <%
5 session.abandon
6 %>
7 Logged out Now!!!
8 </body>
9 </html>
Here is the securitylevel1required.asp script:
1 <%
2 response.expires=0
3 if session("securitylevel")>0 then
4 ' nothing to do
5 else
6 response.redirect "securityunauthorized.asp"
7 end if
8 %>
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 Method
written 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. G
Basic Authentication is not secure enough for your purposes G
you want all accounts of every type in one userbase, specifically the NT user account database, for administrative
reasons.
G
Authentix, a third party Basic Authentication filter is the way to go if
You want the high performance that a filter offers G
You want to be able to add and modify users from ASP and don't want the ASP pages to have SysAdmin priviledges G
You want browser independence G
You don't want any chance of compromising NT username/password security G
You want to separate your web-users from your NT Accounts G
You are concerned about performance. In addition to the speed associated with filter based solutions, AuthentiX is
unique in that it does not impersonate an NT account to grant access, eliminating the CPU-expensive call to
LogonUser on every request.
G
You have directories you want to validate against an ODBC database G
You want to authenticate multiple IIS servers against a single ODBC machine on the LAN. G
You want to use browser based remote administration G
you need to protect all content in a directory: htm, asp, gif, jpg, zip, and so on. G
you want advanced features like
limiting concurrent logins, H
bandwith, request and login throttling, H
protect by IP, Domain Name and by referrer H
G
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 from
the Windows NT usernames and passwords, ensuring the the security of your NT accounts.
Definitions
ODBC = Open Database Connectivity. G
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 the
installation process.
Make sure Basic (Clear Text) is off and Allow Anonymous is on. You can leave Windows NT Challenge Response on
or off.
G
Create a user. From the main AuthentiX dialog, click the Users button, then Add. Type a username and password and
click OK. The user will be added to the User List. Click OK.
G
Create a group. From the main AuthentiX dialog, click the Groups button, then Add. Type a Groupname, click on a
user (to highlight it) listed in the Non-Members list box, and click Add. The user will be moved to the Members list
box. Click OK. You should now see the group in the group list. Click OK.
G
Protect a directory. From the main AuthentiX dialog, click the Access button, then Add. Click the Browse button and
select a directory that is part of your web directories, and that you would like to protect. Click the By Group button and
add the group you created in the previous step. Click OK. You should now see that the group is protecting that
directory. Verify that the group is protecting the desired directory and click OK twice
G
Using a browser, go to the URL that the directory is accessed from using IIS. It should prompt you for your username
and password.
G
Type the username and password and you should be granted access. G
You can see how to set up ODBC and other advanced options by downloading the online Windows help file or checking out
the online Guided Tour. Because the pace of enhancements and improvements to this product sometimes outstrips the
documentation, 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 Carroll
String functions are very useful for parsing data from ASCII files, formatting output in complex ways and parsing form input. The
following 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>
The user can enter a city, state and Zip, i.e.
Rockville, MD 20849
San Fransisco, CA xxxxx
Pike's Peak, CO xxxxx
and 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.end
9 END IF
10
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=leftover
20
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 Carroll
The various string functions can be used interchangeably often. We will write the same script using SPLIT, REPLACE and JOIN to
demonstrate all 3 functions and how they often are used for similar tasks. However, your programming situations may be especially
suited 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
1 <!--#include virtual="/learn/test/lib_dbtable.asp"-->
2 <html><head>
3 <title>statesrespond.asp</title>&
4 <body>
5 <%
6 mySQL="select * from publishers " & whereclause
7 myDSN="DSN=student;uid=student;pwd=magic"
8 public allstates
9 tempinput=request("states")
10 allstates=split(tempinput,",")
11
12 maxcounter=ubound(allstates)
13
14 whereclause=" where state='" & allstates(0) & "'"
15 FOR counter=1 TO maxcounter
16 thisstate=allstates(counter)
17 whereclause=whereclause & " OR state='" & thisstate & "'"
18 NEXT
19 mySQL=mySQL & whereclause
20 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 Carroll
The various string functions can be used interchangeably often. We will write the same script using SPLIT, REPLACE and JOIN to
demonstrate all 3 functions and how they often are used for similar tasks. However, your programming situations may be especially
suited 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 can
be 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 " & whereclause
7 myDSN="DSN=student;uid=student;pwd=magic"
8
9 tempinput=request("states")
10
11 whereclause=" where state='" & tempinput
12 whereclause=replace(whereclause, ",","' OR state='")
13 whereclause=whereclause & "'"
14
15 mySQL=mySQL & whereclause
16 response.write mySQL
17 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 Carroll
The various string functions can be used interchangeably often. We will write the same script using SPLIT, REPLACE and JOIN to
demonstrate all 3 functions and how they often are used for similar tasks. However, your programming situations may be especially
suited 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 function
can 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 allstates
9 tempinput=request("states")
10 allstates=split(tempinput,",")
11
12 whereclause=" where state='" & JOIN(allstates, "' OR state='") & "'"
13
14 mySQL=mySQL & whereclause
15 response.write mySQL
16 Call Query2Table(mySQL,myDSN)
17 %>
18 </body></html>
http://www.learnASP.com/learn/arrays.asp by Charles M. Carroll
Page 153
Arrays to store data Part #1 by Charles Carroll
Here 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,z
6
7 x=7
8 y=20
9 z=x+y
10
11 response.write z
12 %>
13 </body></html>
Here is the same example with arrays
1 <html><head>
2 <title>arrays.asp</title>
3 </head><body bgcolor="#FFFFFF">
4 <%
5 dim allstuff(3)
6
7 allstuff(0)=7
8 allstuff(1)=20
9 allstuff(2)=allstuff(0)+allstuff(1)
10
11 response.write allstuff(2)
12 %>
13 </body></html>
http://www.activeserverpages.com/learn/subdates.asp
has 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 Carroll
Assigning an array size with a variable produces a variable unless the Redim command is used.
Method #1: You know the size G
Method #2: the size is in a variable G
1 <html><head>
2 <title>arraysredim.asp</title>
3 </head><body bgcolor="#FFFFFF">
4 <%
5 ' this code
6 dim a_array(100)
7
8 ' this code will fail
9 x=100
10 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>
2 <title>arraysredimcorrect.asp</title>
3 </head><body bgcolor="#FFFFFF">
4 <%
5 dim my_array()
6 x=100
7 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 highcount
15 response.write counter & "&nbsp;&nbsp;&nbsp;"
16 response.write my_array(counter) & "<br>"
17 next
18
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 Carroll
There 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 highcount
25 response.write my_months(counter) & "<br>"
26 next
27 %>
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_months
6
7 my_months=array("Jan","Feb","Mar","Apr", _
8 "May","Jun","Jul","Aug", _
9 "Sep","Oct","Nov","Dec")
10
11 ' finally here is how you loop through an array
12 lowcount=lbound(my_months)
13 highcount=ubound(my_months)
14 response.write "lowcount=" & lowcount & ";highcount=" & highcount & "<p>"
15 for counter=lowcount to highcount
16 response.write my_months(counter) & "<br>"
17 next
18 %>
19 </body></html>
http://www.learnASP.com/learn/dictionary.asp by Charles M. Carroll
Page 156
Dictionary objects to store data by Charles Carroll
This 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 mysample
12 response.write whatever & "="
13 response.write mysample.item(whatever) & "<br>"
14 next
15 set mysample=nothing
16 %>
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"
24 people(2).Add "lname", "Yoshitsugu"
25
26 ' print out one item
27 for each whatever in people(1)
28 response.write whatever & "="
29 response.write people(1).item(whatever) & "<br>"
30 next
31
32 for counter=0 to 2
33 set people(counter)=nothing
34 next
35 %>
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 Carroll
Subroutines 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 sub
17 %>
18
19 <%sub showmonth(listname)%>
20 <select name="<%=listname%>month">
21 <%
22 dim monthname
23 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+1
29 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 31
37 response.write "<option>" & counter & "</option>"
38 next%>
39 </select>
40 <%end sub%>
41
42 <%sub showyear(listname)%>
43 <select name="<%=listname%>year">
44 <%for counter=1964 to 2005
45 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 Carroll
The 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 G
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 & "/" & dyear
8
9 aday=request.querystring("arriveday")
10 amonth=request.querystring("arrivemonth")
11 ayear=request.querystring("arriveyear")
12 arrivedate=aday & "/" & amonth & "/" & ayear
13
14 If isdate(departdate) then
15 response.write "Departure Date is Valid Date<br>"
16 else
17 response.write "Departure Date is INVALID<br>"
18 end if
19
20 If isdate(arrivedate) then
21 response.write "Arrival Date is Valid Date<br>"
22 else
23 response.write "Arrival Date is INVALID<br>"
24 end if
25 %>
26 </BODY></HTML>
http://www.learnASP.com/learn/subdbtable.asp by Charles M. Carroll
Page 159
Query2Table by Charles Carroll
Subroutines can save you having to repeat blocks of code. This code illustrates how we can build tables with minimal code in the
main 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"
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, rstemp
4 set conntemp=server.createobject("adodb.connection")
5 conntemp.open inputDSN
6 set rstemp=conntemp.execute(inputquery)
7 howmanyfields=rstemp.fields.count -1%>
8 <table border=1><tr>
9 <% 'Put Headings On The Table of Field Names
10 for i=0 to howmanyfields %>
11 <td><b><%=rstemp(i).name%></B></TD>
12 <% next %>
13 </tr>
14 <% ' Now lets grab all the records
15 do while not rstemp.eof %>
16 <tr>
17 <% for i = 0 to howmanyfields
18 thisvalue=rstemp(i)
19 If isnull(thisvalue) then
20 thisvalue="&nbsp;"
21 end if%>
22 <td valign=top><%=thisvalue%></td>
23 <% next %>
24 </tr>
25 <%rstemp.movenext
26 loop%>
27 </table>
28 <%
29 rstemp.close
30 set rstemp=nothing
31 conntemp.close
32 set conntemp=nothing
33 end sub%>
http://www.learnASP.com/learn/subdblist.asp by Charles M. Carroll
Page 160
Subroutines Query2List by Charles Carroll
Subroutines 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, rstemp
3 set conntemp=server.createobject("adodb.connection")
4 conntemp.open myDSN
5 set rstemp=conntemp.execute(myquery)
6 %>
7 <Select name="<%=myname%>">
8 <%
9 do while not rstemp.eof
10 thisfield=trim(RStemp(0))
11 if isnull(thisfield) or thisfield="" then
12 ' ignore
13 else
14 response.write "<option>" & thisfield & "</option>"
15 end if
16 rstemp.movenext
17 loop
18 %>
19 </select>
20 <%rstemp.close
21 set rstemp=nothing
22 conntemp.close
23 set conntemp=nothing
24 end sub%>
http://www.learnASP.com/learn/subreusable.asp by Charles M. Carroll
Page 161
Subroutines - A "Flexible Approach" by Charles Carroll
Subroutines can be very cleverly constructed so that you can use the same routine to power several different tasks instead of
copying 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, htmlend
3 dim rowstart, rowend
4 dim fieldstart, fieldend
5 dim namestart, nameend
6 dim fieldnames
7 fieldnames=false
8
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 sub
18
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 sub
28
29 sub query2form(myquery)
30 htmlstart=""
31 htmlend=""
32 rowstart=""
33 rowend="<hr>"
34 fieldstart=""
35 fieldend="<br>"
36 fieldnames=true
37 namestart=""
38 nameend="&nbsp;=&nbsp;"
39 call query2html(myquery)
40 end sub
41
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=false
50 namestart=""
51 nameend="&nbsp;&nbsp;="
52 call query2html(myquery)
53 end sub
54
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 -1
60 redim fsa(howmanyfields)
61 redim fea(howmanyfields)
62 for i = 0 to howmanyfields
63 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)=tempstart
68 fea(i)=tempend
69 next
70 response.write htmlstart & vbcrlf
71 counter=0
72 do until rstemp.eof
73 response.write rowstart & vbcrlf
74 for i = 0 to howmanyfields
75 if fieldnames=true then
76 response.write namestart & rstemp(i).name & nameend
77 end if
78 response.write fsa(i) & rstemp(i) & fea(i) & vbcrlf
79 next
80 response.write rowend & vbcrlf
81 counter=counter+1
82 rstemp.movenext
83 if response.isclientconnected=false then
84 exit do
85 end if
86 loop
87 rstemp.close
88 set rstemp=nothing
89 conntemp.close
90 set conntemp=nothing
91 response.write htmlend
92 end sub
93 %>
http://www.learnASP.com/learn/subDBlistbest.asp by Charles M. Carroll
Page 162
Subroutines Db2list "Best" Approach by Charles Carroll
Subroutines could be considerably more useful if they took optional parameters. Since they don't we can jury rig a system whereby a
subroutine is invoked with two parameters: a delimiter and a string. And the string itself contains the various parameters. This
approach 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 from
publishers^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 myparameters
5 myparameters=SPLIT(myparm,mydelim)
6 parmcount=ubound(myparameters)
7 myquery=myparameters(0)
8 label=myparameters(1)
9 default=myparameters(2)
10 if parmcount>2 then
11 format=lcase(myparameters(3))
12 end if
13 if parmcount>3 then
14 connstring=myparameters(4)
15 else
16 connstring="DSN=Student;uid=student;pwd=magic"
17 end if
18
19 set conntemp=server.createobject("adodb.connection")
20 conntemp.open connstring
21 set rstemp=conntemp.execute(myquery)
22 If format="table" then%>
23 <table width="100%" border="0" cellspacing="1"><td>
24 <%end if
25 response.write label
26 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.movenext
36 loop
37 conntemp.close
38 %>
39 </select>
40 <%If format="table" then%>
41 </td><tr></table>
42 <%end if
43 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 (phil@matchw.com)
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
5
6 '----------------------------------------------------------------
7
8 Sub HTML( Text )
9 Response.Write( Text )
10 End Sub
11
12 '----------------------------------------------------------------
13
14 Sub Test( Text )
15 Response.Write( Text )
16 End Sub
17
18 '----------------------------------------------------------------
19
20 Sub Form_HiddenField( Name, Value )
21
22 HTML "<INPUT "
23 Form_Parm_Type "Hidden"
24 Form_Parm_Name Name
25 Form_Parm_Value Value
26 HTML ">"
27
28 End Sub
29
30 '----------------------------------------------------------------
31
32 Sub Form_Label( Label, Control )
33
34 If Len(Label) > 0 Then
35 HTML "<label "
36 HTML "for=" & Control
37 HTML ">"
38 HTML "<strong>"
39 Display Label
40 HTML "</strong>"
41 HTML "</label>"
42 End If
43
44 End Sub
45
46 '----------------------------------------------------------------
47
48 Sub Form_TextBox( Label, Name, MaxLength, Size, Value )
49
50 Form_Label Label, Name
51
52 HTML "<input "
53 Form_Parm_Type "text"
54 Form_Parm_Name Name
55 Form_Parm_Size Size
56 Form_Parm_ID Name
57 Form_Parm_MaxLength MaxLength
58 Form_Parm_Value Value
59 HTML ">"
60
61 End Sub
62
63 '----------------------------------------------------------------
64
65 Sub Form_Password( Label, Name, MaxLength, Size, Value )
66
67 Form_Label Label, Name
68
69 HTML "<input "
70 Form_Parm_Type "password"
71 Form_Parm_Name Name
72 Form_Parm_Size Size
73 Form_Parm_ID Name
74 Form_Parm_MaxLength MaxLength
75 Form_Parm_Value Value
76 HTML ">"
77
78 End Sub
79
80 '----------------------------------------------------------------
81
82 Sub Form_ScrollingText( Label, Name, Rows, Cols, Value )
83
84 Form_Label Label, Name
85
86 HTML "<textarea "
87 Form_Parm_Name Name
88 If Len(Rows) > 0 Then
89 HTML "rows=" & Rows & " "
90 End If
91 If Len(Cols) > 0 Then
92 HTML "cols=" & Cols & " "
93 End If
94 Form_Parm_ID Name
95 HTML ">"
96
97 If Len(Value) > 0 Then
98 Display Value
99 End If
100
101 HTML "</textarea>"
102
103 End Sub
104
105 '----------------------------------------------------------------
106
107 Sub Form_ResetButton( Name, Value )
108
109 HTML "<input "
110 Form_Parm_Type "reset"
111 Form_Parm_Value Value
112 Form_Parm_Name Name
113 HTML ">"
114
115 End Sub
116
117 '----------------------------------------------------------------
118
119 Sub Form_CommandButton( Name, Value )
120
121 HTML "<input "
122 Form_Parm_Type "button"
123 Form_Parm_Value Value
124 Form_Parm_Name Name
125 HTML ">"
126
127 End Sub
128
129 '----------------------------------------------------------------
130
131 Sub Form_SubmitButton( Name, Value )
132 HTML "<input "
133 Form_Parm_Type "submit"
134 Form_Parm_Value Value
135 Form_Parm_Name Name
136 HTML ">"
137 End Sub
138
139 '----------------------------------------------------------------
140
141 Sub Form_RadioButton( Label, Name, Value, Checked )
142
143 HTML "<input "
144 Form_Parm_Type "radio"
145 Form_Parm_Value Value
146 Form_Parm_Name Name
147 Form_Parm_ID Name & Value
148 If Len(Checked) > 0 Then
149 If Checked Then
150 HTML " checked "
151 End If
152 End If
153 HTML ">"
154
155 Form_Label Label, Name & Value
156
157 End Sub
158
159 '----------------------------------------------------------------
160
161 Sub Form_Checkbox( Label, Name, Value, Checked )
162
163 Form_Label Label, Name
164
165 HTML "<INPUT "
166 Form_Parm_Type "checkbox"
167 Form_Parm_Name Name
168 Form_Parm_Value Value
169 If Len( Checked ) > 0 Then
170 If Checked = True Then
171 HTML " checked "
172 End If
173 End If
174 HTML ">"
175 '
176 End Sub
177
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 Sub
188
189 '----------------------------------------------------------------
190
191 Sub Form_End( Name, Value )
192
193 Form_HiddenField Name, Value
194 HTML "</FORM>"
195
196 End Sub
197
198 '----------------------------------------------------------------
199
200 Sub Form_Table_Begin( Border, Width )
201 HTML "<table "
202 If Len(Border) > 0 Then
203 HTML "border=" & Chr(39) & Border & Chr(39) & " "
204 End If
205 Form_Parm_Width Width
206 HTML ">"
207 End Sub
208
209 '----------------------------------------------------------------
210
211 Sub Form_Table_End()
212 HTML "</table>"
213 End Sub
214
215 '----------------------------------------------------------------
216
217 Sub Form_Table_Row_Begin( Dummy, Align, VAlign )
218 HTML "<tr "
219 Form_Parm_Align Align
220 Form_Parm_VAlign VAlign
221 HTML ">"
222 End Sub
223
224 '----------------------------------------------------------------
225
226 Sub Form_Table_Row_End( Dummy )
227 HTML "</tr>"
228 End Sub
229
230 '----------------------------------------------------------------
231
232 Sub Form_Table_Cell_Begin( Dummy, Width, Align, VAlign )
233 HTML "<td "
234 Form_Parm_Width Width
235 Form_Parm_Align Align
236 Form_Parm_VAlign VAlign
237 HTML ">"
238 End Sub
239
240 '----------------------------------------------------------------
241
242
243 Sub Form_Table_Cell_End( Dummy )
244 HTML "</td>"
245 End Sub
246
247
248 '----------------------------------------------------------------
249
250
251 Sub Form_ComboBox_Begin( Label, Name, Size, Multiple )
252 Form_Label Label, Name
253 HTML "<select "
254 Form_Parm_Name Name
255 Form_Parm_Size Size
256 If Len(Multiple) > 0 Then
257 If Multiple Then
258 HTML " multiple "
259 End If
260 End If
261 HTML ">"
262 End Sub
263
264 '----------------------------------------------------------------
265
266 Sub Form_ComboBox_Item( Value, Selected )
267 HTML "<option "
268 Form_Parm_Value Value
269 If Len(Selected) > 0 Then
270 If Selected Then
271 HTML " selected "
272 End If
273 End If
274 HTML ">"
275 End Sub
276
277 '----------------------------------------------------------------
278
279 Sub Form_ComboBox_End()
280 HTML "</select>"
281 End Sub
282
283 '----------------------------------------------------------------
284
285 Sub Form_Title( Title )
286 HTML "<title>"
287 Display Title
288 HTML "</title>&
289 End Sub
290
291
292 '----------------------------------------------------------------
293
294 Sub Form_Center( Text )
295 HTML "<p align=" & Chr(39) & "center" & Chr(39) & ">"
296 Display Text
297 HTML "</p>"
298 End Sub
299
300 '----------------------------------------------------------------
301
302 Sub Form_Left( Text )
303 HTML "<p align=" & Chr(39) & "left" & Chr(39) & ">"
304 Display Text
305 HTML "</p>"
306 End Sub
307
308 '----------------------------------------------------------------
309
310 Sub Form_Right( Text )
311 HTML "<p align=" & Chr(39) & "right" & Chr(39) & ">"
312 Display Text
313 HTML "</p>"
314 End Sub
315
316 '----------------------------------------------------------------
317
318 Sub Form_Parm_Align( Align )
319 If Len(Align) > 0 Then
320 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 Else
328 End Select
329 End If
330 End Sub
331
332 '----------------------------------------------------------------
333
334 Sub Form_Parm_VAlign( VAlign )
335 If Len(VAlign) > 0 Then
336 Select Case UCase(VAlign)
337 Case "T", "TOP"
338 Display " align=" & Chr(39) & "top" & Chr(39) & " "
339 Case "C", "CENTER"
340 Display " align=" & Chr(39) & "center" & Chr(39) & " "
341 Case "B", "BOTTOM"
342 Display " align=" & Chr(39) & "bottom" & Chr(39) & " "
343 Case Else
344 End Select
345 End If
346 End Sub
347
348 '----------------------------------------------------------------
349
350 Sub Form_Parm_Name( Name )
351 If Len(Name) > 0 Then
352 Display " name=" & Chr(39) & Name & Chr(39) & " "
353 End If
354 End Sub
355
356 '----------------------------------------------------------------
357
358 Sub Form_Parm_Value( Value )
359 If Len(Value) > 0 Then
360 Display " value=" & Chr(39) & Value & Chr(39) & " "
361 End If
362 End Sub
363
364 '----------------------------------------------------------------
365
366 Sub Form_Parm_Type( TypeValue )
367 If Len(TypeValue) > 0 Then
368 Display " type=" & Chr(39) & TypeValue & Chr(39) & " "
369 End If
370 End Sub
371
372 '----------------------------------------------------------------
373
374 Sub Form_Parm_Size( Size )
375 If Len(Size) > 0 Then
376 Display " size=" & Size & " "
377 End If
378 End Sub
379
380 '----------------------------------------------------------------
381
382 Sub Form_Parm_ID( ID )
383 If Len(ID) > 0 Then
384 Display " id=" & Chr(39) & ID & Chr(39) & " "
385 End If
386 End Sub
387
388 '----------------------------------------------------------------
389
390 Sub Form_Parm_MaxLength( MaxLength )
391 If Len(MaxLength) > 0 Then
392 Display " maxlength=" & MaxLength
393 End If
394 End Sub
395
396 '----------------------------------------------------------------
397
398 Sub Form_Parm_Length( Length )
399 If Len(Length) > 0 Then
400 Display " length=" & Length
401 End If
402 End Sub
403
404 '----------------------------------------------------------------
405
406 Sub Form_Parm_Width( Width )
407 If Len(Width) > 0 Then
408 Display " width=" & Width
409 End If
410 End Sub
411
412 '----------------------------------------------------------------
413
414 Sub Anchor_Display( TextToDisplay, HRef )
415 HTML "<a href=" & Chr(39) & HRef & Chr(39) & ">"
416 Display TextToDisplay
417 HTML "</a>"
418 End Sub
419
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, HRef
430 HTML "</p>"
431 HTML "</li>"
432 HTML "</ul>"
433 End Sub
434
435 '----------------------------------------------------------------
436
437 Function FormatMoney( Amount )
438 '
439 ' Standard constants from the MS web site but not built
440 ' into VBScript's default constants.
441 '
442 Const TristateTrue = -1
443 Const TristateFalse = 0
444 Const TristateUseDefault = -2
445 '
446 If IsNull( Amount ) Then
447 FormatMoney = vbNullString
448 Else
449 FormatMoney = FormatCurrency( Amount, 2, TristateTrue _
450 , False, TristateTrue)
451 End If
452 '
453 End Function
454
455 '----------------------------------------------------------------
456 %>
http://www.learnASP.com/learn/functionworkingdays.asp by Charles M. Carroll
Page 164
Functions -- The WorkingDays function
This 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 %>
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 week
10
11 Dim dtEndDate
12 Dim iLoop
13
14 'First add whole weeks
15 dtEndDate=DateAdd("ww",Int(nDaysToAdd/5),dtStartDate)
16
17 'Add any odd days
18 For iLoop = 1 To (nDaysToAdd Mod 5)
19 dtEndDate=DateAdd("d",1,dtEndDate)
20 'If Saturday increment to following Monday
21 If WeekDay(dtEndDate)=vbSaturday Then
22 'Increment date to following Monday
23 dtEndDate=DateAdd("d",2,dtEndDate)
24 End If
25 Next
26 dtAddWorkingDays=dtEndDate
27 End Function
28 %>
http://www.learnASP.com/learn/vbs5.asp by Charles M. Carroll
Page 165
VBScript 5 Highlights by Charles Carroll
Subroutines can save you having to repeat blocks of code. This code illustrates how we can build tables with minimal code in the
main 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 variable
7 Dim myCustomer
8 ' Create a new instance of the Customer Class
9 ' and set the value of myCustomer to be that instance
10 set myCustomer = new Customer
11 ' Add a new customer
12 myCustomer.Add "Charles","Carroll"
13 ' Set their Email address
14 myCustomer.EmailName = "charlescarroll@aspalliance.com"
15 ' Set their credit limit
16 myCustomer.CreditLimit = 5000
17 ' Display the customers fullname
18 response.write myCustomer.FullName
19
20 Class Customer
21 Public FirstName, LastName
22 Private nCreditLimit
23 Private strEmailName
24 Property Get EmailName
25 EmailName = strEmailName
26 End Property
27 Property Let EmailName ( strName)
28 StrEmailName = strName
29 End Property
30 Property Get FullName
31 FullName= FirstName & " " & LastName
32 End Property
33 Property Let CreditLimit ( s )
34 if s >= 0 then
35 nSalary = s
36 End If
37 End Property
38 Property Get CreditLimit
39 Salary = nSalary
40 End Property
41 Sub Add( First, Last )
42 FirstName = First
43 LastName = Last
44 End Sub
45 Function RaiseCreditLimit( Amount )
46 nCreditLimit = nCreditLimit + Amount
47 RaiseSalary = nSalary
48 End Function
49 End Class
50 %>
51 </body>
52 </html>
Execute Function:
1 <html><head>
2 <title>vbs5execute.asp</title>
3 </head>
4 <body>
5 <%
6 S = "Sub Hi" & vbCrLf
7 S = S & " Response.write ""Hi""" & vbCrLf
8 S = S & "End Sub"
9 Execute S
10 Call Hi()
11 %>
12 </body>
13 </html>
Regular Expressions
1 <html><head>
2 <title>vbs5reg.asp</title>&
3 <body>
4 <%
5
6 address="joe@aol.com"
7 validmail=checkemail(address)
8 IF validmail THEN
9 response.write address & " is good!"
10 ELSE
11 response.write address & " is bad!"
12 END IF
13
14 address="sallyaol.com"
15 validmail=checkemail(address)
16 IF validmail THEN
17 response.write address & " is good!"
18 ELSE
19 response.write address & " is bad!"
20 END IF
21
22
23 FUNCTION CheckEmail(parmaddress)
24 set myRegExp = new RegExp
25 ' Set the pattern to check for a word followed by
26 ' an @ followed by a word
27 myRegExp.pattern = "\w+\@[.\w]+"
28 if myRegExp.Test(parmaddress) then
29 CheckEmail=True
30 else
31 CheckEmail=false
32 end if
33 END FUNCTION
34 %>
35 </body>
36 </html>
With
1 <html><head>
2 <title>vbs5with.asp</title>
3 </head>
4 <body>
5 <%
6 with response
7 .write "Hi<br>"
8 .write "how are you doing?<br>"
9 .write "see you around"
10 end with
11 %>
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
is his awesome Visual Interdev listserve. One of the best in the world.
http://www.amundsen.com/mskb/Default.htm
is 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 Editor
This is a very ASP centric HTML editor. Unlike homesite which claims ASP functionality but doesn't have it, or wizard/DTC based
beasts like Visual Interdev this tool truly helps you write ASP Code with:
The Connection Assistant G
The Request Assistant G
buttons that make CASE, IF, LOOPs for you G
Browsing for includes G
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 send
him 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.com
is 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 Editor
This 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
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 Carroll
There are two kinds of data that your program can manipulate that can be used to "remember" data:
Session data
which is "attached" to a person browsing your site. If the same page is accessed by 12 different users each user may have totally
different session values.
Application data
which 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 there
is a potential concurrency issue. The lock and unlock method of the application object eliminate concurrency issues. Once an
application 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 from
databases like in
The 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's
individual 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.lock
4 application("bjplayers")=application("bjplayers")+1
5 application.unlock
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.lock
4 application("bjplayers")=application("bjplayers")-1
5 IF application("bjplayers")<0 THEN
6 application("bjplayers")=0
7 END IF
8 application.unlock
9 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 Carroll
Sometimes data (like a HTML list box) is displayed on many pages of a website. In fact, the database generated list box is displayed
thousands of times a day, and the database is queried every time, but it is uneccessary. The database it is drawn from is not
changing 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 that
displays 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 IF
11 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
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, rstemp
21 set conntemp=server.createobject("adodb.connection")
22 conntemp.open myDSN
23 set rstemp=conntemp.execute(myquery)
24 query2HTMlist="<Select name='" & myname & "'>"
25 do until rstemp.eof
26 thisfield=trim(RStemp(0))
27 if isnull(thisfield) or thisfield="" then
28 ' ignore
29 else
30 query2HTMlist=query2HTMlist & "<option>" & thisfield & "</option>"
31 end if
32 rstemp.movenext
33 loop
34 query2HTMlist=query2HTMlist & "</select>"
35 rstemp.close
36 set rstemp=nothing
37 conntemp.close
38 set conntemp=nothing
39 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" and
immediately can differentiate that user from all other users at a site. Anything stored in that user's session can be retrieved and
manipulated 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 is
collectively 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 their
successes:
1 <%
2 response.write "Coin Tossed!<br>"
3 randomize
4 randomnum=int(rnd*2)+1
5 IF randomnum=1 THEN
6 session("heads")=session("heads")+1
7 ELSE
8 session("tails")=session("tails")+1
9 END IF
10 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 a
session 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 level
determined 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 determine
the contents of any session variables.
G
A cookie is used to co-ordinate the user's session ID. Once again the cookie contains no data (just the session
ID). This means if the user accepts no cookies, you can't use sessions as described here.
G
If you absolutely need sessions without client cookies, installing an ISAPI filter named "Cookie Munger" will
solve your problem, but at a performance penalty.
G
Cookie Munger by Microsoft (FREE)
Cookies are a necessity to maintain ASP session objects. Even though the session objects are physically maintained on the server
the essential ID that identifies a user session is kept in a cookie. This ISAPI filter can only be applied globally but if applied, it actually
rewrites 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 the
page. So conceptually if you send a page back to the users with 20 URLs each URL gets a session ID "munged"/intermixed in so
that 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 Carroll
This page demonstrates what a blank global.asa should look like:
1 <script language=vbscript runat=server>
2 SUB Application_OnStart
3 END SUB
4
5 SUB Application_OnEnd
6 END SUB
7
8 SUB Session_OnStart
9 END SUB
10
11 SUB Session_OnEnd
12 END SUB
13 </script>
A global.asa code is divided into four events, or segments:
session_onstart
if 100 users hit your website for example, 100 session starts are initiated and the code in this event is fired for each user
before their first page is fetched and displayed. But those same 100 users can wander all over your site and another session
start will not occur as long as they are actively fetching pages
G
session_onend
Any user that does not fetch any page from your site for 20 minutes (can be adjusted in the Registry/IIS3 or the
metabase/IIS4) has ended their session. The code you put in this event can not affect the users as they have already left your
site but it can allow you to place cleanup code or code that dumps for, example, session data into a database.
G
application_onstart
The webserver starts. dozens to hundreds to thousands of users hit the site. The minute the first user fetches the first file in an
application directory an application_onstart occurs and never occurs again no matter how many people are visiting. But if a
webserver stops and starts and application_onstart fires. But code inside an application_onstart is code that assumes the
entire casino is a "blank slate" not a busy place. If for example, application_onstarts fire often this is not a desired behavior
since it may have the role of bootsrapping an app and setting certain conditions that don't make sense to set while activity is
G
occuring.
application_onend
The web server stops, the application ends.
G
http://www.learnASP.com/learn/sessionoverview.asp by Charles M. Carroll
Page 175
Session Overview & Myths by Charles Carroll
Session data is greatly misunderstood. Sessions themselves were a subtle and complex issue, but the subject was confused
considerably by bad information people gathered from code others made that misused sessions. It is also confused by anecdotal
performance evidence when a site is small, or the testing is only done within simple stress tests that don't reveal all the speed
issues. 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 you
have 3-10 passengers. Then a mini-van will beat it because you have less trips to make. In client-server terms the Porsche doesn't
SCALE WELL for more than 2 passengers. On the other hand, when a group of 100 wants to go to Atlantic city for the weekend we
recommend a Tour Bus. However, someone taking a Tour Bus to the grocery store has anecdotal evidence it is not as fast as a
Porsche.
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. The
default 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 be
1,000 unique session ids. But if 200 people loose session (due to timeout or explicit .abandon) and 150 new sessions are begun
ASP 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. Think
about it. If 200 news persons a minute hit your site for 5 minutes that is 1,000 sessions and appropriately 1000 x the memory
consumed for session variables. If 500 people go away, you still have 1000 sessions and 500 users (twice as much memory is
consumed 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 most
scripts 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 a
component to a session variable attached to that user all user request must remain on the thread they started on. If they for
example were assigned Thread #3 upon their session start as they access many pages at the site all their activity will remain
on thread #3. I nickname this phenomena Thread Locking.
G
Free-threaded objects have no speed barriers (though as Myth #1 states, you will always have too many in memory if you
store objects as session variables).
G
Apartment-Threaded objects, notably VB components and the Microsoft Access databas driver which are Single-Threaded
apartments (STA) have some performance limits. Simply put, every user request to a STA object must be serialized.
G
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 a
database you might notice no effect. But if person 3 retrieves 2,000 records, person 4 retrieving 2 records will occur after the person
3 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 users
request before moving to another user. The code may be able to move to User 4 and grab their records and then person 5 and later
finish 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 see
http://www.learnasp.com/learn/speedserver.asp. If your webserver had for example 4 threads, then 1000 users might be 250 per
thread or 700 on one thread and 100 each on the other threads. The latter is a severe imbalance as one thread is overworked (thus
slower) while other threads are underworked.
http://www.learnASP.com/learn/globalproblems.asp by Charles M. Carroll
Page 176
Global.asa Overkill by Charles Carroll
A 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 bad
about 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 memory
regardless 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. G
If a object or variable is accessed concurrently for anything other than reading it's value, this is a potential concurrency issue
that needs to be carefully coded so that no problems arise, i.e.
<%
application.lock
... modify app object ...
application.unlock
%>
G
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 20
minutes. See /learn/nosessionobjects.asp for more details.
G
waste threads if you put any objects (made with server.createobject) in a session variable. See /learn/buildvbthreads.asp for
more details.
G
limit the code to users accepting cookies which may mean someone who disables cookies may not use that script at all. G
Session Variable Constraints
Session 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 if
these 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. G
If your site is one giant application (i.e. the root folder is marked as an application) the person browsing the site will have
access to their session variables in every script BUT if individual folders are marked as applications, all scripts within that
directory 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 is
to attach people to data and use it in many scripts this visibility can be an issue.
G
the person using the scripts will never gets "switched" to another server in a web farm situation. G
If the task could be accomplished with hidden fields instead of session variables, then those limitations are not in effect -- and most
tasks 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 quite
useful.
G
If you place any non-object data in session variables the waste is not excessive. G
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. Just
700 wasted session variables...Session variables are the worst way to keep such data; application variables the best or other
mechanisms. 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 memory
all 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 a
database 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 all
users with no wasted memory.
http://www.learnASP.com/learn/globalmore.asp by Charles M. Carroll
Page 177
Global.asa, Sessions, Custom Stats Resources
The global.asa, application and sesion variables are certainly a more complex and controversial subject than most ASP topics. Other
sites 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. vars
http://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 Carroll
Improving server performance is not so well documented and many of the articles lean towards vague, not specific tips. Here are our
tips in we hope as concrete a way as possible.
THREAD TIP:
Increase threads per processor
from 4 to 20 for each CPU.
thanks to Smiling Jack for this one:
http://www.aspmagazine.com/aspmagazine/issue10kb.asp
see
http://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 you
are running any Access code in the box.
Additional Research
We have essentially summarized the information and chosen only the clearest guidelines from the following resources:
Web Application Stress Tool
http://homer.rte.microsoft.com
Improving the Performance of Data Access Components with IIS 4.0
http://msdn.microsoft.com/workshop/server/components/daciisperf.asp
Mike Moore's Tuning IIS
http://www.microsoft.com/isn/whitepapers/tuningiis.asp
IIS4 Tuning Parameters for High Volume Sites
http://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.com
http://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 Carroll
Speed 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't
help 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 to
fastcode@ls.asplists.com
Related Links
Niblacks Excellent ListBox/DB Speed Page @
http://niblack.com/kbase/listbox_x.asp
Timing Tasks to Millisecond accuracy @
http://www.learnasp.com/learn/speedtimer.asp
Web Application Stress Tool @
http://homer.rte.microsoft.com
Caprocks FREE Scalable Dictionary Object Replacement @
http://www.caprockconsulting.com/comsoftware.htm
Study up on Performance Counters @
http://msdn.microsoft.com/workshop/server/iis/usingWCAT.asp
monitor PerfCounters from ASP via a nifty component @
http://www.alphasierrapapa.com/IisDev/Components/
Speed Percieved Table Display @
http://www.learnasp.com/learn/speedtables.asp
Speeding Table Display - All Techniques @
http://www.learnasp.com/learn/speedtablesall.asp
Worlds Fastest ListBox @
http://www.learnasp.com/learn/speedappdata.asp
Charles Carroll's ASP Quick Lessons @
http://www.learnasp.com/learn/speedscale.asp
http://www.learnASP.com/learn/speedtimer.asp by Charles M. Carroll
Page 180
Speed: Measuring Code Speed
by Richard A. Lowe drahcir@home.com
with help from Jonathan McGuire jmcguire@solutionsatimpact.com
Gregory Lybanon glybanon@sbcsystems.com
Charles Carroll charlescarroll@learnasp.com
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 tricks
up its sleeves yet as Richard demonstrates with the nifty Library implemented in Jscript. We will use it to time retrieving and
displaying identical data three different ways:
traditional loop and movenext G
one getrows call G
one getstring call G
This method is great for testing optimizations to 1 script but does not show how the script will run when many users are
simultaneously executing it. Tools like the Stress Tester at:
http://homer.rte.microsoft.com
are 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.GetURL
11 timeNow = milliDif()
12 SET HTTPobj = nothing
13 elapsed=timeNow-timeThen
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 STRresult
19
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.GetURL
11 timeNow = milliDif()
12 SET HTTPobj = nothing
13 elapsed=timeNow-timeThen
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 STRresult
19
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, just
produce 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.GetURL
11 timeNow = milliDif()
12 SET HTTPobj = nothing
13 elapsed=timeNow-timeThen
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 STRresult
19
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 = 0
13 var elapsedmins = 0
14
15 elapsedsecs=Math.floor(parm1/1000)
16 parm1=parm1%1000
17
18 elapsedmins=Math.floor(elapsedsecs/60)
19 elapsedsecs=elapsedsecs%60
20
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"
33
34 return elapsedpretty;
35 }
36 </script>
http://www.learnASP.com/learn/speedtips.asp by Charles M. Carroll
Page 181
Speed Tips by Charles Carroll
There 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 not
allowed) 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 flushing
buffer 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) G
GetString (see /learn/dbtablegetstring.asp) G
Disconnected recordsets (see /learn/dbtabledisconnected.asp). G
#4 Before just believing any article you read on the web or in an ASP book (many articles are not researched thoroughly) and
implementing code changes TIME THE CODE BEFORE AND AFTER changes. /learn/speedtimer.asp has the needed code that will
time 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.asp
This is an attempt to settle this issue once and for all with very clear explanations why. This is NOT recommended by many
who have tried and blown up quiet and busy web servers.
G
http://www.learnasp.com/learn/nosessionobjects.asp G
http://www.learnasp.com/learn/sessionoverview.asp
http://www.learnasp.com/learn/buildvbthreads.asp
http://www.learnasp.com/learn/globalproblems.asp
for earlier and other perspectives on Thread-locking, Serialization and Thread-Local storage.
G
#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 few
lines later could make a huge difference as your scripts run round-robin with other scripts, see /advice/roundrobin.asp for more whys
about this.
#9 Tune your server. At least make the 20 instead of 4 thread tweak (see http://www.learnasp.com/advice/threads.asp). The articles
at /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 a
user run to completion whether the user is there to read output or not running invisibly on server. See: /learn/isclientconnected.asp to
see 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
refresh portions of page without submitting page to server. Remote scripting works in both Netscape and IE; any Javascript capable
browser. 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 Display
Speeding up your scripts involves many big and small script changes. We have prepared this "before" and "after" example to
illustrate 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)
G
Throttling the maximum number of records if it is appropriate
(see www.activeserverpages.com/learn/dbmaxrecs.asp)
G
Side note: If anyone you know believes Access queries are done asynchronously, running a couple of these scripts will prove them
wrong. Access queries execute one web user at a time sequentially.
After Optimization
Here 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, rstemp
4 set conntemp=server.createobject("adodb.connection")
5 ' 0 seconds means wait forever, default is 15
6 conntemp.connectiontimeout=0
7 conntemp.open inputDSN
8 set rstemp=conntemp.execute(inputquery)
9 howmanyfields=rstemp.fields.count -1
10 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><col
width='15%'><tr>"
11 response.write tablestart
12 for i=0 to howmanyfields %>
13 <td><b><%=rstemp(i).name%></B></TD>
14 <% next %>
15 </tr>
16 <% ' Now lets grab all the records
17 DO UNTIL rstemp.eof
18 counter=counter+1
19 response.write "<tr>"
20 for i = 0 to howmanyfields
21 thisvalue=rstemp(i)
22 If isnull(thisvalue) then
23 thisvalue="&nbsp;"
24 end if
25 response.write "<td valign=top>" & thisvalue & "</td>" & vbcrlf
26 next
27 response.write "</tr>"
28 rstemp.movenext
29 IF counter mod 50=0 THEN
30 If response.isclientconnected()=false THEN
31 EXIT DO
32 END IF
33 response.write "</table>" & TableStart
34 response.flush
35 END IF
36
37 loop%>
38 </table>
39 <%
40 rstemp.close
41 set rstemp=nothing
42 conntemp.close
43 set conntemp=nothing
44 end sub%>
45
Before Optimization
Here is the original slow script which basically demonstrates techniques that may work if your data and concurrency load is light, but
the script above demonstrates the typical changes made to speed up a script when it becomes needed or you just want to wring
every 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, rstemp
4 set conntemp=server.createobject("adodb.connection")
5 conntemp.open inputDSN
6 set rstemp=conntemp.execute(inputquery)
7 howmanyfields=rstemp.fields.count -1%>
8 <table border=1><tr>
9 <% 'Put Headings On The Table of Field Names
10 for i=0 to howmanyfields %>
11 <td><b><%=rstemp(i).name%></B></TD>
12 <% next %>
13 </tr>
14 <% ' Now lets grab all the records
15 DO UNTIL rstemp.eof and response.isclientconnected()%>
16 <tr>
17 <% for i = 0 to howmanyfields
18 thisvalue=rstemp(i)
19 If isnull(thisvalue) then
20 thisvalue="&nbsp;"
21 end if%>
22 <td valign=top><%=thisvalue%></td>
23 <% next %>
24 </tr>
25 <%rstemp.movenext
26 loop%>
27 </table>
28 <%
29 rstemp.close
30 set rstemp=nothing
31 conntemp.close
32 set conntemp=nothing
33 end sub%>
http://www.learnASP.com/learn/speedtablesall.asp by Charles M. Carroll
Page 183
Speed/Optimization: All Variations
Fetching records in an optimized way actually has many variations. We will list most of them here, provide code sample and typical
timings for fetching and displaying records. These timings reveal an interesting behavior. Even if a script reports it ran in say, 7
seconds, that refers to the time that script received from the CPU. So that if 7 scripts take 8 seconds each there may be hundreds or
thousands of scripts running on the server that are sharing the CPU. User #1 may see a 7 second result in 21 seconds, so their 7
second report reflects the time spent on the server/CPU for the script and the fact that 14 seconds of other stuff was executed
round-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 writen
periodically.
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 seconds
Query 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 where
GetRows 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 each
array 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.
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=240
8 optimize=optimize_LoopAll
9
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 TimerStart
15 call query2table(mySQL,myDSN,optimize,howmany)
16 Call TimerEnd
17 %>
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=240
8 optimize=optimize_LoopAll_string
9
10 myDSN = "DSN=student;UID=student;pwd=magic"
11 mySQL="select * from authors order by author "
12
13 Call TimerStart
14 call query2table(mySQL,myDSN,optimize,howmany)
15 Call TimerEnd
16 %>
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=240
8 optimize=optimize_GetStringAll
9 myDSN = "DSN=student;UID=student;pwd=magic"
10 mySQL="select * from authors order by author"
11
12 Call TimerStart
13 call query2table(mySQL,myDSN,optimize,howmany)
14 response.write OptimizationName(optimize) & "<br>"
15 Call TimerEnd
16 %>
17 </BODY></HTML>
Here is a table display with a GetString call (buffered):
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=240
8 optimize=optimize_GetStringBuffered
9 myDSN = "DSN=student;UID=student;pwd=magic"
10 mySQL="select * from authors order by author"
11
12 Call TimerStart
13 call query2table(mySQL,myDSN,optimize,howmany)
14 response.write OptimizationName(optimize) & "<br>"
15 Call TimerEnd
16 %>
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=240
8 optimize=optimize_getrowsall
9 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 TimerStart
16 call query2table(mySQL,myDSN,optimize,howmany)
17 call TimerEnd
18
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=240
8 optimize=optimize_GetRowsBuffered
9
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 TimerStart
15 call query2table(mySQL,myDSN,optimize,howmany)
16 Call TimerEnd
17 %>
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"-->
5 <!--#include virtual="/learn/test/lib_dbtablefastv2.asp"-->
6 <%
7 server.scripttimeout=240
8 optimize=optimize_LimitRows
9 myDSN = "DSN=student;UID=student;pwd=magic"
10 mySQL="select * from authors order by author"
11
12 Call TimerStart
13 call query2table(mySQL,myDSN,optimize,howmany)
14 response.write OptimizationName(optimize) & "<br>"
15 Call TimerEnd
16 %>
17 </BODY></HTML>
Here is the optimized library lib_dbtablefastv2.asp which achieves this speed:
1 <%
2 Const optimize_LoopAll = 1
3 Const optimize_GetstringAll = 2
4 Const optimize_GetrowsAll = 3
5 Const optimize_GetrowsBuffered = 4
6 Const optimize_GetStringBuffered = 5
7 Const optimize_LimitRows = 6
8 Const optimize_LoopAll_String = 7
9
10 dim optimize_buffersize
11 dim optimize_started
12 dim optimize_ended
13 dim optimize_SQL
14 dim optimize_DSN
15 dim optimize_howmany
16 dim optimize_cursorlocation
17 dim optimize_maxrecs
18 dim optimize_disconnectRS
19
20 optimize_started=0
21
22 ' performance stuff
23 optimize_buffersize=200
24 'optimize_cursorlocation=aduseclient
25 optimize_maxrecs=500
26 optimize_cursorlocation=aduseserver
27 optimize_disconnectRS=false
28 optimize_stringwrite=false
29
30 SUB TimerStart()
31 optimize_started=now()
32 END SUB
33
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 THEN
41 optimize_howmany=querycount(optimize_DSN,optimize_SQL)
42 END IF
43 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 THEN
49 response.write pad & "cursorlocation=<b>adUseClient</b><br>"
50 END IF
51 IF optimize_cursorlocation=adUseServer THEN
52 response.write pad & "cursorlocation=<b>adUseServer</b><br>"
53 END IF
54 END SUB
55
56 sub query2table(parmQuery, parmDSN,parmMethod,parmcount)
57 ' method 1 = standard
58 ' method 2 = getrows
59 ' method 3 = getstring
60 dim howmany
61 SELECT CASE parmMethod
62 CASE 1
63 Call loopStandard(parmQuery,parmDSN,howmany)
64 CASE 2
65 Call loopGetString(parmQuery,parmDSN,howmany)
66 CASE 3
67 Call loopGetRows(parmQuery,parmDSN,howmany)
68 CASE 4
69 Call loopGetRowsBuffered(parmQuery,parmDSN,howmany)
70 CASE 5
71 Call loopGetStringBuffered(parmQuery,parmDSN,howmany)
72 CASE 6
73 Call LimitRows(parmQuery,parmDSN,howmany)
74 CASE 7
75 Call loopStandardStringWrite(parmQuery,parmDSN,howmany)
76 CASE ELSE
77 response.write "1, 2 or 3 are only valid speedmethods"
78 END SELECT
79 parmcount=howmany
80 If optimize_started<>0 THEN
81 optimize_DSN=parmDSN
82 optimize_SQL=parmquery
83 optimize_howmany=parmcount
84 END IF
85 END SUB
86
87 FUNCTION querycount(parmDSN,parmQuery)
88 set rstemp=Server.CreateObject("adodb.Recordset")
89 rstemp.open parmQuery, parmDSN, adopenstatic
90 querycount=rstemp.recordcount
91 rstemp.close
92 set rstemp=nothing
93 END FUNCTION
94
95
96 SUB loopstandard(inputquery, inputDSN,inputcount)
97 dim conntemp, rstemp
98 set conntemp=server.createobject("adodb.connection")
99 ' 0 seconds means wait forever, default is 15
100 conntemp.connectiontimeout=0
101 conntemp.cursorlocation=optimize_cursorlocation
102 conntemp.open inputDSN
103 set rstemp=conntemp.execute(inputquery)
104 IF optimize_disconnectRS=true THEN
105 conntemp.close
106 END IF
107 howmanyfields=rstemp.fields.count -1
108 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><col
width='15%'><tr>"
109 response.write tablestart
110 for i=0 to howmanyfields %>
111 <td><b><%=rstemp(i).name%></B></TD>
112 <% next %>
113 </tr>
114 <% ' Now lets grab all the records
115 DO UNTIL rstemp.eof
116 counter=counter+1
117 response.write "<tr>"
118 for i = 0 to howmanyfields
119 thisvalue=rstemp(i)
120 If isnull(thisvalue) then
121 thisvalue="&nbsp;"
122 end if
123 response.write "<td valign=top>" & thisvalue & "</td>" & vbcrlf
124 next
125 response.write "</tr>"
126 rstemp.movenext
127 IF counter mod 50=0 THEN
128 If response.isclientconnected()=false THEN
129 EXIT DO
130 END IF
131 response.write "</table>" & TableStart
132 END IF
133
134 loop%>
135 </table>
136 <%
137 inputcount=counter
138 rstemp.close
139 set rstemp=nothing
140 conntemp.close
141 set conntemp=nothing
142 END SUB%>
143
144 <%SUB loopstandardStringWrite(inputquery, inputDSN,inputcount)
145 dim conntemp, rstemp
146 set conntemp=server.createobject("adodb.connection")
147 ' 0 seconds means wait forever, default is 15
148 conntemp.connectiontimeout=0
149 conntemp.cursorlocation=optimize_cursorlocation
150 conntemp.open inputDSN
151 set rstemp=conntemp.execute(inputquery)
152 IF optimize_disconnectRS=true THEN
153 conntemp.close
154 END IF
155 howmanyfields=rstemp.fields.count -1
156 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><col
width='15%'><tr>"
157 response.write tablestart
158 for i=0 to howmanyfields %>
159 <td><b><%=rstemp(i).name%></B></TD>
160 <% next %>
161 </tr>
162 <% ' Now lets grab all the records
163 tempSTR=""
164 DO UNTIL rstemp.eof
165 counter=counter+1
166 tempSTR=tempSTR & "<tr>"
167 for i = 0 to howmanyfields
168 thisvalue=rstemp(i)
169 If isnull(thisvalue) then
170 thisvalue="&nbsp;"
171 end if
172 tempSTR=tempSTR & "<td valign=top>" & thisvalue & "</td>" & vbcrlf
173 next
174 tempSTR=tempSTR & "</tr>"
175 rstemp.movenext
176 IF counter mod 50=0 THEN
177 If response.isclientconnected()=false THEN
178 EXIT DO
179 END IF
180 tempSTR=tempSTR & "</table>" & TableStart
181 response.write tempSTR
182 response.flush
183 tempSTR=""
184 END IF
185 loop%>
186 </table>
187 <%
188 inputcount=counter
189 rstemp.close
190 set rstemp=nothing
191 conntemp.close
192 set conntemp=nothing
193 END SUB%>
194
195 <%SUB loopGetstring(inputquery, inputDSN,inputcount)
196 dim conntemp, rstemp
197 set conntemp=server.createobject("adodb.connection")
198 ' 0 seconds means wait forever, default is 15
199 conntemp.connectiontimeout=0
200 conntemp.open inputDSN
201 set rstemp=conntemp.execute(inputquery)
202 howmanyfields=rstemp.fields.count -1
203 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><col
width='15%'><tr>"
204 response.write tablestart
205 for i=0 to howmanyfields %>
206 <td><b><%=rstemp(i).name%></B></TD>
207 <% next %>
208 </tr>
209 <%
210 ' Now lets grab all the records
211 tempSTR=rstemp.getstring(,, "</td><td>", "</td></tr><TR><TD>", "&nbsp;")
212 response.write tempSTR
213 response.write "</table>"
214 inputcount=-1
215 rstemp.close
216 set rstemp=nothing
217 conntemp.close
218 set conntemp=nothing
219 END SUB%>
220
221
222 <%SUB loopGetstringbuffered(inputquery, inputDSN,inputcount)
223 dim conntemp, rstemp
224 set conntemp=server.createobject("adodb.connection")
225 ' 0 seconds means wait forever, default is 15
226 conntemp.connectiontimeout=0
227 conntemp.open inputDSN
228 set rstemp=conntemp.execute(inputquery)
229 howmanyfields=rstemp.fields.count -1
230 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><col
width='15%'><tr>"
231 response.write tablestart
232 for i=0 to howmanyfields %>
233 <td><b><%=rstemp(i).name%></B></TD>
234 <% next %>
235 </tr>
236 <%
237 ' Now lets grab all the records
238 DO
239 tempSTR=rstemp.getstring(,optimize_buffersize, "</td><td>", "</td></tr><TR><TD>",
"&nbsp;")
240 response.write tempSTR
241 If response.isclientconnected()=false THEN
242 EXIT SUB
243 END IF
244 response.write "</table>" & TableStart
245 LOOP UNTIL rstemp.eof
246 response.write "</table>"
247 inputcount=-1
248 rstemp.close
249 set rstemp=nothing
250 conntemp.close
251 set conntemp=nothing
252 END SUB
253
254 SUB loopGetRows(inputquery, inputDSN,inputcount)
255 dim conntemp, rstemp
256 set conntemp=server.createobject("adodb.connection")
257 ' 0 seconds means wait forever, default is 15
258 conntemp.connectiontimeout=0
259 conntemp.open inputDSN
260 set rstemp=conntemp.execute(inputquery)
261 howmanyfields=rstemp.fields.count -1
262 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><col
width='15%'><tr>"
263 response.write tablestart
264 for i=0 to howmanyfields %>
265 <td><b><%=rstemp(i).name%></B></TD>
266 <% next %>
267 </tr>
268 <%
269 ' Now lets grab all the records
270 alldata=rstemp.getrows
271 numcols=ubound(alldata,1)
272 numrows=ubound(alldata,2)
273
274 FOR rowcounter= 0 TO numrows
275 FOR colcounter=0 to numcols
276 response.write "<td valign=top>"
277 response.write alldata(colcounter,rowcounter)
278 response.write "</td>"
279 NEXT
280 response.write "</tr>" & vbcrlf
281 IF rowcounter mod 50=0 THEN
282 If response.isclientconnected()=false THEN
283 EXIT FOR
284 END IF
285 response.write "</table>" & TableStart
286 END IF
287 NEXT
288 response.write "</table>"
289 inputcount=numrows
290 rstemp.close
291 set rstemp=nothing
292 conntemp.close
293 set conntemp=nothing
294 END SUB
295
296 SUB loopGetRowsBuffered(inputquery, inputDSN,inputcount)
297 dim conntemp, rstemp
298 set conntemp=server.createobject("adodb.connection")
299 ' 0 seconds means wait forever, default is 15
300 conntemp.connectiontimeout=0
301 conntemp.open inputDSN
302 set rstemp=conntemp.execute(inputquery)
303 howmanyfields=rstemp.fields.count -1
304 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><col
width='15%'><tr>"
305 response.write tablestart
306 for i=0 to howmanyfields %>
307 <td><b><%=rstemp(i).name%></B></TD>
308 <% next %>
309 </tr>
310 <%
311 ' Now lets grab all the records
312 DO
313 alldata=rstemp.getrows(optimize_buffersize)
314 numcols=ubound(alldata,1)
315 numrows=ubound(alldata,2)
316
317 FOR rowcounter= 0 TO numrows
318 FOR colcounter=0 to numcols
319 response.write "<td valign=top>"
320 response.write alldata(colcounter,rowcounter)
321 response.write "</td>"
322 NEXT
323 response.write "</tr>" & vbcrlf
324 NEXT
325 howmany=howmany+numrows
326 If response.isclientconnected()=false THEN
327 EXIT SUB
328 END IF
329 response.write "</table>" & TableStart
330 LOOP UNTIL rstemp.eof
331 response.write "</table>"
332 inputcount=howmany
333 rstemp.close
334 set rstemp=nothing
335 conntemp.close
336 set conntemp=nothing
337 END SUB
338
339 SUB LimitRows(inputquery, inputDSN,inputcount)
340 set rstemp=Server.CreateObject("adodb.Recordset")
341 rstemp.maxrecords=optimize_maxrecs
342 'rstemp.open inputquery, inputDSN, adopenforwardonly, adlockReadOnly
343 rstemp.open inputquery, inputDSN,adopenstatic
344
345 howmanyfields=rstemp.fields.count -1
346 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><col
width='15%'><tr>"
347 response.write tablestart
348 for i=0 to howmanyfields %>
349 <td><b><%=rstemp(i).name%></B></TD>
350 <% next %>
351 </tr>
352 <%
353 response.flush
354 tempSTR=rstemp.getstring(,, "</td><td>", "</td></tr><TR><TD>", "&nbsp;")
355 response.write tempSTR
356 response.write "</td></tr></table>"
357
358 inputcount=optimize_maxrecs
359 rstemp.close
360 set rstemp=nothing
361 END SUB
362
363 FUNCTION optimizationName(parmNum)
364 SELECT CASE parmnum
365 CASE optimize_LoopAll
366 optimizationName="LoopAll"
367 CASE optimize_GetstringAll
368 optimizationName="GetstringAll"
369 CASE optimize_GetrowsAll
370 optimizationName="GetrowsAll"
371 CASE optimize_GetrowsBuffered
372 optimizationName="GetrowsBuffered"
373 CASE optimize_GetStringBuffered
374 optimizationName="GetStringBuffered"
375 CASE optimize_LimitRows
376 optimizationName="LimitRows"
377 CASE ELSE
378 optimizationName="undefined"
379 END SELECT
380 END FUNCTION
381
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. Here
we time the difference between arbitrary drivers. We will benchmark with the simplest method: Fetching and displaying all records
with 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=240
8 optimize=optimize_LoopAll
9 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 TimerStart
15 call query2table(mySQL,myDSN,optimize,howmany)
16 Call TimerEnd
17
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=240
8
9 mySQL="select * from authors where au_id<2000 order by author "
10 optimize=optimize_LoopAll
11 myDSN="PROVIDER=MSDASQL;DRIVER={SQL Server};"
12 myDSN=myDSN & "SERVER=sql2.datareturn.com;UID=student;PWD=magic;"
13
14 Call TimerStart
15 call query2table(mySQL,myDSN,optimize,howmany)
16 Call TimerEnd
17 %>
18 </BODY></HTML>
Here is the optimized library lib_dbtablefastv2.asp which achieves this speed:
1 <%
2 Const optimize_LoopAll = 1
3 Const optimize_GetstringAll = 2
4 Const optimize_GetrowsAll = 3
5 Const optimize_GetrowsBuffered = 4
6 Const optimize_GetStringBuffered = 5
7 Const optimize_LimitRows = 6
8 Const optimize_LoopAll_String = 7
9
10 dim optimize_buffersize
11 dim optimize_started
12 dim optimize_ended
13 dim optimize_SQL
14 dim optimize_DSN
15 dim optimize_howmany
16 dim optimize_cursorlocation
17 dim optimize_maxrecs
18 dim optimize_disconnectRS
19
20 optimize_started=0
21
22 ' performance stuff
23 optimize_buffersize=200
24 'optimize_cursorlocation=aduseclient
25 optimize_maxrecs=500
26 optimize_cursorlocation=aduseserver
27 optimize_disconnectRS=false
28 optimize_stringwrite=false
29
30 SUB TimerStart()
31 optimize_started=now()
32 END SUB
33
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 THEN
41 optimize_howmany=querycount(optimize_DSN,optimize_SQL)
42 END IF
43 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 THEN
49 response.write pad & "cursorlocation=<b>adUseClient</b><br>"
50 END IF
51 IF optimize_cursorlocation=adUseServer THEN
52 response.write pad & "cursorlocation=<b>adUseServer</b><br>"
53 END IF
54 END SUB
55
56 sub query2table(parmQuery, parmDSN,parmMethod,parmcount)
57 ' method 1 = standard
58 ' method 2 = getrows
59 ' method 3 = getstring
60 dim howmany
61 SELECT CASE parmMethod
62 CASE 1
63 Call loopStandard(parmQuery,parmDSN,howmany)
64 CASE 2
65 Call loopGetString(parmQuery,parmDSN,howmany)
66 CASE 3
67 Call loopGetRows(parmQuery,parmDSN,howmany)
68 CASE 4
69 Call loopGetRowsBuffered(parmQuery,parmDSN,howmany)
70 CASE 5
71 Call loopGetStringBuffered(parmQuery,parmDSN,howmany)
72 CASE 6
73 Call LimitRows(parmQuery,parmDSN,howmany)
74 CASE 7
75 Call loopStandardStringWrite(parmQuery,parmDSN,howmany)
76 CASE ELSE
77 response.write "1, 2 or 3 are only valid speedmethods"
78 END SELECT
79 parmcount=howmany
80 If optimize_started<>0 THEN
81 optimize_DSN=parmDSN
82 optimize_SQL=parmquery
83 optimize_howmany=parmcount
84 END IF
85 END SUB
86
87 FUNCTION querycount(parmDSN,parmQuery)
88 set rstemp=Server.CreateObject("adodb.Recordset")
89 rstemp.open parmQuery, parmDSN, adopenstatic
90 querycount=rstemp.recordcount
91 rstemp.close
92 set rstemp=nothing
93 END FUNCTION
94
95
96 SUB loopstandard(inputquery, inputDSN,inputcount)
97 dim conntemp, rstemp
98 set conntemp=server.createobject("adodb.connection")
99 ' 0 seconds means wait forever, default is 15
100 conntemp.connectiontimeout=0
101 conntemp.cursorlocation=optimize_cursorlocation
102 conntemp.open inputDSN
103 set rstemp=conntemp.execute(inputquery)
104 IF optimize_disconnectRS=true THEN
105 conntemp.close
106 END IF
107 howmanyfields=rstemp.fields.count -1
108 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><col
width='15%'><tr>"
109 response.write tablestart
110 for i=0 to howmanyfields %>
111 <td><b><%=rstemp(i).name%></B></TD>
112 <% next %>
113 </tr>
114 <% ' Now lets grab all the records
115 DO UNTIL rstemp.eof
116 counter=counter+1
117 response.write "<tr>"
118 for i = 0 to howmanyfields
119 thisvalue=rstemp(i)
120 If isnull(thisvalue) then
121 thisvalue="&nbsp;"
122 end if
123 response.write "<td valign=top>" & thisvalue & "</td>" & vbcrlf
124 next
125 response.write "</tr>"
126 rstemp.movenext
127 IF counter mod 50=0 THEN
128 If response.isclientconnected()=false THEN
129 EXIT DO
130 END IF
131 response.write "</table>" & TableStart
132 END IF
133
134 loop%>
135 </table>
136 <%
137 inputcount=counter
138 rstemp.close
139 set rstemp=nothing
140 conntemp.close
141 set conntemp=nothing
142 END SUB%>
143
144 <%SUB loopstandardStringWrite(inputquery, inputDSN,inputcount)
145 dim conntemp, rstemp
146 set conntemp=server.createobject("adodb.connection")
147 ' 0 seconds means wait forever, default is 15
148 conntemp.connectiontimeout=0
149 conntemp.cursorlocation=optimize_cursorlocation
150 conntemp.open inputDSN
151 set rstemp=conntemp.execute(inputquery)
152 IF optimize_disconnectRS=true THEN
153 conntemp.close
154 END IF
155 howmanyfields=rstemp.fields.count -1
156 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><col
width='15%'><tr>"
157 response.write tablestart
158 for i=0 to howmanyfields %>
159 <td><b><%=rstemp(i).name%></B></TD>
160 <% next %>
161 </tr>
162 <% ' Now lets grab all the records
163 tempSTR=""
164 DO UNTIL rstemp.eof
165 counter=counter+1
166 tempSTR=tempSTR & "<tr>"
167 for i = 0 to howmanyfields
168 thisvalue=rstemp(i)
169 If isnull(thisvalue) then
170 thisvalue="&nbsp;"
171 end if
172 tempSTR=tempSTR & "<td valign=top>" & thisvalue & "</td>" & vbcrlf
173 next
174 tempSTR=tempSTR & "</tr>"
175 rstemp.movenext
176 IF counter mod 50=0 THEN
177 If response.isclientconnected()=false THEN
178 EXIT DO
179 END IF
180 tempSTR=tempSTR & "</table>" & TableStart
181 response.write tempSTR
182 response.flush
183 tempSTR=""
184 END IF
185 loop%>
186 </table>
187 <%
188 inputcount=counter
189 rstemp.close
190 set rstemp=nothing
191 conntemp.close
192 set conntemp=nothing
193 END SUB%>
194
195 <%SUB loopGetstring(inputquery, inputDSN,inputcount)
196 dim conntemp, rstemp
197 set conntemp=server.createobject("adodb.connection")
198 ' 0 seconds means wait forever, default is 15
199 conntemp.connectiontimeout=0
200 conntemp.open inputDSN
201 set rstemp=conntemp.execute(inputquery)
202 howmanyfields=rstemp.fields.count -1
203 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><col
width='15%'><tr>"
204 response.write tablestart
205 for i=0 to howmanyfields %>
206 <td><b><%=rstemp(i).name%></B></TD>
207 <% next %>
208 </tr>
209 <%
210 ' Now lets grab all the records
211 tempSTR=rstemp.getstring(,, "</td><td>", "</td></tr><TR><TD>", "&nbsp;")
212 response.write tempSTR
213 response.write "</table>"
214 inputcount=-1
215 rstemp.close
216 set rstemp=nothing
217 conntemp.close
218 set conntemp=nothing
219 END SUB%>
220
221
222 <%SUB loopGetstringbuffered(inputquery, inputDSN,inputcount)
223 dim conntemp, rstemp
224 set conntemp=server.createobject("adodb.connection")
225 ' 0 seconds means wait forever, default is 15
226 conntemp.connectiontimeout=0
227 conntemp.open inputDSN
228 set rstemp=conntemp.execute(inputquery)
229 howmanyfields=rstemp.fields.count -1
230 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><col
width='15%'><tr>"
231 response.write tablestart
232 for i=0 to howmanyfields %>
233 <td><b><%=rstemp(i).name%></B></TD>
234 <% next %>
235 </tr>
236 <%
237 ' Now lets grab all the records
238 DO
239 tempSTR=rstemp.getstring(,optimize_buffersize, "</td><td>", "</td></tr><TR><TD>",
"&nbsp;")
240 response.write tempSTR
241 If response.isclientconnected()=false THEN
242 EXIT SUB
243 END IF
244 response.write "</table>" & TableStart
245 LOOP UNTIL rstemp.eof
246 response.write "</table>"
247 inputcount=-1
248 rstemp.close
249 set rstemp=nothing
250 conntemp.close
251 set conntemp=nothing
252 END SUB
253
254 SUB loopGetRows(inputquery, inputDSN,inputcount)
255 dim conntemp, rstemp
256 set conntemp=server.createobject("adodb.connection")
257 ' 0 seconds means wait forever, default is 15
258 conntemp.connectiontimeout=0
259 conntemp.open inputDSN
260 set rstemp=conntemp.execute(inputquery)
261 howmanyfields=rstemp.fields.count -1
262 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><col
width='15%'><tr>"
263 response.write tablestart
264 for i=0 to howmanyfields %>
265 <td><b><%=rstemp(i).name%></B></TD>
266 <% next %>
267 </tr>
268 <%
269 ' Now lets grab all the records
270 alldata=rstemp.getrows
271 numcols=ubound(alldata,1)
272 numrows=ubound(alldata,2)
273
274 FOR rowcounter= 0 TO numrows
275 FOR colcounter=0 to numcols
276 response.write "<td valign=top>"
277 response.write alldata(colcounter,rowcounter)
278 response.write "</td>"
279 NEXT
280 response.write "</tr>" & vbcrlf
281 IF rowcounter mod 50=0 THEN
282 If response.isclientconnected()=false THEN
283 EXIT FOR
284 END IF
285 response.write "</table>" & TableStart
286 END IF
287 NEXT
288 response.write "</table>"
289 inputcount=numrows
290 rstemp.close
291 set rstemp=nothing
292 conntemp.close
293 set conntemp=nothing
294 END SUB
295
296 SUB loopGetRowsBuffered(inputquery, inputDSN,inputcount)
297 dim conntemp, rstemp
298 set conntemp=server.createobject("adodb.connection")
299 ' 0 seconds means wait forever, default is 15
300 conntemp.connectiontimeout=0
301 conntemp.open inputDSN
302 set rstemp=conntemp.execute(inputquery)
303 howmanyfields=rstemp.fields.count -1
304 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><col
width='15%'><tr>"
305 response.write tablestart
306 for i=0 to howmanyfields %>
307 <td><b><%=rstemp(i).name%></B></TD>
308 <% next %>
309 </tr>
310 <%
311 ' Now lets grab all the records
312 DO
313 alldata=rstemp.getrows(optimize_buffersize)
314 numcols=ubound(alldata,1)
315 numrows=ubound(alldata,2)
316
317 FOR rowcounter= 0 TO numrows
318 FOR colcounter=0 to numcols
319 response.write "<td valign=top>"
320 response.write alldata(colcounter,rowcounter)
321 response.write "</td>"
322 NEXT
323 response.write "</tr>" & vbcrlf
324 NEXT
325 howmany=howmany+numrows
326 If response.isclientconnected()=false THEN
327 EXIT SUB
328 END IF
329 response.write "</table>" & TableStart
330 LOOP UNTIL rstemp.eof
331 response.write "</table>"
332 inputcount=howmany
333 rstemp.close
334 set rstemp=nothing
335 conntemp.close
336 set conntemp=nothing
337 END SUB
338
339 SUB LimitRows(inputquery, inputDSN,inputcount)
340 set rstemp=Server.CreateObject("adodb.Recordset")
341 rstemp.maxrecords=optimize_maxrecs
342 'rstemp.open inputquery, inputDSN, adopenforwardonly, adlockReadOnly
343 rstemp.open inputquery, inputDSN,adopenstatic
344
345 howmanyfields=rstemp.fields.count -1
346 tablestart="<table border=1 cols=3><col width='15%'><col width='70%'><col
width='15%'><tr>"
347 response.write tablestart
348 for i=0 to howmanyfields %>
349 <td><b><%=rstemp(i).name%></B></TD>
350 <% next %>
351 </tr>
352 <%
353 response.flush
354 tempSTR=rstemp.getstring(,, "</td><td>", "</td></tr><TR><TD>", "&nbsp;")
355 response.write tempSTR
356 response.write "</td></tr></table>"
357
358 inputcount=optimize_maxrecs
359 rstemp.close
360 set rstemp=nothing
361 END SUB
362
363 FUNCTION optimizationName(parmNum)
364 SELECT CASE parmnum
365 CASE optimize_LoopAll
366 optimizationName="LoopAll"
367 CASE optimize_GetstringAll
368 optimizationName="GetstringAll"
369 CASE optimize_GetrowsAll
370 optimizationName="GetrowsAll"
371 CASE optimize_GetrowsBuffered
372 optimizationName="GetrowsBuffered"
373 CASE optimize_GetStringBuffered
374 optimizationName="GetStringBuffered"
375 CASE optimize_LimitRows
376 optimizationName="LimitRows"
377 CASE ELSE
378 optimizationName="undefined"
379 END SELECT
380 END FUNCTION
381
382 %>
383
384
385
386
387
388
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 Carroll
response.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 to
determine if the user is still fetching that page, i.e.
1 <%server.scripttimeout=20
2 ' this times out the script in 20 seconds whether done or not%>
3 <TITLE>infiniteloop.asp</TITLE>
4 <body bgcolor="#FFFFFF">
5 <%
6 DO
7 x=x+1
8 response.write x & "<br>"
9 If x=10000 then
10 x=1
11 end if
12 LOOP
13 %>
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 database
tasks.
1 <%server.scripttimeout=20
2 ' this times out the script in 20 seconds whether done or
3 ' the user hit the STOP button
4 %>
5 <TITLE>infiniteloopfixed.asp</TITLE>
6 <body bgcolor="#FFFFFF">
7 <%
8 DO
9 x=x+1
10 response.write x & "<br>"
11 If x=10000 then
12 x=1
13 end if
14 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 invisibly
wasting CPU and database server resources. So here is a database table listing script that incorporates this
functionality:
1 <TITLE>dbtableisclientconnected.asp</TITLE>
2 <body bgcolor="#FFFFFF">
3 <%
4 ' ASP program that displays a database in table form
5 myDSN="DSN=Student;uid=student;pwd=magic"
6 mySQL="select * from publishers"
7
8 set conntemp=server.createobject("adodb.connection")
9 conntemp.open myDSN
10 set rstemp=conntemp.execute(mySQL)
11 howmanyfields=rstemp.fields.count -1
12 %>
13 <table border=1><tr>
14 <% 'Put Headings On The Table of Field Names
15 for i=0 to howmanyfields %>
16 <td><b><%=rstemp(i).name %></B></TD>
17 <% next %>
18 </tr>
19 <% ' Now lets grab all the records
20 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.movenext
27 loop
28 %>
29 </table>
30
31 <%
32 rstemp.close
33 set rstemp=nothing
34 conntemp.close
35 set conntemp=nothing
36 %>
37 </body></html>
http://www.learnASP.com/learn/nothing.asp by Charles M. Carroll
Page 186
The controversy over Nothing by Charles Carroll
Rule #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 with
SET 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 the
real 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.asp
http://www.learnasp.com/learn/globalproblems.asp
http://www.activeserverpages.com/learn/buildvbthreads.asp
http://www.learnasp.com/learn/nosessionobjects.asp
Scenario #1:
set x=server.createobject("whatever.whatever")
....
set x=nothing
Scenario #2
set x=server.createobject("whatever.whatever")
....
In Scenario #1, I can guarantee
the object is cleared from memory G
exactly the line of code where the object is removed from memory G
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 is
flawless I would like to ask you to buy some undervalued land in Florida.
G
when the object was cleaned from memory (the docs do not say when garbage collection occurs) G
I will also state that large ISPs (Innerhost, DataReturn) will guarantee your webserver will come down several times a day or week
with scenario #2 (depending on how many objects are created throughout the day). With Scenario #1 the webserver stays up without
incident. 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 Carroll
Connection pooling takes care of re-using connections.
Lets say Scripta.asp
creates a connection G
process data G
close connection, set to nothing G
and 1,000 users do this simultaneously. It is not quite simultaneous, let us say that what happens when eight users access a script
and 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-used
1:00am .001 - 1 #1 0
1:00am .002 - 2 #1, #2 0
1:00am .010 - 4 #1, #2, #4, #5, #6 #3
1:00am .013 - 4 #2, #4, #5, #6 #1 #6 using #3
1:00am .014 - 3 #4, #5, #6 #1, #2
1:00am .016 - 2 #6, #7 #2, #4 #7 using #1
1:00am .022 - #7, #8 #1, #3, #4, #5 #8 using #2
1:00am .027 - #7 #1, #3, #4, #5
1:00am .029 - #1, #3, #4, #5 waiting
Because of connection pooling they will use MUCH less than 1,000 brand new connections as conn.open statements will be
provided 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 the
webserver 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 are
running round-robin. The registry may have settings that indicate it is safe to be invoked many times from many clients and
marked 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.
G
behaves unstable when many clients are calling it and it's behavior causes the callers damage since they assume each call is
safe and handling parameters correctly, etc.
G
If they get hit hard and fail in some complex way in some % of their requests, they don't recover gracefully and eat more
resources than normal and/or leave locks on memory, disk, resources, etc. and never release them.
G
Thread Safety testing on home-grown components can be done with tools like http://webtool.rte.microsoft.com. Thread Safety issues
are more likely to be discovered on multiprocessor machines and that it's vital to stress test components on MP machines to ensure
thread safety.
WinInet - Not Thread Safe
Basically this a serious limitation in current ASP. I recommend finding vendors who have seriously stress-tested (Soft-Artisans
comes to mind, Serverobjects.com perhaps) their HTTP components. It is almost guaranteed their implementations are not perfect
and are serialized in some situations and not as fast as WinInet, but better than WinInet because slower and less complex internally
is 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.ASP
explains how it could be used in ASP with light load.
http://support.microsoft.com/support/kb/articles/Q183/1/10.ASP
http://support.microsoft.com/support/kb/articles/Q238/4/25.ASP
explains about Thread-Safe issues.
Other articles can be found by searching for
kbWinInet (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 the
meantime 3rd party is our safest bet.
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 or
are not. ASP Tear from http://www.alphasierrapapa.com/ComponentCenter/ is built on WinInet so shares its limitations.
Dictionaries - Threading Problems in App or Session Vars
The scripting dictionary is useful but if used at session or application scope can be slow and prohibit scalability in terms of
serialization 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.asp
explains how Microsoft had difficulty with scalability at session scope on their site.
http://msdn.microsoft.com/library/techart/d4cache.htm
demonstrates a useful page caching technique.
http://support.microsoft.com/support/kb/articles/Q194/8/03.ASP
discusses 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 fixed
in 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 change
this, 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 this
change, corruption of data may occur.
http://www.learnASP.com/learn/roundrobin.asp by Charles M. Carroll
Page 189
Server Code Execution Pattern by Charles Carroll
A 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 answer
in this environment?". Often they have only learned to get rid of the wrong tactics, but are not so fluent in the new tactics. Here we
will explain the correct things to do.
Round-Robin Code Execution
Scripts 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 server
may be running:
Person1 x.asp lines 1-3
Person2 x.asp lines 1-3
Person1 x.asp lines 4-20
Person3 x.asp lines 1-3
Person4 x.asp lines 1-3
Person2 x.asp lines 4-10
Person1 y.asp lines 1-5
Person3 x.asp lines 4-6
etc.
So if your process opens recordsets a couple of lines before manipulating them this could lead to more open recordsets for the total
webserver than you think.
<%
rs1.open
rs2.open
rs3.open
rs4.open
...
process rs1
...
process rs2
...
process rs3
...
process rs4
rs1.close
rs2.close
rs3.close
rs4.close
%>
It is certainly more wasteful than
...
rs1.open
process rs1
rs1.close
...
rs2.open
...
process rs2
rs2.close
rs3.open
...
process rs3
rs4.close
rs4.open
..
process rs4
rs4.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.asp
http://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
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.asp
reading 500 database records. Every change (Getrows or Getstring, One gulp, or 50 rows at a time, named or numbered fields) was
timed. 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 to
a 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 a
different table to ask what dessert another person wants. Then he comes back to your table and asks person #2 what drink they
want. 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 the
adjacent 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 2k
10 gulps of 1k
3 gulps of 3k + 1k gulp
It 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 much
easier than a couple hundred fragmented gulps.
Now the sane man compromises:
<%response.buffer=true%>
... 1k of HTML and/or 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. G
The whole page serves in 3 controlled gulps NO more chaos. G
Control. Not anarchy. G
I once had an overloaded 100% CPU server. I changed registry so all pages were buffer=true. The server then oscillated instead of
staying 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.asp
shows how to retrieve data fast but doesn't discuss why.
If your data formatting is simple:
http://www.learnasp.com/learn/dbtablegetstring.asp
can accomplish even faster results.
Most people write database retrieval code like his:
<%
Open Database
Do UNTIL eof
city=rs("city")
st=rs("state")
zip=rs("zip")
rs.movenext
... process and format data ....
LOOP
Close 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 fudging
a little here.... It actually will transfer the data in chunk sizes defined by rstemp.cachesize -- setting it or reading it will determine how
many gulps it is reading many records in. A cachesize for example of 50 would reduce the previous examples trips to the backend
databse 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 Database
myarray=rstemp.GetRows
rstemp.close
set rstemp=nothing
close database
maxcounter=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 backend
gets 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 my
main 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 the
scripts spin, round-robin and save their context and store their data at a low-level to serve all those users simultaneously. On a
webserver every millisecond you waste in one script may be multiplied by tens of thousands of users (Amazon.com, Cnn.com) so it
behooves 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 the
loop. Well, if the reads take 1.5 seconds and the processing/formatting takes 2.5 seconds the database is open for 4 seconds. With
Getrows the same operation retrieve might take 3/4 second and the rs and cn are closed and back in the pool for others and the
formatting is done while someone else uses the connection and whatever READ locks placed on the data rows/chunks aren't
affecting 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 timeouts
with movenext. Getstring never timed out. So in a real production situation it makes weak databases feasible and of course reduces
the 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 to
aspscalability@ls.asplists.com
Related Links
Microsoft Enterprise White Paper @
http://www.microsoft.com/NTServer/ntserverenterprise/techdetails/overview/NTSEE.asp
L5: A Self Learning Layer-5 Switch @
http://www.research.ibm.com/people/d/debanjan/papers/l5.pdf
Performance Of TCP Splcing For URL-Aware Redirection (requires membership) @
http://www.usenix.org/events/usits99/cohen.html
Web switches open e-comm doors at Nettaxi @
http://www.nwfusion.com/archive/1999/82163_12-06-1999.html
Server Farms, Port Density, Load-Balancing Switch @
http://www.techweb.com/se/directlink.cgi?INW19991018S0017
Enterprise Scaling Benchmarks @
http://www.devx.com/upload/free/features/entdev/1999/08aug99/cs0899/cs0899.asp
Fitch & Mathers Intro @
http://www.fmcorp.com/
Radware - Excellent Cluster @
http://www.radware.com
Developmentor Load Balancing @
http://www.develop.com/hp/ewald/lb/loadbalancing.htm
-no name- @
http://www.level3.com
-no name- @
http://www.timesten.com
Scalability Resource Kit @
http://www.microsoft.com/siteserver/commerce/DeployAdmin/ResKit.asp
Pure SSL acceleration @
http://www.ipivot.com/products/products-ca1000.html
Faster SSL Acceleration, deals with AOL too @
http://www.ipivot.com/products/products-cd8000.html
Endurance 400 @
http://www.marathontechnologies.com/productinfo/index.htm
ArrowPoint Mother Nature Profile @
http://www.arrowpoint.com/solutions/profiles/mother_nature.html
Commerce Accelerator 1000, claims 50X faster SSL @
http://www.ipivot.com
Cisco'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.com
Interview with Mother Nature Lead Engineer @
http://www.internetwk.com/story/INW19990416S0005
RSW 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
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 Carroll
The 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_keyword
12 objQuery.Columns = "Vpath, DocTitle, Filename, Characterization, Contents,DocKeyWords, Rank"
13 objQuery.SortBy = "Rank [d]"
14 objQuery.MaxRecords = 50
15 objUtil.AddScopeToQuery objQuery, "/", "DEEP"
16
17 linebr="<br>" & vbcrlf
18 Set rstemp = objQuery.CreateRecordSet("nonsequential")
19 DO UNTIL rstemp.eof
20 FOR EACH key in rstemp.fields
21 keyname=lcase(key.name)
22 SELECT CASE keyname
23 CASE "vpath"
24 response.write "<a href='"
25 response.write key
26 response.write "'>" & key & "</a>" & linebr
27 CASE ELSE
28 response.write "<b>" & keyname & ":</b>" & linebr
29 response.write key & linebr
30 END SELECT
31 NEXT
32 response.write "<br><hr>"
33 rstemp.movenext
34 LOOP
35 ' clean up
36 rstemp.close
37 set rstemp=nothing
38 Set objQuery = nothing
39 Set objUtil = nothing
40 %>
41 </body>
42 </html>
http://www.learnASP.com/learn/commerce.asp by Charles M. Carroll
Page 195
ASP Commerce
Active 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 to
ecommerce@ls.asplists.com
Related Links
UPS shipping Interface @
http://www.ups.com/bussol/solutions/index.html
MOD10 Credit Card Validation @
http://www.15seconds.com/issue/970101.htm
How do I setup https://,get a certificate @
http://www.learnasp.com/learn/FAQCommerceCertif.asp
I want to process credit cards, where to start? @
http://www.learnasp.com/learn/FAQCommerceCharge.asp
What ASP Components & Shopping Carts are available? @
http://www.learnasp.com/learn/FAQCommerceCarts.asp
Banner Ad Rotation from Database @
http://www.4guysfromrolla.com/webtech/091299-1.shtml
Install a SSL Certificate @
http://www.4guysfromrolla.com/webtech/062299-1.shtml
E-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 Carroll
Jscript is an alternative language to VBscript that can be used to build ASP pages. It is a language preferred by a small percentage
of 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 allowed
you can join to get help.
jscript Listserver

JOIN, QUIT or Search ARCHIVES:
http://www.asplists.com/asplists/javascript.asp
Send Listserver Questions to
jscript@ls.asplists.com
Related Links
Wise ASP Jscript Column @
http://www.aspalliance.com/wsk
Closing Jscript Database Connections @
http://www.learnasp.com/learn/FAQJscriptCleanUp.asp
JavaScript/Jscript Links @
http://www.learnasp.com/webbuilding/jscript.asp
Phil Malones Jscript column @
http://www.aspalliance.com/philmalone
VB functions converted to Jscript @
http://www.4GuysFromRolla.com/webtech/vb2java.shtml
ListBox from DB using Jscript @
http://www.aspmagazine.com/aspmagazine/issue10jscript.asp
Book: Danny Goodmans Jscript Bible @
http://www.learnasp.com/books/goodmanjscript.asp
Book: Oreilly Definitive JavaScript @
http://www.learnasp.com/books/jscriptdefinitive.asp
Listboxes Dynamically Linked w/Jscript @
http://www.learnasp.com/learn/listdynamic.asp
Listboxes Dynamically Linked w/Jscript + Database @
http://www.learnasp.com/learn/listdynamicdb.asp
Listboxes Dynamically Linked - Online Examples @
http://www.learnasp.com/learn/listdynamicmore.asp
10 Open Window Techniques @
http://www.builder.com/Programming/JSWinTips/?tag=st.cn.sr1.dir
Client Jscript and ASP Mixed @
http://www.clearviewdesign.com/NEWBIE.asp
http://www.learnASP.com/learn/validationmore.asp by Charles M. Carroll
Page 197
Validation Resources
Validation is handled in much more depth at other sites actually. One of my favorite sites www.4guysfromrolla.com has several
validation 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
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 Smith
http://www.asptoday.com/articles/19990611.htm
Professional Form Validation by Jay McKinney
http://www.asptoday.com/articles/19990303.htm
Advanced Form Validation By Andrea Chiarelli
http://www.asptoday.com/articles/19990708.htm
A Library of regular Expressions for Form Validation By Alexander Nakhimovsk
http://www.asptoday.com/articles/19990629.htm
Persisting Form Control Values with ASP by Alex Homer
http://www.asptoday.com/articles/19990331.htm
http://www.learnASP.com/learn/listdynamic.asp by Charles M. Carroll
Page 198
Dynamic Client Dependent Lists/JScript
Sometimes you need a Listbox that changes in response to a value of another listbox. The most effective way is to use client-side
Jscript 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">Jeff
8 <OPTION Value="Charles">Charles
9 <OPTION Value="Rick">Rick
10 <OPTION Value="Kevin">Kevin
11 </Select>
12 <BR><BR>
13 Contacts:
14 <!-- We want to define at least one option so that the select tag is created
15 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 contacts
26 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 //Charles
33 Contacts[0][0]="Bill";
34 Contacts[0][1]="Bob";
35 Contacts[0][2]="Chuck";
36
37 //Jeff
38 Contacts[1][0]="Vern";
39 Contacts[1][1]="Matt";
40
41 //Rick
42 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 //Kevin
49 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 Salesperson
55 function BuildContacts(num)
56 {
57 //Select the first Contact
58 document.myForm.SalesContacts.selectedIndex=0;
59
60 //For every contact in the array for this person, add a new option
61 for(ctr=0;ctr<Contacts[num].length;ctr++)
62 {
63 document.myForm.SalesContacts.options[ctr]=new
Option(Contacts[num][ctr],Contacts[num][ctr]);
64 }
65 //Set the length of the select list
66 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 Resources
There are actually many approaches to creating dynamic lists with Jscript where a change in one listbox affects what options appear
in 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
Dynamic Dependent Lists/JScript
generated from Relational Database
This example shows how to tie a relational database together to form dependent list boxes with Client Jscript. We have made a
generic 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 query
7 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 first
4 set conntemp=server.createobject("adodb.connection")
5 conntemp.open myDSN
6 set rstemp=conntemp.execute(query)
7 list1="<select name=""" & listname1 & """"
8 list1=list1 & " OnChange=""Build" & key
9 list1=list1 & "(this.selectedIndex);"">"
10 list2="<select name=""" & listname2 & """>"
11 loopcounter=0
12 lastvalue=rstemp(0)
13 redim tempArray(1)
14 thisgroupcount=0
15 howmanygroups=0
16 DO UNTIL rstemp.eof
17 loopcounter=loopcounter+1
18 thisvalue=rstemp(0)
19 thisvalue2=rstemp(1)
20 if thisvalue<>lastvalue then
21 tempSTR=key & "[" & howmanygroups & _
22 "]=new Array(" & thisgroupcount & ");" & _
23 vbcrlf & tempSTR
24 thisgroupcount=0
25 howmanygroups=howmanygroups+1
26 end if
27 if thisgroupcount=0 then
28 tempSTR=tempSTR & "// " & thisvalue & vbcrlf
29 list1 = list1 & "<option>" & thisvalue & "</option>" & vbcrlf
30 end if
31 tempSTR=TempSTR & key & "[" & howmanygroups & "][" & thisgroupcount & "]=""" &
thisvalue2 & """;" & vbCRLF
32 thisgroupcount=thisgroupcount+1
33 if howmanygroups=0 then
34 list2 = list2 & "<option>" & thisvalue2 & "</option>" & vbcrlf
35 end if
36 lastvalue=thisvalue
37 rstemp.movenext
38 IF response.isclientconnected=false THEN
39 EXIT DO
40 END IF
41 LOOP
42 tempSTR=key & "[" & howmanygroups & _
43 "]=new Array(" & thisgroupcount & ");" & _
44 vbcrlf & tempSTR
45 list1=list1 & "</select>"
46 list2=list2 & "</select>"
47 myevent=vbcrlf & key & "=new Array(" & howmanygroups+1
48 myevent=myevent & ");" & vbcrlf & tempSTR
49 rstemp.close
50 set rstemp=nothing
51 conntemp.close
52 set conntemp=nothing
53 tempSTR =vbcrlf & "function Build" & Key & "(num)" & vbcrlf
54 tempSTR =tempSTR & "{" & vbcrlf
55 tempSTR =tempSTR & "document." & myForm & "."
56 tempSTR =tempSTR & listname2 & ".selectedIndex=0;" & vbcrlf
57 tempSTR =tempSTR & "for(ctr=0;ctr<" & key & "[num].length;ctr++)" & vbcrlf
58 tempSTR =tempSTR & "{" & vbcrlf
59 tempSTR =tempSTR & "document." & myform & "." & listname2
60 tempSTR =tempSTR & ".options[ctr]=new Option(" & key & "[num][ctr],"
61 tempSTR =tempSTR & key & "[num][ctr]);" & vbcrlf
62 tempSTR =tempSTR & "}" & vbcrlf
63 tempSTR =tempSTR & "document." & myForm & "." & listname2
64 tempSTR =tempSTR & ".length=" & key & "[num].length;" & vbcrlf
65 tempSTR =tempSTR & "}" & vbcrlf
66 myfun=tempSTR
67 END SUB
68 %>
http://www.learnASP.com/learn/listdual.asp by Charles M. Carroll
Page 201
Dual List Boxes by Bill Wilkinson (billw@chilisoft.com)
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 Available
7 Dim Chosen
8 If Session("BeenHere") <> "DoneThat" Then
9 ' First time to this page!
10 '
11 ' In "real life" you'd probably populate the
12 ' "initialItems" array from a database query,
13 ' but for demo purposes we'll do it this way:
14 '
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 chosen
20 Next
21 '
22 ' save for next time here
23 '
24 Set Session("Choices") = Available
25 '
26 ' set the flag so we don't do this again
27 '
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 do
44 '
45 ' We might be here because of "Add" button,
46 ' "Remove" button, or just because user hit
47 ' "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").Count
53 item = Request.Form("ItemsAvailable")(i)
54 If item <> "#" Then
55 Available(item) = "yes" ' now chosen!
56 End If
57 Next
58 '
59 End If
60 If Request.Form("RemoveFromChosen") = "<< Remove" Then
61 ' user asked to remove some previously chosen values
62 For i = 1 To Request.Form("ItemsChosen").Count
63 item = Request.Form("ItemsChosen")(i)
64 If item <> "#" Then
65 Available(item) = "no" ' no longer chosen
66 End If
67 Next
68 '
69 End If
70 '
71 ' save for next time here
72 '
73 Set Session("Choices") = Available
74
75 End If
76
77 ' miscellany:
78 iCount = Available.count + 1
79
80 %>
81
82 <center>
83
84 <font Size="+2">
85 Dual List Query Demo: Page 1
86 </font>
87
88 <%
89 If Left( Message, 1 ) <> "#" Then
90 %>
91 <p>
92 <font Size="+1"><em>
93 <strong>Notice:</strong> <% = Message %>
94 </em></font>
95 <%
96 End If
97 %>
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.keys
115 For i = 0 To UBound( aKeys )
116 item = aKeys( i )
117 ' In this demo, we do NOT display already chosen
118 ' items in the "available" Select list...but
119 ' you could easily eliminate the following
120 ' If...Then test and always display all available
121 ' choices, if you preferred!
122 '
123 If Available( item ) = "no" Then
124 %>
125 <option Value="<% = item %>"><%= item %></option>
126 <%
127 End If
128 Next
129 '
130 ' Value="#" option is just to give a minimum
131 ' width to the Select list when it would
132 ' 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;
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 = 0
156 aKeys = Available.keys
157 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" Then
163 chosenCount = chosenCount + 1
164 %>
165 <option Value="<% = item %>"><%= item %></option>
166 <%
167 End If
168 Next
169 %>
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") = chosenCount
194 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 until
5 ' you have set up the session variable
6 ' with the list of choices.
7 '
8 If Session("BeenHere") <> "DoneThat" Then
9 Response.Redirect "DualList.asp"
10 End If
11 '
12 ' We don't try to process queries until
13 ' we have at least one item chosen...
14 ' Naturally, you could change this to
15 ' use some default instead!
16 '
17 If Session("ChosenCount") = 0 Then
18 Session("Message") = "You must place at least one item in the right hand list before
asking for a query."
19 Response.Redirect "DualList.asp"
20 End If
21 %>
22
23 <HTML>
24 <BODY>
25
26 <CENTER>
27 <FONT Size="+2">
28 Dual List Query Demo: Page 2
29 </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.keys
44 For i = 0 To UBound( aKeys )
45 item = aKeys( i )
46 If Chosen( item ) = "yes" Then
47 Response.Write "<LI>" & item & vbCrLf
48 End If
49 Next
50 %>
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 Carroll
Perlscript 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 topic
allowed you can join to get help.
aspperlscript Listserver

JOIN, QUIT or Search ARCHIVES:
http://www.asplists.com/asplists/perlscript.asp
Send Listserver Questions to
aspperlscript@ls.asplists.com
Related Links
ActiveState - Perl Suppliers @
http://www.activestate.com
Tobias Martinsson's Site @
http://www.perlscripters.com
Matt'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 Carroll
Remote 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 G
dynamic page construction via Javascript that could be for example fetching database data for a page without reloading the
page.
G
The main limitations are
the browser must be a 4.x browser G
It doesn't work on IE Mac (thanks to "Brad Rhoads" <brad@data-science.com> for that tip) G
The current version requires 3 files: rs.asp, rs.htm and rsprox.class which can be downloaded from
http://msdn.microsoft.com/scripting on the server to work and their exact path must be set in the files (/learn/test/remote/ is the path
in 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 }
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 Sample
Microsoft created an obtuse, complex to read Remote Scripting sample that demonstrates all it's capabilities we will reproduce here
in 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>
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 {
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 Carroll
RDS is limited to IE4 but it's power is astonishing as it transforms ADO into the same kind of technology used by Access and Visual
Basic 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 allowed
you can join to get help.
asprds Listserver

JOIN, QUIT or Search ARCHIVES:
http://www.asplists.com/asplists/rds.asp
Send Listserver Questions to
asprds@ls.asplists.com
Related Links
RDS FAQ by Carl Prothman @
http://www.able-consulting.com/RDS_Faq.htm
RDS Tutorial @
http://msdn.microsoft.com/library/psdk/dasdk/mdat2n8s.htm
RDS Overview @
http://msdn.microsoft.com/library/psdk/dasdk/mdov17z9.htm
RDS Developer's Guide @
http://msdn.microsoft.com/library/psdk/dasdk/mdad5lpz.htm
ADO Sample Applications (includes RDS samples) @
http://msdn.microsoft.com/library/psdk/dasdk/mdas6c1f.htm
ADO Code Examples (includes RDS examples) @
http://msdn.microsoft.com/library/psdk/dasdk/mdae550z.htm
Carl Prothmans RDS Book List @
http://www.able-consulting.com/books_ado.htm
On Creating a Recordset with RDS @
http://www.asptoday.com/articles/19990813.htm
RDS Data Factory @
http://www.asptoday.com/articles/19990607.htm
RDS & COM @
http://www.asptoday.com/articles/19990326.htm
Web-Based DB Apps using RDS & ASP @
http://www.15seconds.com/issue/980527.htm
Intro to RDS @
http://www.aspwatch.com/c/e/e179B1FBB2B7011D3BBF800A0CC3BDC77.asp
Remote 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.htm
has 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
http://www.learnASP.com/learn/ADSI.asp by Charles M. Carroll
Page 207
ADSI and ASP by Charles Carroll
ADSI stands for Active Directory Server Interface
and it basically is a com object to allow ASP (or any language) to interogate and manipulate the types of objects that are managed
by servers traditionally: domains, groups, users, passwords, directory listings. It is intended to be an integral part of NT5 and will also
be extended to communicate with a variety of server architectures (Netscape Servers, Novell servers, LDAP servers) but it is
available 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.htm
has 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/ASP
Component.
ADSI listserv by 15seconds.com
to: -> LISTSERV@LISTSERV.15SECONDS.COM
body (not subject) -> SUBSCRIBE ADSI Your Name
http://www.jfkdesigns.com/default.asp?go=ADSI
has some FREE ADSI scripts
http://www.learnASP.com/learn/MSMQ.asp by Charles M. Carroll
Page 208
MSMQ -- Microsoft Message Que Overview by Charles Carroll
Microsoft Message Que is a programming tool that simplifies building client-server applications that can be robust and reliable even
when 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 request
be eventually serviced or be able to continue without catastrophically failing. It should be able to send a request, and then await an
answer, as opposed to request immediate fullfillment -- something that cannot be accomodated if the service being requested is
temporaily unavailable.
Traditional Approach
Client => 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 Approach
Client => send request through MSMQ
Client => check results through MSMQ
Server => check for requests through MSMQ
Server => 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 no
direct communication.
http://www.learnASP.com/learn/usability.asp by Charles M. Carroll
Page 209
Usability Issues by Charles Carroll
Usability is critical when making a sucessfull website. According to Web Guru, Jakob Neilsen, only 10% of the web sites achieve high
usability. 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 using
rich 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 G
samples of web safe colors. These colors will appear the same on almost everybody's browser. Other colors may appear
dramatically different from browser to browser.
G
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 6
8 safecolor1=websafe(counter)
9 for counter2=1 to 6
10 safecolor2=websafe(counter2)
11 for counter3= 1 to 6
12 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 next
23 next
24 next
25 response.write "</strong></font></table>"
26 %>
27 </body></html>
28 <%
29 function websafe(mynumber)
30 SELECT CASE mynumber
31 CASE 1
32 websafe=0
33 CASE 2
34 websafe=51
35 CASE 3
36 websafe=102
37 CASE 4
38 websafe=153
39 CASE 5
40 websafe=204
41 CASE 6
42 websafe=255
43 END SELECT
44 end function
45 %>
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 string
57 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 } else
71 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
Developing ASP Components
published by Oreilly
written by Shelly Powers
OUR SUMMARY:
This is THE ASP Book of 1999. Lucid, detailed. Great for beginners, full of substance for
experts. Component building in 3 languages: C++, Java and Visual Basic. Microsoft
Transaction Server covered beautifully as well. Find out why Charles Carroll calls Shelly
Powers the component goddess.
BUY IT http://bn.bfast.com/booklink/click?sourceid=10446528&ISBN=1565924460
INFO ONLINE
http://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 of
the 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 topics
we do not touch on. 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.
THIS SITE IS HUGE. YOU COULD SPEND WEEKS THERE!!!
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 best
selling 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
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 (Phil@matchw.com)
Here are the things dealing with the issue of caching in ASP:
1. Response.Expires = 0
2. Response.ExpiresAbsolute = Now() - 1
3. 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 posted
research from time spent with some IIS internals experts revealing this can be a very touchy parameter to rely upon and
usually 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 use
something 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 through
4.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 ever
Response.Redirect anywhere in my code except sample code I post to the lists (then again, the only time I use
Response.Write is to the list because I rely on my Utilities-Form.inc library for Display() and HTML()). Everything is
Redirect(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
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) and
have gotten used to a bunch of tiny little routines scattered throughout my app with a bunch of #include statements. Some of
this might seem like overkill, but you have to understand just how pervasive and frustrating caching can be in a scripted app
environment. Caching is great for pure HTML because it reduces server overhead. But if you do much scripting against
databases, or time-based functions, it's not unusual to see rather bizarre things happen. Shopping cart applications will
suddenly "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 previous
order. 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, your
users may be dealing with it for you -- you can turn caching off for your application in IIS [itself], but what if you are behind
a firewall or proxy server which does caching for you? Or, if the user has caching turned on in their browser or they could be
behind one or more layers of firewalls or proxy servers, all of which have been sold under the premise of delivering better
performance through caching? Unless and until you can control every layer of access to your app, telling your server not to
cache 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 an
app 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 Explicit
use Option Explicit when writing VBScript.
<% option explicit%>
goes at the top of the script!
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 SQL
Command #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 mySQL
set rstemp=conntemp.execute(mySQL)
rstemp.close
set rstemp=nothing
http://www.learnASP.com/learn/namedconstants.asp by Charles M. Carroll
Page 221
ASP Commandment #4: Named Constants
Command #4: use named constants from adovbs.inc instead of numeric constants. (granted, adovbs.inc isn't complete and requires
some 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, adopenstatic
response.write rstemp.recordcount & " records in<br>" & sqltemp
rstemp.close
set 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, 3
response.write rstemp.recordcount & " records in<br>" & sqltemp
rstemp.close
set rstemp=nothing
%>
http://www.learnASP.com/learn/cleanup.asp by Charles M. Carroll
Page 222
ASP Commandment #5: Clean Up Objects
Close each object when done with them. This frees up the "handle" to the resource. This applies to objects that support close
methods, 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 forget
it 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 listbox
9 set conntemp=server.createobject("adodb.connection")
10 conntemp.open myDSN
11 set rstemp=conntemp.execute(mySQL)
12 if rstemp.eof then
13 response.write "no data for<br>"
14 response.write mySQL
15 conntemp.close
16 set conntemp=nothing
17 response.end
18 end if
19
20 %>
21 <form action="dblistrespond.asp" method="post">
22 <Select name="authorname">
23 <%
24 ' Now lets grab all the data
25 do until rstemp.eof %>
26 <option> <%=RStemp(0)%> </option>
27 <%
28 rstemp.movenext
29 loop
30
31 rstemp.close
32 set rstemp=nothing
33 conntemp.close
34 set conntemp=nothing
35 %>
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.MapPath
Use Server.MapPath() whenever referring to files stored locally on the server instead of a static path (except in the rare occasions
where 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.readall
response.write tempSTR
thisfile.Close
set thisfile=nothing
set 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.readall
response.write tempSTR
thisfile.Close
set thisfile=nothing
set fs=nothing
%>
http://www.learnASP.com/learn/nosessionobjects.asp by Charles M. Carroll
Page 224
ASP Commandment #7: No COM objects in Sessions
Do not store any COM objects in a Session() variable because of memory waste and threading issues. Do not store any COM
objects 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 G
/advice/dbsessionapp.asp
Session and application level data basics at
/learn/globalproblems.asp.
G
STA and Memory Model Issues at
/learn/buildvbthreads.asp
G
Memory Waste Scenarios
Let 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 arrive
Scenario 1:
object in session_onstart
Scenario 2: objects created/destroyed on a page per
page basis
End Result:
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
End Result:
50 objects in memory
with 50 people on your site. No unused threads must
be 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 than
450 objects in Scenario 1 for better performance. Basically set object=nothing may be ignored and the object placed in an "instant
ready" 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 Expensive
Do not fetch any values obtained via ASP/COM more than once. Store them and use the stored values. It speeds up code
significantly. 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 something
end if
if rstemp("city")="New York" then
' do something
end if
if rstemp("city")="New Orleans" then
' do something
end if
%>
This is good:
<%
thecity=rstemp("city")
if thecity="Dallas" then
' do something
end if
if thecity="New York" then
' do something
end if
if thecity="New Orleans" then
' do something
end if
%>
http://www.learnASP.com/learn/securecode.asp by Charles M. Carroll
Page 226
Secure Your Code and Data
In addition to coding, you need to consider security from an ASP coders point of view.This means:
NO .inc Extensions
Do not name your include files with a .inc extension
name them with a .asp extension.
Be careful where you place .mdb files
Do not place .mdb files inside your web structure where they can be downloaded. Place them in a directory on the machine but not
within 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 ASP
Security Topics:
aspSecurity Listserver

JOIN, QUIT or Search ARCHIVES:
http://www.asplists.com/asplists/securecode.asp
Send Listserver Questions to
aspSecurity@ls.asplists.com
Related Links
Security 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 Libraries
You should create many subroutines and functions and instead of placing them in each page just use the include facility to access
them. 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 %>
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 it
8 For i = 1 TO 1000
9 n = i
10 Response.Write n & AddSuffix(n) & ".<BR>"
11 NEXT
12 %>
13
14 </body>
15 </html>
16 <%
17 FUNCTION AddSuffix(num)
18 temp=right(num,1)
19 If temp= 1 Then
20 AddSuffix = AddSuffix & "st"
21 ElseIf temp = 2 Then
22 AddSuffix = AddSuffix & "nd"
23 ElseIf temp = 3 Then
24 AddSuffix = AddSuffix & "rd"
25 ElseIf temp<11 Then
26 AddSuffix = AddSuffix & "th"
27 End If
28 END FUNCTION
29 %>
This is the CASE example:
1 <html><head>
2 <title>suffixcase.asp by Dwaine Maltais rmaltais@wilmington.net</title>
3 </head>
4
5 <body>
6 <%
7 ' ok test it
8 FOR i = 1 TO 1000
9 n = i
10 Response.Write AddSuffix(n) & "<br>"
11 NEXT
12 %>
13
14 </body>
15 </html>
16 <%
17 Function AddSuffix(num)
18 numpart = RIGHT(num,1)
19 SELECT CASE numpart
20 CASE "1"
21 IF InStr(num,"11") THEN
22 num = num & "th"
23 ELSE
24 num = num & "st"
25 END IF
26 CASE "2"
27 IF InStr(num,"12") THEN
28 num = num & "th"
29 ELSE
30 num = num & "nd"
31 END IF
32 CASE "3"
33 IF InStr(num,"13") THEN
34 num = num & "th"
35 ELSE
36 num = num & "rd"
37 END IF
38 CASE "4"
39 num = num & "th"
40 CASE ELSE
41 num = num & "th"
42 END SELECT
43 AddSuffix = num
44 END FUNCTION
45 %>
http://www.learnASP.com/learn/errorstrategies.asp by Charles M. Carroll
Page 229
Error Trapping Strategies by Charles Carroll
DRAFT - not ready yet!
There are several ways to deal with errors. For example:
write errors to custom log G
write errors to IIS log G
email someone when a page error occurs G
place errors in a custom dictionary/collection G
We will provide code for each scenario and discuss the pros and cons of each approach.
http://www.learnASP.com/learn/errorsecrets.asp by Charles M. Carroll
Page 230
Error Trapping Secrets by Charles Carroll
DRAFT - Not Ready yet
Blah, Blah, Blah.
http://www.learnASP.com/learn/shoulds.asp by Charles M. Carroll
Page 231
ASP Commandments: Shoulds
Thou should:
specify all of the parameters for their ADO command, connection, and recordset objects so defaults don't rear their ugly heads
and 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).
G
make sure that ASP scripts that are dynamic in nature have caching turned off. Thou shalt find scripts and caching are like oil
and water...they mix not well, except on salads. If caching isn't turned off by default, it should be possible to alter a single
variable in each script file so caching can be switched on/off at will to avoid retrofitting scripts with the code required to break
caching.
/learn/cachenomore.asp has up to date guidelines on how to disable script caching.
G
remember using .Execute to create an ADO recordset will result in a read-only recordset and thou can neither edit these
records nor add new records.
G
Use the correct cursortype or a SQL count to determine how many records are in a table or query, instead of a counting loop
or a movelast.
see /learn/dbcount.asp for an example.
G
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
http://www.learnASP.com/learn/txtread.asp by Charles M. Carroll
Page 233
Text File Reading
1 <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=0
11 do while not thisfile.AtEndOfStream
12 counter=counter+1
13 thisline=thisfile.readline
14 response.write thisline & "<br>"
15 loop
16
17 thisfile.Close
18 set thisfile=nothing
19 set fs=nothing
20 %>
21 </body></html>
http://www.learnASP.com/learn/txtwrite.asp by Charles M. Carroll
Page 234
Text File Writing by Charles Carroll
The 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 air
8 Set fstemp = server.CreateObject("Scripting.FileSystemObject")
9 Set filetemp = fstemp.CreateTextFile(whichFN, true)
10 ' true = file can be over-written if it exists
11 ' false = file CANNOT be over-written if it exists
12
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.Close
17
18 ' Now open it and add some lines
19 forappending =8
20 set filetemp=fstemp.OpentextFile(whichFN, forappending)
21 filetemp.writeline "a line we added later"
22 filetemp.writeline "another line we added later..."
23 filetemp.close
24
25 set filetemp=nothing
26 set fstemp=nothing
27
28 If err.number=0 then
29 response.write "File was appended sucessfully!"
30 else
31 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 if
39
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 & whichname
8 forreading=1
9
10 Set fs = CreateObject("Scripting.FileSystemObject")
11 Set thisfile = fs.OpenTextFile(whichFN, forreading, False)
12 counter=0
13 do while not thisfile.AtEndOfStream
14 counter=counter+1
15 thisline=thisfile.readline
16 response.write thisline & "<br>"
17 loop
18 thisfile.Close
19
20 set thisfile=nothing
21 set fs=nothing
22
23 %>
24 </body></html>
http://www.learnASP.com/learn/mb1.asp by Charles M. Carroll
Page 235
Reading/Parsing an ASCII File by Charles Carroll
Let us say you have an ASCII file of questions that you want to convert to HTML (listing below). The next page will show you the
typical parsing code used for such a task.
1 EI At a party do you - interact with many, including strangers / interact with a few, known
to you
2 SN Are you more - realistic than speculative / speculative than realistic
3 SN It is worse to - have your "head in the clouds" / be "in a rut"
4 TF Are you more impressed by - principles / emotions
5 TF Are you more drawn toward the - convincing / touching
6 JP Do you prefer to work - to deadlines / just "whatever"
7 JP Do you tend to choose - rather carefully / somewhat impulsively
8 EI At parties do you - stay late, with increasing energy / leave early, with decreased
energy
9 SN Are you more attracted to - sensible people / imaginative people
10 SN Are you more interested in - what is actual / what is possible
11 TF In judging others are you more swayed by - laws than circumstances / circumstances than
laws
12 TF In approaching others is your inclination to be - objective / personal
13 JP Are you more - punctual / leisurely
14 JP Does it bother you more having things - incomplete / completed
15 EI In your social groups do you - keep abreast of other's happenings / get behind on the
news
16 SN In doing ordinary things are your more likely to - do it the usual way / do it your own
way
17 SN Writers should - "say what they mean and mean what they say" / express things more by use
of analogy
18 TF Which appeals to you more - consistency of thought / harmonious human relationships
19 TF Are you more comfortable in making - logical judgments / value judgmants
20 JP Do you want things - settled and decided / unsettled and undecided
21 JP Would you say you are more - serious and determined / easy-going
22 EI In phoning do you - rarely question that it will all be said / rehearse what you'll say
23 SN Facts - "speak for themselves" / illustrate principles
24 SN Are visinaries - somewhat annoying / rather fascinating
25 TF Are you more often - a cool-headed person / a warm-hearted person
26 TF Is it worse to be - unjust / merciless
27 JP Should one usually let events occur - by careful selection and choice / randomly and by
chance
28 JP Do you feel better about - having purchased / having the option to buy
29 EI In company do you - initiate conversation / wait to be approached
30 SN Common sense is - rarely questionable / frequently questionable
31 SN Children often do not - make themselves useful enough / exercise their fantasy enough
32 TF In making decisions do you feel more comfortable with - standards / feelings
33 TF Are you more - firm than gentle / gentle than firm
34 JP Which is more admirable - the ability to organize and be methodical / the ability to
adapt and make do
35 JP Do you put more value on the - definite / open-ended
36 EI Does new and non routine interaction with others - stimulate and energize you / tax your
reserves
37 SN Are you more frequently - a practical sort of person / a fanciful sort of person
38 SN Are you more likely to - see how others are useful / see how others see
39 TF Which is more satisfying - to discuss an issue thoroughly / to arrive at agreement on an
issue
40 TF Which rules you more - your head / your heart
41 JP Are you more comfortable with work that is - contracted / done on a casual basis
42 JP Do you tend to look for - the orderly / whatever turns up
43 EI Do you prefer - many friends with brief contact / a few friends with more lengthy contact
44 SN Do you go more by - facts / principles
45 SN Are you more interested in -production and distribution / design and research
46 TF Which is more of a compliment - "There is a very logical person." / "There is a very
sentimental person."
47 TF Do you value in yourself more that you are - unwavering / devoted
48 JP Do you more often prefer the - final and unalterable statement / tentative and
preliminary statement
49 JP Are you more comfortable - after a decision / before a decision
50 EI Do you - speak easily and length with strangers / find little to say to strangers
51 SN Are you more likely to trust your - experience / hunch
52 SN Do you feel - more practical than ingenious / more ingenious than practical
53 TF Which person is more to be complimented - one of clear reason / strong feeling
54 TF Are you inclined more to be - fair minded / sysmpathetic
55 JP Is it preferable mostly to -make sure things are arranged / just let things happen
56 JP In relationships should most things to - renegotiable / random and circumstantial
57 EI When the phone rings do you - hasten to get to it first / hope someone else will answer
58 SN Do you prize more in yourself - a strong sense of reality / a vivid imagination
59 SN Are you drawn more to - fundamentals / overtones
60 TF Which seems the greater error - to be too passionate / to be too objective
61 JP Do you see yourself as basically - the structured and scheduled / the unstructured and
unscheduled
62 JP Are you a person that is more - routinized than whimsical / whimsical than routinized
63 EI Are you inclined to be - easy to approach / somewhat reserved
64 SN In writings do you prefer - the more literal / the more figurative
65 SN Is it harder for you to - identify with others / utilize others
66 TF Which do you wish more for yourself - clarity of reason / strength of compassion
67 TF Which is the greater fault - being indiscriminate / being critical
68 EI Do you prefer the - planned event / unplanned event
69 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 Carroll
Here 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, answer2
13 dim char1, char2, counter
14 Dim fs, findslash, findhyphen
15 dim rest
16 Dim thisfile, thisline
17 dim question
18 dim whichfile
19 whichfile=server.mappath("mb.txt")
20 Set fs = CreateObject("Scripting.FileSystemObject")
21 Set thisfile = fs.OpenTextFile(whichfile, 1, False)
22 counter=0
23 do while not thisfile.AtEndOfStream
24 counter=counter+1
25 thisline=thisfile.readline
26 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 loop
50 thisfile.Close
51 set fs=nothing
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 Carroll
Here 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 key
9 dim ecount, icount
10 dim scount, ncount
11 dim tcount, fcount
12 dim jcount, pcount
13 dim ucount
14 For Each Key in Request.Form
15 SELECT CASE request.form(key)
16 CASE "E"
17 ecount=ecount+1
18 CASE "I"
19 icount=icount+1
20 CASE "S"
21 scount=scount+1
22 CASE "N"
23 ncount=ncount+1
24 CASE "T"
25 tcount=tcount+1
26 CASE "F"
27 fcount=fcount+1
28 CASE "J"
29 jcount=jcount+1
30 CASE "P"
31 pcount=pcount+1
32 CASE "U"
33 ucount=ucount+1
34 END SELECT
35 Next
36 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>
http://www.learnASP.com/learn/cl.asp by Charles M. Carroll
Page 238
Content Linking Prev/Next
1 <%
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) Then
7 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 TOC
1 <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 Carroll
Here is a script that will turn the Content Linking elements into a pull-down list so people can arbitrarily jump from one topic to
another....
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)%>
13 >
14 <%
15 desc=TL.GetNthDescription("/learn/learn.txt",i)
16 if mid(desc,1,1)="*" then
17 desc=mid(desc,2)
18 else
19 desc="&nbsp;&nbsp;&nbsp;&nbsp;" & desc
20 end if
21 %>
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 Carroll
The 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.Files
11 For Each file in filecollection
12 response.write file.name & "<br>"
13 Next
14
15 set filesystem=nothing
16 set folder=nothing
17 set filecollection=nothing
18 %>
19 </body></html>
http://www.learnASP.com/learn/fileobjects2.asp by Charles M. Carroll
Page 242
FileObjects Part 2 by Charles Carroll
The 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 <%
5 dirtowalk="/learn/test"
6 Set fs = CreateObject("Scripting.FileSystemObject")
7 Set f = fs.GetFolder(server.mappath(dirtowalk))
8 Set fc = f.Files
9 For Each whatever in fc
10 response.write "<A HREF='"
11 response.write whatever.name
12 response.write "'>"
13 response.write whatever.name
14 response.write "</A><br>"
15 Next
16 %>
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.Files
9 For Each whatever in fc
10 response.write "<IMG SRC='/images/"
11 response.write whatever.name
12 response.write "'>"
13 response.write whatever.name & "<br>"
14 Next
15 %>
16 </body></html>
http://www.learnASP.com/learn/fileobjects3.asp by Charles M. Carroll
Page 243
FileObjects Part 3 by Steven Harper
Steven Harper@ScapaSMD.com, 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 then
15 Response.Write("Fixed")
16 end if
17 if f.DriveType=1 then
18 Response.Write("Removable")
19 end if
20 Response.Write("<BR>")
21 Response.Write(" File System : ")
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=nothing
34 set fs=nothing
35
36 %>
37 </body></html>
http://www.learnASP.com/learn/fileobjects4.asp by Charles M. Carroll
Page 244
FileObjects Part 4 by "Tim Foster" tfoster@pdxinc.com
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" then
9 additional = additional & "/"
10 folderspec = folderspec & additional
11 end if
12
13 Set fs = CreateObject("Scripting.FileSystemObject")
14 Set f = fs.GetFolder(server.mappath(folderspec))
15 Set fd = f.subfolders
16
17 response.write "<h2>FOLDERS</h2><blockquote>"
18 For Each whatever in fd
19 response.write "<A HREF='"
20 response.write request.servervariables("script_name")
21 response.write "?pathh=" & whatever.name
22 response.write "'>"
23 response.write whatever.name & " - " & whatever.datecreated
24 response.write "</A><br>"
25 Next
26
27 response.write "</blockquote><hr>"
28
29
30 response.write "<h2>FILES</h2><blockquote>"
31
32 Set fc = f.files
33
34 For Each whatever in fc
35 response.write "<A HREF='"
36 response.write folderspec & whatever.name
37 response.write "'>"
38 response.write whatever.name & " - " & whatever.datecreated
39 response.write "</A><br>"
40 Next
41
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ño
Daniel Gorroño Santurtzi danielgo@sarenet.es
Bizkaia - Euskal Herria
This ingenious piece of code demonstrates how to read a file using the file system object and extract bytes that contain the height
and 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 HW
3
4 Function AscAt(s, n)
5 AscAt = Asc(Mid(s, n, 1))
6 End Function
7
8 Function HexAt(s, n)
9 HexAt = Hex(AscAt(s, n))
10 End Function
11
12
13 Function isJPG(fichero)
14 If inStr(uCase(fichero), ".JPG") <> 0 Then
15 isJPG = true
16 Else
17 isJPG = false
18 End If
19 End Function
20
21
22 Function isPNG(fichero)
23 If inStr(uCase(fichero), ".PNG") <> 0 Then
24 isPNG = true
25 Else
26 isPNG = false
27 End If
28 End Function
29
30
31 Function isGIF(fichero)
32 If inStr(uCase(fichero), ".GIF") <> 0 Then
33 isGIF = true
34 Else
35 isGIF = false
36 End If
37 End Function
38
39
40 Function isBMP(fichero)
41 If inStr(uCase(fichero), ".BMP") <> 0 Then
42 isBMP = true
43 Else
44 isBMP = false
45 End If
46 End Function
47
48
49 Function isWMF(fichero)
50 If inStr(uCase(fichero), ".WMF") <> 0 Then
51 isWMF = true
52 Else
53 isWMF = false
54 End If
55 End Function
56
57
58 Function isWebImg(f)
59 If isGIF(f) Or isJPG(f) Or isPNG(f) Or isBMP(f) Or isWMF(f) Then
60 isWebImg = true
61 Else
62 isWebImg = true
63 End If
64 End Function
65
66
67 Function ReadImg(fichero)
68 If isGIF(fichero) Then
69 ReadImg = ReadGIF(fichero)
70 Else
71 If isJPG(fichero) Then
72 ReadImg = ReadJPG(fichero)
73 Else
74 If isPNG(fichero) Then
75 ReadImg = ReadPNG(fichero)
76 Else
77 If isBMP(fichero) Then
78 ReadImg = ReadPNG(fichero)
79 Else
80 If isWMF(fichero) Then
81 ReadImg = ReadWMF(fichero)
82 Else
83 ReadImg = Array(0,0)
84 End If
85 End If
86 End If
87 End If
88 End If
89 End Function
90
91
92 Function ReadJPG(fichero)
93 Dim fso, ts, s, HW, nbytes
94 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.Close
101 ReadJPG = HW
102 End Function
103
104
105 Function ReadPNG(fichero)
106 Dim fso, ts, s, HW, nbytes
107 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.Close
114 ReadPNG = HW
115 End Function
116
117
118 Function ReadGIF(fichero)
119 Dim fso, ts, s, HW, nbytes
120 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.Close
127 ReadGIF = HW
128 End Function
129
130
131 Function ReadWMF(fichero)
132 Dim fso, ts, s, HW, nbytes
133 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.Close
140 ReadWMF = HW
141 End Function
142
143
144 Function ReadBMP(fichero)
145 Dim fso, ts, s, HW, nbytes
146 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.Close
153 ReadBMP = HW
154 End Function
155
156
157 Function isDigit(c)
158 If inStr("0123456789", c) <> 0 Then
159 isDigit = true
160 Else
161 isDigit = false
162 End If
163 End Function
164
165
166 Function isHex(c)
167 If inStr("0123456789ABCDEFabcdef", c) <> 0 Then
168 isHex = true
169 Else
170 ishex = false
171 End If
172 End Function
173
174
175 Function HexToDec(cadhex)
176 Dim n, i, ch, decimal
177 decimal = 0
178 n = Len(cadhex)
179 For i=1 To n
180 ch = Mid(cadhex, i, 1)
181 If isHex(ch) Then
182 decimal = decimal * 16
183 If isDigit(c) Then
184 decimal = decimal + ch
185 Else
186 decimal = decimal + Asc(uCase(ch)) - Asc("A")
187 End If
188 Else
189 HexToDec = -1
190 End If
191 Next
192 HexToDec = decimal
193 End Function
194 %>
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
Simple VB Component by Charles Carroll
This is a very simple component written in Visual Basic. You can create it by
making a new "Active-X DLL" project G
under the Project; References menu, you must activate the "Microsoft Active Server Pages" library otherwise it won't
recognize the response object and won't compile.
G
The project name ==> charlescarroll
The class name ==> simplecomponent
G
Here is the Visual Basic source code for the component:
14 ' projectname =charlescarroll
15 ' classname =simplecomponent
16 Private ASPresponse As response
17 Public Sub onstartpage(sc As ScriptingContext)
18 Set ASPresponse = sc.response()
19 End Sub
20 Public Sub hello()
21 ASPresponse.Write "Hello"
22 End Sub
23 Public Sub goodbye()
24 ASPresponse.Write "Goodbye"
25 End Sub
26
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.hello
7 response.write "<br>"
8 parrot.goodbye
9 %>
10 </body></html>
http://www.learnASP.com/learn/buildregister.asp by Charles M. Carroll
Page 248
Registering A Component
The minimum recommended steps to register your C++/Visual Basic ASP component are:
Copy your component to where your System DLLs are
(probably \winnt\system32)
G
DO NOT leave the component in the original directory!!!! Make sure the .DLL/component is only in the system directory and
nowhere else. If regsvr32 is executed and it rgeisters a DLL that is not in the system directory your ASP pages may fail to
instantiate the component with the dreaded message "Active X DLL cannot create object".
G
from a command prompt
regsvr32 <your component name>
G
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)
G
DO NOT leave the component in the original directory!!!! Make sure the .DLL/component is only in the system directory and
nowhere else. If regsvr32 is executed and it rgeisters a DLL that is not in the system directory your ASP pages may fail to
instantiate the component with the dreaded message "Active X DLL cannot create object".
G
from a command prompt G
regsvr32 <old component name> -u
from a command prompt
regsvr32 <your component name>
G
start and stop web service to purge old component from memory G
http://www.learnASP.com/learn/buildvbado.asp by Charles M. Carroll
Page 249
VB Component: DBHelper from Web Page
Here 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.maketable
9 set mycomponent=nothing
10 %>
11 </body></html>
http://www.learnASP.com/learn/buildvbado2.asp by Charles M. Carroll
Page 250
VB Component: DBHelper by Charles Carroll
This page has the source code to the component. We have specified:
project name=charlescarroll
class name=dbhelperver001
Remember 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 G
Microsoft "Active Server Pages" object library G
14 ' projectname =charlescarroll
15 ' classname =dbhelperver001
16 Private ASPresponse As Response
17 Private ASPserver As Server
18 Private htmlstart, htmlend, rowstart, rowend
19 Private fieldstart, fieldend, namestart, nameend
20 Public Sub onstartpage(sc As ScriptingContext)
21 Set ASPresponse = sc.Response()
22 Set ASPserver = sc.Server()
23 End Sub
24 Public Property Let connect(temp As Variant)
25 myconnect = temp
26 End Property
27 Public Property Get connect() As Variant
28 connectme = myconnect
29 End Property
30 Public Property Get fieldnames() As Variant
31 fieldnames = myfieldnames
32 End Property
33
34 Public Property Let fieldnames(temp As Variant)
35 myfieldnames = temp
36 End Property
37
38 Public Property Let query(temp As Variant)
39 myquery = temp
40 End Property
41 Public Property Get query() As Variant
42 query = myquery
43 End Property
44
45 Public Property Let selectdefault(temp As Variant)
46 myselectdefault = temp
47 End Property
48 Public Property Get selectdefault() As Variant
49 selectdefault = myselectdefault
50 End Property
51 Public Property Let selectname(temp As Variant)
52 myselectname = temp
53 End Property
54 Public Property Get selectname() As Variant
55 selectname = myselectname
56 End Property
57
58 Public Sub query2list()
59 htmlstart = "<select name='" & selectname & "'>"
60 htmlend = "</select>"
61 rowstart = "<option>"
62 rowend = "</option>"
63 fieldstart = ""
64 fieldend = ""
65 Call query2html
66 End Sub
67
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 query2html
76 End Sub
77
78 Public Sub query2form()
79 htmlstart = ""
80 htmlend = ""
81 rowstart = ""
82 rowend = "<hr>"
83 fieldstart = ""
84 fieldend = "<br>"
85 fieldnames = True
86 namestart = ""
87 nameend = "&nbsp;=&nbsp;"
88 Call query2html
89 End Sub
90
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 = False
99 namestart = ""
100 nameend = "&nbsp;&nbsp;="
101 Call query2html
102 End Sub
103
104 Public Sub CustomDisplay(PARMhtmlstart, PARMhtmlend, PARMrowstart, PARMrowend, _
105 PARMfieldstart, PARMfieldend, PARMfieldnames, _
106 PARMnamestart, PARMnameend)
107 htmlstart = PARMhtmlstart
108 htmlend = PARMhtmlend
109 rowstart = PARMrowstart
110 rowend = PARMrowend
111 fieldstart = PARMfieldstart
112 fieldend = PARMfieldend
113 fieldnames = PARMfieldnames
114 namestart = PARMnamestart
115 nameend = PARMnameend
116 Call query2html
117 End Sub
118
119
120 Private Sub query2html()
121 On Error GoTo Badnews
122 attempt = "creating connection"
123 Set conntemp = ASPserver.CreateObject("adodb.connection")
124
125 attempt = "opening connection"
126 conntemp.Open myconnect
127
128 attempt = "making recordset"
129 Set rstemp = conntemp.Execute(myquery)
130 howmanyfields = rstemp.Fields.Count - 1
131 ReDim fsa(howmanyfields)
132 ReDim fea(howmanyfields)
133 For i = 0 To howmanyfields
134 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) = myfieldstart
139 fea(i) = myfieldend
140 Next
141 ASPresponse.Write htmlstart & vbCrLf
142 Counter = 0
143 Do While Not rstemp.EOF
144 ASPresponse.Write rowstart & vbCrLf
145 For i = 0 To howmanyfields
146 If fieldnames = True Then
147 ASPresponse.Write namestart & rstemp(i).Name & nameend
148 End If
149 ASPresponse.Write fsa(i) & rstemp(i) & fea(i) & vbCrLf
150 Next
151 ASPresponse.Write rowend & vbCrLf
152 Counter = Counter + 1
153 rstemp.MoveNext
154 Loop
155 rstemp.Close
156 Set rstemp = Nothing
157 conntemp.Close
158 Set conntemp = Nothing
159 ASPresponse.Write htmlend
160 Exit Sub
161 Badnews:
162 temp = "Error: " & attempt & "<br>"
163 temp = temp & Err.Description & "<br>"
164 temp = temp & Err.Number
165 ASPresponse.Write temp
166 End Sub
167
http://www.learnASP.com/learn/buildvbguidelines.asp by Charles M. Carroll
Page 251
VB ASP Component Building Guidelines by Charles Carroll
Component written in Visual Basic can be written using programming techniques that will cause them to be unstable in a web server
environment. Commands, Functions and Objects that are fine in most standalone or client/server VB programs may not be
appropriate 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 website
faces well.
G
Do not use traditional file access methods (Open #, Close #). Instead use the scripting FileSystemObject. G
http://www.learnASP.com/learn/buildvb.asp by Charles M. Carroll
Page 252
Generic VB Component Building Steps
Making a VB ASP component is easy:
Use File; New Project G
choose Active-X DLL G
You will now be in the editor and there will be a class open G
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.
G
The project name and class name are set with the (name) property. They are NOT in anyway connected to the
filename although you may make the filenames match the project and class names.
G
If you need to use one of the five built-in ASP objects (collectively called the scripting context) you can add a
special event to your class called OnStartPage. Anytime your component is created from an ASP script, ASP will
call 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:
G
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: G
Public Function onendpage(sc As Object)
End Function
http://www.learnASP.com/learn/buildvb2.asp by Charles M. Carroll
Page 253
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) G
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.
G
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 to
vbcomponents@ls.asplists.com
Related Links
I want to build my first VB component! @
http://www.learnasp.com/learn/buildvbsimple.asp
I get error overwriting DLL when updating component! @
http://www.learnasp.com/learn/FAQvbDLLoverwrite.asp
ASP Component Building Book @
Http://www.learnasp.com/books/components.asp
BulletProof VB Components by Charles Alexander @
http://www.microsoft.com/mind/0899/aspcomp/aspcomp.htm
SafeArrays. Accessing from VB by Shelley Powers @
http://www.yasd.com/devaspcomp/bonus/arrays.htm
Duwamish Books Sample @
http://msdn.microsoft.com/library/techart/dw1intro.htm
Fitch 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 Details
by Charles Carroll
special 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.0
by 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 their
session times out. This is the internal workings of the ASP execution environment. Don Box wrote this fascinating detail up a couple
of 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). G
If you place a object marked apartment into the SessionObject you have an object which can only live and be called from the G
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 on
the first available thread.
G
So imagine - you have a four processor machine running IIS/ASP - forty people come into your site, now each of those requests is
now tied to a specific thread, now two requests stop (are not currently making requests) - one more comes in and gets dispatched to
one of these two threads that are free, and one of the two that stopped comes back - but another Session is using that thread - there
are 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 works
correctly). Overall placing object marked Apartment into the SessionObject is a very bad thing. You are way better off instantiating on
every page. You are correct - that you cannot place an Apartment threaded object into the ApplicationObject - which is probably
what 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 Apartment
when 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 the
Multi-Threaded Apartment (MTA), the page which is executing in a Single-Threaded Apartment (STA) will not get direct access to the
object - but will talk to the object through what is called a proxy. The proxy looks just like the interface to the Page (has the same
methods etc), but when the page calls a method, the proxy forwards the method call (parameters, name etc) to a COM provided
channel. This channel calls what is refered to as a stub - which again looks just like the object - but lives in the same Apartment as
the Object (in this case the MTA). Then finally the object gets called and then returns throught the same method. This is 1000xs
slower that if the object lived in the same Apartment as the page (because of a thread switch - so switching threads you can see is
very 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 process
boundaries. 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 you
have to ask yourself - is tying my sessions down to a specific thread a major performance hit - and that really depends on how many
users 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 to
accomplish 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 page
level. 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 get
locked 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
Send Listserver Questions to
javacomponents@ls.asplists.com
Related Links
Robert Zembowicz White Papers @
http://www.robertz.com/Papers/
Frank Leahy's Tutorial @
http://www.hotwired.com/webmonkey/99/29/index2a.html?tw=programming
ASP Component Building w/Java Book @
Http://www.learnasp.com/books/components.asp
Java 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 Building
Building ASP components with C and/or C plus ATL is possible as well. The following links will explain the process and provide some
valuable information on debugging, etc:
Developing ASP Components with ATL by George Reilly:
http://www.microsoft.com/workshop/server/asp/comp.asp
This 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 to
low-levelcomponents@ls.asplists.com
Related Links
An Incredible High Quality Dcom List @
http://discuss.microsoft.com/archives/dcom.html
The 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.asp
ASP Component Building Book @
Http://www.learnasp.com/books/components.asp
Busy ATL Listserve @
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 Components
Microsoft 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 all
websites as well.
Without involving MTX, every request to create an instance of a component (ala server.createobject) and destroy the instance
of that component (ala set object=nothing) is sent directly to the component. IIS tends to cache objects so that when you
destroy an instance, IIS probably will not remove it from memory so that the next creation attempt will be instant since it is already in
memory. This is a direct violation of the DCOM rule that when there are zero instances of a component in memory, the component
is 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. G
MTX objects need not run as the "standard ASP User". Components registered with MTX can impersonate a specific user. G
The typical segments of code that would be unique to components managed by MTX would look like this:
Concept Code
Capture Context shared by all MTX
managed components
private mycntxt as ObjectContext
set mycntxt= GetObjectContext()
Tell MTX your component has completed
it's task sucessfully
mycntxt.SetComplete
Tell MTX your component has not
completed it's task sucessfully
mycntxt.SetAbort
Tell MTX to create an instance of your
component (don't use new, createobject,
or server.createobject)
mycntxt.CreateInstance("... objectname ..")
http://www.learnASP.com/learn/buildmtx2.asp by Charles M. Carroll
Page 259
MTX: Transaction Essentials
Transaction Server is based on established client server paradigms of reliable transaction processing. The concepts are consistent
regardless 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 Components
ASP pages that need to take advantages of transactions can without being forced to move the ASP script into a component. First
one 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.0
written by Roger Jennings, Steven D. Grey, Rick A. Lievano
published by Sams Publishing
No writeup yet.
Coming soon.
BUY http://bn.bfast.com/booklink/click?sourceid=10446528&ISBN=0672311305
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 MTX
Registering a Component with MTX requires that you specify how the component participates (or doesn't participate) in a
transaction. The possibilties are:
Requires a Transaction - run within a existing transaction, or if there is no existing transaction, MTX will create one. G
Requires a New Transaction - MTX starts a new transaction each time that component is activated. G
Support Transactions - run within a existing transaction, or if there is no existing transaction, MTX will run the component
without a transaction.
G
Does Not Support Transactions - This component will always run outside of existing transactions. G

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 Objects
www.serverobjects.com is a great place to get a variety of components. Here we will give you a simple script utilizing
genusa mail that e-mails me each time you run the page.
http://www.activeserverpages.com/learn/test/serverobjectsmail.asp
is 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
6 ' is not part of ASP per se,
7 ' but a third party utility from serverobjects.com
8 Set Mailer = Server.CreateObject("SMTPsvg.Mailer")
9 Mailer.RemoteHost = "relay.datareturn.com"
10
11 Mailer.FromName = "Some Student"
12 Mailer.FromAddress = "somestudent@activeserverpages.com"
13 Mailer.AddRecipient "Charles Carroll","cc@thebestweb.com"
14 Mailer.AddBCC "Charles Carroll","charles@activeserverpages.com"
15 Mailer.Subject = "ASPMail Tutorial"
16
17 Mailer.BodyText = "Hi. Just trying the mail example" & vbCrLf
18 Mailer.BodyText = "Line 2"
19 Mailer.BodyText = "Line 3"
20 If Mailer.SendMail then
21 Msg = "mail sent sucessfully!"
22 Else
23 Msg = "mail was not sent sucessfully"
24 End If
25 response.write Msg
26 %>
27 </body></html>
http://www.learnASP.com/learn/uploadsimple.asp by Charles M. Carroll
Page 266
Upload File -- Simple Example by David Wihl
utilizes 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 the
ActiveServerPages.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 simple
HTML 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 your
20 browser does not support File Upload. For Internet Explorer 3.02 users, a
21 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>
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" ... > H
<INPUT TYPE="FILE" NAME="f1"> H
G
To process the form:
First create an instance of the SA-FileUp component H
Second, invoke the .SaveAs method and specify a filename H
G
It is possible to retrieve other properties, such as total size of the upload. G
http://www.learnASP.com/learn/uploadmultipart.asp by Charles M. Carroll
Page 267
Upload File -- Multi-Part Form by David Wihl
utilizes 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 form
along 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, you
must change the Encoding Type to "multipart/form-data". The ASP Request.Form object does not understand data transmitted using
this encoding type.
SA-FileUp provides a Form object that provides identical functionality to the ASP Request.Form object, but can understand the
encoding type that is specific to file uploads.
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 additional
form 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 form
element.
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" ... > H
G
ASP's Request.Form object does not understand this encoding type. Instead use, SA-FileUp's Form object
which offers identical functionality.
G
To refer to elements on the form, use the name of the element on the form, i.e. upl.Form("descrip") G
http://www.learnASP.com/learn/uploadlimitsize.asp by Charles M. Carroll
Page 268
Upload Limit File Size by David Wihl
utilizes 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've
seen 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 firm
limit 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 then
stop. 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 the
default 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%> bytes
per 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, including
the 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.
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 total
including 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. G
Some properties are Read Only such as TotalBytes, and some are Read/Write such as MaxBytes. G
The amount of information transmitted by the browser is always larger than the file because of addition encoding
information and form elements.
G
That completes our tutorial for now. Please see our many code samples for other examples of SA-FileUp functionality,
including:
Uploading to a Database G
Secure download from the server to the browser G
Saving the upload in binary format G
Manipulating files on the web server. G
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 Wihl
utilizes 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 files
with 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"), neither
Netscape Navigator or Microsoft Internet Explorer support wildcarded names at this time. When they do, the current version of
SA-FileUp will be able to process wildcarded filenames. For now, it is necessary to have an additional input tag for every file you
want 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 %>
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 is
ambiguous. 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 called
the 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. G
For each uploaded file, SA-FileUp creates a new SAFile object to represent the uploaded file. G
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 Page
using 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>
4 <%
5 ' counters to watch
6 Dim arrFriendlyName,arrCounterPath
7 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, i
16 Set objQPerfCnt = CreateObject("Softwing.AspQPerfCounters")
17 bResult = objQPerfCnt.OpenQuery()
18 for i = 0 to UBound(arrCounterPath)
19 bResult = objQPerfCnt.AddCounter(arrCounterPath(i))
20 next
21 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>" & vbCrLf
26 next
27 %>
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 to
aspsoftwing@ls.asplists.com
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
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
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 G
www.thawte.com G
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 G
www.cybercash.com G
www.charge.com G
ww.swreg.com G
http://www.authorizenet.com/ G
http://www.securetrading.co.uk (may do just the UK) G
http://www.worldpay.com G
http://www.merchantservices.com G
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 G
IPCharge from www.gosoftinc.com G
IISCart from http://www.iiscart.com G
PCAuthX used with Tellan's PCAuthorize*Hub at http://www.active4.com/default.asp?PI=PCAUTHX G
www.mercantec.com G
http://www.storefront.net G
http://www1.viaweb.com/softartisans/saxcheck.html G
ActiveShopper at http://www.active4.com G
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 are
disposed of properly by adding:
rs.close
Set rs = Nothing
conn.close
Set 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
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 bgrade@aris.com
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 things
that 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. G
A "System" DSN (Data Source Name) should be configured on the machine where IIS resides. Or you may use a "DSNless" connection. A
connection of this type still requires you have the correct ODBC driver. See below.
G
Your DSN connection consists of an ODBC driver. Here are your most utilized choices: G
Microsoft ODBC Driver for Oracle 2.00.00.6325 (Microsoft supplied driver) G
Microsoft ODBC for Oracle 2.573.3513.00 (Microsoft supplied driver) G
Oracle ODBC Driver 7.x or 8.x (Oracle supplied driver) G
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.5
driver 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 at
this level while developing.
The TNSNAMES.ORA file needs to have been configured on the machine where IIS resides. This file is located in you
ORANT\NETWORK (or NET80)\ADMIN\ directory. An Example configuration is provided below:
G
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)
)
)
(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. G
The CONNECT_DATA string is made up of the Oracle SID. The SID is the name of the Oracle Instance. G
The PORT parameter is defaulted to 1521 and 1526. These are the default installations where the listener listens for requests from the
machine where Oracle is installed.
G
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 CONNECTIVITY
FOR ORACLE FROM ASP").
2.
Once selected, you will see the following screen minus everything below connect string. If you want the advanced configuration as shown
below 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 developer
has 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 take
when debugging are:
ALWAYS run your command through SQL*PLUS if your statement fails. This way you eliminate the fact that it could be a syntax
problem with Oracle.
G
If you have successfully tested the statement against the database outside of ASP, make sure your statement is syntactically correct with
ADO.
G
Make sure all concatenated statements have the correct spaces in them. G
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 slight
performance 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. G
Make sure that you DO NOT have spaces in your table names. G
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 the
following:
G
Verify the instance is running (i.e. Oracle is up). G
Make sure you have a TNSNAMES.ORA entry. See "WHAT DO I NEED FOR CONNECTIVITY FOR ORACLE FROM ASP". G
Check to see that the "TNS listener" service is running on the machine where Oracle resides. G
Check to make sure that you have the correct ODBC driver. See "WHAT DO I NEED FOR CONNECTIVITY FOR ORACLE FROM
ASP".
G
If you can connect via SQL*PLUS, check the following: G
Check to make sure that you have the correct ODBC driver. See "WHAT DO I NEED FOR CONNECTIVITY FOR ORACLE FROM
ASP".
G
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 Reference
written by David Sussman & Alex Homer
published by WROX
book @
http://www.activeserverpages.com/books/wroxadoref.asp
ASP and RDS Database Programming
written by Matt Brown, David Sussman, Peter DeBetta, John Pappa, Eric Wilson
published by WROX Press
book @
http://www.activeserverpages.com/books/wroxadords.asp
Oracle Programming with Visual Basic
written by Nick Snowdon, published by Sybex
According to "Bryan P.O'Neil" bponeil@sourceinformation.com:
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,
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 Procedure
by Surya Rao
HOW TO CALL A STORED PROCEDURE FROM AN ASP PAGE:
=================================================
Folks, contrary to popular belief there are many ways
to call stored procedures from an ASP page. I've tried
it with Oracle (the only REAL RDBMS ;-) and it works.
If this bit below, is useful, it can be archived for
future use by the LISTMASTER, with any changes.
Assume you have a procedure like this one below,
and that it has been already created on the
Oracle database. This procedure doesn't return
anything, 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 the
following 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 side
tasks and return you a recordset. You can only use this method if
your stored procedure doesn't return any OUTPUT values.
<% 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") = "...."
'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 <michiel@itcomposer.nl>
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 be
unloaded before it can be overwritten. The solution depends on the version of Internet Information Server (IIS) and if Microsoft
Transaction 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 Internet
Service Manager. After the webservice has stopped, the DLL can be overwritten. When the webservice restarts the new DLL is in
place and will be used for subsequent calls.
IIS version 4
If the DLL is not registered as an MTX package and the website(s) using the DLL do not run in a separate memory space (check
this with the Internet Service Manager), the same course of action as with IIS 3 is to be taken. Because of the complexity of the
webservice 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, stopping
those 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 Server
Explorer for that package, after which you can overwrite the DLL. If the DLL hasn’t been unloaded yet, you can force it to unload with
the Transaction Server Explorer by choosing Shutdown (right click on a package). After the new DLL is in place choose Refresh All
Components (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, you
have 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 G
http://www.activeserverpages.com/learn/buildregister.asp G
That should get you started.
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 Objects
Response Object
Send 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 Object
create COM objects, some conversion facilities and overall scripting control.
Request Object
Read submitted form data, cookies and server variables.
Session Object
allows you to attach data to a specific user browsing your site that is isolated and invisible to other users.
Application Object
Allows 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 Objects
Some objects will not be needed for all web pages. Those objects are included with ASP but are created explicity by the page when
needed 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 of
having 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 reads
and updates possible.
Dictionary object - provides an alternative to arrays that can be accessed/keyed by names instead of numbers and elements
can be added or removed in any sequence.
Misc. Objects - Content Linker, Permission Checker, Ad Rotator, Page Counter, etc.
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
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
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
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
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
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
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
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

You're Reading a Free Preview

Download
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->