by Charles Carroll

Transcription

by Charles Carroll
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
●
All the ASP programs used in this tutorial can be obtained @
http://www.learnasp.com/learn/download.asp
http://www.learnASP.com/learn/core.asp by Charles M. Carroll
Page 3
What is ASP? (whatis.asp) - Page 4
Simple ASP Page, Server Scripting (whatisexample.asp) - Page 5
MS Online Documentation (docs.asp) - Page 6
Response: Basics (res.asp) - Page 7
Response: Buffers, Redirect (res2.asp) - Page 8
Response: Redirection (res3.asp) - Page 9
Response: Quotes & Special Characters (res4.asp) - Page 10
Response: Encoding URLs, HTML (res5.asp) - Page 11
Include: Basics (inc.asp) - Page 12
Include: Dynamic FileName (includedynamic.asp) - Page 13
Include: Sample Exercise (booksample.asp) - Page 14
Format: Numbers #1 (formatnumbers.asp) - Page 15
Format: Numbers #2 (formatnumbers2.asp) - Page 16
Format: Dates #1 (formatdates.asp) - Page 17
Date/Time on ASP Pages by Tony Arguelles (datetime.asp) - Page 18
Loops: DO WHILE/UNTIL #1 (DoLoop.asp) - Page 19
Loops: Timeouts #2 (DoLoop2.asp) - Page 20
Loops: Intercepting Timeouts #3 (DoLoop3.asp) - Page 21
Server Variables: Popular Ones (server.asp) - Page 22
Server Variables: Domain/Host Name (server2.asp) - Page 23
Server Variables: Displaying All (serverall.asp) - Page 24
Random Content/Rotating Info (randomadvice.asp) - Page 25
http://www.learnASP.com/learn/whatis.asp by Charles M. Carroll
Page 4
(surprisingly even though ASP was shipped in Feb 1996, most explanations are still HUGE in books and use quite scary 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:
1. an abbreviation for Active Server Pages
2. FREE and already built into Win2000.
3. 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
4. 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.
5. 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.
More ASP facts:
1. 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.
2. 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.
3. 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)
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:
1. A user asks for a page say:
http://www.coyoteindustries.com/hi.asp
2. 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.
<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>
<html><head>
<TITLE>hi.asp</TITLE>
</head>
<body bgcolor="#FFFFFF">
Today is Tue 02:00pm and all is well<br>
Good Day!
</body></html>
Before 12pm the user at the browser receives
<<<<<<<
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
/iishelp
/iishelp/iis/htm/asp/intr1orp.htm
/IISSamples/ExAir/default.asp
/iishelp/iis/htm/asp/comp275c.htm
/iishelp/JScript/htm/JStoc.htm
/iishelp/VBScript/htm/VBStoc.htm
/iishelp/iis/htm/asp/iissiref.htm
/iishelp/iis/htm/asp/iiwaref.htm
click here
NT4 Option Pak
ASP objects reference
Ex Air
Installable Components for ASP
JScript Language Reference
VBScript Language Reference
Server Side Include Reference
ASP Quick reference card
ASP Tutorial*
IIS3 Docs
/iasdocs/aspdocs/roadmap.asp
/aspsamp/samples/samples.htm
/AdvWorks/default.asp
Roadmap / Official IIS3 Docs
IIS3 Code Samples
AdventureWorks
* 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
●
response.write alternate syntax <%= %> which allows ASP simply placed in HTML
●
response.end which effectively halts a script in it's tracks.
●
response.redirect which transfers control to another page
Here is a script utilizing response.write to send some information to the browser. It also uses dateadd, a built-in function
documented at http://help.activeserverpages.com/iishelp/VBScript/htm/vbs90.htm.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<html><head>
<title>response.asp</title>&
<body color="#FFFFFF">
<%
when=now()
tommorow=dateadd("d",1,when)
twoweekslater=dateadd("ww",2,when)
fourteenweekdayslater=dateadd("w",14,when)
monthlater=dateadd("m",1,when)
sixminuteslater=dateadd("n",6,when)
sixhourslater=dateadd("h",6,when)
fortysecslater=dateadd("s",40,when)
response.write
response.write
response.write
response.write
response.write
"Now <b>" & when & "</b><br>"
"tommorow <b>" & tommorow & "</b><br>"
"2 weeks from Now <b>" & twoweekslater & "</b><br>"
"fourteen working days from Now <b>" & fourteenweekdayslater & "</b><br>"
"1 month from Now <b>" & monthlater & "</b><br>"
20
21
22
23
24
%>
six minutes from now <b> <%=sixminuteslater%> </b><br>
six hours from now <b> <%=sixhourslater%> </b><br>
fourty seconds later <b> <%=fortysecslater%> </b><br>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<%response.buffer=false%>
<html><head>
<title>dailystuff.asp</title>
</head>
<body>
<%
whatweekday=Weekday(now())
select case whatweekday
case vbSunday
response.redirect "http://www.cnn.com"
case vbMonday
response.redirect "http://www.activeserverpages.com"
case vbTuesday
response.redirect "http://www.aspalliance.com"
case vbWednesday
response.redirect "http://www.aspconvention.com"
case vbThursday
response.redirect "http://www.aspmagazine.com"
case vbFriday
response.redirect "http://www.dilbert.com"
case vbSaturday
response.redirect "http://www.movielink.com"
end select
%>
</body>
</html>
Here is the fixed page that will NOT display the error:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<%response.buffer=true%>
<html><head>
<title>dailystuff.asp</title>
</head>
<body>
<%
whatweekday=Weekday(now())
select case whatweekday
case vbSunday
response.redirect "http://www.cnn.com"
case vbMonday
response.redirect "http://www.activeserverpages.com"
case vbTuesday
response.redirect "http://www.aspalliance.com"
case vbWednesday
response.redirect "http://www.aspconvention.com"
case vbThursday
response.redirect "http://www.aspmagazine.com"
case vbFriday
response.redirect "http://www.dilbert.com"
case vbSaturday
response.redirect "http://www.movielink.com"
end select
%>
</body>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
<html><head>
<TITLE>FormJump.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<form action="FormJumpRespond.asp" method="get">
<SELECT NAME="wheretogo">
<OPTION SELECTED VALUE="fun">Fun</OPTION>
<OPTION value="news">Daily News</OPTION>
<OPTION value="docs">ASP IIS3 Roadmap/Docs</OPTION>
<OPTION value="main">MainPage of ActiveServerPages.com</OPTION>
<OPTION value="sample">IIS 3 Sample ASP scripts</OPTION>
</SELECT>
<input type=submit value="Choose Destination">
</form>
</body></html>
The responder that reacts to this form is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<%response.buffer=true%>
<html><head>
<title>formjumprespond.asp</title>&
<body bgcolor="#FFFFFF">
<%
' My ASP program that redirects to URL
thisURL="http://www.activeserverpages.com"
where=Request.QueryString("Wheretogo")
Select Case where
case "main"
response.redirect thisURL & "/"
case "samples"
response.redirect thisURL & "/aspsamp/samples/samples.htm"
case "docs"
response.redirect thisURL & "/iasdocs/aspdocs/roadmap.asp"
case "news"
response.redirect "http://www.cnn.com"
case "fun"
response.redirect "http://www.dilbert.com"
End Select
response.write "All dressed up and I don't know where to go<br>"
response.write "I recommend --> " & "<br>"
response.write server.htmlencode(thisURL & "/learn/test/res2.asp?where=fun") & "<br>"
response.write "for a good laugh!" & "<P>"
%>
</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
2
3
4
5
6
<html><head>
<title>res4.asp</title>
</head><body bgcolor="#FFFFFF">
<%
' The response object can be used to write text a variety of ways
' 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html><head>
<title>res5.asp</title>
</head><body bgcolor="#FFFFFF">
<%
' The response object can be used to write text
' but sometimes some functions must be used to transform
' the text instead of sending as is to the browser
response.write
response.write
response.write
response.write
"<B>Hyperion</b> by <I>Dan Simmons</i> is a great novel"
"<p>"
server.htmlencode("<B>Hyperion</b> by <I>Dan Simmons</i> is a great novel")
"<p>"
response.write "Joe Smith & Hilda = a team"
response.write "<p>"
17
18
19
20
response.write server.URLencode("Joe Smith & Hilda = a team")
%>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<html><head>
<TITLE>includedynamic.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<%
whichfile="bookscifi.asp"
Call ReadDisplayFile(whichfile)
response.write "<hr>"
whichfile="bookhorror.asp"
Call ReadDisplayFile(whichfile)
response.write "<hr>"
whichfile="/learn/test/bookmarketing.asp"
Call ReadDisplayFile(whichfile)
response.write "<hr>"
%>
</body></html>
<%
SUB ReadDisplayFile(FileToRead)
whichfile=server.mappath(FileToRead)
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
END SUB
%>
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
●
sessions and application variables to track users accessing these pages
●
the content linker component
all come together in this example.
Here is the code for bookheader.asp:
1
Recommended Books for <%=session("fname")%> &nbsp; <%=session("lname")%><br><hr>
Here is the code for bookfooter.asp:
1
<hr><br>
2
Recommended Books has <%=application("howmany")%> people reading it now!
Here is the code for bookfuture.asp:
1
2
3
4
5
6
7
8
9
10
11
<html><head>
<title>bookfuture.asp</title>&
<!--#include file="bookheader.asp"-->
<body>
<h1>Future Books</h1>
<ul>
<li><b><i>Visions</b></i><br>Michio Kaku</li>
<li><b><i>Future Magic</b></i><br>Robert Forward</li>
</ul>
<!--#include file="bookfooter.asp"-->
</body></html>
Here is the code for bookhorror.asp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html><head>
<title>bookhorror.asp</title>&
<!--#include file="bookheader.asp"-->
<body>
<h1>Horror Books</h1>
<ul>
<li><b><i>Carrion Comfort</b></i><br>Dan Simmons</li>
<li><b><i>The Stand</b></i><br>Steven King</li>
<li><b><i>Children of Darkness</b></i><br>Dan Simmons</li>
<li><b><i>Thinner</b></i><br>Steven King</li>
<li><b>Fires of Eden<i></b></i><br>Dan Simmons</li>
</ul>
<!--#include file="bookfooter.asp"-->
</body></html>
Here is the code for bookmarketing.asp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html><head>
<title>bookMarketing.asp</title>&
<!--#include file="bookheader.asp"-->
<body>
<h1>Marketing Books</h1>
<ul>
<li><b><i>22 Immutable Laws of Branding</b></i><br>Reiss and Reiss</li>
<li><b><i>22 Immutable Laws of Marketing</b></i><br>Reiss and Trout</li>
<li><b><i>Marketing Warfare</b></i><br>Reiss and Trout</li>
<li><b><i>Horse Sense</b></i><br>Reiss and Trout</li>
<li><b><i>Words That Sell</b></i><br>by ??</li>
</ul>
<!--#include file="bookfooter.asp"-->
</body></html>
Here is the code for booknovels.asp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html><head>
<title>booknovels.asp</title>&
<!--#include file="bookheader.asp"-->
<body>
<h1>Recommended Novels</h1>
<ul>
<li><b><i>A Prayer for Owen Meaney</b></i><br>John Irving</li>
<li><b><i>Cider House Rules</b></i><br>John Irving</li>
<li><b><i>Heart of the Country</b></i><br>Greg Mathhews</li>
<li><b><i>All That Remains</b></i><br>Patricia Cornwell</li>
<li><b><i>Presumed Innocent</b></i><br>Scott Turrow</li>
<li><b><i>Time to Kill</b></i><br>John Grisham</li>
<li><b><i>Disclosure</b></i><br>Michael Chrichton</li>
<li><b><i>Mount Dragon</b></i><br>Lincoln and Childs</li>
</ul>
<!--#include file="bookfooter.asp"-->
17
</body></html>
Here is the code for bookscifi.asp:
1
2
3
4
5
6
7
8
9
10
11
12
13
<html><head>
<title>bookscifi.asp</title>&
<!--#include file="bookheader.asp"-->
<body>
<h1>Science Fiction Recommended Books</h1>
<ul>
<li><b><i>Ender's Game</b></i><br>Orson Scott Card</li>
<li><b><i>Hyperion</b></i><br>Dan Simmons</li>
<li><b><i>Childhood's End</b></i><br>Arthur Clarke</li>
<li><b><i>TommyKnockers</b></i><br>Steven King</li>
</ul>
<!--#include file="bookfooter.asp"-->
</body></html>
Here is the code for bookselfhelp.asp:
1
2
3
4
5
6
7
8
9
10
11
12
<html><head>
<title>bookselfhelp.asp</title>&
<!--#include file="bookheader.asp"-->
<body>
<h1>Self Help Books</h1>
<ul>
<li><b><i>Road Less Travelled</b></i><br>Scott Peck</li>
<li><b><i>The Seven Habits of Highly Effective People</b></i><br>Steven Covey</li>
<li><b><i>First Things First</b></i><br>Steven Covey</li>
</ul>
<!--#include file="bookfooter.asp"-->
</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
expression
iDigits
meaning
the variable holding the raw number
number of digits to right of decimal point
1 for leading zeros
bleadingDigit
0 for no leading zeros
1 for parenthesis around negative numbers
bParen
0 for no parenthesis around negative numbers
1 to display numbers as per regional settings in the Control Panel
bGroupDigits
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<html><head>
<TITLE>formatnumbers2.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<%
' My ASP formatting number sample
mynumber=123.4567
response.write "<hr>" & mynumber & "<br>"
response.write "formatnumber(mynumber,0)"
response.write formatnumber(mynumber,0) &
response.write "formatnumber(mynumber,2)"
response.write formatnumber(mynumber,2) &
response.write "formatnumber(mynumber,6)"
response.write formatnumber(mynumber,6) &
& "<br>"
"<hr>"
& "<br>"
"<hr>"
& "<br>"
"<hr>"
mynumber=.4567
response.write mynumber & "<br>"
'0 means means no leading zeroes
response.write "formatnumber(mynumber,2,0)" & "<br>"
response.write formatnumber(mynumber,2,0) & "<hr>"
'1 means means pad with leading zeroes
'response.write "formatnumber(mynumber,2,1)" & "<br>"
'response.write formatnumber(mynumber,2,1) & "<hr>"
'mynumber=-123.4567
'response.write mynumber & "<br>"
'0 means means no parentheses for negative numbers
'response.write "formatnumber(mynumber,2,0,0)" & "<br>"
'response.write formatnumber(mynumber,2,0,0) & "<hr>"
'1 means means yes parentheses for negative numbers
'response.write "formatnumber(mynumber,2,0,1)" & "<br>"
'response.write formatnumber(mynumber,2,0,1) & "<hr>"
%>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<html><head>
<title>formatdates.asp</title>
</head><body bgcolor="#FFFFFF"><html>
<%'My ASP program that formats dates
response.write "<hr>"
for counter=0 to 4
currentdate=now()
response.write "today is..." & "<br>"
response.write currentdate & "<P>"
select case counter
case 0
whichformat="vbgeneraldate"
case 1
whichformat="vblongdate"
case 2
whichformat="vbshortdate"
case 3
18
19
20
21
22
23
24
25
whichformat="vblongtime"
case 4
whichformat="vbshorttime"
end select
response.write "FormatDate(now()," & whichformat & ")="
response.write Formatdatetime(currentdate,counter) & "<P><HR>"
next%>
</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 [email protected]
Summary
Including the date and/or time on a web page can be a subtle yet valuable addition when designing a web site. The addition of 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
date
Argument Description
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
vbLongTime
3
vbShortTime
4
Passing this value returns a
date formatted just like the
default of 0 (mm/dd/yy).
Passing this value returns the
time in hh:mm:ss PM/AM
format.
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: [email protected]
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
●
WHILE, WEND
Either of these statements can be followed by UNTIL or WHILE.
DO UNTIL
.....code to be repeated...
LOOP
DO
.....code to be repeated...
LOOP UNTIL
http://www.learnASP.com/learn/DoLoop2.asp by Charles M. Carroll
Page 20
Do Loop and Timeouts by Charles 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
2
3
4
5
6
7
8
9
10
11
12
13
14
<%response.buffer=true%>
<TITLE>doloop1.asp</TITLE>
<body bgcolor="#FFFFFF">
<HTML>
<%
DO
counter=counter+1
response.write counter & "<br>"
response.flush
LOOP
%>
</BODY>
</HTML>
Here is an infinite loop that we explicitly set a timeout for:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<%
response.buffer=true
server.scripttimeout=20
%>
<TITLE>loop2.asp</TITLE>
<body bgcolor="#FFFFFF">
<HTML>
<%
DO
counter=counter+1
response.write counter & "<br>"
response.flush
LOOP
%>
</BODY>
16
17
18
</HTML>
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<%@ TRANSACTION=Required%>
<%
response.buffer=true
server.scripttimeout=20
%>
<HTML>
<TITLE>loop3.asp</TITLE>
<body bgcolor="#FFFFFF">
</BODY>
<%
DO
counter=counter+1
response.write counter & "<br>"
LOOP
response.flush
response.write "Script executed without incident"
%>
</HTML>
<%
Sub OnTransactionAbort()
response.clear
Response.Write "The Script Timed Out"
end sub
%>
loop4.asp succeeds and does not trigger the trap:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<%@ TRANSACTION=Required%>
<%
response.buffer=true
server.scripttimeout=40
%>
<HTML>
<TITLE>loop4.asp</TITLE>
<body bgcolor="#FFFFFF">
</BODY>
<%
DO UNTIL counter=400
counter=counter+1
response.write counter & "<br>"
LOOP
response.flush
response.write "Script Exexuted without incident!"
%>
</HTML>
<%
Sub OnTransactionAbort()
response.clear
Response.Write "The Script Timed Out"
23
24
end sub
%>
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")
ref=request.servervariables("http_referer")
br=request.servervariables("http_user_agent")
lan=request.servervariables("http_accept_language")
user=request.servervariables("logon_user")
name of script, i.e./learn/server.asp in this case
name of site page (unless they just typed the URL)
they clicked on to get here.
Identification string emitted by browser.
en for english. Basically indicates language the
browser is targetted to.
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
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
CASE "www.asptraining.com"
response.write "Welcome Training Customer!"
CASE "www.activeserverpages.com"
response.write "Welcome To Our Reference Site!"
CASE "www.learnasp.com"
response.write "Welcome To Our Tutorial!"
CASE "www.aspeuro.com"
response.write "Welcome To Our European Site!"
CASE "www.asplists.com","www.asplist.com"
response.write "Welcome To Our ASP listservers!"
CASE "www.aspconventions.com","www.aspconvention.com"
response.write "Welcome To Our ASP convention site!"
CASE ELSE
response.write "Welcome!"
END SELECT
%>
</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
3
4
5
6
<%
for each thing in request.servervariables
tempvalue=request.servervariables(thing)
response.write thing & "=" & tempvalue & "<br>"
next
%>
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
●
skipping the variables ALL_HTTP and ALL-RAW since they are just a "glob" of all the other vars
●
place blank variables at the end
●
display code to retrieve that variable so you can cut and paste into script
<html><head>
<TITLE>serverall.asp</TITLE>&
<body bgcolor="#FFFFFF">
<%
Response.Write("<P><B>Server Variables</b><br>")
BlankVars="<P><B>Blank Server Variables</b><br>" & vbcrlf
quote=chr(34)
For Each Key in Request.ServerVariables
If instr(Key,"_ALL")+instr(key,"ALL_")=0 then
tempvalue=trim(request.servervariables(Key))
If len(tempvalue)=0 then
BlankVars=BlankVars & Key & ", "
Else
response.write "request.servervariables(" & quote
response.write Key & quote & ") "
response.write " =<br><B>" & tempvalue & "</b><p>" & vbcrlf
End If
end if
Next
response.write mid(BlankVars,1,len(BlankVars)-2)
%>
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
●
INT function
●
SELECT CASE
The script randomadvice.asp shows different advice every time the pge is refreshed:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<html><head>
<TITLE>randomadvice.asp</TITLE>
</head>
<body bgcolor="#FFFFFF">
<%
' generate a random number 1-6
randomize
randomnum=int(rnd*6)+1
SELECT CASE randomnum
CASE 1,2,3%>
Plant your crops early this year<br>
No frost expected<br>
<%CASE 4%>
Never play cards<br>with a man named after a city<br>
<%CASE 5%>
You can never be too rich, too thin or backup too often<br>
<%CASE 6%>
A swallow keeps away the stork<br>
<%END SELECT%>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<html><head>
<TITLE>bc.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<% Set bc = Server.CreateObject("MSWC.BrowserType") %>
Browser Name: <%=bc.browser %><p>
Browser Version: <%=bc.version%><p>
<% if (bc.frames = TRUE) then %>
I noticed you do frames<p>
<% else %>
I noticed you are frame challenged<p>
<% end if %>
<% if (bc.tables = TRUE) then %>
I noticed you do tables<p>
<% else %>
I noticed you can't do tables<p>
<% end if %>
<% if (bc.BackgroundSounds = TRUE)then %>
I noticed you allow me to play music<p>
<% else %>
I noticed you aren't a music listener<p>
<% end if %>
<%
I
<%
I
<%
if (bc.vbscript = TRUE) then %>
noticed you are VBscript capable<p>
else %>
noticed you can't understand VB Script<p>
end if %>
<% if (bc.javascript = TRUE) then %>
I noticed you understand JScript<p>
<% else %>
I noticed you don't understand JScript<p>
<%
end if
set bc=nothing
%>
</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.
●
There are two ways to get a known, reliable browscap.ini. which are explained below.
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
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<%
set bh = server.createobject("cyScape.browserObj")
if (bh.browser = "WebTV") then
fontColor = "003366" 'a suitable alternate color for WebTV folks only
else
fontColor = "000066" 'your favorite shade of blue for all folks
end if
%>
<html>
<head>
<title></title>
</head>
<body>
<p>Welcome to my page. The <font color="<%=fontColor%>important" text</font>is highlighted
for your convenience. </p>
</font>
</body>
</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
3
4
5
6
7
8
9
10
<%
set bh = server.createobject("cyScape.browserObj")
if (bh.majorver >=4 ) and (bh.Browser ="IE" or bh.Browser ="Netscape") then
else
response.redirect("PageForNonIEorNNv4.asp")
end if
set bh = nothing
%>
<html><body> </body></html>
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
3
4
5
6
7
8
9
10
11
12
13
14
15
<%
set bh = server.createobject("cyScape.browserObj")
if bh.version>=4 and bh.browser="IE" then
%>
<a href='x.asp' title=' This is the alternate text. '>
<% else %>
</a>
<a href='x.asp'>
<%
end if
set bh = nothing
%>
<p>
Hover here</a>
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
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%
set bh = Server.CreateObject("cyScape.browserObj")
if bh.browser = "AOL" and bh.majorver <= 3 then
response.redirect "noaol3.asp"
end if
%>
<html>
<head>
<title>AOL check script</title>
</head>
<body>
<p>You are not using AOL v3 or lower</p>
</body>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html>
<head>
<title>Purchase</title>
</head>
<body>
<p>Payment info:<br>
<%
set bh = Server.CreateObject("cyScape.browserObj")
if bh.ActiveXControls then
response.write "... send MS Wallet control"
else
response.write "... send alternative code for collecting payment info"
end if
%></p>
<p>%&gt;</p>
</body>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html>
<head>
<title>Resolve IP</title>
</head>
<body>
<p>Hello user connected from <%
set bh = Server.CreateObject("cyScape.browserObj")
hostname = bh.ResolveIP
if hostname <> "" then
response.write hostname
else
response.write "Unknown"
end if
%> </p>
<p>%&gt;</p>
</body>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<html>
<head>
<title>Resolve IP</title>
</head>
<body>
<%
ipToLookup = "198.137.240.91"
%>
<p>The host name for <%=ipToLookup%> is <%
set bh = Server.CreateObject("cyScape.browserObj")
hostname = bh.ResolveIP(ipToLookup)
if hostname <> "" then
response.write hostname
else
response.write "Unknown"
end if
%> </p>
<p>%&gt;</p>
</body>
</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
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%
set bh = Server.CreateObject("cyScape.browserObj")
if not bh.frames then 'note: this could also be written as "if bh.frames = false"
response.redirect "noframes.asp"
end if
%>
<html>
<head>
<title></title>
</head>
<body>
<p>HTML code to load your frameset goes here </p>
</body>
</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
2
3
4
5
6
7
8
9
10
<TITLE>errordivide1.asp</TITLE>
<body bgcolor="#FFFFFF">
<%
' ASP program that works if numbers are legit
x=7
y=2
z=x/y
response.write z & "<br>"
%>
</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
2
3
4
5
6
7
8
9
10
<TITLE>errordivide2.asp</TITLE>
<body bgcolor="#FFFFFF">
<%
' ASP program that works if numbers are legit
x=7
y=2 ' if changed to 0 this will crash
z=x/y
response.write z & "<br>"
%>
</body></html>
Now we use the VBScript error trapping to present a message instead of a catastrophic script error.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<TITLE>errordivide3.asp</TITLE>
<body bgcolor="#FFFFFF">
<%
' ASP program that works if numbers are legit
on error resume next
x=7
y=0
z=x/y
response.write z & "<br>"
If
err.number=0 then
response.end
end if
pad="&nbsp;&nbsp;&nbsp;&nbsp;"
response.write "<b>VBScript Errors Occured!<br>"
response.write parm_msg & "</b><br>"
response.write pad & "Error Number= #<b>" & err.number & "</b><br>"
response.write pad & "Error Desc.= <b>" & err.description & "</b><br>"
response.write pad & "Help Context= <b>" & err.HelpContext & "</b><br>"
response.write pad & "Help File Path=<b>" & err.helpfile & "</b><br>"
response.write pad & "Error Source= <b>" & err.source & "</b><br><hr>"
%>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<TITLE>dbtablewitherrortrap.asp</TITLE>
<body bgcolor="#FFFFFF">
<!--#include file="lib_errors.asp"-->
<%
on error resume next
attempt="create connection object"
set conntemp=server.createobject("adodb.connection")
Call ErrorVBScriptReport(attempt)
attempt="opening DSN"
conntemp.open "DSN=Student;uid=student;pwd=magic"
Call ErrorVBScriptReport(attempt)
Call ErrorADOReport(attempt,conntemp)
attempt="select * from authors where AU_ID<16"
set rstemp=conntemp.execute(attempt)
Call ErrorVBScriptReport(attempt)
Call ErrorADOReport(attempt,conntemp)
If rstemp.eof then
response.write "No records matched your query" & "<P>"
response.write attempt
response.end
end if
attempt="counting fields"
howmanyfields=rstemp.fields.count -1
Call ErrorVBScriptReport(attempt)
Call ErrorADOReport(attempt,conntemp)
%>
<table border=1>
<tr>
<% 'Put Headings On The Table of Field Names
for i=0 to howmanyfields %>
<td><b><%=rstemp(i).name %></B></TD>
<% next %>
</tr>
<% ' Now lets grab all the records
do while not rstemp.eof %>
<tr>
<% for i = 0 to howmanyfields%>
<td valign=top><%=rstemp.fields(i)%></td>
<% next %>
</tr>
<%
rstemp.movenext
loop
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
%>
</table>
</BODY>
</HTML>
The error trapping library looks like this:
1
2
3
4
<%
SUB ErrorVBScriptReport(parm_msg)
If err.number=0 then
exit sub
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
end if
pad="&nbsp;&nbsp;&nbsp;&nbsp;"
response.write "<b>VBScript Errors Occured!<br>"
response.write parm_msg & "</b><br>"
response.write pad & "Error Number= #<b>" & err.number & "</b><br>"
response.write pad & "Error Desc.= <b>" & err.description & "</b><br>"
response.write pad & "Help Context= <b>" & err.HelpContext & "</b><br>"
response.write pad & "Help File Path=<b>" & err.helpfile & "</b><br>"
response.write pad & "Error Source= <b>" & err.source & "</b><br><hr>"
END SUB
SUB ErrorADOReport(parm_msg,parm_conn)
HowManyErrs=parm_conn.errors.count
IF HowManyErrs=0 then
exit sub
END IF
pad="&nbsp;&nbsp;&nbsp;&nbsp;"
response.write "<b>ADO Reports these Database Error(s) executing:<br>"
response.write SQLstmt & "</b><br>"
for counter= 0 to HowManyErrs-1
errornum=parm_conn.errors(counter).number
errordesc=parm_conn.errors(counter).description
response.write pad & "Error#=<b>" & errornum & "</b><br>"
response.write pad & "Error description=<b>"
response.write errordesc & "</b><p>"
next
END SUB
%>
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
2
3
4
5
6
7
8
9
10
11
12
13
<html><head>
<title>dbtroubleshoot.asp</title>&
<body>
<!--#include file="lib_errors.asp"-->
<%
on error resume next
Set Conn = Server.CreateObject("ADODB.Connection")
conn.open "DSN=student;uid=student;password=magic"
SQLstmt = "INSERT INTO junk (city,state,zip) VALUES ('Rockville','MD','20849')"
Set RS = Conn.Execute(SQLStmt)
Call ErrorVBScriptReport("Insert Statement")
14
15
16
17
18
19
20
21
Call ErrorADOReport(SQLstmt,conn)
rs.close
set rs=nothing
Conn.Close
set conn=nothing%>
</body></html>
Here is the include file that displays appropriate errors:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<%
SUB ErrorVBScriptReport(parm_msg)
If err.number=0 then
exit sub
end if
pad="&nbsp;&nbsp;&nbsp;&nbsp;"
response.write "<b>VBScript Errors Occured!<br>"
response.write parm_msg & "</b><br>"
response.write pad & "Error Number= #<b>" & err.number & "</b><br>"
response.write pad & "Error Desc.= <b>" & err.description & "</b><br>"
response.write pad & "Help Context= <b>" & err.HelpContext & "</b><br>"
response.write pad & "Help File Path=<b>" & err.helpfile & "</b><br>"
response.write pad & "Error Source= <b>" & err.source & "</b><br><hr>"
END SUB
SUB ErrorADOReport(parm_msg,parm_conn)
HowManyErrs=parm_conn.errors.count
IF HowManyErrs=0 then
exit sub
END IF
pad="&nbsp;&nbsp;&nbsp;&nbsp;"
response.write "<b>ADO Reports these Database Error(s) executing:<br>"
response.write SQLstmt & "</b><br>"
for counter= 0 to HowManyErrs-1
errornum=parm_conn.errors(counter).number
errordesc=parm_conn.errors(counter).description
response.write pad & "Error#=<b>" & errornum & "</b><br>"
response.write pad & "Error description=<b>"
response.write errordesc & "</b><p>"
next
END SUB
%>
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<html><head>
<title>dbtroubleshoot.asp</title>&
<body>
<%
on error resume next
Set Conn = Server.CreateObject("ADODB.Connection")
my_DSN="DSN=student;uid=student;password=magic2"
conn.open my_DSN
Call CheckOpen
Conn.Close
set conn=nothing
SUB CheckOpen
If err.number>0 then%>
<b>VBScript Errors Occured:</b><br>
Error Number=<%=err.number%><br>
Error Descr.=<%=err.description%><br>
Help Context=<%=err.helpcontext%><br>
Help Path=<%=err.helppath%><br>
Native Error=<%=err.nativeerror%><br>
Source=<%=err.source%><br>
SQLState=<%=err.sqlstate%><P>
<%else%>
No VBScript problems occured!<p>
<%end if
IF conn.errors.count> 0 then%>
<b>ADO Reports these Database Error(s):</b><br>
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<%
maxerrors=conn.errors.count-1
for counter= 0 to maxerrors
DBErrorNum=conn.errors(counter).number
DBErrorDesc=conn.errors(counter).description
SELECT CASE DBErrorNum
CASE -2147467259
response.write "Problem => <b>Bad DSN</b><br>"
response.write "DSN => <b>" & my_DSN & "</b><br>"
CASE -2147217843
response.write "Problem => <b>Bad Login Info</b><br>"
response.write "DSN => <b>" & my_DSN & "</b><br>"
exit sub
CASE ELSE%>
Error # = <b><%=DBErrorNum%></b><br>
Error description = <b><%=DBerrorDesc%></b><p>
<%END SELECT
next
else%>
Everything Went Fine
<%
end if
END SUB%>
</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
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<body bgcolor="#FFFFFF">
<%
dim successSTR, FailSTR, checkSTR
whichfile=server.mappath("component.ini")
Set fs = CreateObject("Scripting.FileSystemObject")
Set thisfile = fs.OpenTextFile(whichfile, 1, False)
counter=0
do
UNTIL thisfile.AtEndOfStream
counter=counter+1
thisline=thisfile.readline
attempt=trim(thisline)
pad="&nbsp;&nbsp;&nbsp;&nbsp;"
DO WHILE attempt=""
thisline=thisfile.readline
attempt=trim(thisline)
LOOP
If mid(thisline,1,1)="[" then
' ignore
CheckSTR=CheckSTR & thisline & " "
lastcategory=category
category=lcase(thisline)
oldcategory=mid(category,1,Len(category)-1)
category=replace(category,"www.","<a href='http://www.")
IF instr(category,"href")>0 then
category=mid(category,2)
category=category & "'>" & oldcategory & "]</a>"
END IF
group= "<b>" & category & " component group</b><br>"
successcount=0
failcount=0
thisline=thisfile.readline
attempt=thisline
end if
on error resume next
set tempobject=server.createobject(attempt)
eol="<br>" & vbcrlf
whicherr=err.number
If whicherr=0 then
if successcount=0 then
successSTR=successSTR & group
end if
vleft="&nbsp;(ver="
vright=")&nbsp;"
SELECT CASE lcase(attempt)
CASE "adodb.connection"
version= vleft & tempobject.version & vright
CASE ELSE
version=""
END SELECT
successSTR= successSTR & pad & "<b>" & attempt & version & "</b> successfull!" & eol
successcount=successcount+1
else
if failcount=0 then
FailSTR=FailSTR & group
end if
IF whicherr=-2147221005 THEN
msg = " is not registered!"
ELSE
msg = " failed. Error #" & whicherr
END IF
FailSTR= failSTR & pad & "<b>" & attempt & "</b>" & msg & eol
failcount=failcount+1
end if
set tempobject=nothing
69
70
71
72
73
74
75
76
77
78
loop
thisfile.Close
set thisfile=nothing
set fs=nothing
response.write "Checked: " & checkSTR & "<hr>"
response.write successSTR & "<hr>"
response.write failSTR
%>
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
[standard]
mswc.browsertype
mswc.nextlink
scripting.dictionary
scripting.filesystemobject
[ado]
adodb.recordset
adodb.connection
adodb.command
[cdo]
CDONTS.NewMail
[cyscape]
cyScape.browserObj
[indexserver]
ixsso.Query
ixsso.Util
[Lyris]
Lyris.LCP
[http://msdn.microsoft.com/scripting]
Wscript.Shell
[msfreebies]
iissample.asp2htm
iissample.contentrotator
iissample.registry
iissample.summaryinfos
iissample.tracer
mswc.adrotator
mswc.counters
mswc.myinfo
MSWC.PageCounter
MSWC.PermissionChecker
mswc.tools
mswc.loadbalance
[msXML]
microsoft.XMLHTTP
microsoft.XMLDOM
[www.aspdb.com]
ASPdb.Free
ASPdb.View
ASPdb.Pro
ASPdb.EP
[www.serverobjects.com]
ASPChart.Chart
AspConv.Expert
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
AspDNS.Lookup
AspFile.FileObj
AspHTTP.Conn
AspImage.Image
AspInet.FTP
AspMX.Lookup
AspNNTP.Conn
AspPager.Pager
SMTPsvg.Mailer
[www.softartisans.com]
SoftArtisans.FileUp
SoftArtisans.SACheck
SoftArtisans.SASessionPro
SoftArtisans.FileManager
EZsite.Calender
EZsite.CalendarManager
EZsite.WebNotes
[www.active4.com]
ActiveLaunch.Control
ActiveSAR.SearchAndReplace
ActiveShopper.Cart
ActiveShopper.BasketItem
FileTouch.Control
PCAuthX.Authorizer
Prt2Disk.Control
SemClient.Control
SPrinterPro.Object
TimeSpan.Control
WWWPrint.Client
[Zaks Software]
ZaksPop3.Server
JavaPop3.Mailer
[www.persits.com]
Persits.MailSender
[www.oceantek.com]
ASPL.Login
[www.able-consulting.com]
ACI.WhoIs
[www.softwing.com]
Softwing.EventLogReader
Softwing.OdbcRegTool
w3info.w3info.1
InetCtls.Inet.1
Softwing.AspQPerfCounters
SQLOLE.SQLServer
SOFTWING.ASPEventlog
SOFTWING.ASPtear
SOFTWING.EDConverter
SOFTWING.EventLogReader
SOFTWING.FileCache.1
SOFTWING.OdbcRegTool
SOFTWING.LocaleFormatter
SOFTWING.Profiler
[www.dougdean.com]
EZsite.EZuploadLite
[www.algonet.se/~jekman]
lightcom.xBrowser
lightcom.xContent
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
lightcom.xPop3
lightcom.xSMTP
lightcom.xTree
lightcom.xBrowser
JESoftware.xContent
JESoftware.xPop3
JESoftware.xSMTP
JESoftware.xTree
[tech.dimac.net]
Socket.TCP
[www.de-info.com]
checkemail.maccheckemail
[www.pstruh.cz]
TCPIP.Trace
TCPIP.DNS
[www.dana-net.com/products/aspcomponents/magicregistry]
MagicRegistry.Tricks
http://www.learnASP.com/learn/connectioninfo.asp by Charles M. Carroll
Page 49
Connection Info by Christophe Wille
[email protected] http://www.softwing.com/iisdev
If you want to know what drivers and other vital details are being used for a DSN, here is some code to the rescue.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html><head>
<title>connectioninfo.asp by Christophe Wille http://www.softwing.com</title>
</head>
<!--#include file="lib_connectioninfo.asp"-->
<body>
<%
response.write "<hr>SQL Server Connection"
Call DSNinfo("DSN=student;uid=student;pwd=magic")
response.write "<hr>Access Connection Connection"
theDSN="DRIVER={Microsoft Access Driver (*.mdb)};DBQ="
theDSN=theDSN & server.mappath("/learn/test/biblio.mdb")
Call DSNInfo(theDSN)
%>
</body>
</html>
The Include file looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<%
SUB DSNInfo(strDSN)
Set cnn1 = Server.CreateObject("ADODB.Connection")
Set rsQuery = Server.CreateObject("ADODB.RecordSet")
cnn1.open strDSN
response.write
response.write
response.write
response.write
response.write
response.write
response.write
response.write
response.write
"ADO Version: " & cnn1.Version
"<BR>" & vbcrlf
strVersionInfo & "DBMS Name: " & cnn1.Properties("DBMS Name")
"<BR>" & vbcrlf
"DBMS Version: " & cnn1.Properties("DBMS Version")
"<BR>" & vbcrlf
"OLE DB Version: " & cnn1.Properties("OLE DB Version")
"<BR>" & vbcrlf
"Provider Name: " & cnn1.Properties("Provider Name")
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
response.write
response.write
response.write
response.write
response.write
"<BR>" & vbcrlf
"Provider Version: " & cnn1.Properties("Provider Version")
"<BR>" & vbcrlf
"Provider Friendly Name: " & cnn1.Properties("Provider Friendly Name")
"<BR>" & vbcrlf
If
0 = Instr(LCase(cnn1.Properties("Provider Name")),"oledb") then
' ### no OLE DB Provider used, therefore :
response.write "Driver Name: " & cnn1.Properties("Driver Name")
response.write "<BR>" & vbcrlf
response.write "Driver Version: " & cnn1.Properties("Driver Version")
response.write "<BR>" & vbcrlf
response.write "Driver ODBC Version: " & cnn1.Properties("Driver ODBC Version")
response.write "<BR><BR>"
end if
Set rsQuery = nothing
Set cnn1 = nothing
END SUB
%>
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
●
without placing your code on the World-Wide-Web or a server until it is tested off-line and totally debugged.
The address of your personal web server is:
http://127.0.0.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).
●
The form must pass the variables onto a .asp file to process the form.
●
An excellent form tutorial can be found at:
http://www.mountaindragon.com/html/forms.htm
Form with GET
●
<form action="x.asp" name="whatever" method=get>
....
<input type=submit>
<input type=reset>
</form>
there is a limit on the number of characters (approximately 4,000 but varies depending on server and browsers involved.
●
The form will show it's parameter in the browser address window, for example:
testform.asp?state=md&city=Germantown
would be the URL in the browser, if the state and city field were populated.
●
An ASP script picks up a form field with:
<%whatever=request.querystring("whichfield")%>
Form with POST
●
<form action="x.asp" name="whatever" method="post">
....
<input type=submit>
<input type=reset>
</form>
It supports many more characters than get (megabytes of data in case of file uploads)
●
The form will not show it's parameter in the browser address window, for example:
http://whatever.com/testform.asp
would be the only URL in the browser, regardless of how many fields and how much data is passed.
●
An ASP script picks up the form field with:
<%whatever=request.form("whichfield")%>
Tips:
Tip #1: If using response.redirect to simulate a GET don't forget to encode:
/learn/encode.asp
Tip #2: a text link to post above form would look like this:
<a href="javascript:submitform(document.forms['whatever'])">
whatever</a>
thanks to Remko van der Vossen <[email protected]> for this tip I looked high and low for.
http://www.learnASP.com/learn/formtextbox.asp by Charles M. Carroll
Page 53
Forms - Text Box
(by John Kauffman & Charles Carroll)
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.
This is not a limit to the number of characters that can
<INPUT NAME="ZipCode" SIZE="10">
be entered. Do not use size as a validation technique
to limit verbose users.
This controls the maximum number of characters that
<INPUT NAME="State" MaxLength="2">
can be entered.
The name of Bertrand will appear when the page is
<INPUT NAME="NameLast" VALUE="Bertrand">
opened and will re-appear if the form is reset.
<INPUT NAME="NameLast">
1
2
3
4
5
6
7
8
9
10
11
<html><head>
<title>FormTextBox.asp</title>
</head><body bgcolor="#FFFFFF">
<Form action = "FormTextBoxRespond.asp" method="get">
Fill Out This Form For Us:<p>
Last Name -> <Input NAME="NameLast" size ="10"><br>
Country -> <Input NAME="Country" value="USA" size=10><br>
State -> <Input NAME="State" MaxLength="2" size=2><br>
<Input type="submit" value="Give me your data!">
<hr></form>
</body></html>
1
2
3
4
5
6
7
8
9
10
11
12
<html><head>
<title>FormTextBoxRespond.asp</title>
</head><body bgcolor="#FFFFFF">
<%
lname=request.querystring("namelast")
cty=request.querystring("country")
st=request.querystring("state")
response.write lname & "<br>"
response.write cty & "<br>"
response.write st & "<br>"%>
</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
2
<html><head>
<TITLE>formTextArea.asp</TITLE>
3
4
5
6
7
8
9
10
11
12
</head><body bgcolor="#FFFFFF">
<form action="FormTextAreaRespond.asp" method="post">
<p>TextArea Example</p>
<p>Please type your special shipping comments:</p>
<TEXTAREA NAME="shippingComments" ROWS=5 COLS=50>
shipping comments go here
</textarea>
<p><input type=submit value="send in comments!">
</form>
</body></html>
The responder to the form will look like this:
1
2
3
4
5
6
7
8
9
<html><head>
<TITLE>formTextArearespond.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<%
comm=request.form("shippingcomments")
response.write comm
%>
<hr>
</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
2
3
4
5
6
7
8
9
10
11
12
13
<html><head>
<TITLE>FormCheckBox.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<form action="FormCheckBoxRespond.asp" method="post">
<p>CheckBox Form Example</p>
<p>How do you want your order confirmed?</p>
<input TYPE="checkbox" NAME="USMail">confirmation sent by first class US Postal Service<br>
<input TYPE="checkbox" NAME="UPS">confirmation sent by UPS overnight letter service<br>
<input TYPE="checkbox" NAME="EMail" CHECKED>confirmation sent by EMail<br>
<input TYPE="checkbox" NAME="Fax">confirmation sent by Fax<br>
<input TYPE="checkbox" NAME="Tel" CHECKED>confirmation made by telephone call<br><br>
<input type="submit"><input type="reset">
</form><hr></body></html>
The responder looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html><head>
<TITLE>formCheckBoxRespond.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<%
If
request.form("USMail")="on" then
response.write "<br>We will confirm
end if
If
request.form("UPS")="on" then
response.write "<br>We will confirm
end if
If
request.form("EMail")="on" then
response.write "<br>We will confirm
end if
If
request.form("fax")="on" then
response.write "<br>We will confirm
by US Mail"
by UPS"
by EMail"
by fax"
16
17
18
19
20
21
end if
If
request.form("tel")="on" then
response.write "<br>We will confirm by tel"
end if%>
</body>
</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
2
3
4
5
6
7
8
9
10
11
12
<html><head>
<TITLE>formRadio.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<form action="FormRadiorespond.asp" method="post">
<p><b>Radio Buttons </b> example</p>
<p>Which Regional Office will you be visiting?</p>
<input TYPE="radio" NAME="City" VALUE="NY">New York City
<input TYPE="radio" NAME="City" VALUE="LA">Los Angeles
<input TYPE="radio" NAME="City" VALUE="SV" CHECKED>Savannah
<br><input type="submit" value="choose a city">
</form>
</body></html>
The responder looks like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html><head>
<TITLE>formradiorespond.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<%myCity = request.form("City")
Select Case ucase(MyCity)
case "NY"
response.write "New York meeting is on Jan 3"
case "LA"
response.write "LA meeting meeting is on Jan 15"
case "SV"
response.write "Savannah meeting is on Jan 20"
End Select%>
</body>
</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
2
3
<html><head>
<TITLE>FormListBox.asp</TITLE>
</head><body bgcolor="#FFFFFF">
4
5
6
7
8
9
10
11
12
13
<form action="FormListBoxRespond.asp" method="post">
<SELECT NAME="state">
<OPTION SELECTED VALUE="md">Maryland</OPTION>
<OPTION value="dc">District of Columbia</OPTION>
<OPTION value="va">Virginia</OPTION>
<OPTION value="whoknows">Somewhere Else!</OPTION>
</SELECT>
<input type=submit value="Choose State">
</form>
</body></html>
The responder looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html><head>
<TITLE>formlistboxrespond.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<%mystate = request.form("state")
Select Case ucase(mystate)
case "DC"
response.write "DC meeting on 15th"
case "MD"
response.write "MD meeting on 20th"
case else
response.write "No meetings for you to attend!"
End Select%>
</body>
</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
2
3
4
5
6
7
8
9
<html><head>
<TITLE>case.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<form action="caserespond.asp" method="get">
Your First Name<INPUT NAME="FirstName" MaxLength=20><p>
Your Last Name<INPUT NAME="LastName" MaxLength=20><p>
<INPUT TYPE=submit><p><INPUT TYPE=reset>
</form>
</body></html>
Here is the select case that will determine what the form input means.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html><head>
<TITLE>caserespond.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<%
fname=request.querystring("Firstname")
lname=request.querystring("Lastname")
%>
Nice to Meet You <%=fname%> <%=lname%><p>
<%If fname="" then%>
Sorry we are not on a first name basis...<p>
<%end if
select case lcase(lname)
case "washington","adams"
response.write "The first president has same last name<p>"
case "jefferson"
response.write "The third president has same last name<p>"
17
18
19
20
case "lincoln"
response.write "The sixteenth president has same last name<p>"
end select%>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html><head>
<TITLE>case2.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<form action="case2respond.asp" method="get">
Your First Name<INPUT NAME="FirstName" MaxLength=20><p>
Your Last Name<INPUT NAME="LastName" MaxLength=20><p>
Your Title
<INPUT TYPE="Radio" name="Title" VALUE="employee">Entry Level
<INPUT TYPE="Radio" name="Title" VALUE="temp" CHECKED>Temporary Employee
<INPUT TYPE="Radio" name="Title" VALUE="manager">Management Candidate
<INPUT TYPE="Radio" name="Title" VALUE="executive">Executive
<INPUT TYPE="Radio" name="Title" VALUE="vice-prez">The Vice President of...
<INPUT TYPE="Radio" name="Title" VALUE="CEO">The Boss<p>
<INPUT TYPE=submit><p>
</form>
</body></html>
Here is the select case that will determine what the form input means.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<html><head>
<TITLE>case2respond.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<%
fname=request.querystring("Firstname")
lname=request.querystring("Lastname")
title=request.querystring("title")
response.write "Nice to Hire You " & fname & " " & lname & "<p>"
Select Case lcase(Title)
case "employee","temp"
response.write("The washroom is in the hall")
case "manager","executive"
response.write("Here is your key to the Executive washroom")
case "ceo", "vice-prez"
response.write("The maid will attend to your private washroom")
End Select%>
</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
3
4
5
6
7
8
<TITLE>if.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<form action="ifrespond.asp" method=get>
Your First Name<INPUT NAME="FirstName" MaxLength=20><p>
Your Last Name<INPUT NAME="LastName" MaxLength=20><p>
<INPUT TYPE=submit><p><INPUT TYPE=reset>
</form></body></html>
Now we make a asp file that examines their first name and last name after the form is submitted.
1
2
3
4
5
6
7
8
9
10
11
<html><head>
<TITLE>ifrespond.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<%fname=request.querystring("Firstname")
lname=request.querystring("Lastname")
If fname="George" and lname="Washington" then%>
Hi.<p>You must be the first president!
<%else%>
Hi!<p>Nice to Meet You
<%end if%>
</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
2
3
4
5
6
7
8
<html><head>
<TITLE>if2.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<form action="if2respond.asp" method=get>
Your First Name<INPUT NAME="FirstName" MaxLength=20><p>
Your Last Name<INPUT NAME="LastName" MaxLength=20><p>
<INPUT TYPE=submit><p><INPUT TYPE=reset>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<html><head>
<TITLE>if2respond.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<%
fname=lcase(request.querystring("Firstname"))
lname=lcase(request.querystring("Lastname"))
If fname="george" and lname="washington" then%>
Hi.<p>You must be the first president!
<%elseIf fname="ronald" and lname="reagan" then%>
Hi.<p>You must be the actor president!
<%elseIf fname="jimmy" and lname="carter" then%>
Hi.<p>You must be the peanut farmer president!
<%elseIf fname="naoko" or fname="charles" then%>
Hi.<p>Your name reminds me of someone<p>
but I am not sure who!
<%else%>
Hi!<p>Nice to Meet You
<%end if%>
</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
2
3
4
5
6
7
8
9
<html><head>
<TITLE>if3.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<form action="if3respond.asp" method=get>
Your First Name<INPUT NAME="FirstName" MaxLength=20><p>
Your Last Name<INPUT NAME="LastName" MaxLength=20><p>
Your Salary <INPUT NAME="Salary" MaxLength=7><p>
<INPUT TYPE=submit><p><INPUT TYPE=reset>
</form></body></html>
This example shows how IF can deal with ranges and use various other boolean operators.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<html><head>
<TITLE>if3respond.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<%
fname=request.querystring("Firstname")
lname=request.querystring("Lastname")
salary=request.querystring("Salary")
response.write "Nice to Meet You " & fname & " " & lname & "<p>"
if salary>100000 then%>
Would you like to loan me some money?<p>
<%
sstaxMarginal=15
else
SSTaxMarginal=15
end if
If salary>6700 and salary<30000 then
SSTaxMarginal=0%>
Would you like me to loan you some money?<p>
<%end if
If salary<6700 then
SSTaxMarginal=0
end if
%>
By the way your marginal tax rate is <%=sstaxmarginal%>
</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
2
3
4
5
6
<html><head>
<TITLE>if4.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<form action="if4respond.asp" method=get>
Your First Name<INPUT NAME="FirstName" MaxLength=20><p>
Your Last Name<INPUT NAME="LastName" MaxLength=20><p>
7
8
9
Your Salary <INPUT NAME="Salary" MaxLength=7><p>
<INPUT TYPE=submit><p><INPUT TYPE=reset>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<html><head>
<TITLE>if4respond.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<%fname=request.querystring("Firstname")
lname=request.querystring("Lastname")
salary=request.querystring("Salary")
response.write "Nice to Meet You " & fname & " " & lname & "<p>"
if salary>80000 then
salarygrade=4
end if
if salary <=80000 then
salarygrade=3
end if
If salary <=60000 then
salarygrade=2
end if
if salary <=40000 then
salarygrade=1
end if
response.write ("Your Salary is $" & salary)
response.write (", your Grade is " & salarygrade & ".<p>")
%>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<html><head>
<TITLE>monthlyForm.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<form action="monthlyFormRespond.asp" method="post">
<p>CheckBox Form Example</p>
<p><b>Check Off The Days You Worked</b></p>
<%
my_month=request.querystring("whichmonth")
'
response.write my_month & "<br>"
if my_month="" then
my_date=now()
else
my_month=month("1/" & (request.querystring("whichmonth")) & "/1999")
my_date=dateserial(year(now()),my_month,1)
end if
'response.write my_date & "<br>"
If my_month=12 then
my_day=1
my_month=1
my_year=my_year+1
else
my_day=1
24
25
26
27
28
29
30
31
32
33
34
35
36
my_month=month(my_date)+1
my_year=year(my_date)
end if
for counter=1 to lastdayofmonth%>
<input TYPE="checkbox" NAME="workingday<%=counter%>">day <%=counter%> Worked?<br>
<%next%>
<input type="submit" value="Submit Days Worked">
</form>
</body></html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html><head>
<TITLE>monthlyFormRespond.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<%
daysworked=0
for each whatever in request.form
thisvalue=request.form(whatever)
If thisvalue="on" then
daysworked=daysworked+1
end if
next
response.write "Thanks for working <b>" & daysworked & "</b> days"
%>
</body></html>
lastdayofmonth=day(DateSerial(Year(my_Date), my_Month,0))
'response.write lastdayofmonth & "<br>"
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
●
Not all browsers support mailto (Netscape does, several IE versions before 4.0 do not, many browsers do not)
●
The user may have a faulty email configuration that keeps the browser from sending the mail
Server side mail has none of these limitations. Here is a form that will be sent to you provided you change the variables at the top 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
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%
' change these to reflect where form should go
fromName="Whoever"
fromAddress="[email protected]"
toName="Charles M. Carroll"
toAddress="[email protected]"
subject="form send mail tutorial"
relay="relay.datareturn.com"
%>
<html><head>
<title>FormToBeMailed.asp</title>
</head><body bgcolor="#FFFFFF">
<form action="FormToBeMailedrespond.asp" method="GET">
Fill Out This Form For Us:<p>
First Name -&gt; <input NAME="NameFirst" size="10"><br>
Last Name -&gt; <input NAME="NameLast" size="10"><br>
Country -&gt; <input NAME="Country" value="USA" size="10"><br>
18
19
20
21
22
23
24
25
26
27
28
29
30
31
State -&gt; <input NAME="State" MaxLength="2" size="2"><br>
email copy to -&gt; <input NAME="emailcopy" MaxLength="20" size="20"><br>
<input type="submit"><input type="reset">
<% ' do not touch these lines. Needed to send mail! %>
<input type="hidden" name="mail-from" value="<%=fromName%>">
<input type="hidden" name="mail-fromAddress" value="<%=fromAddress%>">
<input type="hidden" name="mail-to" value="<%=ToName%>">
<input type="hidden" name="mail-toaddress" value="<%=toaddress%>">
<input type="hidden" name="mail-subject" value="<%=subject%>">
<input type="hidden" name="mail-relay" value="<%=relay%>">
</form>
</body></html>
Here is the generic form responder that can be used with this or any form:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<html><head>
<title>serverobjectsmailrespond.asp</title>
</head><body bgcolor="#FFFFFF">
<%
' ASPMail(tm) from http://www.serverobjects.com
' is not part of ASP per se,
' but a excellent third party component
my_from=request("mail-fromName")
my_fromAddress=request("mail-fromaddress")
my_to=request("mail-toName")
my_toAddress=request("mail-toaddress")
my_subject=request("mail-subject")
my_relay=request("mail-relay")
Set Mailer = Server.CreateObject("SMTPsvg.Mailer")
Mailer.RemoteHost = my_relay
Mailer.FromName = my_from
Mailer.FromAddress = my_fromAddress
Mailer.AddRecipient my_to, my_toaddress
Mailer.Subject = my_subject
for each whatever in request.querystring
If instr(whatever,"mail-")=0 then
Mailer.BodyText = whatever & "=" & vbcrlf
Mailer.BodyText = request.querystring(whatever) & vbcrlf & vbcrlf
end if
next
for each whatever in request.form
If instr(whatever,"mail-")=0 then
Mailer.BodyText = whatever & "=" & vbcrlf
Mailer.BodyText = request.form(whatever) & vbcrlf & vbcrlf
end if
next
my_emailcopy=request("emailcopy")
If my_emailcopy="" then
else
Mailer.AddRecipient "form filler",my_emailcopy
end if
If
Mailer.SendMail then
Msg = "mail sent sucessfully!"
Else
Msg = "mail was not sent sucessfully"
End If
response.write Msg
%>
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
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<%
response.buffer=true
%>
<html><head>
<TITLE>cookiesform.asp</TITLE>&
<body bgcolor="#FFFFFF">
<%
ln=Request.Cookies("thatperson")("lastname")
fn=Request.Cookies("thatperson")("firstname")
st=Request.Cookies("thatperson")("state")
%>
<Form action = "cookiesformrespond.asp">
Form with Cookies<p>
Please enter your First Name<p>
<Input NAME="NameFirst" size ="40" value=<%=fn%>>
<p>
Please enter your Last Name<p>
<Input NAME="NameLast" size ="40" value=<%=ln%>>
<p>
Please enter your State abbreviation<p>
<Input NAME="State" MaxLength="2" value=<%=st%>>
<Input type=submit></form>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<%response.buffer=true%>
<html><head>
<TITLE>cookiesformrespond.asp</TITLE>&
<body bgcolor="#FFFFFF">
<%
l=request.querystring("namelast")
f=request.querystring("namefirst")
st=request.querystring("state")
cookypath="/learn/test"
cookydomain=".www.activeserverpages.com"
cookydie=date+365
Response.Cookies("thatperson")("lastname") = l
Response.Cookies("thatperson")("firstname") = f
Response.Cookies("thatperson")("state") = st
Response.Cookies("thatperson").Expires = cookydie
Response.Cookies("thatperson").Domain = cookydomain
Response.Cookies("thatperson").Path = cookypath
response.write Request.Cookies("thatperson")("lastname") & "<p>"
response.write Request.Cookies("thatperson")("firstname") & "<p>"
20
21
22
response.write Request.Cookies("thatperson")("state") & "<p>"
%>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
<%response.buffer=true%>
<html><head>
<TITLE>cookiesformforget.asp</TITLE>&
<body bgcolor="#FFFFFF">
<%
cookiepath="/learn/test"
cookiedomain=".www.activeserverpages.com"
cookiesdie=date-365
Response.Cookies("thatperson").Expires = cookiesdie
Response.Cookies("thatperson").Domain = cookiesdomain
Response.Cookies("thatperson").Path = cookiespath
response.write "I will not remember you"
%>
</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
2
3
4
5
6
7
8
9
10
11
12
<%response.buffer=true%>
<!--#include file="cookielib.asp"-->
<html><head>
<TITLE>cookiesub.asp</TITLE>&
<body bgcolor="#FFFFFF">
<%
Call AddCookie("Person", "Firstname", "Robert", 365)
Call AddCookie("Person", "LastName", "Forward", 365)
response.write GetCookie("person","firstname")
response.write GetCookie("person","lastname")
%>
</body></html>
Here is the library code that does most of the work:
1
2
3
4
5
6
7
8
9
10
<%
'=======================================================================
' CookieLib.asp by Paul Rigor (http://www.mysticpc.com)
' online at http://www.activeserverpages.com/learn/cookiesub.asp
' copyright 1998 by Paul Rigor
'
' application("cookiedomain") and application("cookiepath") can be
' set if firewall precludes accurate server variable
'
' AddCookie(Cname, CKey, CValue, CExpDays)
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
' Example: Call AddCookie("MyCookie", "Cost", "$1.00", 100)
'
' KillCookie(Cname,CKey)
' Example: Call KillCookie("MyCookie", "Cost")
'
' GetCookie(Cname,Ckey)
'
Example: Call GetCookie("MyCookie", "Cost")
'
' Cname = Cookie Name: Required, for cookie name
'
Ckey = Cookie Key: Optional(empty sting), use if cookie should be a dictionary
'
Cvalue = Cookie Value: Required, what the cookie should be set to.
'
CExpDays = Cookie Expiration: number of days cookie is valid, default 365
Function AddCookie(Cname, CKey, CValue, CExpDays)
If Cname = "" Then
Exit Function
End If
If IsNumeric(CExpDays) = False Then CExpDays = 0
If CExpDays < 1 Then CExpDays = 365
If CValue = "" Then CValue = " "
If CKey <> "" Then
Response.Cookies(Cname)(CKey) = CValue
Else
Response.Cookies(Cname) = CValue
End If
Response.Cookies(CName).Expires = Date + CExpDays
Response.Cookies(CName).Domain = GetCookieDomain()
Response.Cookies(CName).Path = GetCookiePath()
End Function
Function KillCookie(Cname,CKey)
If CKey <> "" Then
Call AddCookie(Cname, Ckey, "", 0)
Else
Response.Cookies(Cname).Expires = Date - 365
Response.Cookies(CName).Domain = GetCookieDomain()
Response.Cookies(CName).Path = GetCookiePath()
End If
End Function
Function GetCookie(Cname, Ckey)
If CKey <> "" Then
GetCookie = Request.Cookies(Cname)(Ckey)
Else
GetCookie = Request.Cookies(Cname)
End If
End Function
Function GetCookieDomain()
If Application("CookieDomain") <> "" Then
GetCookieDomain = Application("CookieDomain")
Else
GetCookieDomain = Request.ServerVariables("SERVER_NAME")
End If
End Function
Function GetCookiePath()
If Application("CookiePath") <> "" Then
GetCookiePath = Application("CookiePath")
Else
TmpPath = Request.ServerVariables("SCRIPT_NAME")
TmpPath = Split(TmpPath, "/")
For PathArryCnt = 0 to Ubound(TmpPath) - 1
GetCookiePath = GetCookiePath & TmpPath(PathArryCnt) & "/"
78
79
80
81
82
Next
If GetCookiePath = "/" Then GetCookiePath = ""
End If
End Function
%>
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
3
4
5
6
7
8
9
10
11
12
<%
response.write "Coin Tossed!<br>"
randomize
randomnum=int(rnd*2)+1
IF randomnum=1 THEN
session("heads")=session("heads")+1
ELSE
session("tails")=session("tails")+1
END IF
response.write "Heads= " & session("heads") & "<br>"
response.write "Tails= " & session("tails") & "<br>"
%>
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.
●
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.
●
If you absolutely need sessions without client cookies, installing an ISAPI filter named "Cookie Munger" will
solve your problem, but at a performance penalty.
Cookie Munger by Microsoft (FREE)
Cookies are a necessity to maintain ASP session objects. Even though the session objects are physically maintained on the 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
2
3
4
5
6
7
8
9
10
<html><head>
<TITLE>surveypage1.asp</TITLE>
</head>
<body bgcolor="#FFFFFF">
<form action="surveypage2.asp" method="post">
First Name<br>
&nbsp;&nbsp;&nbsp;
<input type="text" name="first" size="20"><br>
Last Name<br>
&nbsp;&nbsp;&nbsp;
11
12
13
14
15
<input type="text" name="last" size="20">
<p>&nbsp;&nbsp;&nbsp;
<input type="submit" value="Next Question ->"></p>
</form>
</body></html>
surveypage2.asp asks the user the next questions:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html><head>
<TITLE>surveypage2.asp</TITLE>
</head>
<body bgcolor="#FFFFFF">
<form action="surveypage3.asp" method="post">
<%
first=request.form("first")
last=request.form("last")
%>
Hair Color<br>
&nbsp;&nbsp;&nbsp;
<input type="text" name="haircolor" size="20"><br>
Favorite Color<br>
&nbsp;&nbsp;&nbsp;
<input type="text" name="favoritecolor" size="20">
<p>&nbsp;&nbsp;&nbsp;
<input type="hidden" name="first" value="<%=first%>">
<input type="hidden" name="last" value="<%=last%>">
<input type="submit" value="Next Question ->"></p>
</form>
</body></html>
surveypage3.asp asks the user yet some more questions:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<html><head>
<TITLE>surveypage2.asp</TITLE>
</head>
<body bgcolor="#FFFFFF">
<%
first=request.form("first")
last=request.form("last")
haircolor=request.form("haircolor")
favoritecolor=request.form("favoritecolor")
%>
<form action="surveypage3respond.asp" method="post">
Street Address<br>
&nbsp;&nbsp;&nbsp;
<input type="text" name="street" size="20">
<br>
City<br>
&nbsp;&nbsp;&nbsp;
<input type="text" name="city" size="20"><br>
State<br>
&nbsp;&nbsp;&nbsp;
<input type="text" name="state" size="20">
<br>
Zip<br>
&nbsp;&nbsp;&nbsp;
<input type="text" name="zip" size="20">
<br>
&nbsp;&nbsp;&nbsp;
<input
<input
<input
<input
type="hidden"
type="hidden"
type="hidden"
type="hidden"
name="first" value="<%=first%>">
name="last" value="<%=last%>">
name="haircolor" value="<%=haircolor%>">
name="favoritecolor" value="<%=favoritecolor%>">
<input type="submit" value="Final Step ->">
</form>
</body></html>
surveypage3respond.asp gathers all the answers and responds:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<html><head>
<TITLE>surveypage3respond.asp</TITLE>
</head>
<body bgcolor="#FFFFFF">
<%
first=request.form("first")
last=request.form("last")
haircolor=request.form("haircolor")
favoritecolor=request.form("favoritecolor")
street=request.form("street")
city=request.form("city")
state=request.form("state")
zip=request.form("zip")
%>
Thanks for all your information<br>
We are happy to meet you <%=first%>&nbsp;<%=last%><br>
We know your hair color is <%=haircolor%><br>
and your favorite color is <%=favoritecolor%><br>
and we will ship all items to<br>
<%=first%>&nbsp;<%=last%><br>
<%=street%><br>
<%=city%>&nbsp;<%=state%>&nbsp;<%=zip%>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<html><head>
<TITLE>surveypage1.asp</TITLE>
</head>
<body bgcolor="#FFFFFF">
<%
first=request.cookies("prefs")("first")
last=request.cookies("prefs")("last")
%>
<form action="surveypage2c.asp" method="post">
First Name<br>
&nbsp;&nbsp;&nbsp;
<input type="text" name="first" size="20" value="<%=first%>"><br>
Last Name<br>
&nbsp;&nbsp;&nbsp;
<input type="text" name="last" size="20" value="<%=last%>">
<p>&nbsp;&nbsp;&nbsp;
<input type="submit" value="Next Question ->"></p>
</form>
<%
For Each cookie in Response.Cookies
Response.Cookies(cookie).Expires = now()+365
Next
%>
</body></html>
surveypage2c.asp asks the user the next questions:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<%response.buffer=true%>
<html><head>
<TITLE>surveypage2c.asp</TITLE>
</head>
<body bgcolor="#FFFFFF">
<%
first=request("first")
last=request("last")
haircolor=request.cookies("prefs")("haircolor")
favoritecolor=request.cookies("prefs")("favoritecolor")
%>
<form action="surveypage3c.asp" method="post">
Hair Color<br>
&nbsp;&nbsp;&nbsp;
<input type="text" name="haircolor" size="20" value="<%=haircolor%>"><br>
Favorite Color<br>
&nbsp;&nbsp;&nbsp;
<input type="text" name="favoritecolor" size="20" value="<%=favoritecolor%>">
<p>
<%
response.cookies("prefs")("first")=first
response.cookies("prefs")("last")=last
For Each cookie in Response.Cookies
Response.Cookies(cookie).Expires = now()+365
Next
%>
<input type="submit" value="Next Question ->"></p>
</form>
</body></html>
surveypage3c.asp asks the user yet some more questions:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<%response.buffer=true%>
<html><head>
<TITLE>surveypage3c.asp</TITLE>
</head>
<body bgcolor="#FFFFFF">
<%
haircolor=request("haircolor")
favoritecolor=request("favoritecolor")
street=request.cookies("prefs")("street")
city=request.cookies("prefs")("city")
state=request.cookies("prefs")("state")
zip=request.cookies("prefs")("zip")
%>
<form action="surveypage3crespond.asp" method="post">
Street Address<br>
&nbsp;&nbsp;&nbsp;
<input type="text" name="street" size="20" value="<%=street%>">
<br>
City<br>
&nbsp;&nbsp;&nbsp;
<input type="text" name="city" size="20" value="<%=city%>"><br>
State<br>
&nbsp;&nbsp;&nbsp;
<input type="text" name="state" size="20" value="<%=state%>">
<br>
Zip<br>
&nbsp;&nbsp;&nbsp;
<input type="text" name="zip" size="20" value="<%=zip%>">
<br>
<%
response.cookies("prefs")("haircolor")=haircolor
response.cookies("prefs")("favoritecolor")=favoritecolor
For Each cookie in Response.Cookies
Response.Cookies(cookie).Expires = now()+365
Next
%>
37
38
39
<input type="submit" value="Final Step ->">
</form>
</body></html>
surveypage3crespond.asp gathers all the answers and responds:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<%response.buffer=true%>
<html><head>
<TITLE>surveypage3respond.asp</TITLE>
</head>
<body bgcolor="#FFFFFF">
<%
first=request.cookies("prefs")("first")
last=request.cookies("prefs")("last")
haircolor=request.cookies("prefs")("haircolor")
favoritecolor=request.cookies("prefs")("favoritecolor")
street=request("street")
city=request("city")
state=request("state")
zip=request("zip")
%>
Thanks for all your information<br>
We are happy to meet you <%=first%>&nbsp;<%=last%><br>
We know your hair color is <%=haircolor%><br>
and your favorite color is <%=favoritecolor%><br>
and we will ship all items to<br>
<%=first%>&nbsp;<%=last%><br>
<%=street%><br>
<%=city%>&nbsp;<%=state%>&nbsp;<%=zip%>
<%
response.cookies("prefs")("street")=street
response.cookies("prefs")("city")=city
response.cookies("prefs")("state")=state
response.cookies("prefs")("zip")=zip
For Each cookie in Response.Cookies
Response.Cookies(cookie).Expires = now()+365
Next
%>
</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
[email protected]
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<html><head>
<TITLE>dbsimple.asp</TITLE>
</head>
<body bgcolor="#FFFFFF">
<%
' this code opens the database
myDSN="DSN=Student;uid=student;pwd=magic"
set conntemp=server.createobject("adodb.connection")
conntemp.open myDSN
' this code retrieves the data
mySQL="select * from publishers where state='NY'"
set rstemp=conntemp.execute(mySQL)
' this code detects if data is empty
If rstemp.eof then
response.write "No records matched<br>"
response.write mySQL & "<br>So cannot make table..."
connection.close
set connection=nothing
response.end
end if
%>
<table border=1>
<%
' This code puts fieldnames into column headings
response.write "<tr>"
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
for each whatever in rstemp.fields
response.write "<td><B>" & whatever.name & "</B></TD>"
next
response.write "</tr>"
' Now lets grab all the records
DO UNTIL rstemp.eof
' put fields into variables
pubid=rstemp("pubid")
name=rstemp("name")
company_name=rstemp("company_name")
address=rstemp("address")
city=rstemp("city")
state=rstemp("state")
zip=rstemp("zip")
telephone=rstemp("telephone")
fax=rstemp("fax")
comments=rstemp("comments")
' write the fields to browser
cellstart="<td align=""top"">"
response.write "<tr>"
response.write cellstart & pubid & "</td>"
response.write cellstart & name & "</td>"
response.write cellstart & company_name & "</td>"
response.write cellstart & address & "</td>"
response.write cellstart & city & "</td>"
response.write cellstart & state & "</td>"
response.write cellstart & zip & "</td>"
response.write cellstart & telephone & "</td>"
response.write cellstart & fax & "</td>"
response.write cellstart & comments & "</td>"
response.write "</tr>"
rstemp.movenext
LOOP
%>
</table>
<%
' Now close and dispose of resources
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
%>
</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
2
3
4
5
6
7
<html><head>
<TITLE>dbtable.asp</TITLE>
</head>
<body bgcolor="#FFFFFF">
<%
' ASP program that displays a database in table form
myDSN="DSN=Student;uid=student;pwd=magic"
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
mySQL="select * from publishers where state='NY'"
showblank="&nbsp;"
shownull="-null-"
set conntemp=server.createobject("adodb.connection")
conntemp.open myDSN
set rstemp=conntemp.execute(mySQL)
If rstemp.eof then
response.write "No records matched<br>"
response.write mySQL & "<br>So cannot make table..."
conntemp.close
set conntemp=nothing
response.end
end if
%>
<table border=1><tr>
<% 'Put Headings On The Table of Field Names
for each whatever in rstemp.fields%>
<td><b><%=whatever.name%></B></TD>
<% next %>
</tr>
<% ' Now lets grab all the records
DO UNTIL rstemp.eof %>
<tr>
<% for each whatever in rstemp.fields
thisfield=whatever.value
if isnull(thisfield) then
thisfield=shownull
end if
if trim(thisfield)="" then
thisfield=showblank
end if%>
<td valign=top><%=thisfield%></td>
<% next %>
</tr>
<%rstemp.movenext
LOOP%>
</table>
<%
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
%>
</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
2
3
4
5
6
<html><head>
<TITLE>dblist.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<%
myDSN="DSN=Student;uid=student;pwd=magic"
mySQL="select author from authors where AU_ID<100"
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
' displays a database field as a listbox
set conntemp=server.createobject("adodb.connection")
conntemp.open myDSN
set rstemp=conntemp.execute(mySQL)
if rstemp.eof then
response.write "no data for<br>"
response.write mySQL
conntemp.close
set conntemp=nothing
response.end
end if
%>
<form action="dblistrespond.asp" method="post">
<Select name="authorname">
<%
' Now lets grab all the data
do until rstemp.eof %>
<option> <%=RStemp(0)%> </option>
<%
rstemp.movenext
loop
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
%>
<input type="submit" value="Choose Author">
</Select></form>
</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
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<%
' Generic interface to the Northwinds Employee table.
Session("dbGenericPath") = "/learn/test/genericdb/"
Session("dbExitPage") = "http://www.activeserverpages.com"
Session("dbTitle") = "Pubs"
Session("dbType") = "SQL"
Session("dbConn") = "DSN=student;uid=student;pwd=magic"
Session("dbRs") = "Publishers"
Session("dbKey") = 1
Session("dbOrder") = 2
Session("dbRecsPerPage") = 10
Session("dbFooter") = 1
Session("dbDispList") = "011101000000100010"
Session("dbDispView") = "111111111111111111"
Session("dbDispEdit") = "011111111111111111"
Session("dbSearchFields") = "011100010010001000"
Session("dbDefault6") = Date()
Session("dbCombo11") = "LIST, ??, Unknown, CA, Canada, US, United States, DE, Denmark"
Session("dbDefault17") = 10
Session("dbWhere") = ""
Session("dbDebug") = 1
Session("dbCanEdit") = 1
Session("dbCanAdd") = 1
Session("dbCanDelete") = 1
Session("dbConfirmDelete") = 1
Session("dbViewPage") = Request.ServerVariables("PATH_INFO")
Response.Redirect Session("dbGenericPath") & "GenericList.asp"
%>
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
[email protected]
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)
●
present the data anew to the provider/driver since the ASCII file may have changed since last connection.
The designers of ASP have seen File DSNs fail on big busy sites because of reason a) so discourage them. System DSNs thay 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
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<TITLE>sqlDSNless.asp</TITLE>
<body bgcolor="#FFFFFF"></HEAD>
<%
mydb="PROVIDER=MSDASQL;DRIVER={SQL Server};"
mydb=mydb & "SERVER=sql2.datareturn.com;DATABASE=;"
mydb=mydb & "UID=student;PWD=magic;"
mySQL="select * from publishers where state='NY'"
call query2table(mySQL,mydb)
%>
<!--#include virtual="/learn/test/lib_dbtable.asp"-->
</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/dsn1.asp by Charles M. Carroll
Page 90
Setting up a system DSN on Windows 95/NT
©1998, 1999 by Rob Martinson [email protected]
The easiest way to begin learning ASP, is to install Microsoft PWS, and develop locally. To do this, you must also setup a DSN (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 [email protected]
Setting up a system DSN on Windows 95/NT
Once the ODBC Data Source Administrator window is open, select the System DSN tab at the top (I'm doing a system 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 [email protected]
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 [email protected]
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 [email protected]
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 [email protected]
That's it! Your System DSN is setup and running. All you need to do now is get ASP to use it (which is pretty easy).
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
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<%
response.buffer=true
Response.ExpiresAbsolute = Now() - 1
Response.AddHeader "Cache-Control", "private"
%>
<html><head>
<title>authorshow.asp</title>
<meta http-equiv="pragma" content="no-cache">
</head><body bgcolor="#FFFFFF">
<%
myDSN="DSN=Student;uid=student;pwd=magic"
mySQL="select * from authors where AU_ID<100 order by author"
IDfield="AU_ID"
scriptresponder="authoredit.asp"
set conntemp=server.createobject("adodb.connection")
conntemp.open myDSN
set rstemp=conntemp.execute(mySQL)
howmanyfields=rstemp.fields.count -1
%>
<table border="1">
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<tr>
<td valign="top">---</td>
<% 'Put Headings On The Table of Field Names
for i=0 to howmanyfields %>
<td><b><%=rstemp(i).name %></b></td>
<% next %>
</tr>
<% ' Now lets grab all the records
do while not rstemp.eof %>
<tr><td valign="top">
<%my_link=scriptresponder & "?which=" & rstemp(idfield)%>
<a HREF="<%=my_link%>">Edit</a></td>
<% for i = 0 to howmanyfields%>
<td valign="top"><%=rstemp(i)%></td>
<% next %>
</tr>
<%
rstemp.movenext
loop
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
%>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<html><head>
<title>authoredit.asp</title>
</head><body bgcolor="#FFFFFF">
<%
' My ASP program that given an AU_ID, allows editing a record
myDSN="DSN=Student;uid=student;pwd=magic"
set conntemp=server.createobject("adodb.connection")
conntemp.open myDSN
form_ID=request.querystring("which")
sqltemp="select * from authors "
sqltemp=sqltemp & " where AU_ID=" & form_id
set rstemp=conntemp.execute(sqltemp)
form_auID=rstemp("AU_ID")
form_author=rstemp("Author")
form_year_born=rstemp("Year_Born")
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
%>
<body>
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<form name="myauthor" action="authoreditrespond.asp" method="POST">
<input type="hidden" name="id" value="<%=form_auid%>">
<p>Author ID: <%=form_auid%></p>
<p> Author Name:
<input type="TEXT" name="name" value="<%=form_author%>"></p>
<p> Year Born:
<input type="TEXT" name="year" value="<%=form_year_born%>"></p>
<p> <input type="SUBMIT"> </p>
</form>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<HTML><HEAD>
<TITLE>authoreditrespond.asp</TITLE>
<body bgcolor="#FFFFFF"></HEAD>
<%
on error resume next
form_name=request.form("name")
form_year=request.form("year")
form_ID=request.form("ID")
Set Conn = Server.CreateObject("ADODB.Connection")
conn.open "DSN=Student;uid=student;pwd=magic"
' change apostrophe to double apostrophe
form_name=Replace(form_name, "'", "''")
SQLstmt
SQLStmt
SQLstmt
SQLStmt
=
=
=
=
"UPDATE
SQLstmt
SQLstmt
SQLStmt
authors SET "
& "Author='" & form_name & "',"
& "year_born=" & form_year
& " WHERE AU_ID=" & form_id
Set RS = Conn.Execute(SQLStmt)
If
err.number>0 then
response.write "VBScript Errors Occured:" & "<P>"
response.write "Error Number=" & err.number & "<P>"
response.write "Error Descr.=" & err.description & "<P>"
response.write "Help Context=" & err.helpcontext & "<P>"
response.write "Help Path=" & err.helppath & "<P>"
response.write "Native Error=" & err.nativeerror & "<P>"
response.write "Source=" & err.source & "<P>"
response.write "SQLState=" & err.sqlstate & "<P>"
end if
IF conn.errors.count> 0 then
response.write "Database Errors Occured" & "<P>"
response.write SQLstmt & "<P>"
for counter= 0 to conn.errors.count
response.write "Error #" & conn.errors(counter).number & "<P>"
response.write "Error desc. -> " & conn.errors(counter).description & "<P>"
40
41
42
43
44
45
46
47
48
49
50
51
52
next
else
response.write "<B>Everything Went Fine. Record is updated now!</b>"
response.write "<br>" & SQLstmt
end if
rs.close
set rs=nothing
Conn.Close
set conn=nothing
%>
</BODY>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<html><head>
<TITLE>dbconvert.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<%
whichname="/upload/tests/authors.txt"
myDSN="DSN=Student;uid=student;pwd=magic"
mySQL="select * from authors where au_id<100"
showblank=""
shownull="<null>"
linestart=chr(34)
lineend=chr(34)
delimiter=chr(34) & "," & chr(34)
delimitersub=""
whichFN=server.mappath(whichname)
Set fstemp = server.CreateObject("Scripting.FileSystemObject")
Set filetemp = fstemp.CreateTextFile(whichFN, true)
' true = file can be over-written if it exists
' false = file CANNOT be over-written if it exists
set conntemp=server.createobject("adodb.connection")
conntemp.open myDSN
set rstemp=conntemp.execute(mySQL)
' this code detects if data is empty
If rstemp.eof then
response.write "No data to convert for SQL statement<br>"
response.write mySQL & "<br>"
connection.close
set connection=nothing
response.end
end if
DO
UNTIL rstemp.eof
thisline=linestart
for each whatever in rstemp.fields
thisfield=whatever.value
if isnull(thisfield) then
thisfield=shownull
end if
if trim(thisfield)="" then
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
thisfield=showblank
end if
thisfield=replace(thisfield,delimiter,delimitersub)
thisline=thisline & thisfield & delimiter
next
tempLen=len(thisline)
tempLenDelim=len(delimiter)
thisline=mid(thisline,1,tempLEN-tempLenDelim) & lineend
filetemp.WriteLine(thisline)
' response.write thisline & "<br>"
rstemp.movenext
LOOP
filetemp.Close
set filetemp=nothing
set fstemp=nothing
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
If
err.number=0 then
response.write "File was converted sucessfully!<br>"
response.write "Converted file is at <a href='"
response.write whichname & "'>" & whichname & "</a>"
else
response.write "VBScript Errors Occured!<br>"
response.write "Error Number=#<b>" & err.number & "</b><br>"
response.write "Error Desc. =<b>" & err.description & "</b><br>"
response.write "Help Path =<b>" & err.helppath & "</b><br>"
response.write "Native Error=<b>" & err.nativeerror & "</b><br>"
response.write "Error Source =<b>" & err.source & "</b><br>"
response.write "SQL State=#<b>" & err.sqlstate & "</b><br>"
end if
%>
</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
17
18
19
20
21
22
23
24
25
response.write thistask
Conn.Execute(mySQL)
Call ErrorVBScriptReport(thistask)
Call ErrorADOReport(mySQL,conn)
next
Conn.Close
set conn=nothing
%>
</BODY>
</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
[email protected]
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<% response.buffer=true %>
<HTML>
<Head><Title>ASPdb1.asp</Title></Head>
<%
Set MyDb = Server.CreateObject("ASPdb.Pro")
MyDb.dbUnit = 1000
MyDb.dbMDB=Server.MapPath("/learn/test/nwind.mdb")
MyDb.dbColor = "11"
MyDb.dbGridTableTag = "border=3"
MyDb.dbMode= "Grid"
MyDb.dbSQL = "Select * FROM Customers"
MyDb.dbNavigationItem = "top, bottom, next, prev, filter"
MyDb.ASPdbPro
set myDB=nothing
%>
</BODY>
</HTML>
Now we will display publishers:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<% response.buffer=true %>
<HTML>
<Head><Title>ASPdb1.asp</Title></Head>
<%
Set MyDb = Server.CreateObject("ASPdb.Pro")
MyDb.dbUnit = 1000
MyDb.dbMDB=Server.MapPath("/learn/test/biblio.mdb")
MyDb.dbColor = "11"
MyDb.dbGridTableTag = "border=3"
MyDb.dbMode= "Grid"
MyDb.dbSQL = "Select * FROM Publishers"
MyDb.dbNavigationItem = "top, bottom, next, prev, filter"
MyDb.ASPdbPro
set myDB=nothing
%>
</BODY>
</HTML>
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
end if
if
UL12 = "ASPDBEDITDEL" then
MSG1 = "<CENTER><FONT SIZE=4 COLOR=red><B>"
MSG1 = MSG1 + "You are about to DELETE all of the Information for: " + THISNAME
MSG1 = MSG1 + "</B></FONT><P>"
response.write(MSG1)
end if
if
UL12 = "ASPDBEDITEDI" then
MSG1 = "<CENTER><FONT SIZE=4 COLOR=red><B>"
MSG1 = MSG1 + "You are about to EDIT all of the Information for: " + THISNAME
MSG1 = MSG1 + "</B></FONT><P>"
response.write(MSG1)
end if
Mydb.dbMDB = Server.MapPath("Pro-Demo.mdb") ' Has fields: Name, Age, Salary, NetWorth
MyDb.DBColor = "11,auto,white"
MyDb.dbGridTableTag = "border=3 cellspacing=3 cellpadding=3"
MyDb.dbFormTableTag = "border=3 cellspacing=3 cellpadding=3"
MyDb.dbGridDisplayFlds = "Name,Age,Salary,NetWorth"
MyDb.DbMode = "dual-horiz"
MyDb.dbGridInc = 10
MyDb.dbButtonAnchor=false
MyDb.dbExportFlds = "Name"
Mydb.dbFilterDropFlds = "Name,,People,Name,,,,,Distinct; Salary,,People,Salary,,,,,Distinct"
Mydb.dbEditDropFlds = "Salary,,,9250.75/11000/15000/21000/25000/32000/38000/44000/75000"
Mydb.dbEditFlds = "Name,Age[10],Salary,NetWorth[123]" ' added Name 07-27-98
MyDb.dbEditUpdateROFlds = "Name" ' ***** NEW!!!!! *****
EP = "TableName=People,BookMarkFlds=0,TableTag=Border=2"
EP = EP & ",RecordScope=single,CriteriaSize=4x25,EditSemiColon=;"
Mydb.dbEditParams = EP
MyDb.dbSQL = "Select * from People"
MyDb.dbMagicCell = _
"1, align=Left , <font size=2 face=ARIAL color=black><I><B>#1#</B></I>;" & _
"2, align=Center, <font size=2 face=ARIAL color=black> #2#;" & _
"3, align=right , <font size=2 face=ARIAL color=black>format=[currency];" & _
"4, align=right , <font size=2 face=ARIAL color=black>format=[currency];"
MyDb.dbImageDir="images/"
Mydb.dbNavigation="both"
Mydb.dbNavigationItem="Next, Prev, Gridrow, Filter, add, update, edit, delete"
Mydb.dbNavigationIcon="std"
MyDb.aspDBPro
set mydb=nothing
%>
</HTML>
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<TITLE>dbtablegetstring.asp</TITLE>
<body bgcolor="#FFFFFF">
<%
whichDSN="DSN=Student;uid=student;pwd=magic"
mySQL="select * from publishers where state='NY'"
' ASP program that displays a database in table form
set conntemp=server.createobject("adodb.connection")
conntemp.open whichDSN
set rstemp=conntemp.execute(mySQL)
If rstemp.eof then
response.write "No records matched<br>"
response.write mySQL & "<br>So cannot make table..."
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
response.end
end if
response.write "<table border='1'><tr>"
'Put Headings On The Table of Field Names
for each whatever in rstemp.fields
response.write "<td><b>" & whatever.name & "</B></TD>"
next
response.write "</tr><tr><td>"
response.write rstemp.getstring(,, "</td><td>", "</td></tr><TR><TD>", "-null-")
response.write "</td></tr></table>"
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
%>
</body></html>
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:
1
2
3
4
5
6
7
8
9
10
11
●
http://www.learnasp.com/learn/arrays.asp
●
http://www.learnasp.com/learn/arrays2.asp
●
http://www.learnasp.com/learn/arrays3.asp
<%@enablesessionstate=false%>
<%response.buffer=true%>
<html><head>
<TITLE>dbtablegetrows.asp</TITLE>
</head>
<body bgcolor="#FFFFFF">
<%
' displays a database in table form via GetRows
myDSN="DSN=Student;uid=student;pwd=magic"
mySQL="select * from publishers where state='NY'"
showblank="&nbsp;"
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
shownull="-null-"
set conntemp=server.createobject("adodb.connection")
conntemp.open myDSN
set rstemp=conntemp.execute(mySQL)
If rstemp.eof then
response.write "No records matched<br>"
response.write mySQL & "<br>So cannot make table..."
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
response.end
end if
response.write "<table border='1'><tr>"
'Put Headings On The Table of Field Names
for each whatever in rstemp.fields
response.write "<td><b>" & whatever.name & "</B></TD>"
next
response.write "</tr>"
' Now lets grab all the records
alldata=rstemp.getrows
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
numcols=ubound(alldata,1)
numrows=ubound(alldata,2)
FOR rowcounter= 0 TO numrows
FOR colcounter=0 to numcols
thisfield=alldata(colcounter,rowcounter)
if isnull(thisfield) then
thisfield=shownull
end if
if trim(thisfield)="" then
thisfield=showblank
end if
response.write "<td valign=top>"
response.write thisfield
response.write "</td>"
NEXT
response.write "</tr>" & vbcrlf
NEXT
response.write "</table>"
%>
</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
2
3
<%@enablesessionstate=false%>
<%response.buffer=true%>
<!--#include virtual="/adovbs.inc"-->
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<html><head>
<TITLE>dbtabledisconnected.asp</TITLE>
</head>
<body bgcolor="#FFFFFF">
<%
' displays a database in table form via GetRows
myDSN="DSN=Student;uid=student;pwd=magic"
mySQL="select * from publishers where state='NY'"
showblank="&nbsp;"
shownull="-null-"
set conntemp=server.createobject("adodb.connection")
conntemp.open myDSN
' to disconnect a recordset it must be created explicitly
set rstemp=server.createobject("adodb.recordset")
rstemp.cursorlocation=aduseclient
rstemp.open mySQL,conntemp
' this line below disconnects the recordset
set rstemp.activeconnection=nothing
If
rstemp.eof then
response.write "No records matched<br>"
response.write mySQL & "<br>So cannot make table..."
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
response.end
end if
response.write "<table border='1'><tr>"
'Put Headings On The Table of Field Names
for each whatever in rstemp.fields
response.write "<td><b>" & whatever.name & "</B></TD>"
next
response.write "</tr>"
DO UNTIL rstemp.eof
response.write "<tr>"
for each whatever in rstemp.fields
thisfield=whatever.value
if isnull(thisfield) then
thisfield=shownull
end if
if trim(thisfield)="" then
thisfield=showblank
end if
response.write "<td valign=top>" & thisfield & "</td>"
next
response.write "</tr>"
rstemp.movenext
LOOP
response.write "</table>"
%>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<html><head>
<TITLE>dbmaxrecs.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<!--#INCLUDE VIRTUAL="/ADOVBS.INC" -->
<%
set rstemp=Server.CreateObject("adodb.Recordset")
rstemp.maxrecords=15
connectme="DSN=Student;uid=student;pwd=magic"
rstemp.open "select * from titles", _
connectme,adopenstatic
' table display
howmanyfields=rstemp.fields.count -1
%>
<table border=1><tr>
<%
for i=0 to howmanyfields %>
<td><b><%=rstemp(i).name %></B></TD>
<% next %>
</tr>
<%
do while not rstemp.eof %>
<tr>
<% for i = 0 to howmanyfields%>
<td valign=top><% = rstemp.fields(i).value %>&nbsp;</td>
<% next %>
</tr>
<%
rstemp.movenext
loop
rstemp.close
set rstemp=nothing
%>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<html><head>
<TITLE>dbtablepaged.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<!--#INCLUDE VIRTUAL="/ADOVBS.INC" -->
<%
connectme="DSN=Student;uid=student;pwd=magic"
sqltemp="select * from publishers"
'
'
'
'
'
'
'
'
'
'
'
'
Troubleshooting TIP:
if you use this code and get an error, for example:
ADODB.Recordset error 800a0cb3
The operation requested by the application is not
supported by the provider.
You may have a driver that is out of date, see:
http://www.learnasp.com/learn/connectioninfo.asp
for code that will identify what your driver version is
this script works with Access, SQLserver and Oracle
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
' with up-to-date drivers
If
aduseclient="" THEN
ref="http://www.learnasp.com/adovbs.inc"
response.write "You forgot to include:<br>"
response.write "/adovbs.inc<br>"
response.write "Get the file from <a href='" & ref & "'>" & ref & "<br>"
response.end
END IF
mypage=request("whichpage")
If mypage="" then
mypage=1
end if
mypagesize=request("pagesize")
If mypagesize="" then
mypagesize=10
end if
mySQL=request("SQLquery")
IF mySQL="" THEN
mySQL=SQLtemp
END IF
set rstemp=Server.CreateObject("ADODB.Recordset")
rstemp.cursorlocation=aduseclient
rstemp.cachesize=5
rstemp.open mySQL,connectme
rstemp.movefirst
rstemp.pagesize=mypagesize
maxpages=cint(rstemp.pagecount)
maxrecs=cint(rstemp.pagesize)
rstemp.absolutepage=mypage
howmanyrecs=0
howmanyfields=rstemp.fields.count -1
response.write "Page " & mypage & " of " & maxpages & "<br>"
response.write "<table border='1'><tr>"
'Put Headings On The Table of Field Names
FOR i=0 to howmanyfields
response.write "<td><b>" & rstemp(i).name & "</b></td>"
NEXT
response.write "</tr>"
' Now loop through the data
DO UNTIL rstemp.eof OR howmanyrecs>=maxrecs
response.write "<tr>"
FOR i = 0 to howmanyfields
fieldvalue=rstemp(i)
If isnull(fieldvalue) THEN
fieldvalue="n/a"
END IF
If trim(fieldvalue)="" THEN
fieldvalue="&nbsp;"
END IF
response.write "<td valign='top'>"
response.write fieldvalue
response.write "</td>"
next
response.write "</tr>"
rstemp.movenext
howmanyrecs=howmanyrecs+1
LOOP
response.write "</table><p>"
' close, destroy
rstemp.close
set rstemp=nothing
88
89
' Now make the page _ of _ hyperlinks
90
Call PageNavBar
91
92
sub PageNavBar()
93
' Thanks to Jeff Emrich <[email protected]>
94
pad=""
95
scriptname=request.servervariables("script_name")
96
response.write "<table rows='1' cols='1' width='97%'><tr>"
97
response.write "<td>"
98
response.write "<font size='2' color='black' face='Verdana, Arial,Helvetica,
sans-serif'>"
99
if (mypage mod 10) = 0 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
155
156
157
158
159
160
161
Response.Write ref
end if
response.write "<br></font>"
response.write "</td>"
response.write "</table>"
end sub
%>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<head><html>
<TITLE>dbcount.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<!--#INCLUDE VIRTUAL="/ADOVBS.INC" -->
<%
' change these for your site
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
howmanyrecs=rstemp.recordcount
response.write howmanyrecs & " records in<br>" & sqltemp
rstemp.close
set rstemp=nothing
%>
</body></html>
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 ([email protected])
ADO cursor types affects the properties and methods that are available as this table illustrates.
Property
Forward-Only Dynamic Keyset
AbsolutePage
N/A
N/A
R/W
AbsolutePosition
N/A
N/A
R/W
ActiveConnection
R/W
R/W
R/W
BOF
R/O
R/O
R/O
Bookmark
N/A
N/A
R/W
CacheSize
R/W
R/W
R/W
CursorLocation
R/W
R/W
R/W
CursorType
R/W
R/W
R/W
EditMode
R/O
R/O
R/O
EOF
R/O
R/O
R/O
Filter
R/W
R/W
R/W
LockType
R/W
R/W
R/W
MarshalOptions
R/W
R/W
R/W
MaxRecords
R/W
R/W
R/W
PageCount
N/A
N/A
R/O
PageSize
R/W
R/W
R/W
RecordCount
N/A
N/A
R/O
Source
R/W
R/W
R/W
State
R/O
R/O
R/O
Status
R/O
R/O
R/O
Method
AddNew
Yes
Yes
Yes
CancelBatch
Yes
Yes
Yes
CancelUpdate
Yes
Yes
Yes
Clone
N/A
N/A
Yes
Close
Yes
Yes
Yes
Delete
Yes
Yes
Yes
GetRows
Yes
Yes
Yes
Move
Yes
Yes
Yes
MoveFirst
Yes
Yes
Yes
MoveLast
N/A
Yes
Yes
MoveNext
Yes
Yes
Yes
MovePrevious
N/A
Yes
Yes
NextRecordset
Yes
Yes
Yes
Open
Yes
Yes
Yes
Requery
Yes
Yes
Yes
Static
R/W
R/W
R/W
R/O
R/W
R/W
R/W
R/W
R/O
R/O
R/W
R/W
R/W
R/W
R/O
R/W
R/O
R/W
R/O
R/O
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Resync
Supports
Update
UpdateBatch
N/A
Yes
Yes
Yes
N/A
Yes
Yes
Yes
Yes
Yes
Yes
Yes
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
2
3
4
5
6
7
8
9
10
<html><head>
<title>dbnewrec.asp</title>&
<body bgcolor="#FFFFFF">
<% ' My ASP program that allows you to append a record %>
<form name="myauthor" action="dbnewrecSQL.asp" method="GET">
<p>Author ID: <input type="TEXT" name="id"></p>
<p> Author Name: <input type="TEXT" name="name"></p>
<p> Year Born: <input type="TEXT" name="year"></p>
<p> <input type="SUBMIT"> </p>
</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
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
SQLStmt = SQLStmt & "VALUES (" & auid
SQLStmt = SQLStmt & ",'" & auname & "'"
SQLStmt = SQLStmt & "," & int(auyear) & ")"
Set RS = Conn.Execute(SQLStmt)
set rs=nothing
If err.number>0 then
response.write "VBScript Errors Occured:" & "<P>"
response.write "Error Number=" & err.number & "<P>"
response.write "Error Descr.=" & err.description & "<P>"
response.write "Help Context=" & err.helpcontext & "<P>"
response.write "Help Path=" & err.helppath & "<P>"
response.write "Native Error=" & err.nativeerror & "<P>"
response.write "Source=" & err.source & "<P>"
response.write "SQLState=" & err.sqlstate & "<P>"
else
response.write "No VBScript Errors Occured" & "<P>"
end if
IF conn.errors.count> 0 then
response.write "Database Errors Occured" & "<br>"
response.write "<b>" & SQLstmt & "</b><P>"
for counter= 0 to conn.errors.count
response.write "Error #" & conn.errors(counter).number & "<P>"
response.write "Error desc. -> " & conn.errors(counter).description & "<P>"
next
else
response.write "No Database Errors Occured!" & "<P>"
end if
Conn.Close
set conn=nothing
%>
</BODY>
</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
2
3
4
5
6
7
8
9
10
<html><head>
<title>dbnewrec.asp</title>&
<body bgcolor="#FFFFFF">
<% ' My ASP program that allows you to append a record %>
<form name="myauthor" action="dbnewADOrespond.asp" method="GET">
<p>Author ID: <input type="TEXT" name="id"></p>
<p> Author Name: <input type="TEXT" name="name"></p>
<p> Year Born: <input type="TEXT" name="year"></p>
<p> <input type="SUBMIT"> </p>
</form></body></html>
The form responder looks like this:
1
2
3
4
5
6
7
8
9
10
<TITLE>dbnewADO.asp</TITLE>
<body bgcolor="#FFFFFF">
<HTML>
<!--#INCLUDE VIRTUAL="/ADOVBS.INC" -->
<!--#INCLUDE VIRTUAL="/learn/test/lib_errors.asp" -->
<%
on error resume next
auname=request.querystring("name")
auyear=request.querystring("year")
auID=request.querystring("ID")
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
If
auid<9000 then
auid=auid+9000
end if
conn="DSN=Student;uid=student;pwd=magic"
Set RS = Server.CreateObject("ADODB.Recordset")
RS.Open "authors",Conn,adopenstatic,adlockoptimistic
RS.AddNew
'RS("AU_ID")=auid
RS("Author") = auname
RS("Year_Born")= int(auyear)
RS.Update
Call ErrorVBscriptReport("Adding Record")
Call ErrorADOReport("Adding Record",RS.activeconnection)
RS.Close
set rs=nothing
%>
</BODY>
</HTML>
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
●
eliminate multiple response.writes
●
eliminate do until eof tests.
The script to display the table utilizing getstring is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<TITLE>dbtablegetstring.asp</TITLE>
<body bgcolor="#FFFFFF">
<%
whichDSN="DSN=Student;uid=student;pwd=magic"
mySQL="select * from publishers where state='NY'"
' ASP program that displays a database in table form
set conntemp=server.createobject("adodb.connection")
conntemp.open whichDSN
set rstemp=conntemp.execute(mySQL)
If rstemp.eof then
response.write "No records matched<br>"
response.write mySQL & "<br>So cannot make table..."
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
response.end
end if
response.write "<table border='1'><tr>"
'Put Headings On The Table of Field Names
for each whatever in rstemp.fields
response.write "<td><b>" & whatever.name & "</B></TD>"
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
next
response.write "</tr><tr><td>"
response.write rstemp.getstring(,, "</td><td>", "</td></tr><TR><TD>", "-null-")
response.write "</td></tr></table>"
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
%>
</body></html>
A similar script to display a list box utilizing getstring is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!--#INCLUDE VIRTUAL="/ADOVBS.INC" -->
<html><head>
<TITLE>dblistgetstring.asp</TITLE>&
<body bgcolor="#FFFFFF">
<%
' ASP program that displays a database in list form
myDSN="DSN=Student;uid=student;pwd=magic"
mySQL="select distinct state from publishers"
set conntemp=server.createobject("adodb.connection")
conntemp.open "DSN=Student;uid=student;pwd=magic"
' Const adCmdUnknown, adCmdText, adCmdTable (no) , adCmdStoredProc
set rstemp=server.createobject("adodb.recordset")
rstemp.open mySQL, conntemp, adopenforwardonly, _
adlockReadOnly, adCmdUnknown
response.write "<form><select name='state'><option>"
tempSTR=rstemp.getstring(,, "", "</option><option>", "&nbsp;")
response.write tempSTR
response.write "</select></form>"
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
%>
</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
2
3
4
<HEAD><TITLE>sqlservertablelist.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<%
whichDSN="DSN=student;uid=student;pwd=magic"
5
6
7
8
9
call query2table("select name,type from sysobjects where type='U'", whichDSN)
%>
<!--#include virtual="/learn/test/lib_dbtable.asp"-->
</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
2
3
4
5
6
7
8
9
<HEAD><TITLE>accesstablelist.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<%
whichDSN="DRIVER={Microsoft Access Driver (*.mdb)}; "
whichDSN=whichDSN & "DBQ=" & server.mappath("/learn/test/biblio.mdb")
call query2table("select * from MsysObjects WHERE type = 1",whichDSN)
%>
<!--#include virtual="/learn/test/lib_dbtable.asp"-->
</BODY></HTML>
The Include file looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<%
sub query2table(inputquery, inputDSN)
dim conntemp, rstemp
set conntemp=server.createobject("adodb.connection")
conntemp.open inputDSN
set rstemp=conntemp.execute(inputquery)
howmanyfields=rstemp.fields.count -1%>
<table border=1><tr>
<% 'Put Headings On The Table of Field Names
for i=0 to howmanyfields %>
<td><b><%=rstemp(i).name%></B></TD>
<% next %>
</tr>
<% ' Now lets grab all the records
do while not rstemp.eof %>
<tr>
<% for i = 0 to howmanyfields
thisvalue=rstemp(i)
If isnull(thisvalue) then
thisvalue="&nbsp;"
end if%>
<td valign=top><%=thisvalue%></td>
<% next %>
</tr>
<%rstemp.movenext
loop%>
</table>
<%
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
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
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<TITLE>dbschemas.asp</TITLE>
</head>
<body bgcolor="#FFFFFF">
<!--#INCLUDE VIRTUAL="/ADOVBS.INC" -->
<!--#INCLUDE VIRTUAL="/learn/test/lib_fieldtypes.asp" -->
<%
myDSN="DSN=Student;uid=student;pwd=magic"
set conntemp=server.createobject("adodb.connection")
conntemp.open myDSN
Set rsSchema = conntemp.OpenSchema(adSchemaColumns)
thistable=""
pad="&nbsp;&nbsp;&nbsp;"
DO UNTIL rsSchema.EOF
prevtable=thistable
thistable=rsSchema("Table_Name")
thiscolumn=rsSchema("COLUMN_NAME")
IF thistable<>prevtable THEN
response.write "Table=<b>" & thistable & "</b><br>"
response.write "TABLE_CATALOG=<b>" & rsSchema("TABLE_CATALOG") & "</b><br>"
response.write "TABLE_SCHEMA=<b>" & rsSchema("TABLE_SCHEMA") & "</b><p>"
END IF
response.write "<br>" & pad & "Field=<b>" & thiscolumn & "</b><br>"
response.write pad & "Type=<b>" & fieldtypename(rsSchema("DATA_TYPE")) & "</b><br>"
DIM colschema(27)
colschema(0)="TABLE_CATALOG"
colschema(1)="TABLE_SCHEMA"
colschema(2)="TABLE_NAME"
colschema(3)="COLUMN_NAME"
colschema(4)="COLUMN_GUID"
colschema(5)="COLUMN_PROP_ID"
colschema(6)="ORDINAL_POSITION"
colschema(7)="COLUMN_HASDEFAULT"
colschema(8)="COLUMN_DEFAULT"
colschema(9)="COLUMN_FLAGS"
colschema(10)="IS_NULLABLE"
colschema(11)="DATA_TYPE"
colschema(12)="TYPE_GUID"
colschema(13)="CHARACTER_MAXIMUM_LENGTH"
colschema(14)="CHARACTER_OCTET_LENGTH"
colschema(15)="NUMERIC_PRECISION"
colschema(16)="NUMERIC_SCALE"
colschema(17)="DATETIME_PRECISION"
colschema(18)="CHARACTER_SET_CATALOG"
colschema(19)="CHARACTER_SET_SCHEMA"
colschema(20)="CHARACTER_SET_NAME"
colschema(21)="COLLATION_CATALOG"
colschema(22)="COLLATION_SCHEMA"
colschema(23)="COLLATION_NAME"
colschema(24)="DOMAIN_NAME"
colschema(25)="DOMAIN_CATALOG"
colschema(26)="DOMAIN_SCHEMA"
colschema(27)="DESCRIPTION"
ON ERROR RESUME NEXT
FOR counter=4 to 27
thisColInfoType=colschema(counter)
thisColInfo=rsSchema(thisColInfoType)
If err.number<>0 then
thiscolinfo="-error-"
err.clear
END IF
IF thisColInfo<>"" THEN
response.write pad & pad & pad & thiscolinfotype
69
70
71
72
73
74
75
76
77
78
79
80
81
82
response.write "=<b>" & thiscolinfo & "</b><br>"
END IF
NEXT
response.flush
rsSchema.MoveNext
LOOP
rsSchema.Close
set rsSchema=nothing
conntemp.close
set conntemp=nothing
%>
</body></html>
Here is the contents of lib_fieldtypes.asp which is included to make this example work:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<%
FUNCTION fieldtypename(parm1)
SELECT CASE Parm1
CASE 0
fieldtypename="adEmpty"
CASE 16
fieldtypename="adTinyInt"
CASE 2
fieldtypename="adSmallInt"
CASE 3
fieldtypename="adInteger"
CASE 20
fieldtypename="adBigInt"
CASE 17
fieldtypename="adUnsignedTinyInt"
CASE 18
fieldtypename="adUnsignedSmallInt"
CASE 19
fieldtypename="adUnsignedInt"
CASE 21
fieldtypename="adUnsignedBigInt"
CASE 4
fieldtypename="adSingle"
CASE 5
fieldtypename="adDouble"
CASE 6
fieldtypename="adCurrency"
CASE 14
fieldtypename="adDecimal"
CASE 131
fieldtypename="adNumeric"
CASE 11
fieldtypename="adBoolean"
CASE 10
fieldtypename="adError"
CASE 132
fieldtypename="adUserDefined"
CASE 12
fieldtypename="adVariant"
CASE 9
fieldtypename="adIDispatch"
CASE 13
fieldtypename="adIUnknown"
CASE 72
fieldtypename="adGUID"
CASE 7
fieldtypename="adDate"
CASE 133
fieldtypename="adDBDate"
CASE 134
fieldtypename="adDBTime"
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
CASE 135
fieldtypename="adDBTimeStamp"
CASE 8
fieldtypename="adBSTR"
CASE 129
fieldtypename="adChar"
CASE 200
fieldtypename="adVarChar"
CASE 201
fieldtypename="adLongVarChar"
CASE 130
fieldtypename="adWChar"
CASE 202
fieldtypename="adVarWChar"
CASE 203
fieldtypename="adLongVarWChar"
CASE 128
fieldtypename="adBinary"
CASE 204
fieldtypename="adVarBinary"
CASE 205
fieldtypename="adLongVarBinary"
CASE ELSE
fieldtypename="Undefined by ADO"
END SELECT
END FUNCTION
%>
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<html><head>
<TITLE>dbschemasall.asp</TITLE>
</head>
<body bgcolor="#FFFFFF">
<!--#INCLUDE VIRTUAL="/ADOVBS.INC" -->
<!--#INCLUDE VIRTUAL="/learn/test/lib_schemas.asp" -->
<%
myDSN="DSN=Student;uid=student;pwd=magic"
DIM colschema(30)
colschema(0)=adSchemaProviderSpecific
colschema(1)=adSchemaAsserts
colschema(2)=adSchemaCatalogs
colschema(3)=adSchemaCharacterSets
colschema(4)=adSchemaCollations
colschema(5)=adSchemaColumns
colschema(6)=adSchemaCheckConstraints
colschema(7)=adSchemaConstraintColumnUsage
colschema(8)=adSchemaConstraintTableUsage
colschema(9)=adSchemaKeyColumnUsage
colschema(10)=adSchemaReferentialContraints
colschema(11)=adSchemaTableConstraints
colschema(12)=adSchemaColumnsDomainUsage
colschema(13)= adSchemaIndexes
colschema(14)=adSchemaColumnPrivileges
colschema(15)=adSchemaTablePrivileges
colschema(16)=adSchemaUsagePrivileges
colschema(17)=adSchemaProcedures
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
colschema(18)=adSchemaSchemata
colschema(19)=adSchemaSQLLanguages
colschema(20)=adSchemaStatistics
colschema(21)=adSchemaTables
colschema(22)=adSchemaTranslations
colschema(23)=adSchemaProviderTypes
colschema(24)=adSchemaViews
colschema(25)=adSchemaViewColumnUsage
colschema(26)=adSchemaViewTableUsage
colschema(27)=adSchemaProcedureParameters
colschema(28)=adSchemaForeignKeys
colschema(29)=adSchemaPrimaryKeys
colschema(30)=adSchemaProcedureColumns
FOR counter=1 to 30
thisSchema=colSchema(counter)
Call Schema2Table(myDSN,thisSchema)
response.write "<p>"
NEXT
%>
</body></html>
The include file lib_schemas.asp looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<%
FUNCTION schemaName(parm1)
SELECT CASE parm1
CASE adSchemaProviderSpecific
schemaname="adSchemaProviderSpecific"
CASE adSchemaAsserts
schemaName="adSchemaAsserts"
CASE adSchemaCatalogs
schemaName="adSchemaCatalogs"
CASE adSchemaCharacterSets
schemaName="adSchemaCharacterSets"
CASE adSchemaCollations
schemaName="adSchemaCollations"
CASE adSchemaColumns
schemaName="adSchemaColumns"
CASE adSchemaCheckConstraints
schemaName="adSchemaCheckConstraints"
CASE adSchemaConstraintColumnUsage
schemaName="adSchemaConstraintColumnUsage"
CASE adSchemaConstraintTableUsage
schemaName="adSchemaConstraintTableUsage"
CASE adSchemaKeyColumnUsage
schemaName="adSchemaKeyColumnUsage"
CASE adSchemaReferentialContraints
schemaName="adSchemaReferentialContraints"
CASE adSchemaTableConstraints
schemaName="adSchemaTableConstraints"
CASE adSchemaColumnsDomainUsage
schemaName="adSchemaColumnsDomainUsage"
CASE adSchemaIndexes
schemaName="adSchemaIndexes"
CASE adSchemaColumnPrivileges
schemaName="adSchemaColumnPrivileges"
CASE adSchemaTablePrivileges
schemaName="adSchemaTablePrivileges"
CASE adSchemaUsagePrivileges
schemaName="adSchemaUsagePrivileges"
CASE adSchemaProcedures
schemaName="adSchemaProcedures"
CASE adSchemaSchemata
schemaName="adSchemaSchemata"
CASE adSchemaSQLLanguages
schemaName="adSchemaSQLLanguages"
CASE adSchemaStatistics
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
schemaName="adSchemaStatistics"
CASE adSchemaTables
schemaName="adSchemaTables"
CASE adSchemaTranslations
schemaName="adSchemaTranslations"
CASE adSchemaProviderTypes
schemaName="adSchemaProviderTypes"
CASE adSchemaViews
schemaName="adSchemaViews"
CASE adSchemaViewColumnUsage
schemaName="adSchemaViewColumnUsage"
CASE adSchemaViewTableUsage
schemaName="adSchemaViewTableUsage"
CASE adSchemaProcedureParameters
schemaName="adSchemaProcedureParameters"
CASE adSchemaForeignKeys
schemaName="adSchemaForeignKeys"
CASE adSchemaPrimaryKeys
schemaName="adSchemaPrimaryKeys"
CASE adSchemaProcedureColumns
schemaName="adSchemaProcedureColumns"
CASE ELSE
schemaName="-unknown-"
END SELECT
END FUNCTION
SUB Schema2Table(parmDSN, parmSchemaName)
set conntemp=server.createobject("adodb.connection")
conntemp.open parmDSN
on error resume next
set rsSchema=conntemp.OpenSchema(parmSchemaName)
IF err.number=3251 THEN
response.flush
response.write "<b>" & SchemaName(parmSchemaName)
response.write "</b><br> is not supported<br>"
err.clear
ELSE
Call Schema2Table(thisSchema)
response.write "<P><b>" & schemaName(parmSchemaName) & "</b><br>"
response.write "<table border=1><tr>"
'Put Headings On The Table of Field Names
for each whatever in rsSchema.fields
response.write "<td><b>" & whatever.name & "</b></td>"
next
response.write "</tr>"
DO UNTIL rsSchema.eof
response.write "<tr>"
for each whatever in rsSchema.fields
thisfield=whatever.value
if isnull(thisfield) then
thisfield="&nbsp;"
end if
if trim(thisfield)="" then
thisfield="&nbsp;"
end if
response.write "<td valign=top>" & thisfield & "</td>"
next
response.write "</tr>"
rsSchema.MoveNext
LOOP
response.write "</table><br>"
response.flush
END IF
rsSchema.Close
112
113
114
115
116
117
set rsSchema=nothing
conntemp.close
set conntemp=nothing
END SUB
%>
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.
●
fields with spaces in their names must be surrounded with []
●
set parameters must have commas between them
Text fields with single quote ' cannot be placed into SQL statements unmodified. Notice how the last example below uses the
VBScript replace command to transform a string that may contain embedded ' .
Statement with Flaws
Improved Statement (fixes in red)
added space before SET
UPDATE mytableSET LocID=0007,Material=13 UPDATE mytable SET
LocID='0007',Material='13 1/4',
1/4 Description=T-shirts ListPrice=35
Description='T-shirts', [List Price]=35
WHERE CusID=97
WHERE CusID=97
INSERT INTO authors (AU_ID, author,
INSERT INTO authors (AU_ID, author,
year_born) VALUES (7000, Joe
year_born) VALUES (7000, 'Joe
Smith,1950)
Smith',1950)
SELECT * from atable where state = 'MD'
SELECT * from atable where state = MD
and
and
year born<1955
and [year born]<1955
<%
<%
key=request.querystring("id")
key=request.querystring("id")
au=request.querystring("author")
au=request.querystring("author")
au=Replace(au, "'", "''")
birthyear=request.querystring("year")
birthyear=request.querystring("year")
SQLstmt="INSERT INTO authors (AU_ID,
SQLstmt="INSERT INTO authors (AU_ID,
author, year_born) VALUES ("
author, year_born) VALUES ("
SQLstmt= SQLstmt & key & ","
SQLstmt= SQLstmt & key & ",'"
SQLstmt= SQLstmt & author & ","
SQLstmt= SQLstmt & author & "',"
SQLstmt= SQLstmt & birthyear & ")"
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
2
3
<TITLE>db1parm.asp</TITLE>
<body bgcolor="#FFFFFF">
<%
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
' My ASP program that talks to a database
set conntemp=server.createobject("adodb.connection")
conntemp.open "DSN=Student;uid=student;pwd=magic"
p1=request.querystring("ID")
temp="select * from authors where AU_ID=" & p1
set rstemp=conntemp.execute(temp)
howmanyfields=rstemp.fields.count -1
%>
<table border=1>
<tr>
<% 'Put Headings On The Table of Field Names
for i=0 to howmanyfields %>
<td><b><%=rstemp(i).name %></B></TD>
<% next %>
</tr>
<% ' Now lets grab all the records
do while not rstemp.eof %>
<tr>
<% for i = 0 to howmanyfields%>
<td valign=top><% = rstemp(i) %></td>
<% next %>
</tr>
<% rstemp.movenext
loop
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing%>
</table>
</body>
</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
●
To double check it is in the database try:
Test This -->/learn/test/db1parm.asp?id=9000
●
Now try:
Test This -->/learn/test/dbupdate.asp?name=NewPerson&id=9000&year=1964
to change the "NewPerson" Birthday to 1964 again and
Test This -->/learn/test/dbupdate.asp?name=NewPerson&id=9000&year=1901
The script is:
1
<TITLE>dbupdate.asp</TITLE>
2
<body bgcolor="#FFFFFF">
3
<HTML>
4
<%
5
on error resume 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
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
SQLStmt = SQLstmt & "SET Author='" & auname & "',"
SQLstmt = SQLstmt & "year_born=" & auyear
SQLStmt = SQLStmt & " WHERE AU_ID=" & auid
Set RS = Conn.Execute(SQLStmt)
If err.number>0 then
response.write "VBScript Errors Occured:" & "<P>"
response.write "Error Number=" & err.number & "<P>"
response.write "Error Descr.=" & err.description & "<P>"
response.write "Help Context=" & err.helpcontext & "<P>"
response.write "Help Path=" & err.helppath & "<P>"
response.write "Native Error=" & err.nativeerror & "<P>"
response.write "Source=" & err.source & "<P>"
response.write "SQLState=" & err.sqlstate & "<P>"
else
response.write "No problems occured!" & "<P>"
end if
IF conn.errors.count> 0 then
response.write "Database Errors Occured" & "<P>"
for counter= 0 to conn.errors.count
response.write "Error #" & conn.errors(counter).number & "<P>"
response.write "Error desc. -> " & conn.errors(counter).description & "<P>"
next
else
response.write SQLstmt
response.write "Everything Went Fine. Author is updated now!" & "<P>"
end if
set rstemp=nothing
Conn.Close
set conntemp=nothing
%>
</BODY>
</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
[email protected]
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'
●
Numeric fields need no special characters before and after
"select * from publishers where PubID=10"
●
If you aren't sure how to spell the text field or are looking for sound alikes, LIKE supports %% wildcards
"select * from publishers where Name like 'A%%'"
These basic WHERE clause guidelines above are the fundamental building block of searches.
It is also helpful to utilize the equality operators, i.e.
<>
>
<
>=
<=
●
not equal
greater than
less than
greater than OR equal
less than or equal
Numeric fields benefit most from the equality operators:
"select * from publishers where PubID>10"
http://www.learnASP.com/learn/SQLwhere2.asp by Charles M. Carroll
Page 128
SQL Where Examples by Charles Carroll
Here are some where statements and their results.
1
2
3
4
5
6
7
<HEAD><TITLE>SQLwhere1.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<%
call query2table("select * from publishers where name like 'A%%'")
%>
<!--#include virtual="/learn/test/subdbtable.inc"-->
</BODY></HTML>
1
2
3
4
5
6
7
<HEAD><TITLE>SQLwhere2.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<%
call query2table("select * from titles where Year_Published >= 1994")
%>
<!--#include virtual="/learn/test/subdbtable.inc"-->
</BODY></HTML>
1
2
3
4
5
6
7
<HEAD><TITLE>SQLwhere3.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<%
call query2table("select * from publishers where fax like '212%%'")
%>
<!--#include virtual="/learn/test/subdbtable.inc"-->
</BODY></HTML>
1
2
3
4
5
6
7
<HEAD><TITLE>sqlwhere4.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<%
call query2table("select * from publishers where state<> 'NY'")
%>
<!--#include virtual="/learn/test/subdbtable.inc"-->
</BODY></HTML>
The Include file looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<%
sub query2table(inputquery)
set conntemp=server.createobject("adodb.connection")
conntemp.open "DSN=Student;uid=student;pwd=magic"
set rstemp=conntemp.execute(inputquery)
howmanyfields=rstemp.fields.count -1%>
<table border=1><tr>
<% 'Put Headings On The Table of Field Names
for i=0 to howmanyfields %>
<td><b><%=rstemp(i).name%></B></TD>
<% next %>
</tr>
<% ' Now lets grab all the records
do while not rstemp.eof %>
<tr>
<% for i = 0 to howmanyfields
thisvalue=rstemp(i)
If isnull(thisvalue) then
thisvalue="&nbsp;"
end if%>
<td valign=top><%=thisvalue%></td>
<% next %>
</tr>
<%rstemp.movenext
loop%>
</table>
<%
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
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
2
3
4
<HEAD><TITLE>sqlwhereform1.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<Form action = "sqlwhereForm1respond.asp" method=GET>
Choose A State:<p>
5
6
7
State: <Input NAME="st" MaxLength="2" size="3"><P>
<Input type="submit" value="Get Data">&nbsp;<Input type="reset" value="Clear State"></form>
</BODY></HTML>
1
2
3
4
5
6
7
8
9
10
11
12
13
<HEAD><TITLE>sqlwhereform1respond.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<%
myDSN="DSN=student;uid=student;pwd=magic"
mystate=request.querystring("st")
SQLtemp="select * from publishers where state='"
SQLtemp=SQLtemp & mystate & "'"
call query2table(SQLtemp,myDSN)
%>
<!--#include virtual="/learn/test/lib_dbtable.asp"-->
</BODY></HTML>
The file lib_subdbtable.asp looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<%
sub query2table(inputquery, inputDSN)
dim conntemp, rstemp
set conntemp=server.createobject("adodb.connection")
conntemp.open inputDSN
set rstemp=conntemp.execute(inputquery)
howmanyfields=rstemp.fields.count -1%>
<table border=1><tr>
<% 'Put Headings On The Table of Field Names
for i=0 to howmanyfields %>
<td><b><%=rstemp(i).name%></B></TD>
<% next %>
</tr>
<% ' Now lets grab all the records
do while not rstemp.eof %>
<tr>
<% for i = 0 to howmanyfields
thisvalue=rstemp(i)
If isnull(thisvalue) then
thisvalue="&nbsp;"
end if%>
<td valign=top><%=thisvalue%></td>
<% next %>
</tr>
<%rstemp.movenext
loop%>
</table>
<%
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
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
2
<HEAD><TITLE>SQLwhereform2.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
3
4
5
6
7
8
9
<Form action = "SQLwhereForm2respond.asp" method=GET>
Choose A City:<p>
City: <Input NAME="cy" MaxLength="20" size="23"><P>
<input TYPE="checkbox" NAME="ExactSearch" CHECKED>Exact Search<P>
* note if Exact Search is -> NOT CHECKED <-<br>You can use % as a wildcard<p>
<Input type="submit" value="Get Data">&nbsp;<Input type="reset" value="Clear City"></form>
</BODY></HTML>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<HTML><HEAD>
<TITLE>sqlwhereform2respond.asp</TITLE>&
<body bgcolor="#FFFFFF">
<%
myDSN="DSN=student;uid=student;pwd=magic"
mycity=request.querystring("cy")
myexactsearch=request.querystring("exactsearch")
SQLtemp="select * from publishers where city"
If myexactsearch="on" then
SQLtemp=SQLtemp & " ='"
Else
SQLtemp=SQLtemp & " LIKE '"
End If
SQLtemp=SQLtemp & mycity & "'"
'response.write SQLtemp
call query2table(SQLtemp,myDSN)
%>
<!--#include virtual="/learn/test/lib_dbtable.asp"-->
</BODY></HTML>
The file lib_dbtable.asp looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<%
sub query2table(inputquery, inputDSN)
dim conntemp, rstemp
set conntemp=server.createobject("adodb.connection")
conntemp.open inputDSN
set rstemp=conntemp.execute(inputquery)
howmanyfields=rstemp.fields.count -1%>
<table border=1><tr>
<% 'Put Headings On The Table of Field Names
for i=0 to howmanyfields %>
<td><b><%=rstemp(i).name%></B></TD>
<% next %>
</tr>
<% ' Now lets grab all the records
do while not rstemp.eof %>
<tr>
<% for i = 0 to howmanyfields
thisvalue=rstemp(i)
If isnull(thisvalue) then
thisvalue="&nbsp;"
end if%>
<td valign=top><%=thisvalue%></td>
<% next %>
</tr>
<%rstemp.movenext
loop%>
</table>
<%
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
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
2
3
4
5
6
7
8
9
10
11
12
13
<HEAD><TITLE>SQLwhereform3.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<Form action = "SQLwhereForm3respond.asp" method=GET>
Choose A City:<p>
City:
<%
call query2list("select distinct city from publishers", _
"cy","DSN=student;uid=student;pwd=magic")
%>
<P>
<Input type="submit" value="Get Data">&nbsp;<Input type="reset" value="Clear City"></form>
</BODY></HTML>
<!--#include virtual="/learn/test/lib_dblist.asp"-->
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<html><head><TITLE>sqlwhereform3respond.asp</TITLE></head>
<body bgcolor="#FFFFFF">
<%
myDSN="DSN=student;uid=student;pwd=magic"
mycity=request.querystring("cy")
myexactsearch=request.querystring("exactsearch")
SQLtemp="select * from publishers where city"
If myexactsearch="on" then
SQLtemp=SQLtemp & " ='"
Else
SQLtemp=SQLtemp & " LIKE '"
End If
SQLtemp=SQLtemp & mycity & "'"
'response.write SQLtemp
call query2table(SQLtemp,myDSN)
%>
<!--#include virtual="/learn/test/lib_dbtable.asp"-->
</body></html>
The file lib_dbtable.asp looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<%
sub query2table(inputquery, inputDSN)
dim conntemp, rstemp
set conntemp=server.createobject("adodb.connection")
conntemp.open inputDSN
set rstemp=conntemp.execute(inputquery)
howmanyfields=rstemp.fields.count -1%>
<table border=1><tr>
<% 'Put Headings On The Table of Field Names
for i=0 to howmanyfields %>
<td><b><%=rstemp(i).name%></B></TD>
<% next %>
</tr>
<% ' Now lets grab all the records
do while not rstemp.eof %>
<tr>
<% for i = 0 to howmanyfields
thisvalue=rstemp(i)
If isnull(thisvalue) then
thisvalue="&nbsp;"
end if%>
<td valign=top><%=thisvalue%></td>
<% next %>
24
25
26
27
28
29
30
31
32
33
</tr>
<%rstemp.movenext
loop%>
</table>
<%
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
end sub%>
The file lib_dblist.asp looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<%sub query2list(myquery,myname,myDSN)
dim conntemp, rstemp
set conntemp=server.createobject("adodb.connection")
conntemp.open myDSN
set rstemp=conntemp.execute(myquery)
%>
<Select name="<%=myname%>">
<%
do while not rstemp.eof
thisfield=trim(RStemp(0))
if isnull(thisfield) or thisfield="" then
' ignore
else
response.write "<option>" & thisfield & "</option>"
end if
rstemp.movenext
loop
%>
</select>
<%rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
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
2
3
4
5
6
7
8
9
10
<HEAD><TITLE>SQLcities.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<Form action = "SQLcitiesrespond.asp" method="POST">
Choose City (or Cities):<p>
<%
call query2listm("select distinct city from publishers", _
"cy","DSN=student;uid=student;pwd=magic")
%>
<P>
<Input type="submit" value="Get Data">&nbsp;<Input type="reset" value="Clear City"></form>
11
12
13
</BODY></HTML>
<!--#include virtual="/learn/test/lib_dblistm.asp"-->
The responder looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<HEAD><TITLE>sqlcitiesrespond.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<%
citycount=request.form("cy").count
If citycount=0 then%>
<B>You never choose a city!</b><br>
<a href="sqlcities.asp">Choose City</a>
<%
response.end
end if
firstcity=request.form("cy")(1)
SQLtemp="select * from publishers "
SQLtemp = SQLtemp & " where city='" & firstcity & "'"
for counter=2 to citycount
whichcity=request.form("cy")(counter)
SQLtemp = SQLtemp & " or city='" & whichcity & "' "
next
response.write SQLtemp
call query2table(SQLtemp,"DSN=student;uid=student;pwd=magic")
%>
<!--#include virtual="/learn/test/lib_dbtable.asp"-->
</BODY></HTML>
The file lib_dbtable.asp looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<%
sub query2table(inputquery, inputDSN)
dim conntemp, rstemp
set conntemp=server.createobject("adodb.connection")
conntemp.open inputDSN
set rstemp=conntemp.execute(inputquery)
howmanyfields=rstemp.fields.count -1%>
<table border=1><tr>
<% 'Put Headings On The Table of Field Names
for i=0 to howmanyfields %>
<td><b><%=rstemp(i).name%></B></TD>
<% next %>
</tr>
<% ' Now lets grab all the records
do while not rstemp.eof %>
<tr>
<% for i = 0 to howmanyfields
thisvalue=rstemp(i)
If isnull(thisvalue) then
thisvalue="&nbsp;"
end if%>
<td valign=top><%=thisvalue%></td>
<% next %>
</tr>
<%rstemp.movenext
loop%>
</table>
<%
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
end sub%>
The file lib_dblistm.asp looks like this:
1
<%
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
SUB query2listm(myquery,myname,myDSN)
dim conntemp, rstemp
set conntemp=server.createobject("adodb.connection")
conntemp.open myDSN
set rstemp=conntemp.execute(myquery)
%>
<Select name="<%=myname%>" multiple>
<%
do while not rstemp.eof
thisfield=trim(RStemp(0))
if isnull(thisfield) or thisfield="" then
' ignore
else
response.write "<option>" & thisfield & "</option>"
end if
rstemp.movenext
loop
%>
</select>
<%rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
END SUB
%>
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'
●
If you count a specific field you must groupby that field or it won't work:
"select count(city),city from publishers group by city"
●
The AS operator allows you to specify a name for the counted field:
"select count(city) as howmany,city from publishers group by city"
1
2
3
4
5
6
7
<HEAD><TITLE>SQLcount1.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<%
call query2table("select count(*) from publishers where state='NY'")
%>
<!--#include virtual="/learn/test/subdbtable.inc"-->
</BODY></HTML>
1
2
3
4
5
6
7
<HEAD><TITLE>SQLcount2.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<%
call query2table("select count(city),city from publishers group by city")
%>
<!--#include virtual="/learn/test/subdbtable.inc"-->
</BODY></HTML>
1
2
3
4
5
6
7
<HEAD><TITLE>SQLcount3.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<%
call query2table("select count(city) as howmany,city from publishers group by city")
%>
<!--#include virtual="/learn/test/subdbtable.inc"-->
</BODY></HTML>
1
2
3
4
5
6
7
<HEAD><TITLE>SQLcount4.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<%
call query2table("select count(*),city,state from publishers group by city,state")
%>
<!--#include virtual="/learn/test/subdbtable.inc"-->
</BODY></HTML>
The Include file looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<%
sub query2table(inputquery)
set conntemp=server.createobject("adodb.connection")
conntemp.open "DSN=Student;uid=student;pwd=magic"
set rstemp=conntemp.execute(inputquery)
howmanyfields=rstemp.fields.count -1%>
<table border=1><tr>
<% 'Put Headings On The Table of Field Names
for i=0 to howmanyfields %>
<td><b><%=rstemp(i).name%></B></TD>
<% next %>
</tr>
<% ' Now lets grab all the records
do while not rstemp.eof %>
<tr>
<% for i = 0 to howmanyfields
thisvalue=rstemp(i)
If isnull(thisvalue) then
thisvalue="&nbsp;"
end if%>
<td valign=top><%=thisvalue%></td>
<% next %>
</tr>
<%rstemp.movenext
loop%>
</table>
<%
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
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.
● IIS Basic Authentication
Can expose your NT usernames and passwords unless all connections are over SSL.
● 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.
● Write your own filter
Flexible, but resource intensive to build.
● Cookie Based Authentication with ASP pages
Only protects ASP pages. Can be slow. Requires cookies. Cookie-based systems can be susceptible to spoofing.
● Self-Authenticating ISAPI dlls, CGI-scripts using Basic Authentication.
Good performance, all content generated though a single URL. Doesn't use conventional directory/file/html format.
● Certificate based.
Secure, but intimidating for webmasters and surfers alike. Requires SSL.
http://www.learnASP.com/learn/authenticatecomparisons.asp by Charles M.
Carroll
Page 139
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)
●
Performance is critical. If (as you hope), your site becomes wildly popular, you don't want a dead-slow server (impacts
SSL/Certificates, ASP)
Which Type
Why use it?
Why not use it?
How to use it.
Why
Why not
How
Why
Why not
How
Why
Why not
How
Why
Why not
How
Why
Why not
How
Why
Why not
How
Why
Why not
How
IIS NT Challenge Response
IIS Basic Authentication
A Third Party Basic Authentication filter
Write your own Basic Authentication filter
Cookie Based Authentication with ASP pages
Self-authenticating scripts
Certificate based authentication.
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
● there aren't too many users
● you can require the use of a compatible browser (Internet Explorer is the only browser which supports NTCR).
You won't want to use NTFS if
● you want compatibility with browsers other than IE, or older browsers
● you want to protect directories on FAT partitions
●
●
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.
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.
Definitions
●
●
●
NTCR = NT Challenge Response
NTLM = NT Lan Manager
NTFS = NT File System
How to set up NTCR
In Internet Service Manager (IIS1-3) or the Microsoft Management Console for IIS (IIS4 and up) select the directory 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.
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.
● 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).
● Create an account for the each user to whom you want to give access, remove the permissions for
"IUSR_machinename" from the directory, and add permissions for the users you added.
Alternatively you could set up a group, permit access to that group, and add permitted users to that group.
Remember the user will need execute rights if the directory has any ASP, ISAPI extensions, counters etc.
http://www.learnASP.com/learn/authenticatecookies.asp by Charles M. Carroll
Page 142
Authentication -- Cookie 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.
● You don't mind excluding those who cannot or will not accept cookies.
● You don't have gif/jpeg/pdf or other non-ASP content, so you are not concerned about someone else creating
web-pages linking directly to your non-ASP protected content.
You won't want Cookie Based Authentication with ASP pages if
● You want to protect all content, not just ASP pages.
● You are worried about performance. Any reasonably large amount of Active Server Pages can have a 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.
● Cookie-based systems can be susceptible to spoofing.
Definitions
●
ASP = Active Server Pages.
How to use Cookie Based Authentication with ASP pages
We have a example in this Tutorial on the next pages that implements session based authentication for people who want to
implement this:
● http://www.activeserverpages.com/learn/security.asp
●
http://www.activeserverpages.com/learn/security2.asp
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
●
You accept the need for SSL and don't mind paying the performance penalty.
●
You already have a certificate or you don't mind paying for one and setting it up.
You won't want Certificate based authentication if :
●
The process of issuing a client certificate is too complex and intimidating for both you and your users
●
You do not want the performance hit of having all protected information exchanged via SSL
Definitions
●
SSL = secure socket layer.
●
MMC = Microsoft Management Console.
How to use Certificate based 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.
●
Select a directory you want to protect in the MMC
●
Click on the Secure Communicatations Edit button on the Directory Security property sheet and use the certificate you
obtained. Select both Enable Client Certificates and Require Client Certificate
●
Enable client certificates for this resource
●
Issue client certificates for access to this resource.
There are several good references to help understand and use Client Certificate technology. Some articles that are 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
●
"Web Project, Digital IDs" by Jon Udell in the March Edition of Byte magazine.
●
"Issuing digital certificates with Microsoft Certificate Server" section of the IIS Security White Paper by Microsoft.
http://www.learnASP.com/learn/authenticatebuild.asp by Charles M. Carroll
Page 144
Authentication -- Write your own 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
●
●
Authentication filter is not an option.
you have the skills, resources and time.
you want to validate against a specific or proprietary type of datasource, such as flat-file, or your own
database.
You won't want to write your own Basic Authentication filter if
● you have a short deadline
● you do not have the skills or resources required
● Basic Authentication is not secure enough for your purposes
● you want all accounts of every type in one userbase, specifically the NT user account database, for
administrative reasons.
● a third party tool like AuthentiX meets all your needs
Definitions
●
ISAPI = Internet Server Application Programming Interface
How to write your own Basic Authentication filter
You will need to build a dll that conforms to the ISAPI filter specification and has the following entry points:
● GetFilterVersion
● HttpFilterProc
The GetFilterVersion function is the first entry point called by the Internet Information Server. In this function 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.
●
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
●
You can also try logging out at test/securitylogout.asp which will put you back to square one. No security level will exist then.
The next page details the source code for all scripts needed to implement our example but here is the list:
securitylogin.asp
securityloginrespond.asp
securitylogout.asp
the login screen where someone can enter username/password and confirm
security level. It is a form that submits to securityloginrespond.asp
the screen to abandon someone's username/password and security level
securitylevel1required.asp
securitylevel2required.asp
securitylevel3required.asp
securitytestlevel1.asp
securitytestlevel2.asp
securitytestlevel3.asp
which can be included on individual pages to limit access to people with that
security level, i.e/:
<!--#include file="securitylevel1required.asp"-->
which demonstrate how security is implemented. These scripts cannot be
seen unless you login.
which anyone attempting to access a page without appropriate security level
is redirected to.
a 3 column Access database: username, password, security level. Sample
data is:
user=chaz, password=chaz, securitylevel=1
/learn/test/customsecurity.mdb user=chaz2, password=chaz2, securitylevel=2
user=chaz3, password=chaz3, securitylevel=3
Download Database
securitynotallowed.asp
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
2
3
4
5
6
7
8
9
<html><head>
<title>securitylogin.asp</title>
</head><body bgcolor="#FFFFFF">
<form action="securityloginrespond.asp" method="POST">
Sign In Page:<p>
Name -&gt; <input NAME="userName" size="20"><br>
Password -&gt; <input NAME="userPassword" size="20"><br>
<input type="submit"><input type="reset">
</form></body></html>
Here is the securityloginrespond.asp script:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<html><head>
<TITLE>securityloginrespond.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<%
dbname="/learn/test/secret/customsecurity.mdb"
myname=request.form("username")
mypassword=request.form("userpassword")
set conntemp=server.createobject("adodb.connection")
cnpath="DBQ=" & server.mappath(dbname)
conntemp.Open "DRIVER={Microsoft Access Driver (*.mdb)}; " & cnpath
sqltemp="select * from users where user='"
sqltemp=sqltemp & myname & "'"
set rstemp=conntemp.execute(SQLTemp)
If rstemp.eof then%>
we don't have a user named <%=Myname%> on file!<br>
Try <A href='securitylogin.asp'>Logging in</a> again
<%response.end
end if
If rstemp("Password")=mypassword then
session("name")=rstemp("user")
session("securitylevel")=rstemp("securitylevel")
response.write "Security Level=" & session("securitylevel")
else%>
Password Unrecognized<br>
25
26
27
28
29
30
31
32
33
Try <A href='securitylogin.asp'>Logging in</a> again
<%response.end
end if
rstemp.close
conntemp.close
set rstemp=nothing
set conntemp=nothing
%>
</body></html>
Here is the securitylogout.asp script:
1
2
3
4
5
6
7
8
9
<html><head>
<title>securitylogout.asp</title>&
<body>
<%
session.abandon
%>
Logged out Now!!!
</body>
</html>
Here is the securitylevel1required.asp script:
1
2
3
4
5
6
7
8
<%
response.expires=0
if session("securitylevel")>0 then
' nothing to do
else
response.redirect "securityunauthorized.asp"
end if
%>
Here is the securityunauthorized.asp script:
1
2
3
4
5
<html><head>
<title>unauthorized</title>&
<body>
You are unauthorized to read that page!
</body></html>
Here is the securitytestlevel1.asp script:
1
2
3
4
5
6
7
8
9
<!--#include file="securitylevel1required.asp"-->
<html><head>
<title>New Page </title>
<META HTTP-EQUIV="Expires" CONTENT="Tue, 04 Dec 1993 21:29:02 GMT">
</head><body>
My level 1 secret is Pretty Hot!!!<br>
Our president may not be as honest as we believed!
</body>
</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.
● Basic Authentication is not secure enough for your purposes
●
you want all accounts of every type in one userbase, specifically the NT user account database, for administrative
reasons.
Authentix, a third party Basic Authentication filter is the way to go if
●
●
●
●
●
●
●
●
●
●
●
You want the high performance that a filter offers
You want to be able to add and modify users from ASP and don't want the ASP pages to have SysAdmin priviledges
You want browser independence
You don't want any chance of compromising NT username/password security
You want to separate your web-users from your NT Accounts
You are concerned about performance. In addition to the speed associated with filter based solutions, AuthentiX is
unique in that it does not impersonate an NT account to grant access, eliminating the CPU-expensive call to
LogonUser on every request.
You have directories you want to validate against an ODBC database
You want to authenticate multiple IIS servers against a single ODBC machine on the LAN.
You want to use browser based remote administration
you need to protect all content in a directory: htm, asp, gif, jpg, zip, and so on.
you want advanced features like
❍ limiting concurrent logins,
❍ bandwith, request and login throttling,
❍ protect by IP, Domain Name and by referrer
AuthentiX is a fast, filter based third party tool for IIS authentication developed by Flicks Software (me).
It allows you to protect content directories and individual files by asking for usernames and passwords held separately from
the Windows NT usernames and passwords, ensuring the the security of your NT accounts.
Definitions
●
ODBC = Open Database Connectivity.
How to set up AuthentiX, a third party Basic Authentication filter
Setting up AuthentiX is easy and straighforward.
Download the free evaluation version, unzip it and run setup.exe. Installshield will guide you through the rest of 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.
● 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.
● 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.
● 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
● Using a browser, go to the URL that the directory is accessed from using IIS. It should prompt you for your username
and password.
● Type the username and password and you should be granted access.
You can see how to set up ODBC and other advanced options by downloading the online Windows help file or checking out
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
2
3
4
5
6
7
8
9
<html><head>
<title>citystatezip.asp</title>
</head><body bgcolor="#FFFFFF">
<Form action = "citystatezipRespond.asp" method="post">
Enter City <b>,</b> State Zip<p>
<Input NAME="CSZ" size ="40"><p>
<Input type="submit" value="Here is my Data!">
</form>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<html><head>
<title>citystateziprespond.asp</title>
</head><body>
<%
alldata=request("csz")
IF instr(alldata,",")=0 THEN%>
You need a comma<br>,<br>between city and state!<p>
<%response.end
END IF
findcomma=instr(alldata,",")
city=mid(alldata,1,findcomma-1)
leftover=trim(mid(alldata,findcomma+1))
findspace=instr(leftover," ")
state=mid(leftover,1,findspace)
leftover=mid(leftover,findspace+1)
zip=leftover
response.write "city=" & city & "<br>"
response.write "state=" & state & "<br>"
response.write "zip=" & zip & "<br>"
%>
</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
2
3
4
5
6
7
8
9
<html><head>
<title>states.asp</title>
</head><body bgcolor="#FFFFFF">
<form action="statesplitrespond.asp" method="post">
Enter State (or many states separated by <b>,<b><p>
<input NAME="states" size="40"><p>
<input type="submit" value="Get The Publishers!">
</form>
</body></html>
statesplitrespond.asp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!--#include virtual="/learn/test/lib_dbtable.asp"-->
<html><head>
<title>statesrespond.asp</title>&
<body>
<%
mySQL="select * from publishers " & whereclause
myDSN="DSN=student;uid=student;pwd=magic"
public allstates
tempinput=request("states")
allstates=split(tempinput,",")
maxcounter=ubound(allstates)
whereclause=" where state='" & allstates(0) & "'"
FOR counter=1 TO maxcounter
thisstate=allstates(counter)
whereclause=whereclause & " OR state='" & thisstate & "'"
NEXT
mySQL=mySQL & whereclause
Call Query2Table(mySQL,myDSN)
%>
</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
2
3
4
5
6
7
8
9
<html><head>
<title>statereplace.asp</title>
</head><body bgcolor="#FFFFFF">
<form action="statereplacerespond.asp" method="post">
Enter State (or many states separated by <b>,<b><p>
<input NAME="states" size="40"><p>
<input type="submit" value="Get The Publishers!">
</form>
</body></html>
statereplacerespond.asp
1
2
3
4
5
6
7
8
9
10
11
<!--#include virtual="/learn/test/lib_dbtable.asp"-->
<html><head>
<title>statesrespond.asp</title>&
<body>
<%
mySQL="select * from publishers " & whereclause
myDSN="DSN=student;uid=student;pwd=magic"
tempinput=request("states")
whereclause=" where state='" & tempinput
12
13
14
15
16
17
18
19
whereclause=replace(whereclause, ",","' OR state='")
whereclause=whereclause & "'"
mySQL=mySQL & whereclause
response.write mySQL
Call Query2Table(mySQL,myDSN)
%>
</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
2
3
4
5
6
7
8
9
<html><head>
<title>statejoin.asp</title>
</head><body bgcolor="#FFFFFF">
<form action="statejoinrespond.asp" method="post">
Enter State (or many states separated by <b>,<b><p>
<input NAME="states" size="40"><p>
<input type="submit" value="Get The Publishers!">
</form>
</body></html>
statejoinrespond.asp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!--#include virtual="/learn/test/lib_dbtable.asp"-->
<html><head>
<title>statejoinrespond.asp</title>&
<body>
<%
mySQL="select * from publishers "
myDSN="DSN=student;uid=student;pwd=magic"
public allstates
tempinput=request("states")
allstates=split(tempinput,",")
whereclause=" where state='" & JOIN(allstates, "' OR state='") & "'"
mySQL=mySQL & whereclause
response.write mySQL
Call Query2Table(mySQL,myDSN)
%>
</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
●
1
2
3
4
5
6
7
8
9
10
11
12
13
Method #2: the size is in a variable
<html><head>
<title>arraysredim.asp</title>
</head><body bgcolor="#FFFFFF">
<%
' this code
dim a_array(100)
' this code will fail
x=100
dim my_array(x)
%>
</body></html>
Assigning an array size with a variable produces an error unless the Redim command is used.
1
<html><head>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<title>arraysredimcorrect.asp</title>
</head><body bgcolor="#FFFFFF">
<%
dim my_array()
x=100
redim preserve my_array(x)
my_array(20)="Hi!"
my_array(40)="How are You"
lowcount=lbound(my_array)
highcount=ubound(my_array)
response.write "lowcount=" & lowcount & ";highcount=" & highcount & "<p>"
for counter=lowcount to highcount
response.write counter & "&nbsp;&nbsp;&nbsp;"
response.write my_array(counter) & "<br>"
next
%>
</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
2
3
4
5
6
7
<html><head>
<title>arraysloadbest.asp</title>
</head><body bgcolor="#FFFFFF">
<%
dim my_months
my_months=array("Jan","Feb","Mar","Apr", _
8
9
10
11
12
13
14
15
16
17
18
19
"May","Jun","Jul","Aug", _
"Sep","Oct","Nov","Dec")
' finally here is how you loop through an array
lowcount=lbound(my_months)
highcount=ubound(my_months)
response.write "lowcount=" & lowcount & ";highcount=" & highcount & "<p>"
for counter=lowcount to highcount
response.write my_months(counter) & "<br>"
next
%>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<html><head>
<title>dictionarybasics.asp</title>
</head><body bgcolor="#FFFFFF">
<%
set mysample=server.CreateObject("Scripting.Dictionary")
mysample.Add "haircolor", "brown"
mysample.add "eyecolor" , "blue"
mysample.add "dateofbirth", "5/13/64"
for each whatever in mysample
response.write whatever & "="
response.write mysample.item(whatever) & "<br>"
next
set mysample=nothing
%>
</body></html>
This is how to make an array of dictionary objects.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<html><head>
<title>dictionaryarrays.asp</title>
</head><body bgcolor="#FFFFFF">
<%
dim people(3)
Set people(0)
people(0).Add
people(0).Add
people(0).Add
people(0).add
people(0).add
= server.CreateObject("Scripting.Dictionary")
"fname", "Jane"
"lname", "Doe"
"haircolor", "brown"
"eyecolor" , "blue"
"dateofbirth", "1/10/60"
Set people(1)
people(1).Add
people(1).Add
people(1).Add
people(1).Add
people(1).add
people(1).add
= server.CreateObject("Scripting.Dictionary")
"fname", "Reginald"
"mname", "Elton"
"lname", "Dwight"
"haircolor", "red"
"eyecolor" , "dusty"
"dateofbirth", "1/10/60"
Set people(2) = server.CreateObject("Scripting.Dictionary")
people(2).Add "fname", "Hitoshi"
24
25
26
27
28
29
30
31
32
33
34
35
36
people(2).Add "lname", "Yoshitsugu"
' print out one item
for each whatever in people(1)
response.write whatever & "="
response.write people(1).item(whatever) & "<br>"
next
for counter=0 to 2
set people(counter)=nothing
next
%>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<HEAD><TITLE>subdates.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<form action="subdatesrespond.asp">
Depart:
<%call showdateform("depart")%>
<br>
Arrive:
<%call showdateform("arrive")%>
<input type="submit" value="Ready To Travel">
</form>
<%
sub showdateform(mylistname)
call showmonth(mylistname)
call showday(mylistname)
call showyear(mylistname)
end sub
%>
<%sub showmonth(listname)%>
<select name="<%=listname%>month">
<%
dim monthname
monthname=array("Jan","feb","Mar","Apr", _
"May","Jun","Jul","Aug", _
"Sep","Oct","Nov","Dec")
for counter=0 to 11
temp=monthname(counter)
response.write "<option value='" & counter+1
response.write "'>" & temp & "</option>"
next%>
</select>
<%end sub%>
<%sub showday(listname)%>
<select name="<%=listname%>day">
<%for counter=1 to 31
response.write "<option>" & counter & "</option>"
next%>
</select>
<%end sub%>
42
43
44
45
46
47
48
49
50
51
<%sub showyear(listname)%>
<select name="<%=listname%>year">
<%for counter=1964 to 2005
response.write "<option>" & counter & "</option>"
next%>
</select>
<%end sub%>
</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:
●
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
isdate() to validate a date
<HEAD><TITLE>subdatesrespond.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<%
dday=request.querystring("departday")
dmonth=request.querystring("departmonth")
dyear=request.querystring("departyear")
departdate=dday & "/" & dmonth & "/" & dyear
aday=request.querystring("arriveday")
amonth=request.querystring("arrivemonth")
ayear=request.querystring("arriveyear")
arrivedate=aday & "/" & amonth & "/" & ayear
If
isdate(departdate) then
response.write "Departure Date is Valid Date<br>"
else
response.write "Departure Date is INVALID<br>"
end if
If
isdate(arrivedate) then
response.write "Arrival Date is Valid Date<br>"
else
response.write "Arrival Date is INVALID<br>"
end if
%>
</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
2
3
4
<HEAD><TITLE>subdbtable.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<%
myDSN="DSN=student;uid=student;pwd=magic"
5
6
7
8
9
mySQL="select * from publishers"
call query2table(mySQL,myDSN)
%>
<!--#include virtual="/learn/test/lib_dbtable.asp"-->
</BODY></HTML>
1
2
3
4
5
6
7
8
9
<HEAD><TITLE>subdbtable2.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<%
myDSN="DSN=student;uid=student;pwd=magic"
mySQL="select * from titles"
call query2table(mySQL,myDSN)
%>
<!--#include virtual="/learn/test/lib_dbtable.asp"-->
</BODY></HTML>
1
2
3
4
5
6
7
8
9
<HEAD><TITLE>subdbtable3.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<%
myDSN="DSN=student;uid=student;pwd=magic"
mySQL="select * from authors"
call query2table(mySQL,myDSN)
%>
<!--#include virtual="/learn/test/lib_dbtable.asp"-->
</BODY></HTML>
1
2
3
4
5
6
7
8
9
10
11
12
13
<HEAD><TITLE>subdbtable4.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<%
myDSN="DSN=student;uid=student;pwd=magic"
mySQL= "SELECT Publishers.Name, Titles.Title "
mySQL= mySQL & "FROM Publishers "
mySQL= mySQL & "INNER JOIN Titles ON Publishers.PubID = Titles.PubID "
mySQL= mySQL & "order by Name"
1
2
3
4
5
6
7
8
9
<HEAD><TITLE>subdbtable5.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<%
myDSN="DSN=student;uid=student;pwd=magic"
mySQL="select * from title_author"
call query2table(mySQL, myDSN)
%>
<!--#include virtual="/learn/test/lib_dbtable.asp"-->
</BODY></HTML>
1
2
3
4
5
6
7
8
9
<HEAD><TITLE>subdbtable6.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<%
myDSN="DSN=student;uid=student;pwd=magic"
mySQL="select name,type from sysobjects"
call query2table(mySQL,myDSN)
%>
<!--#include virtual="/learn/test/lib_dbtable.asp"-->
</BODY></HTML>
call query2table(mySQL,myDSN)
%>
<!--#include virtual="/learn/test/lib_dbtable.asp"-->
</BODY></HTML>
The Include file lib_dbtable.asp looks like this:
1
2
3
4
5
6
<%
sub query2table(inputquery, inputDSN)
dim conntemp, rstemp
set conntemp=server.createobject("adodb.connection")
conntemp.open inputDSN
set rstemp=conntemp.execute(inputquery)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
howmanyfields=rstemp.fields.count -1%>
<table border=1><tr>
<% 'Put Headings On The Table of Field Names
for i=0 to howmanyfields %>
<td><b><%=rstemp(i).name%></B></TD>
<% next %>
</tr>
<% ' Now lets grab all the records
do while not rstemp.eof %>
<tr>
<% for i = 0 to howmanyfields
thisvalue=rstemp(i)
If isnull(thisvalue) then
thisvalue="&nbsp;"
end if%>
<td valign=top><%=thisvalue%></td>
<% next %>
</tr>
<%rstemp.movenext
loop%>
</table>
<%
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
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
2
3
4
5
6
7
8
9
10
11
12
13
<html><head>
<TITLE>subdblist.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<form>
<%
theDSN="DSN=student;uid=student;pwd=magic"
call query2list("select distinct city from publishers","cy",theDSN)
call query2list("select distinct state from publishers","st",theDSN)
call query2list("select distinct zip from publishers","zp",theDSN)
%>
</form>
<!--#include virtual="/learn/test/subdblist.inc"-->
</body></html>
The include file lib_dblist.asp looks like:
1
2
3
4
5
6
7
8
9
10
11
<%sub query2list(myquery,myname,myDSN)
dim conntemp, rstemp
set conntemp=server.createobject("adodb.connection")
conntemp.open myDSN
set rstemp=conntemp.execute(myquery)
%>
<Select name="<%=myname%>">
<%
do while not rstemp.eof
thisfield=trim(RStemp(0))
if isnull(thisfield) or thisfield="" then
12
13
14
15
16
17
18
19
20
21
22
23
24
' ignore
else
response.write "<option>" & thisfield & "</option>"
end if
rstemp.movenext
loop
%>
</select>
<%rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
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
2
3
4
5
6
7
<HEAD><TITLE>subreusabledataform.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<!--#include virtual="/learn/test/subflexible.asp"-->
<%
call query2entryform("select * from publishers where pubid=16")
%>
</BODY></HTML>
1
2
3
4
5
6
7
8
9
10
<HEAD><TITLE>subreusabledatalist.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<!--#include virtual="/learn/test/lib_subflexible.asp"-->
<%
call query2list("select distinct state from publishers","thestate")
call query2list("select distinct city from publishers","thecity")
call query2list("select distinct zip from publishers","thezip")
%>
</BODY></HTML>
1
2
3
4
5
6
7
<HEAD><TITLE>subreusabledatatable.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<!--#include virtual="/learn/test/subflexible.asp"-->
<%
call query2table("select * from publishers")
%>
</BODY></HTML>
1
2
3
4
5
6
7
<HEAD><TITLE>subreusableform.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<!--#include virtual="/learn/test/subflexible.asp"-->
<%
call query2form("select * from publishers")
%>
</BODY></HTML>
The library file lib_subflexible.asp looks like:
1
2
3
4
5
<%
dim
dim
dim
dim
htmlstart, htmlend
rowstart, rowend
fieldstart, fieldend
namestart, nameend
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
dim fieldnames
fieldnames=false
sub query2list(myquery,listname)
htmlstart="<select name='" & listname & "'>"
htmlend="</select>"
rowstart="<option>"
rowend="</option>"
fieldstart=""
fieldend=""
call query2html(myquery)
end sub
sub query2table(myquery)
htmlstart="<table border=1>"
htmlend="</table>"
rowstart="<tr>"
rowend="</tr>"
fieldstart="<td valign=top>"
fieldend="</td>"
call query2html(myquery)
end sub
sub query2form(myquery)
htmlstart=""
htmlend=""
rowstart=""
rowend="<hr>"
fieldstart=""
fieldend="<br>"
fieldnames=true
namestart=""
nameend="&nbsp;=&nbsp;"
call query2html(myquery)
end sub
sub query2entryform(myquery)
htmlstart=""
htmlend=""
rowstart=""
rowend=""
fieldstart="%name%&nbsp;=&nbsp;<input type='text name='%name%' value='"
fieldend="' size='%size%'><br>"
fieldnames=false
namestart=""
nameend="&nbsp;&nbsp;="
call query2html(myquery)
end sub
sub query2html(inputquery)
set conntemp=server.createobject("adodb.connection")
conntemp.open "DSN=Student;uid=student;pwd=magic"
set rstemp=conntemp.execute(inputquery)
howmanyfields=rstemp.fields.count -1
redim fsa(howmanyfields)
redim fea(howmanyfields)
for i = 0 to howmanyfields
tempstart=replace(fieldstart,"%name%",rstemp(i).name)
tempend=replace(fieldend,"%name%",rstemp(i).name)
tempstart=replace(tempstart,"%size%",rstemp(i).actualsize)
tempend=replace(tempend,"%size%",rstemp(i).actualsize)
fsa(i)=tempstart
fea(i)=tempend
next
response.write htmlstart & vbcrlf
counter=0
do until rstemp.eof
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
response.write rowstart & vbcrlf
for i = 0 to howmanyfields
if fieldnames=true then
response.write namestart & rstemp(i).name & nameend
end if
response.write fsa(i) & rstemp(i) & fea(i) & vbcrlf
next
response.write rowend & vbcrlf
counter=counter+1
rstemp.movenext
if response.isclientconnected=false then
exit do
end if
loop
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
response.write htmlend
end sub
%>
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
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<%
sub db2list(mydelim,myparm)
dim myparameters
myparameters=SPLIT(myparm,mydelim)
parmcount=ubound(myparameters)
myquery=myparameters(0)
label=myparameters(1)
default=myparameters(2)
if parmcount>2 then
format=lcase(myparameters(3))
end if
if parmcount>3 then
connstring=myparameters(4)
else
connstring="DSN=Student;uid=student;pwd=magic"
end if
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
set conntemp=server.createobject("adodb.connection")
conntemp.open connstring
set rstemp=conntemp.execute(myquery)
If format="table" then%>
<table width="100%" border="0" cellspacing="1"><td>
<%end if
response.write label
If format="table" then%>
</td><td>
<%end if%>
<Select>
<option value="<%=default%>" selected><%=default%></option>
<%
do while not rstemp.eof %>
<option><%=RStemp(0)%></option>
<%
rstemp.movenext
loop
conntemp.close
%>
</select>
<%If format="table" then%>
</td><tr></table>
<%end if
end sub%>
http://www.learnASP.com/learn/libhtml.asp by Charles M. Carroll
Page 163
Library of HTML Commands by Phil Paxton
©1999 by Phil Paxton ([email protected])
Subroutines and Functions can be used, for example, to provide a layer of abstraction over HTML.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!--#include virtual="/learn/test/lib_htmlstuff.asp"-->
<html><head>
<title>libhtmldemo.asp by Phil Paxton</title>&
<body>
<form action="lib_htmldemorespond.asp">
<%
Call Form_TextBox("first name","Fname",20,20,"")
response.write "<br>"
Call Form_TextBox("Last Name","Lname",20,20,"")
response.write "<br>"
Call Form_TextBox("City","cy",20,20,"")
response.write "<br>"
Call Form_TextBox("State","st",2,2,"")
response.write "<br>"
Call Form_TextBox("Zip Code","zp",10,10,"")
response.write "<br>"
Call Form_SubmitButton("Register Me","register")
%>
</form>
</body>
</html>
The library that enables this (named lib_htmlstuff.asp) looks like:
1
2
3
4
<%
Sub Display( Text )
Response.Write( Text )
End Sub
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
'---------------------------------------------------------------Sub HTML( Text )
Response.Write( Text )
End Sub
'---------------------------------------------------------------Sub Test( Text )
Response.Write( Text )
End Sub
'---------------------------------------------------------------Sub Form_HiddenField( Name, Value )
HTML "<INPUT "
Form_Parm_Type "Hidden"
Form_Parm_Name Name
Form_Parm_Value Value
HTML ">"
End Sub
'---------------------------------------------------------------Sub Form_Label( Label, Control )
If Len(Label) > 0 Then
HTML "<label "
HTML "for=" & Control
HTML ">"
HTML "<strong>"
Display Label
HTML "</strong>"
HTML "</label>"
End If
End Sub
'---------------------------------------------------------------Sub Form_TextBox( Label, Name, MaxLength, Size, Value )
Form_Label Label, Name
HTML "<input "
Form_Parm_Type "text"
Form_Parm_Name Name
Form_Parm_Size Size
Form_Parm_ID Name
Form_Parm_MaxLength MaxLength
Form_Parm_Value Value
HTML ">"
End Sub
'---------------------------------------------------------------Sub Form_Password( Label, Name, MaxLength, Size, Value )
Form_Label Label, Name
HTML "<input "
Form_Parm_Type "password"
Form_Parm_Name Name
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
Form_Parm_Size Size
Form_Parm_ID Name
Form_Parm_MaxLength MaxLength
Form_Parm_Value Value
HTML ">"
End Sub
'---------------------------------------------------------------Sub Form_ScrollingText( Label, Name, Rows, Cols, Value )
Form_Label Label, Name
HTML "<textarea "
Form_Parm_Name Name
If Len(Rows) > 0 Then
HTML "rows=" & Rows & " "
End If
If Len(Cols) > 0 Then
HTML "cols=" & Cols & " "
End If
Form_Parm_ID Name
HTML ">"
If Len(Value) > 0 Then
Display Value
End If
HTML "</textarea>"
End Sub
'---------------------------------------------------------------Sub Form_ResetButton( Name, Value )
HTML "<input "
Form_Parm_Type "reset"
Form_Parm_Value Value
Form_Parm_Name Name
HTML ">"
End Sub
'---------------------------------------------------------------Sub Form_CommandButton( Name, Value )
HTML "<input "
Form_Parm_Type "button"
Form_Parm_Value Value
Form_Parm_Name Name
HTML ">"
End Sub
'---------------------------------------------------------------Sub Form_SubmitButton( Name, Value )
HTML "<input "
Form_Parm_Type "submit"
Form_Parm_Value Value
Form_Parm_Name Name
HTML ">"
End Sub
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
'---------------------------------------------------------------Sub Form_RadioButton( Label, Name, Value, Checked )
HTML "<input "
Form_Parm_Type "radio"
Form_Parm_Value Value
Form_Parm_Name Name
Form_Parm_ID Name & Value
If Len(Checked) > 0 Then
If Checked Then
HTML " checked "
End If
End If
HTML ">"
Form_Label Label, Name & Value
End Sub
'---------------------------------------------------------------Sub Form_Checkbox( Label, Name, Value, Checked )
Form_Label Label, Name
HTML "<INPUT "
Form_Parm_Type "checkbox"
Form_Parm_Name Name
Form_Parm_Value Value
If Len( Checked ) > 0 Then
If Checked = True Then
HTML " checked "
End If
End If
HTML ">"
'
End Sub
'---------------------------------------------------------------Sub Form_Begin( Action )
HTML
HTML
HTML
HTML
"<form "
"method=post "
"action =" & Chr(39) & Action & Chr(39) & " "
">"
End Sub
'---------------------------------------------------------------Sub Form_End( Name, Value )
Form_HiddenField Name, Value
HTML "</FORM>"
End Sub
'---------------------------------------------------------------Sub Form_Table_Begin( Border, Width )
HTML "<table "
If Len(Border) > 0 Then
HTML "border=" & Chr(39) & Border & Chr(39) & " "
End If
Form_Parm_Width Width
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
HTML ">"
End Sub
'---------------------------------------------------------------Sub Form_Table_End()
HTML "</table>"
End Sub
'---------------------------------------------------------------Sub Form_Table_Row_Begin( Dummy, Align, VAlign )
HTML "<tr "
Form_Parm_Align Align
Form_Parm_VAlign VAlign
HTML ">"
End Sub
'---------------------------------------------------------------Sub Form_Table_Row_End( Dummy )
HTML "</tr>"
End Sub
'---------------------------------------------------------------Sub Form_Table_Cell_Begin( Dummy, Width, Align, VAlign )
HTML "<td "
Form_Parm_Width Width
Form_Parm_Align Align
Form_Parm_VAlign VAlign
HTML ">"
End Sub
'---------------------------------------------------------------Sub Form_Table_Cell_End( Dummy )
HTML "</td>"
End Sub
'---------------------------------------------------------------Sub Form_ComboBox_Begin( Label, Name, Size, Multiple )
Form_Label Label, Name
HTML "<select "
Form_Parm_Name Name
Form_Parm_Size Size
If Len(Multiple) > 0 Then
If Multiple Then
HTML " multiple "
End If
End If
HTML ">"
End Sub
'---------------------------------------------------------------Sub Form_ComboBox_Item( Value, Selected )
HTML "<option "
Form_Parm_Value Value
If Len(Selected) > 0 Then
If Selected Then
HTML " selected "
End If
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
End If
HTML ">"
End Sub
'---------------------------------------------------------------Sub Form_ComboBox_End()
HTML "</select>"
End Sub
'---------------------------------------------------------------Sub Form_Title( Title )
HTML "<title>"
Display Title
HTML "</title>&
End Sub
'---------------------------------------------------------------Sub Form_Center( Text )
HTML "<p align=" & Chr(39) & "center" & Chr(39) & ">"
Display Text
HTML "</p>"
End Sub
'---------------------------------------------------------------Sub Form_Left( Text )
HTML "<p align=" & Chr(39) & "left" & Chr(39) & ">"
Display Text
HTML "</p>"
End Sub
'---------------------------------------------------------------Sub Form_Right( Text )
HTML "<p align=" & Chr(39) & "right" & Chr(39) & ">"
Display Text
HTML "</p>"
End Sub
'---------------------------------------------------------------Sub Form_Parm_Align( Align )
If Len(Align) > 0 Then
Select Case UCase(Align)
Case "L", "LEFT"
Display " align=" & Chr(39) & "left" & Chr(39) & " "
Case "C", "CENTER"
Display " align=" & Chr(39) & "center" & Chr(39) & " "
Case "R", "RIGHT"
Display " align=" & Chr(39) & "right" & Chr(39) & " "
Case Else
End Select
End If
End Sub
'---------------------------------------------------------------Sub Form_Parm_VAlign( VAlign )
If Len(VAlign) > 0 Then
Select Case UCase(VAlign)
Case "T", "TOP"
Display " align=" & Chr(39) & "top" & Chr(39) & " "
Case "C", "CENTER"
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
Display " align=" & Chr(39) & "center" & Chr(39) & " "
Case "B", "BOTTOM"
Display " align=" & Chr(39) & "bottom" & Chr(39) & " "
Case Else
End Select
End If
End Sub
'---------------------------------------------------------------Sub Form_Parm_Name( Name )
If Len(Name) > 0 Then
Display " name=" & Chr(39) & Name & Chr(39) & " "
End If
End Sub
'---------------------------------------------------------------Sub Form_Parm_Value( Value )
If Len(Value) > 0 Then
Display " value=" & Chr(39) & Value & Chr(39) & " "
End If
End Sub
'---------------------------------------------------------------Sub Form_Parm_Type( TypeValue )
If Len(TypeValue) > 0 Then
Display " type=" & Chr(39) & TypeValue & Chr(39) & " "
End If
End Sub
'---------------------------------------------------------------Sub Form_Parm_Size( Size )
If Len(Size) > 0 Then
Display " size=" & Size & " "
End If
End Sub
'---------------------------------------------------------------Sub Form_Parm_ID( ID )
If Len(ID) > 0 Then
Display " id=" & Chr(39) & ID & Chr(39) & " "
End If
End Sub
'---------------------------------------------------------------Sub Form_Parm_MaxLength( MaxLength )
If Len(MaxLength) > 0 Then
Display " maxlength=" & MaxLength
End If
End Sub
'---------------------------------------------------------------Sub Form_Parm_Length( Length )
If Len(Length) > 0 Then
Display " length=" & Length
End If
End Sub
'---------------------------------------------------------------Sub Form_Parm_Width( Width )
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
If Len(Width) > 0 Then
Display " width=" & Width
End If
End Sub
'---------------------------------------------------------------Sub Anchor_Display( TextToDisplay, HRef )
HTML "<a href=" & Chr(39) & HRef & Chr(39) & ">"
Display TextToDisplay
HTML "</a>"
End Sub
'---------------------------------------------------------------Sub MenuItem ( TextToDisplay, HRef )
HTML "<ul>"
HTML "<li>"
HTML "<p "
Form_Parm_Align "Left"
Form_Parm_VAlign "Bottom"
HTML ">"
Anchor_Display TextToDisplay, HRef
HTML "</p>"
HTML "</li>"
HTML "</ul>"
End Sub
'---------------------------------------------------------------Function FormatMoney( Amount )
'
' Standard constants from the MS web site but not built
' into VBScript's default constants.
'
Const TristateTrue = -1
Const TristateFalse = 0
Const TristateUseDefault = -2
'
If IsNull( Amount ) Then
FormatMoney = vbNullString
Else
FormatMoney = FormatCurrency( Amount, 2, TristateTrue _
, False, TristateTrue)
End If
'
End Function
'---------------------------------------------------------------%>
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
2
3
4
5
<title>functionworkingdays.asp</title>
<body bgcolor="#FFFFFF">
<%
response.write "3 working days from today is " & dtaddWorkingDays(now(),3) & "<p>"
%>
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2 working days from today is <%=dtaddWorkingDays(now(),2)%>
</body>
<%Function dtAddWorkingDays(dtStartDate, nDaystoAdd)
'Adds working days based on a five day week
Dim dtEndDate
Dim iLoop
'First add whole weeks
dtEndDate=DateAdd("ww",Int(nDaysToAdd/5),dtStartDate)
'Add any odd days
For iLoop = 1 To (nDaysToAdd Mod 5)
dtEndDate=DateAdd("d",1,dtEndDate)
'If Saturday increment to following Monday
If WeekDay(dtEndDate)=vbSaturday Then
'Increment date to following Monday
dtEndDate=DateAdd("d",2,dtEndDate)
End If
Next
dtAddWorkingDays=dtEndDate
End Function
%>
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
2
3
4
5
6
7
8
9
10
<html><head>
<title>vbs5eval.asp</title>
</head>
<body>
<%
x="2+2*3"
response.write eval(x)
%>
</body>
</html>
Classes:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<html><head>
<title>vb5classes.asp</title>
</head>
<body>
<%
' Create a myCustomer variable
Dim myCustomer
' Create a new instance of the Customer Class
' and set the value of myCustomer to be that instance
set myCustomer = new Customer
' Add a new customer
myCustomer.Add "Charles","Carroll"
' Set their Email address
myCustomer.EmailName = "[email protected]"
' Set their credit limit
myCustomer.CreditLimit = 5000
' Display the customers fullname
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
response.write myCustomer.FullName
Class Customer
Public FirstName, LastName
Private nCreditLimit
Private strEmailName
Property Get EmailName
EmailName = strEmailName
End Property
Property Let EmailName ( strName)
StrEmailName = strName
End Property
Property Get FullName
FullName= FirstName & " " & LastName
End Property
Property Let CreditLimit ( s )
if s >= 0 then
nSalary = s
End If
End Property
Property Get CreditLimit
Salary = nSalary
End Property
Sub Add( First, Last )
FirstName = First
LastName = Last
End Sub
Function RaiseCreditLimit( Amount )
nCreditLimit = nCreditLimit + Amount
RaiseSalary = nSalary
End Function
End Class
%>
</body>
</html>
Execute Function:
1
2
3
4
5
6
7
8
9
10
11
12
13
<html><head>
<title>vbs5execute.asp</title>
</head>
<body>
<%
S = "Sub Hi" & vbCrLf
S = S & " Response.write ""Hi""" & vbCrLf
S = S & "End Sub"
Execute S
Call Hi()
%>
</body>
</html>
Regular Expressions
1
2
3
4
5
6
7
8
9
10
11
12
13
<html><head>
<title>vbs5reg.asp</title>&
<body>
<%
address="[email protected]"
validmail=checkemail(address)
IF validmail THEN
response.write address & " is good!"
ELSE
response.write address & " is bad!"
END IF
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
address="sallyaol.com"
validmail=checkemail(address)
IF validmail THEN
response.write address & " is good!"
ELSE
response.write address & " is bad!"
END IF
FUNCTION CheckEmail(parmaddress)
set myRegExp = new RegExp
' Set the pattern to check for a word followed by
' an @ followed by a word
myRegExp.pattern = "\w+\@[.\w]+"
if myRegExp.Test(parmaddress) then
CheckEmail=True
else
CheckEmail=false
end if
END FUNCTION
%>
</body>
</html>
With
1
2
3
4
5
6
7
8
9
10
11
12
13
<html><head>
<title>vbs5with.asp</title>
</head>
<body>
<%
with response
.write "Hi<br>"
.write "how are you doing?<br>"
.write "see you around"
end with
%>
</body>
</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
●
The Request Assistant
●
buttons that make CASE, IF, LOOPs for you
●
Browsing for includes
I personally use it instead of Visual Interdev.
Take a look at the screenshots @
http://www.aspexpress.com/screenShots/screenshots.asp
Of course I am biased, because the author is a student of mine (we hold classes, see www.asptraining.com) and whenever I 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
3
4
5
<%
response.write "Welcome to the BlackJack Table<br>"
application.lock
application("bjplayers")=application("bjplayers")+1
application.unlock
6
7
response.write "There are " & application("bjplayers") & " players here!<br>"
%>
Here is a file called appblackjacklook.asp that displays how many people are at the table.
1
2
3
4
<%
response.write "Over at the BlackJack Table<br>"
response.write "There are " & application("bjplayers") & " players there!<br>"
%>
Here is a file called appblackjackleave.asp that could be included in any script where someone left the blackjack table!
1
2
3
4
5
6
7
8
9
10
<%
response.write "Thanks for playing BlackJack!<br>"
application.lock
application("bjplayers")=application("bjplayers")-1
IF application("bjplayers")<0 THEN
application("bjplayers")=0
END IF
application.unlock
response.write "There are " & application("bjplayers") & " players still at the table!<br>"
%>
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<HTML>
<TITLE>listmakedemo.asp</TITLE>
<body bgcolor="#FFFFFF">
</BODY>
<%
IF
application("citylist")="" OR _
application("statelist")="" OR _
application("ziplist")="" THEN%>
<!--#include virtual="/learn/test/listmake.asp"-->
<%END IF
response.write application("citylist") & "<br>"
response.write application("statelist") & "<br>"
response.write application("ziplist") & "<br>"
%>
</HTML>
The listbox could be placed in an application variable, ala a "generator" script we will call listmake.asp.
1
2
3
4
5
6
7
8
9
10
<HTML>
<TITLE>listmake.asp</TITLE>
<body bgcolor="#FFFFFF">
</BODY>
<%
myDSN="DSN=student;uid=student;pwd=magic"
mySQL="select distinct city from publishers"
application("citylist")=query2htmlist(mySQL,"cities",myDSN)
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
mySQL="select distinct state from publishers"
application("statelist")=query2htmlist(mySQL,"state",myDSN)
mySQL="select distinct zip from publishers"
application("ziplist")=query2htmlist(mySQL,"zip",myDSN)
%>
</HTML>
<%function query2htmList(myquery,myname,myDSN)
dim conntemp, rstemp
set conntemp=server.createobject("adodb.connection")
conntemp.open myDSN
set rstemp=conntemp.execute(myquery)
query2HTMlist="<Select name='" & myname & "'>"
do until rstemp.eof
thisfield=trim(RStemp(0))
if isnull(thisfield) or thisfield="" then
' ignore
else
query2HTMlist=query2HTMlist & "<option>" & thisfield & "</option>"
end if
rstemp.movenext
loop
query2HTMlist=query2HTMlist & "</select>"
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
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
3
4
5
6
7
8
9
10
11
12
<%
response.write "Coin Tossed!<br>"
randomize
randomnum=int(rnd*2)+1
IF randomnum=1 THEN
session("heads")=session("heads")+1
ELSE
session("tails")=session("tails")+1
END IF
response.write "Heads= " & session("heads") & "<br>"
response.write "Tails= " & session("tails") & "<br>"
%>
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.
●
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.
●
If you absolutely need sessions without client cookies, installing an ISAPI filter named "Cookie Munger" will
solve your problem, but at a performance penalty.
Cookie Munger by Microsoft (FREE)
Cookies are a necessity to maintain ASP session objects. Even though the session objects are physically maintained on the 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
2
3
4
5
6
7
8
9
10
11
12
13
<script language=vbscript runat=server>
SUB Application_OnStart
END SUB
SUB Application_OnEnd
END SUB
SUB Session_OnStart
END SUB
SUB Session_OnEnd
END SUB
</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
●
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.
●
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
occuring.
●
application_onend
The web server stops, the application ends.
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.
●
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).
●
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.
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.
●
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
%>
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.
●
waste threads if you put any objects (made with server.createobject) in a session variable. See /learn/buildvbthreads.asp for
more details.
●
limit the code to users accepting cookies which may mean someone who disables cookies may not use that script at all.
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.
●
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.
●
the person using the scripts will never gets "switched" to another server in a web farm situation.
If the task could be accomplished with hidden fields instead of session variables, then those limitations are not in effect -- and 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.
●
If you place any non-object data in session variables the waste is not excessive.
Examples of Wasteful Code and Alternatives...
Code that is particularly wasteful is code that places database connection info in the global.asa, i.e.
session_onstart
session("dbname")="DSN=employees;"
session("dbuser")="whoever"
session("dbpass")="majic"
end sub
and the script that goes with it looks like this:
... code ....
set conntemp=server.createobject("adodb.connection")
conntemp.open session("dbname") & "uid=" & session("dbuser") & ";pwd=" & session("dbpass")
... code ....
Why? Do 700 users hitting that site hit 700 different databases with 700 different userids and passwords at the database level. 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
[email protected]
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 [email protected]
with help from Jonathan McGuire [email protected]
Gregory Lybanon [email protected]
Charles Carroll [email protected]
Measuring speed to the millisecond was considered impossible with ASP. People built COM components that wrapped up API calls!
So we called a COM component that called an API and then we distorted the measurement with overhead. Scripting has a few 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
●
one getrows call
●
one getstring call
This method is great for testing optimizations to 1 script but does not show how the script will run when many users 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html><head>
<TITLE>timedbtable.asp</TITLE>
</head>
<body bgcolor="#FFFFFF">
<!--#include file="lib_timethis.asp"-->
<%
Set HttpObj = Server.CreateObject("AspHTTP.Conn")
HttpObj.Url = "http://www.learnasp.com/learn/test/dbtable.asp"
timeThen = milliDif()
strResult = HttpObj.GetURL
timeNow = milliDif()
SET HTTPobj = nothing
elapsed=timeNow-timeThen
msg="<br>Process time in ms: " & elapsed & "<br>" & elapsedpretty(elapsed)
bodytag="<body bgcolor=""#FFFFFF"">"
STRresult=replace(STRResult,bodytag,bodytag & msg)
response.write STRresult
%>
</body></html>
Here we retrieve data by fetching all the data into an array in one "gulp" (/learn/dbtablegetrows.asp):
1
2
3
4
5
6
7
8
9
10
11
12
13
<html><head>
<TITLE>timedbtablegetrows.asp</TITLE>
</head>
<body bgcolor="#FFFFFF">
<!--#include file="lib_timethis.asp"-->
<%
Set HttpObj = Server.CreateObject("AspHTTP.Conn")
HttpObj.Url = "http://www.learnasp.com/learn/test/dbtablegetrows.asp"
timeThen = milliDif()
strResult = HttpObj.GetURL
timeNow = milliDif()
SET HTTPobj = nothing
elapsed=timeNow-timeThen
14
15
16
17
18
19
20
21
msg="<br>Process time in ms: " & elapsed & "<br>" & elapsedpretty(elapsed)
bodytag="<body bgcolor=""#FFFFFF"">"
STRresult=replace(STRResult,bodytag,bodytag & msg)
response.write STRresult
%>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html><head>
<TITLE>timedbtablegetstring.asp</TITLE>
</head>
<body bgcolor="#FFFFFF">
<!--#include file="lib_timethis.asp"-->
<%
Set HttpObj = Server.CreateObject("AspHTTP.Conn")
HttpObj.Url = "http://www.learnasp.com/learn/test/dbtablegetstring.asp"
timeThen = milliDif()
strResult = HttpObj.GetURL
timeNow = milliDif()
SET HTTPobj = nothing
elapsed=timeNow-timeThen
msg="<br>Process time in ms: " & elapsed & "<br>" & elapsedpretty(elapsed)
bodytag="<body bgcolor=""#FFFFFF"">"
STRresult=replace(STRResult,bodytag,bodytag & msg)
response.write STRresult
%>
</body></html>
The library that accomplishes this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<SCRIPT LANGUAGE=JScript RUNAT=Server>
function y2k(number)
{
return (number < 1000) ? number + 1900 : number;
}
function milliDif()
{
var d = new Date();
return d.getTime()
}
function elapsedpretty(parm1)
{
var elapsedsecs = 0
var elapsedmins = 0
elapsedsecs=Math.floor(parm1/1000)
parm1=parm1%1000
elapsedmins=Math.floor(elapsedsecs/60)
elapsedsecs=elapsedsecs%60
elapsedpretty=elapsedmins + " minute"
if(elapsedmins!=1)
elapsedpretty=elapsedpretty+"s"
elapsedpretty = elapsedpretty+" " + elapsedsecs+" second"
if(elapsedsecs!=1)
elapsedpretty=elapsedpretty+"s"
elapsedpretty = elapsedpretty+ " "+parm1+" millisecond"
if(parm1!=1)
elapsedpretty=elapsedpretty+"s"
33
34
35
36
return elapsedpretty;
}
</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)
●
GetString (see /learn/dbtablegetstring.asp)
●
Disconnected recordsets (see /learn/dbtabledisconnected.asp).
#4 Before just believing any article you read on the web or in an ASP book (many articles are not researched thoroughly) 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.
●
http://www.learnasp.com/learn/nosessionobjects.asp
●
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.
#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)
●
Throttling the maximum number of records if it is appropriate
(see www.activeserverpages.com/learn/dbmaxrecs.asp)
Side note: If anyone you know believes Access queries are done asynchronously, running a couple of these scripts will prove 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
2
3
4
5
6
7
8
9
10
11
12
13
<%response.buffer=true%>
<HEAD><TITLE>dbtablefast.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<%
myDSN = "DSN=student;UID=student;pwd=magic"
mySQL="select * from authors order by author"
call query2table(mySQL,myDSN)
%>
<!--#include virtual="/learn/test/lib_dbtablefast.asp"-->
</BODY></HTML>
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
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
thisvalue=rstemp(i)
If isnull(thisvalue) then
thisvalue="&nbsp;"
end if
response.write "<td valign=top>" & thisvalue & "</td>" & vbcrlf
next
response.write "</tr>"
rstemp.movenext
IF counter mod 50=0 THEN
If response.isclientconnected()=false THEN
EXIT DO
END IF
response.write "</table>" & TableStart
response.flush
END IF
loop%>
</table>
<%
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
end sub%>
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
2
3
4
5
6
7
8
9
10
<HEAD><TITLE>dbtableslow.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<%
myDSN = "DSN=student;uid=student;pwd=magic"
mySQL= "SELECT * from authors order by Author"
call query2table(mySQL,myDSN)
%>
<!--#include virtual="/learn/test/lib_dbtableslow.asp"-->
</BODY></HTML>
Here is the original slow library lib_dbtableslow.asp :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<%
sub query2table(inputquery, inputDSN)
dim conntemp, rstemp
set conntemp=server.createobject("adodb.connection")
conntemp.open inputDSN
set rstemp=conntemp.execute(inputquery)
howmanyfields=rstemp.fields.count -1%>
<table border=1><tr>
<% 'Put Headings On The Table of Field Names
for i=0 to howmanyfields %>
<td><b><%=rstemp(i).name%></B></TD>
<% next %>
</tr>
<% ' Now lets grab all the records
DO UNTIL rstemp.eof and response.isclientconnected()%>
<tr>
<% for i = 0 to howmanyfields
thisvalue=rstemp(i)
If isnull(thisvalue) then
thisvalue="&nbsp;"
end if%>
<td valign=top><%=thisvalue%></td>
<% next %>
24
25
26
27
28
29
30
31
32
33
</tr>
<%rstemp.movenext
loop%>
</table>
<%
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<%response.buffer=true%>
<HEAD><TITLE>dbtableLoopAll.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<!--#include virtual="/adovbs.inc"-->
<!--#include virtual="/learn/test/lib_dbtablefastv2.asp"-->
<%
server.scripttimeout=240
optimize=optimize_LoopAll
myDSN = "DSN=student;UID=student;pwd=magic"
'mySQL="select * from authors order by author "
mySQL="select * from authors order by author "
Call TimerStart
call query2table(mySQL,myDSN,optimize,howmany)
Call TimerEnd
%>
</BODY></HTML>
Here is a table display with a simple LOOP assembling a string:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<%response.buffer=true%>
<HEAD><TITLE>dbtableLoopAllstring.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<!--#include virtual="/adovbs.inc"-->
<!--#include virtual="/learn/test/lib_dbtablefastv2.asp"-->
<%
server.scripttimeout=240
optimize=optimize_LoopAll_string
myDSN = "DSN=student;UID=student;pwd=magic"
mySQL="select * from authors order by author "
Call TimerStart
call query2table(mySQL,myDSN,optimize,howmany)
Call TimerEnd
%>
</BODY></HTML>
Here is a table display with a GetString call and no LOOP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%response.buffer=true%>
<HEAD><TITLE>dbtablegetstringall.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<!--#include virtual="/adovbs.inc"-->
<!--#include virtual="/learn/test/lib_dbtablefastv2.asp"-->
<%
server.scripttimeout=240
optimize=optimize_GetStringAll
myDSN = "DSN=student;UID=student;pwd=magic"
mySQL="select * from authors order by author"
Call TimerStart
call query2table(mySQL,myDSN,optimize,howmany)
response.write OptimizationName(optimize) & "<br>"
Call TimerEnd
%>
</BODY></HTML>
Here is a table display with a GetString call (buffered):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%response.buffer=true%>
<HEAD><TITLE>dbtablegetstringbuffered.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<!--#include virtual="/adovbs.inc"-->
<!--#include virtual="/learn/test/lib_dbtablefastv2.asp"-->
<%
server.scripttimeout=240
optimize=optimize_GetStringBuffered
myDSN = "DSN=student;UID=student;pwd=magic"
mySQL="select * from authors order by author"
Call TimerStart
call query2table(mySQL,myDSN,optimize,howmany)
response.write OptimizationName(optimize) & "<br>"
Call TimerEnd
%>
</BODY></HTML>
Here is a table display with a GetRows call and no LOOP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<%response.buffer=true%>
<HEAD><TITLE>dbtablegetrowsall.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<!--#include virtual="/adovbs.inc"-->
<!--#include virtual="/learn/test/lib_dbtablefastv2.asp"-->
<%
server.scripttimeout=240
optimize=optimize_getrowsall
response.write OptimizationName(optimize) & "<p>"
myDSN = "DSN=student;UID=student;pwd=magic"
mySQL="select * from authors order by author "
call TimerStart
call query2table(mySQL,myDSN,optimize,howmany)
call TimerEnd
%>
</BODY></HTML>
Here is a table display with a GetRows (buffered):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<%response.buffer=true%>
<HEAD><TITLE>dbtableGetRowsBuffered.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<!--#include virtual="/adovbs.inc"-->
<!--#include virtual="/learn/test/lib_dbtablefastv2.asp"-->
<%
server.scripttimeout=240
optimize=optimize_GetRowsBuffered
myDSN = "DSN=student;UID=student;pwd=magic"
'mySQL="select * from authors order by author "
mySQL="select * from authors order by author "
Call TimerStart
call query2table(mySQL,myDSN,optimize,howmany)
Call TimerEnd
%>
</BODY></HTML>
Here is a table display of a portion of the records:
1
2
3
4
<%response.buffer=true%>
<HEAD><TITLE>dbtablelimitrows.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<!--#include virtual="/adovbs.inc"-->
5
6
7
8
9
10
11
12
13
14
15
16
17
<!--#include virtual="/learn/test/lib_dbtablefastv2.asp"-->
<%
server.scripttimeout=240
optimize=optimize_LimitRows
myDSN = "DSN=student;UID=student;pwd=magic"
mySQL="select * from authors order by author"
Call TimerStart
call query2table(mySQL,myDSN,optimize,howmany)
response.write OptimizationName(optimize) & "<br>"
Call TimerEnd
%>
</BODY></HTML>
Here is the optimized library lib_dbtablefastv2.asp which achieves this speed:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<%
Const
Const
Const
Const
Const
Const
Const
dim
dim
dim
dim
dim
dim
dim
dim
dim
optimize_LoopAll = 1
optimize_GetstringAll = 2
optimize_GetrowsAll = 3
optimize_GetrowsBuffered = 4
optimize_GetStringBuffered = 5
optimize_LimitRows = 6
optimize_LoopAll_String = 7
optimize_buffersize
optimize_started
optimize_ended
optimize_SQL
optimize_DSN
optimize_howmany
optimize_cursorlocation
optimize_maxrecs
optimize_disconnectRS
optimize_started=0
' performance stuff
optimize_buffersize=200
'optimize_cursorlocation=aduseclient
optimize_maxrecs=500
optimize_cursorlocation=aduseserver
optimize_disconnectRS=false
optimize_stringwrite=false
SUB TimerStart()
optimize_started=now()
END SUB
SUB TimerEnd()
optimize_ended=now()
elapsed=DateDiff("s", optimize_started, optimize_ended)
response.write "SQL=<b>" & optimize_SQL & "</b><br>"
response.write "DSN=<b>" & optimize_DSN & "</b><br>"
response.write "Query took <b>" & elapsed & " seconds.</b><br>"
IF optimize_howmany=-1 THEN
optimize_howmany=querycount(optimize_DSN,optimize_SQL)
END IF
response.write "Query processed <b>" & optimize_howmany & " records.</b><br>"
response.write "Speed =<b>" & optimize_howmany/elapsed & " records per second.</b><br>"
response.write "Notes:<br>"
pad="&nbsp;&nbsp;&nbsp;&nbsp;"
response.write pad & "buffersize=<b>" & optimize_buffersize & "</b><br>"
IF optimize_cursorlocation=adUseClient THEN
response.write pad & "cursorlocation=<b>adUseClient</b><br>"
END IF
IF optimize_cursorlocation=adUseServer THEN
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
381
382
383
384
385
386
387
388
389
390
391
392
393
394
END FUNCTION
%>
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<%response.buffer=true%>
<HEAD><TITLE>dbtableSQLoledb.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<!--#include virtual="/adovbs.inc"-->
<!--#include virtual="/learn/test/lib_dbtablefastv2.asp"-->
<%
server.scripttimeout=240
optimize=optimize_LoopAll
mySQL="select * from authors where au_id<2000 order by author "
myDSN="PROVIDER=SQLOLEDB;DATA SOURCE=sql2.datareturn.com;"
myDSN=myDSN & "USER ID=student;PASSWORD=magic;"
Call TimerStart
call query2table(mySQL,myDSN,optimize,howmany)
Call TimerEnd
%>
</BODY></HTML>
Here is a table display against a SQL server with a ODBC driver:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<%response.buffer=true%>
<HEAD><TITLE>dbtableSQLODBC.asp</TITLE></HEAD>
<HTML><body bgcolor="#FFFFFF">
<!--#include virtual="/adovbs.inc"-->
<!--#include virtual="/learn/test/lib_dbtablefastv2.asp"-->
<%
server.scripttimeout=240
mySQL="select * from authors where au_id<2000 order by author "
optimize=optimize_LoopAll
myDSN="PROVIDER=MSDASQL;DRIVER={SQL Server};"
myDSN=myDSN & "SERVER=sql2.datareturn.com;UID=student;PWD=magic;"
Call TimerStart
call query2table(mySQL,myDSN,optimize,howmany)
16
17
18
Call TimerEnd
%>
</BODY></HTML>
Here is the optimized library lib_dbtablefastv2.asp which achieves this speed:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<%
Const
Const
Const
Const
Const
Const
Const
dim
dim
dim
dim
dim
dim
dim
dim
dim
optimize_LoopAll = 1
optimize_GetstringAll = 2
optimize_GetrowsAll = 3
optimize_GetrowsBuffered = 4
optimize_GetStringBuffered = 5
optimize_LimitRows = 6
optimize_LoopAll_String = 7
optimize_buffersize
optimize_started
optimize_ended
optimize_SQL
optimize_DSN
optimize_howmany
optimize_cursorlocation
optimize_maxrecs
optimize_disconnectRS
optimize_started=0
' performance stuff
optimize_buffersize=200
'optimize_cursorlocation=aduseclient
optimize_maxrecs=500
optimize_cursorlocation=aduseserver
optimize_disconnectRS=false
optimize_stringwrite=false
SUB TimerStart()
optimize_started=now()
END SUB
SUB TimerEnd()
optimize_ended=now()
elapsed=DateDiff("s", optimize_started, optimize_ended)
response.write "SQL=<b>" & optimize_SQL & "</b><br>"
response.write "DSN=<b>" & optimize_DSN & "</b><br>"
response.write "Query took <b>" & elapsed & " seconds.</b><br>"
IF optimize_howmany=-1 THEN
optimize_howmany=querycount(optimize_DSN,optimize_SQL)
END IF
response.write "Query processed <b>" & optimize_howmany & " records.</b><br>"
response.write "Speed =<b>" & optimize_howmany/elapsed & " records per second.</b><br>"
response.write "Notes:<br>"
pad="&nbsp;&nbsp;&nbsp;&nbsp;"
response.write pad & "buffersize=<b>" & optimize_buffersize & "</b><br>"
IF optimize_cursorlocation=adUseClient THEN
response.write pad & "cursorlocation=<b>adUseClient</b><br>"
END IF
IF optimize_cursorlocation=adUseServer THEN
response.write pad & "cursorlocation=<b>adUseServer</b><br>"
END IF
END SUB
sub query2table(parmQuery, parmDSN,parmMethod,parmcount)
' method 1 = standard
' method 2 = getrows
' method 3 = getstring
dim howmany
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
2
3
4
5
6
7
8
9
10
11
12
13
14
<%server.scripttimeout=20
' this times out the script in 20 seconds whether done or not%>
<TITLE>infiniteloop.asp</TITLE>
<body bgcolor="#FFFFFF">
<%
DO
x=x+1
response.write x & "<br>"
If x=10000 then
x=1
end if
LOOP
%>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<%server.scripttimeout=20
' this times out the script in 20 seconds whether done or
' the user hit the STOP button
%>
<TITLE>infiniteloopfixed.asp</TITLE>
<body bgcolor="#FFFFFF">
<%
DO
x=x+1
response.write x & "<br>"
If x=10000 then
x=1
end if
LOOP WHILE response.isclientconnected()
%>
</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
2
3
4
<TITLE>dbtableisclientconnected.asp</TITLE>
<body bgcolor="#FFFFFF">
<%
' ASP program that displays a database in table form
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
myDSN="DSN=Student;uid=student;pwd=magic"
mySQL="select * from publishers"
set conntemp=server.createobject("adodb.connection")
conntemp.open myDSN
set rstemp=conntemp.execute(mySQL)
howmanyfields=rstemp.fields.count -1
%>
<table border=1><tr>
<% 'Put Headings On The Table of Field Names
for i=0 to howmanyfields %>
<td><b><%=rstemp(i).name %></B></TD>
<% next %>
</tr>
<% ' Now lets grab all the records
do until (rstemp.eof or response.isclientconnected=false)%>
<tr>
<% for i = 0 to howmanyfields%>
<td valign=top><%=rstemp(i)%></td>
<% next %>
</tr>
<%rstemp.movenext
loop
%>
</table>
<%
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
%>
</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
●
exactly the line of code where the object is removed from memory
In Scenario #2, I cannot guarantee:
●
that the object WAS cleared from memory
(I am basing this on a promise in the MS docs, and that the IIS code internally is flawless). IIS is good but if you think it is
flawless I would like to ask you to buy some undervalued land in Florida.
●
when the object was cleaned from memory (the docs do not say when garbage collection occurs)
I will also state that large ISPs (Innerhost, DataReturn) will guarantee your webserver will come down several times a day or 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
●
process data
●
close connection, set to nothing
and 1,000 users do this simultaneously. It is not quite simultaneous, let us say that what happens when eight users access a script
and create, close and destroy eight connections.
User
#1
#2
#3
#4
#5
#6
#7
#8
Time - open conns
1:00am .001 - 1
1:00am .002 - 2
1:00am .010 - 4
1:00am .013 - 4
1:00am .014 - 3
1:00am .016 - 2
1:00am .022 1:00am .027 1:00am .029 -
Open conn. time
1:00am .001
1:00am .002
1:00am .003
1:00am .003
1:00am .007
1:00am .009
1:00am .016
1:00am .017
Open conns
#1
#1, #2
#1, #2, #4, #5, #6
#2, #4, #5, #6
#4, #5, #6
#6, #7
#7, #8
#7
Process Start time
1:00am .002
1:00am .003
1:00am .004
1:00am .004
1:00am .008
1:00am .010
1:00am .017
1:00am .018
Pool to be reused
0
0
#3
#1
#1, #2
#2, #4
#1, #3, #4, #5
#1, #3, #4, #5
#1, #3, #4, #5 waiting
Close time
1:00am .012
1:00am .013
1:00am .009
1:00am .015
1:00am .014
1:00am .021
1:00am .028
1:00am .026
Being Re-used
#6 using #3
#7 using #1
#8 using #2
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.
●
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.
●
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.
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.
The whole page serves in 3 controlled gulps NO more chaos.
Control. Not anarchy.
I once had an overloaded 100% CPU server. I changed registry so all pages were buffer=true. The server then oscillated instead 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
[email protected]
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
2
3
4
5
6
7
8
9
<html><head>
<title>iskeyword.asp</title>
</head><body bgcolor="#FFFFFF">
<Form action = "iskeywordRespond.asp" method="get">
Choose The Word You Want to Search For::<p>
Search Word: <Input NAME="Keyword" size ="30"><br>
<Input type="submit" value="Find The Documents!">
</form>
</body></html>
The iskeywordrespond.asp looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<html><head>
<title>iskeywordrespond.asp</title>
</head>
<body>
<%
Set objQuery = Server.CreateObject("ixsso.query")
Set objUtil = Server.CreateObject("ixsso.util")
my_keyword=request("keyword")
objquery.catalog=""
objQuery.Query = my_keyword
objQuery.Columns = "Vpath, DocTitle, Filename, Characterization, Contents,DocKeyWords, Rank"
objQuery.SortBy = "Rank [d]"
objQuery.MaxRecords = 50
objUtil.AddScopeToQuery objQuery, "/", "DEEP"
linebr="<br>" & vbcrlf
Set rstemp = objQuery.CreateRecordSet("nonsequential")
DO UNTIL rstemp.eof
FOR EACH key in rstemp.fields
keyname=lcase(key.name)
SELECT CASE keyname
CASE "vpath"
response.write "<a href='"
response.write key
response.write "'>" & key & "</a>" & linebr
CASE ELSE
response.write "<b>" & keyname & ":</b>" & linebr
response.write key & linebr
END SELECT
NEXT
response.write "<br><hr>"
rstemp.movenext
LOOP
' clean up
rstemp.close
set rstemp=nothing
Set objQuery = nothing
Set objUtil = nothing
40
41
42
%>
</body>
</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
[email protected]
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
[email protected]
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<HTML>
<HEAD><TITLE>Dynamic Select Lists</Title></Head>
<BODY OnLoad="BuildContacts(0);">
<FORM Name="myForm">
Salesperson:
<SELECT Name="SalesNames" OnChange="BuildContacts(this.selectedIndex);">
<OPTION Value="Jeff">Jeff
<OPTION Value="Charles">Charles
<OPTION Value="Rick">Rick
<OPTION Value="Kevin">Kevin
</Select>
<BR><BR>
Contacts:
<!-- We want to define at least one option so that the select tag is created
with the correct dimensions-->
<SELECT Name="SalesContacts">
<OPTION Value="">-------</Select>
</Form>
</Body>
</Html>
<SCRIPT Language="JavaScript"><!-//Build arrays for each person's contacts
Contacts=new Array(4);
Contacts[0]=new Array(3);
Contacts[1]=new Array(2);
Contacts[2]=new Array(5);
Contacts[3]=new Array(4);
//Charles
Contacts[0][0]="Bill";
Contacts[0][1]="Bob";
Contacts[0][2]="Chuck";
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<html><head>
<title>listdynamicdb.asp</title>&
<BODY OnLoad="StartMeUp();">
<FORM Name="myForm">
<%
dim query
myDSN="DSN=Student;uid=student;pwd=magic"
mySQL= "SELECT Titles.Title, Publishers.Name "
mySQL= mySQL & "FROM Publishers "
mySQL= mySQL & "INNER JOIN Titles ON Publishers.PubID = Titles.PubID "
call listmaker(myDSN, mySQL, _
pubnames,"publist",booknames,"booklist",_
pubevent,pubfun, "myForm")
%>
Publisher:
<%response.write pubnames%><br>
Books:
<%response.write booknames%><br>
</Form>
</Body></Html>
<SCRIPT Language="JavaScript"><!-function StartMeUp()
{
alert("All Books are Loaded Now. Thanks for waiting!");
}
<%=pubevent%>
<%=pubfun%>
--></Script>
<!--#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
([email protected])
One nice thing to do is allow users to use one list box and another to transfer elements elegantly. It makes for a friendly interface.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html>
<body>
<%
Dim Available
Dim Chosen
If Session("BeenHere") <> "DoneThat" Then
' First time to this page!
'
' In "real life" you'd probably populate the
' "initialItems" array from a database query,
' but for demo purposes we'll do it this way:
'
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
initialItems = Array("Apples","Oranges","Grapes","Berries","Kiwis")
'
Set Available = CreateObject("Scripting.Dictionary")
For i = 0 To UBound( initialItems )
Available.add initialItems( i ), "no" ' no means not chosen
Next
'
' save for next time here
'
Set Session("Choices") = Available
'
' set the flag so we don't do this again
'
Session("BeenHere") = "DoneThat"
Else ' if BeenHere *DOES* equal "DoneThat"...
'
' Been here before...process requests...
'
' First, retrieve what we remembered from before...
'
Set Available = Session("Choices")
'
' including any error message?
'
Message = Session("Message")
'
' Then decide what to do
'
' We might be here because of "Add" button,
' "Remove" button, or just because user hit
' "BACK" in the browser.
'
If Request.Form("AddFromAvailable") = "Add >>" Then
' user asked to add some value(s)
For i = 1 To Request.Form("ItemsAvailable").Count
item = Request.Form("ItemsAvailable")(i)
If item <> "#" Then
Available(item) = "yes" ' now chosen!
End If
Next
'
End If
If Request.Form("RemoveFromChosen") = "<< Remove" Then
' user asked to remove some previously chosen values
For i = 1 To Request.Form("ItemsChosen").Count
item = Request.Form("ItemsChosen")(i)
If item <> "#" Then
Available(item) = "no" ' no longer chosen
End If
Next
'
End If
'
' save for next time here
'
Set Session("Choices") = Available
End If
' miscellany:
iCount = Available.count + 1
%>
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
5
6
7
8
9
10
11
12
<%
'
' Protection: You can't come here until
' you have set up the session variable
' with the list of choices.
'
If Session("BeenHere") <> "DoneThat" Then
Response.Redirect "DualList.asp"
End If
'
' 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
[email protected]
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
●
dynamic page construction via Javascript that could be for example fetching database data for a page without reloading the
page.
The main limitations are
●
●
the browser must be a 4.x browser
It doesn't work on IE Mac (thanks to "Brad Rhoads" <[email protected]> for that tip)
The current version requires 3 files: rs.asp, rs.htm and rsprox.class which can be downloaded 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<HTML><HEAD><TITLE>remote1.htm</TITLE></HEAD>
<BODY onload="handleRSExecute()">
<script language="JavaScript" src="/learn/test/remote/rs.htm"></script>
<script language="JavaScript">RSEnableRemoteScripting("/learn/test/remote/");</script>
<h2>Simple Remote Scripting Example</h2>
<form name="remote1">
The Test <input type="text" name="test" value="none"><br>
<SCRIPT LANGUAGE="javascript">
var serverURL = "remote1.asp";
function myCallBack(co)
{
// document.write (co.return_value);
remote1.test.value=co.return_value;
}
16
17
18
19
20
21
22
23
24
function handleRSExecute()
{
var co = RSExecute(serverURL,"Method3");
myCallBack(co);
}
</SCRIPT>
</form>
</HTML>
Our sample remote1.asp looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<%@ LANGUAGE=VBSCRIPT %>
<% RSDispatch %>
<!--#INCLUDE VIRTUAL="/learn/test/remote/rs.asp"-->
<SCRIPT RUNAT=SERVER Language=javascript>
function Description()
{
this.Method1 = Method1;
this.Method2 = Method2;
this.Method3 = Method3;
}
public_description = new Description();
function Method1()
{
return "method1";
}
function Method2()
{
return "method2";
}
function Method3()
{
return "method3";
}
</script>
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
2
3
4
5
6
7
8
9
10
<HTML>
<HEAD>
<TITLE>SIMPLE CLIENT</TITLE>
</HEAD>
<BODY>
<script language="JavaScript" src="/learn/test/remote/rs.htm"></script>
<script language="JavaScript">RSEnableRemoteScripting("/learn/test/remote/");</script>
<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
74
75
76
77
78
79
80
81
82
var co = RSExecute(serverURL,"Method3",myCallBack,errorCallBack,"Invalid RSExecute");
}
</SCRIPT>
</form>
</BODY>
</HTML>
remotems.asp looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<%@ LANGUAGE=VBSCRIPT %>
<% RSDispatch %>
<!--#INCLUDE VIRTUAL="/learn/test/remote/rs.asp"-->
<SCRIPT RUNAT=SERVER Language=javascript>
function Description()
{
this.Method1 = Method1;
this.Method2 = Method2;
}
public_description = new Description();
function Method1()
{
return new Date;
}
function Method2()
{
return new Array("blue","red","green","yellow","orange","purple","cyan","magenta");
}
</SCRIPT>
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
[email protected]
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: -> [email protected]
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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
●
how easy it is to mix Jscript and VBscript in the same file
●
samples of web safe colors. These colors will appear the same on almost everybody's browser. Other colors may appear
dramatically different from browser to browser.
<html><head>
<title>websafe.asp</title>&
<body>
<%
spacer="&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"
response.write "<strong><font size='2'><table border=1>"
for counter=1 to 6
safecolor1=websafe(counter)
for counter2=1 to 6
safecolor2=websafe(counter2)
for counter3= 1 to 6
safecolor3=websafe(counter3)
hexcolor=convertToHex(safecolor1,safecolor2,safecolor3)
response.write "<tr><td>" & hexcolor & "</td>"
response.write "<td bgcolor='" & hexcolor & "'>"
response.write "Black Text</td>"
response.write "<td bgcolor='" & hexcolor & "'>" & spacer & "</td>"
response.write "<td bgcolor='" & hexcolor & "'><font color='white'>"
response.write "White Text</td>"
response.write "<td bgcolor='" & white & "'><font color='" & hexcolor & "'>"
response.write "Colored Text</font></td></tr>"
next
next
next
response.write "</strong></font></table>"
%>
</body></html>
<%
function websafe(mynumber)
SELECT CASE mynumber
CASE 1
websafe=0
CASE 2
websafe=51
CASE 3
websafe=102
CASE 4
websafe=153
CASE 5
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
websafe=204
CASE 6
websafe=255
END SELECT
end function
%>
<script language=jscript runat=server>
function convertToHex(R, G, B) {
var n = B;
n += G << 8;
n += R << 16;
return convertBase(n);
}
// turns decimal integer into hexadecimal string
function convertBase(num) {
var i = 0; var j = 20;
var str = "#";
while(j >= 0) {
i = (num >> j)%16;
if(i >= 10) {
if(i == 10) str += "A";
else if(i == 11) str +=
else if(i == 12) str +=
else if(i == 13) str +=
else if(i == 14) str +=
else str += "F";
} else
str += i;
j -= 4;
}
"B";
"C";
"D";
"E";
return str;
}
</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
INFO ONLINE
http://bn.bfast.com/booklink/click?sourceid=10446528&ISBN=1565924460
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 ([email protected])
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html><head>
<TITLE>dblist.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<%
myDSN="DSN=Student;uid=student;pwd=magic"
mySQL="select author from authors where AU_ID<100"
' displays a database field as a listbox
set conntemp=server.createobject("adodb.connection")
conntemp.open myDSN
set rstemp=conntemp.execute(mySQL)
if rstemp.eof then
response.write "no data for<br>"
response.write mySQL
conntemp.close
set conntemp=nothing
response.end
end if
%>
<form action="dblistrespond.asp" method="post">
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<Select name="authorname">
<%
' Now lets grab all the data
do until rstemp.eof %>
<option> <%=RStemp(0)%> </option>
<%
rstemp.movenext
loop
rstemp.close
set rstemp=nothing
conntemp.close
set conntemp=nothing
%>
<input type="submit" value="Choose Author">
</Select></form>
</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
/advice/dbsessionapp.asp
●
Session and application level data basics at
/learn/globalproblems.asp.
●
STA and Memory Model Issues at
/learn/buildvbthreads.asp
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
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
Scenario 2: objects created/destroyed on a page per
page basis
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
[email protected]
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!--#include virtual="/learn/test/lib_htmlstuff.asp"-->
<html><head>
<title>libhtmldemo.asp by Phil Paxton</title>&
<body>
<form action="lib_htmldemorespond.asp">
<%
Call Form_TextBox("first name","Fname",20,20,"")
response.write "<br>"
Call Form_TextBox("Last Name","Lname",20,20,"")
response.write "<br>"
Call Form_TextBox("City","cy",20,20,"")
response.write "<br>"
Call Form_TextBox("State","st",2,2,"")
response.write "<br>"
Call Form_TextBox("Zip Code","zp",10,10,"")
response.write "<br>"
Call Form_SubmitButton("Register Me","register")
%>
19
20
21
</form>
</body>
</html>
Here displaying a listbox from a database has been simplified by a subroutine:
1
2
3
4
5
6
7
8
9
10
11
12
13
<html><head>
<TITLE>subdblist.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<form>
<%
theDSN="DSN=student;uid=student;pwd=magic"
call query2list("select distinct city from publishers","cy",theDSN)
call query2list("select distinct state from publishers","st",theDSN)
call query2list("select distinct zip from publishers","zp",theDSN)
%>
</form>
<!--#include virtual="/learn/test/subdblist.inc"-->
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<html><head>
<title>suffixif.asp</title>
</head>
<body>
<%
' ok test it
For i = 1 TO 1000
n = i
Response.Write n & AddSuffix(n) & ".<BR>"
NEXT
%>
</body>
</html>
<%
FUNCTION AddSuffix(num)
temp=right(num,1)
If temp= 1 Then
AddSuffix = AddSuffix & "st"
ElseIf temp = 2 Then
AddSuffix = AddSuffix & "nd"
ElseIf temp = 3 Then
AddSuffix = AddSuffix & "rd"
ElseIf temp<11 Then
AddSuffix = AddSuffix & "th"
End If
END FUNCTION
%>
This is the CASE example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<html><head>
<title>suffixcase.asp by Dwaine Maltais [email protected]</title>
</head>
<body>
<%
' ok test it
FOR i = 1 TO 1000
n = i
Response.Write AddSuffix(n) & "<br>"
NEXT
%>
</body>
</html>
<%
Function AddSuffix(num)
numpart = RIGHT(num,1)
SELECT CASE numpart
CASE "1"
IF InStr(num,"11") THEN
num = num & "th"
ELSE
num = num & "st"
END IF
CASE "2"
IF InStr(num,"12") THEN
num = num & "th"
ELSE
num = num & "nd"
END IF
CASE "3"
IF InStr(num,"13") THEN
num = num & "th"
ELSE
num = num & "rd"
END IF
CASE "4"
num = num & "th"
CASE ELSE
num = num & "th"
END SELECT
AddSuffix = num
END FUNCTION
%>
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
●
write errors to IIS log
●
email someone when a page error occurs
●
place errors in a custom dictionary/collection
We will provide code for each scenario and discuss the pros and cons of each approach.
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).
●
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.
●
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.
●
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.
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html><head>
<TITLE>txtread.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<%
whichfile=server.mappath("/aspheader.asp")
Set fs = CreateObject("Scripting.FileSystemObject")
Set thisfile = fs.OpenTextFile(whichfile, 1, False)
counter=0
do while not thisfile.AtEndOfStream
counter=counter+1
thisline=thisfile.readline
response.write thisline & "<br>"
loop
thisfile.Close
set thisfile=nothing
set fs=nothing
%>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<html><head>
<TITLE>txtwrite.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<%
whichFN=server.mappath("/upload/tests/tempfile.txt")
' first, create the file out of thin air
Set fstemp = server.CreateObject("Scripting.FileSystemObject")
Set filetemp = fstemp.CreateTextFile(whichFN, true)
' true = file can be over-written if it exists
' false = file CANNOT be over-written if it exists
filetemp.WriteLine("This is a brand new file!!!!")
filetemp.writeblanklines(3)
filetemp.WriteLine("This is the last line of the file we created!")
filetemp.Close
' Now open it and add some lines
forappending =8
set filetemp=fstemp.OpentextFile(whichFN, forappending)
filetemp.writeline "a line we added later"
filetemp.writeline "another line we added later..."
filetemp.close
set filetemp=nothing
set fstemp=nothing
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
If
err.number=0 then
response.write "File was appended sucessfully!"
else
response.write
response.write
response.write
response.write
response.write
response.write
response.write
"VBScript Errors Occured!<br>"
"Error Number=#<b>" & err.number & "</b><br>"
"Error Desc. =<b>" & err.description & "</b><br>"
"Help Path =<b>" & err.helppath & "</b><br>"
"Native Error=<b>" & err.nativeerror & "</b><br>"
"Error Source =<b>" & err.source & "</b><br>"
"SQL State=#<b>" & err.sqlstate & "</b><br>"
end if
%>
</body></html>
This code displays the file we created:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<html><head>
<TITLE>txtwritedisplay.asp</TITLE>
</head><body bgcolor="#FFFFFF">
<%
whichname="tempfile.txt"
whichdir=Server.Mappath ("/upload/tests/")
whichFN=whichdir & whichname
forreading=1
Set fs = CreateObject("Scripting.FileSystemObject")
Set thisfile = fs.OpenTextFile(whichFN, forreading, False)
counter=0
do while not thisfile.AtEndOfStream
counter=counter+1
thisline=thisfile.readline
response.write thisline & "<br>"
loop
thisfile.Close
set thisfile=nothing
set fs=nothing
%>
</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
to you
2
SN
3
SN
4
TF
5
TF
6
JP
7
JP
8
EI
energy
9
SN
At a party do you - interact with many, including strangers / interact with a few, known
Are you more - realistic than speculative / speculative than realistic
It is worse to - have your "head in the clouds" / be "in a rut"
Are you more impressed by - principles / emotions
Are you more drawn toward the - convincing / touching
Do you prefer to work - to deadlines / just "whatever"
Do you tend to choose - rather carefully / somewhat impulsively
At parties do you - stay late, with increasing energy / leave early, with decreased
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
67
68
69
TF
TF
EI
JP
Which do you wish more for yourself - clarity of reason / strength of compassion
Which is the greater fault - being indiscriminate / being critical
Do you prefer the - planned event / unplanned event
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<%option explicit%>
<html>
<head>
<title>mb.asp</title>
</head>
<body bgcolor="#FFFFFF">
<form method="post" action="mbrespond.asp">
<%
dim answer1, answer2
dim char1, char2, counter
Dim fs, findslash, findhyphen
dim rest
Dim thisfile, thisline
dim question
dim whichfile
whichfile=server.mappath("mb.txt")
Set fs = CreateObject("Scripting.FileSystemObject")
Set thisfile = fs.OpenTextFile(whichfile, 1, False)
counter=0
do while not thisfile.AtEndOfStream
counter=counter+1
thisline=thisfile.readline
char1=mid(thisline,1,1)
char2=mid(thisline,2,1)
rest=mid(thisline,3)
findhyphen=instr(thisline,"-")
question=mid(rest,1,findhyphen-2)
rest=mid(rest,findhyphen)
findslash=instr(rest,"/")
answer1=mid(rest,1,findslash-1)
answer2=mid(rest,findslash+1)
'response.write char1 & "<br>"
'response.write char2 & "<br>"
'response.write rest & "<p>"
response.write question & "<br>"
'response.write answer1 & "<br>"
'response.write answer2 & "<p>"
%>
<p><input TYPE="radio" name="Q<%=counter%>" VALUE="U" CHECKED>Undecided<br>
<input TYPE="radio" name="Q<%=counter%>" VALUE="<%=char1%>"><%=answer1%><br>
<input TYPE="radio" name="Q<%=counter%>" VALUE="<%=char2%>"><%=answer2%></p>
<p><%
loop
thisfile.Close
set fs=nothing
52
53
54
55
%> <input type="submit"></p>
</form>
</body>
</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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<%option explicit%>
<html>
<head>
<title>mbrespond.asp</title>
</head>
<%
dim key
dim ecount, icount
dim scount, ncount
dim tcount, fcount
dim jcount, pcount
dim ucount
For Each Key in Request.Form
SELECT CASE request.form(key)
CASE "E"
ecount=ecount+1
CASE "I"
icount=icount+1
CASE "S"
scount=scount+1
CASE "N"
ncount=ncount+1
CASE "T"
tcount=tcount+1
CASE "F"
fcount=fcount+1
CASE "J"
jcount=jcount+1
CASE "P"
pcount=pcount+1
CASE "U"
ucount=ucount+1
END SELECT
Next
Response.write "E=" & ecount & "<br>"
Response.write "I=" & icount & "<br>"
Response.write "S=" & scount & "<br>"
Response.write "N=" & ncount & "<br>"
Response.write "T=" & tcount & "<br>"
Response.write "F=" & fcount & "<br>"
Response.write "J=" & jcount & "<br>"
Response.write "P=" & pcount & "<br>"
Response.write "U=" & ucount & "<br>"
%>
<body bgcolor="#FFFFFF">
</body>
</html>
http://www.learnASP.com/learn/cl.asp by Charles M. Carroll
Page 238
Content Linking Prev/Next
1
2
3
4
5
6
7
8
9
10
11
12
<%
Set NL = Server.CreateObject ("MSWC.NextLink")
tocname="/learn/learn.txt"
nextref=NL.GetNextURL(tocname)
nextdes=NL.GetNextDescription(tocname)
If (NL.GetListIndex (tocname)>1) Then
prevref=NL.GetPreviousURL(tocname)
prevdes=NL.GetPreviousDescription(tocname)
%>
Prev:<a href="<%=prevref%>"><%=prevdes%></a>&nbsp;&nbsp;Next:
<% End If %>
<a href="<%=nextref%>"><%=nextdes%></a>
http://www.learnASP.com/learn/cl2.asp by Charles M. Carroll
Page 239
Content Linking TOC
1
2
3
4
5
6
7
8
9
10
11
12
<TITLE>cl2.asp</TITLE>
<body bgcolor="#FFFFFF">
<%
Set TL = Server.CreateObject ("MSWC.NextLink")
for i=1 to cint(TL.GetListCount("/learn/learn.txt"))%>
Description:
<%=TL.GetNthDescription ("/learn/learn.txt",i)%>,
(URL=<%=TL.GetNthURL ("/learn/learn.txt",i)%>).
Page <%=i%>.<p>
<% next%>
</body>
</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
2
3
4
5
6
7
8
9
10
11
12
<HTML><HEAD><TITLE>cljump.asp</TITLE></HEAD>
<body bgcolor="#FFFFFF">
<FORM ACTION="cljumprespond.asp">
<%
Set TL = Server.CreateObject ("MSWC.NextLink")
maxi= cint(TL.GetListCount("/learn/learn.txt"))
%>
<SELECT name="whichtopic">
<OPTION SELECTED VALUE="">Select a Topic...
<%for i=1 to maxi%>
<OPTION value=
<%=TL.GetNthURL("/learn/learn.txt",i)%>
13
14
15
16
17
18
19
20
21
22
23
24
25
26
>
<%
desc=TL.GetNthDescription("/learn/learn.txt",i)
if mid(desc,1,1)="*" then
desc=mid(desc,2)
else
desc="&nbsp;&nbsp;&nbsp;&nbsp;" & desc
end if
%>
<%=desc%>
<%next%>
</SELECT>&nbsp;&nbsp;<INPUT VALUE="Jump to Lesson" TYPE=submit></FORM>
</BODY>
</HTML>
The script named cljumprespond.asp that implements the jump looks like this:
1
2
3
<%
response.redirect request.querystring("whichtopic")
%>
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<html><head>
<title>fileobjects.asp</title>
</head><body>
<%
mypath="/learn/test"
Set filesystem = CreateObject("Scripting.FileSystemObject")
Set folder = filesystem.GetFolder(server.mappath(mypath))
Set filecollection = folder.Files
For Each file in filecollection
response.write file.name & "<br>"
Next
set filesystem=nothing
set folder=nothing
set filecollection=nothing
%>
</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
2
3
4
<html><head>
<title>fileobjectslinks.asp</title>
</head><body>
<%
5
6
7
8
9
10
11
12
13
14
15
16
17
dirtowalk="/learn/test"
Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.GetFolder(server.mappath(dirtowalk))
Set fc = f.Files
For Each whatever in fc
response.write "<A HREF='"
response.write whatever.name
response.write "'>"
response.write whatever.name
response.write "</A><br>"
Next
%>
</body></html>
Now we will display graphics in a directory.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html><head>
<title>fileobjectsgraphics.asp</title>
</head><body>
<%
dirtowalk="/images"
Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.GetFolder(server.mappath(dirtowalk))
Set fc = f.Files
For Each whatever in fc
response.write "<IMG SRC='/images/"
response.write whatever.name
response.write "'>"
response.write whatever.name & "<br>"
Next
%>
</body></html>
http://www.learnASP.com/learn/fileobjects3.asp by Charles M. Carroll
Page 243
FileObjects Part 3 by Steven Harper
Steven [email protected], Internet Developer
The file object can be used to examine the disk as well as this cript submitted by a site viewer, demonstrates.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html><head>
<title>fileobjectsinfo.asp</title>
</head><body>
<%
disktoexamine="C:"
set fs = Server.CreateObject("Scripting.FileSystemObject")
set f = fs.GetDrive(disktoexamine)
Response.Write(" Root Folder : ")
Response.Write(f.RootFolder)
Response.Write("<BR>")
Response.Write(" Type of Drive : ")
if f.DriveType=2 then
Response.Write("Fixed")
end if
if f.DriveType=1 then
Response.Write("Removable")
end if
Response.Write("<BR>")
Response.Write(" File System : ")
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Response.Write(f.FileSystem)
Response.Write("<BR>")
Response.Write(" Total Size on Server's C: &nbsp;&nbsp;")
Response.Write(f.TotalSize)
Response.Write("<BR>")
Response.Write(" Drive Space on Server's C: ")
Response.Write(f.freespace)
Response.Write("<BR>")
Response.Write(" Serial Number : ")
Response.Write(f.SerialNumber)
set f=nothing
set fs=nothing
%>
</body></html>
http://www.learnASP.com/learn/fileobjects4.asp by Charles M. Carroll
Page 244
FileObjects Part 4 by "Tim Foster" [email protected]
The file object examples was modified by one of our readers to support folders and clicking on them to see the contents beneath.
Our readers always come up with some nice variations and new examples.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<html><head>
<title>fileobjectsplusdir.asp</title>
</head><body>
<%
additional = request.querystring("pathh")
folderspec = "/learn/"
if
additional & "x" <> "x" then
additional = additional & "/"
folderspec = folderspec & additional
end if
Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.GetFolder(server.mappath(folderspec))
Set fd = f.subfolders
response.write "<h2>FOLDERS</h2><blockquote>"
For Each whatever in fd
response.write "<A HREF='"
response.write request.servervariables("script_name")
response.write "?pathh=" & whatever.name
response.write "'>"
response.write whatever.name & " - " & whatever.datecreated
response.write "</A><br>"
Next
response.write "</blockquote><hr>"
response.write "<h2>FILES</h2><blockquote>"
Set fc = f.files
For Each whatever in fc
response.write "<A HREF='"
response.write folderspec & whatever.name
response.write "'>"
response.write whatever.name & " - " & whatever.datecreated
39
40
41
42
43
44
45
46
response.write "</A><br>"
Next
response.write "</blockquote><hr>"
%>
</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 [email protected]
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!--#include virtual="/learn/test/lib_graphicdetect.asp"-->
<html><head>
<TITLE>dbtable.asp</TITLE>
</head>
<body bgcolor="#FFFFFF">
<%
graphic="images/learnaspiconmain.gif"
HW = ReadImg(graphic)
Response.Write graphic & " Dimensions: " & HW(0) & "x" & HW(1) & "<br>"
response.write "<img src=""/" & graphic & """"
response.write height=""" & HW(0) & """
response.write width=""" & HW(0) & "">"
%>
</body></html>
The library that is included is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<%
Dim HW
Function AscAt(s, n)
AscAt = Asc(Mid(s, n, 1))
End Function
Function HexAt(s, n)
HexAt = Hex(AscAt(s, n))
End Function
Function isJPG(fichero)
If inStr(uCase(fichero), ".JPG") <> 0 Then
isJPG = true
Else
isJPG = false
End If
End Function
Function isPNG(fichero)
If inStr(uCase(fichero), ".PNG") <> 0 Then
isPNG = true
Else
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
isPNG = false
End If
End Function
Function isGIF(fichero)
If inStr(uCase(fichero), ".GIF") <> 0 Then
isGIF = true
Else
isGIF = false
End If
End Function
Function isBMP(fichero)
If inStr(uCase(fichero), ".BMP") <> 0 Then
isBMP = true
Else
isBMP = false
End If
End Function
Function isWMF(fichero)
If inStr(uCase(fichero), ".WMF") <> 0 Then
isWMF = true
Else
isWMF = false
End If
End Function
Function isWebImg(f)
If isGIF(f) Or isJPG(f) Or isPNG(f) Or isBMP(f) Or isWMF(f) Then
isWebImg = true
Else
isWebImg = true
End If
End Function
Function ReadImg(fichero)
If isGIF(fichero) Then
ReadImg = ReadGIF(fichero)
Else
If isJPG(fichero) Then
ReadImg = ReadJPG(fichero)
Else
If isPNG(fichero) Then
ReadImg = ReadPNG(fichero)
Else
If isBMP(fichero) Then
ReadImg = ReadPNG(fichero)
Else
If isWMF(fichero) Then
ReadImg = ReadWMF(fichero)
Else
ReadImg = Array(0,0)
End If
End If
End If
End If
End If
End Function
Function ReadJPG(fichero)
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
Dim fso, ts, s, HW, nbytes
HW = Array("","")
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.OpenTextFile(Server.MapPath("/" & fichero), 1)
s = Right(ts.Read(167), 4)
HW(0) = HexToDec(HexAt(s,3) & HexAt(s,4))
HW(1) = HexToDec(HexAt(s,1) & HexAt(s,2))
ts.Close
ReadJPG = HW
End Function
Function ReadPNG(fichero)
Dim fso, ts, s, HW, nbytes
HW = Array("","")
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.OpenTextFile(Server.MapPath("/" & fichero), 1)
s = Right(ts.Read(24), 8)
HW(0) = HexToDec(HexAt(s,3) & HexAt(s,4))
HW(1) = HexToDec(HexAt(s,7) & HexAt(s,8))
ts.Close
ReadPNG = HW
End Function
Function ReadGIF(fichero)
Dim fso, ts, s, HW, nbytes
HW = Array("","")
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.OpenTextFile(Server.MapPath("/" & fichero), 1)
s = Right(ts.Read(10), 4)
HW(0) = HexToDec(HexAt(s,2) & HexAt(s,1))
HW(1) = HexToDec(HexAt(s,4) & HexAt(s,3))
ts.Close
ReadGIF = HW
End Function
Function ReadWMF(fichero)
Dim fso, ts, s, HW, nbytes
HW = Array("","")
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.OpenTextFile(Server.MapPath("/" & fichero), 1)
s = Right(ts.Read(14), 4)
HW(0) = HexToDec(HexAt(s,2) & HexAt(s,1))
HW(1) = HexToDec(HexAt(s,4) & HexAt(s,3))
ts.Close
ReadWMF = HW
End Function
Function ReadBMP(fichero)
Dim fso, ts, s, HW, nbytes
HW = Array("","")
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.OpenTextFile(Server.MapPath("/" & fichero), 1)
s = Right(ts.Read(24), 8)
HW(0) = HexToDec(HexAt(s,4) & HexAt(s,3))
HW(1) = HexToDec(HexAt(s,8) & HexAt(s,7))
ts.Close
ReadBMP = HW
End Function
Function isDigit(c)
If inStr("0123456789", c) <> 0 Then
isDigit = true
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
Else
isDigit = false
End If
End Function
Function isHex(c)
If inStr("0123456789ABCDEFabcdef", c) <> 0 Then
isHex = true
Else
ishex = false
End If
End Function
Function HexToDec(cadhex)
Dim n, i, ch, decimal
decimal = 0
n = Len(cadhex)
For i=1 To n
ch = Mid(cadhex, i, 1)
If isHex(ch) Then
decimal = decimal * 16
If isDigit(c) Then
decimal = decimal + ch
Else
decimal = decimal + Asc(uCase(ch)) - Asc("A")
End If
Else
HexToDec = -1
End If
Next
HexToDec = decimal
End Function
%>
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
●
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.
●
The project name ==> charlescarroll
The class name ==> simplecomponent
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)
●
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".
●
from a command prompt
regsvr32 <your component name>
If you are updating a component (i.e. registering a component that replaces another component) instead:
●
Copy your component to where your System DLLs are
(probably \winnt\system32)
●
DO NOT leave the component in the original directory!!!! Make sure the .DLL/component is only in the system directory 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".
●
from a command prompt
regsvr32 <old component name> -u
●
from a command prompt
regsvr32 <your component name>
●
start and stop web service to purge old component from memory
http://www.learnASP.com/learn/buildvbado.asp by Charles M. Carroll
Page 249
VB Component: DBHelper from Web 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
●
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Microsoft "Active Server Pages" object library
' projectname =charlescarroll
' classname =dbhelperver001
Private ASPresponse As Response
Private ASPserver As Server
Private htmlstart, htmlend, rowstart, rowend
Private fieldstart, fieldend, namestart, nameend
Public Sub onstartpage(sc As ScriptingContext)
Set ASPresponse = sc.Response()
Set ASPserver = sc.Server()
End Sub
Public Property Let connect(temp As Variant)
myconnect = temp
End Property
Public Property Get connect() As Variant
connectme = myconnect
End Property
Public Property Get fieldnames() As Variant
fieldnames = myfieldnames
End Property
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
Public Property Let fieldnames(temp As Variant)
myfieldnames = temp
End Property
Public Property Let query(temp As Variant)
myquery = temp
End Property
Public Property Get query() As Variant
query = myquery
End Property
Public Property Let selectdefault(temp As Variant)
myselectdefault = temp
End Property
Public Property Get selectdefault() As Variant
selectdefault = myselectdefault
End Property
Public Property Let selectname(temp As Variant)
myselectname = temp
End Property
Public Property Get selectname() As Variant
selectname = myselectname
End Property
Public Sub query2list()
htmlstart = "<select name='" & selectname & "'>"
htmlend = "</select>"
rowstart = "<option>"
rowend = "</option>"
fieldstart = ""
fieldend = ""
Call query2html
End Sub
Public Sub query2table()
htmlstart = "<table border=1>"
htmlend = "</table>"
rowstart = "<tr>"
rowend = "</tr>"
fieldstart = "<td valign=top>"
fieldend = "</td>"
Call query2html
End Sub
Public Sub query2form()
htmlstart = ""
htmlend = ""
rowstart = ""
rowend = "<hr>"
fieldstart = ""
fieldend = "<br>"
fieldnames = True
namestart = ""
nameend = "&nbsp;=&nbsp;"
Call query2html
End Sub
Public Sub query2entryform()
htmlstart = ""
htmlend = ""
rowstart = ""
rowend = ""
fieldstart = "%name%&nbsp;=&nbsp;<input type='text name='%name%' value='"
fieldend = "' size='%size%'><br>"
fieldnames = False
namestart = ""
nameend = "&nbsp;&nbsp;="
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
Call query2html
End Sub
Public Sub CustomDisplay(PARMhtmlstart, PARMhtmlend, PARMrowstart, PARMrowend, _
PARMfieldstart, PARMfieldend, PARMfieldnames, _
PARMnamestart, PARMnameend)
htmlstart = PARMhtmlstart
htmlend = PARMhtmlend
rowstart = PARMrowstart
rowend = PARMrowend
fieldstart = PARMfieldstart
fieldend = PARMfieldend
fieldnames = PARMfieldnames
namestart = PARMnamestart
nameend = PARMnameend
Call query2html
End Sub
Private Sub query2html()
On Error GoTo Badnews
attempt = "creating connection"
Set conntemp = ASPserver.CreateObject("adodb.connection")
attempt = "opening connection"
conntemp.Open myconnect
attempt = "making recordset"
Set rstemp = conntemp.Execute(myquery)
howmanyfields = rstemp.Fields.Count - 1
ReDim fsa(howmanyfields)
ReDim fea(howmanyfields)
For i = 0 To howmanyfields
tempstart = Replace(fieldstart, "%name%", rstemp(i).Name)
tempend = Replace(fieldend, "%name%", rstemp(i).Name)
tempstart = Replace(tempstart, "%size%", rstemp(i).ActualSize)
tempend = Replace(tempend, "%size%", rstemp(i).ActualSize)
fsa(i) = myfieldstart
fea(i) = myfieldend
Next
ASPresponse.Write htmlstart & vbCrLf
Counter = 0
Do While Not rstemp.EOF
ASPresponse.Write rowstart & vbCrLf
For i = 0 To howmanyfields
If fieldnames = True Then
ASPresponse.Write namestart & rstemp(i).Name & nameend
End If
ASPresponse.Write fsa(i) & rstemp(i) & fea(i) & vbCrLf
Next
ASPresponse.Write rowend & vbCrLf
Counter = Counter + 1
rstemp.MoveNext
Loop
rstemp.Close
Set rstemp = Nothing
conntemp.Close
Set conntemp = Nothing
ASPresponse.Write htmlend
Exit Sub
Badnews:
temp = "Error: " & attempt & "<br>"
temp = temp & Err.Description & "<br>"
temp = temp & Err.Number
ASPresponse.Write temp
End Sub
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.
●
Do not use traditional file access methods (Open #, Close #). Instead use the scripting FileSystemObject.
http://www.learnASP.com/learn/buildvb.asp by Charles M. Carroll
Page 252
Generic VB Component Building Steps
Making a VB ASP component is easy:
●
Use File; New Project
●
choose Active-X DLL
●
You will now be in the editor and there will be a class open
●
when you are done, the code to invoke it on a page will look like:
set .... = server.createobject("projectname.classname")
choose your project plus class names well.
●
The project name and class name are set with the (name) property. They are NOT in anyway connected to the
filename although you may make the filenames match the project and class names.
●
If you need to use one of the five built-in ASP objects (collectively called the scripting context) you can add 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:
Public Function onstartpage(sc As Object)
'Set ... = sc.response()
'set ... = sc.server()
'set ... = sc.Request()
'set ... = sc.application()
'set ... = sc.session()
End Function
●
If needed, you can add this event:
Public Function onendpage(sc As Object)
End Function
http://www.learnASP.com/learn/buildvb2.asp by Charles M. Carroll
Page 253
VB Components: what you need...
To make a VB ASP component you need the following on your machine:
●
Visual Basic version 4 or version 5 (our instructions only cover version 5 though)
●
A installation of "Active Server Pages" which can be obtained by installing IIS or Visual Interdev. This is because "Project;
References" must include the "Active Server Pages" libary.
People having trouble building components can sign up for our listserv:
vbcomponents Listserver
JOIN, QUIT or Search ARCHIVES:
http://www.asplists.com/asplists/buildvb2.asp
Send Listserver Questions to
[email protected]
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).
●
If you place a object marked apartment into the SessionObject you have an object which can only live and be called from the
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.
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
[email protected]
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
[email protected]
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.
●
MTX objects need not run as the "standard ASP User". Components registered with MTX can impersonate a specific user.
The typical segments of code that would be unique to components managed by MTX would look like this:
Concept
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, mycntxt.CreateInstance("... objectname ..")
or server.createobject)
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
Transaction
Transaction
Transaction
=
=
=
=
Required %>
Requires_New %>
Supported %>
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.
●
Requires a New Transaction - MTX starts a new transaction each time that component is activated.
●
Support Transactions - run within a existing transaction, or if there is no existing transaction, MTX will run the component
without a transaction.
●
Does Not Support Transactions - This component will always run outside of existing transactions.
http://www.learnASP.com/learn/components.asp by Charles M. Carroll
Page 264
ASPMail: Simple Example (serverobjectsmail.asp) - Page 265
Upload: Simple Example (uploadsimple.asp) - Page 266
Upload: Multi-part form (uploadmultipart.asp) - Page 267
Upload: Limit Size (uploadlimitsize.asp) - Page 268
Upload: Many Files (uploadmanyfiles.asp) - Page 269
Perf Counters on ASP page (perfcounters.asp) - Page 270
http://www.learnASP.com/learn/serverobjectsmail.asp by Charles M. Carroll
Page 265
ASPMail™ by Server 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
2
3
4
5
<html><head>
<title>serverobjectsmail.asp</title>
</head><body bgcolor="#FFFFFF">
<%
' ASPMail(tm) from www.serverobjects.com
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
' is not part of ASP per se,
' but a third party utility from serverobjects.com
Set Mailer = Server.CreateObject("SMTPsvg.Mailer")
Mailer.RemoteHost = "relay.datareturn.com"
Mailer.FromName = "Some Student"
Mailer.FromAddress = "[email protected]"
Mailer.AddRecipient "Charles Carroll","[email protected]"
Mailer.AddBCC "Charles Carroll","[email protected]"
Mailer.Subject = "ASPMail Tutorial"
Mailer.BodyText = "Hi. Just trying the mail example" & vbCrLf
Mailer.BodyText = "Line 2"
Mailer.BodyText = "Line 3"
If Mailer.SendMail then
Msg = "mail sent sucessfully!"
Else
Msg = "mail was not sent sucessfully"
End If
response.write Msg
%>
</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
26
27
28
29
</TD>
</TR>
</TABLE>
</form>
</BODY></HTML>
The responder to the form will look like this:
1
2
3
4
5
6
7
8
9
<HTML><HEAD>
<TITLE>Uploadsimplerespond.asp by softwareartisans.com</TITLE>
</HEAD><BODY>
Thank you for uploading your file.<br>
<% Set upl = Server.CreateObject("SoftArtisans.FileUp")
upl.Path = Server.Mappath ("/upload") & "/" & "tests"
upl.SaveAs "upload.tst"%><BR>
Total Bytes Written: <%=upl.TotalBytes%>
</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:
1.
2.
The FORM must have a tag of ENCTYPE="multipart/form-data".
The <INPUT TYPE="FILE"> must have a tag of NAME= .
This tells the browser to transmit the contents of the file when posting the form.
Let's look at the form's processing (formresp.asp). The following line creates an instance of the SA-FileUp object:
<% Set upl = Server.CreateObject("SoftArtisans.FileUp") %>
The following line invokes the .SaveAs method and passes the name of the web server's destination file as a parameter.
<% upl.SaveAs "C:\temp\upload.out" %><BR>
In two lines you've uploaded a file!
For bonus points, the following line retrieves the TotalBytes property and displays it to the user.
Total Bytes Written: <%=upl.TotalBytes%>
What did we learn?
●
To upload files, there must be two elements on the form:
❍ <FORM ENCTYPE="multipart/form-data" ... >
❍ <INPUT TYPE="FILE" NAME="f1">
●
To process the form:
❍ First create an instance of the SA-FileUp component
❍
●
Second, invoke the .SaveAs method and specify a filename
It is possible to retrieve other properties, such as total size of the upload.
http://www.learnASP.com/learn/uploadmultipart.asp by Charles M. Carroll
Page 267
Upload File -- Multi-Part Form by David 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
2
3
4
5
6
7
8
9
<HTML><HEAD>
<TITLE>uploadmultipart.asp by softwareartisans.com</TITLE>
</HEAD><body bgcolor="#FFFFFF">
<form enctype="multipart/form-data" method="post" action="uploadmultipartrespond.asp">
Enter description: <input type="text" name="descrip"><br>
Enter filename to upload: <input type="file" name="f1"><br>
<input type="submit">
</form>
</BODY></HTML>
The responder to the form will look like this:
1
2
3
4
5
6
7
8
9
10
11
12
<HTML><HEAD>
<TITLE>Uploadmultipartrespond.asp by softwareartisans.com</TITLE>
</HEAD><BODY>
Thank you for uploading your file.<br>
<% Set upl = Server.CreateObject("SoftArtisans.FileUp")
upl.Path = server.mappath("\upload") & "/tests"
%>
<% upl.SaveAs "upload.tst" %><BR>
Your description is: '<%=upl.Form("descrip")%>'<BR>
Total Bytes Written: <%=upl.TotalBytes%>
<%set upl=nothing%>
</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" ... >
ASP's Request.Form object does not understand this encoding type. Instead use, SA-FileUp's Form object
which offers identical functionality.
To refer to elements on the form, use the name of the element on the form, i.e. upl.Form("descrip")
http://www.learnASP.com/learn/uploadlimitsize.asp by Charles M. Carroll
Page 268
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
2
3
4
5
6
7
8
<HTML><HEAD>
<TITLE>uploadlimitsize.asp by softartisans.com</TITLE>
</HEAD><body bgcolor="#FFFFFF">
<form enctype="multipart/form-data" method="post" action="uploadlimitsizerespond.asp">
Enter a big file to upload: <input type="file" name="f1"><br>
<input type="submit">
</form>
</BODY></HTML>
The responder to the form will look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<HTML><HEAD>
<TITLE>Uploadlimitsizerespond.asp by softartisans.com</TITLE>
</HEAD><BODY>
Thank you for uploading your file.<br>
<% Set upl = Server.CreateObject("SoftArtisans.FileUp") %>
<% 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>
<%
upl.Path = server.mappath("\upload") & "/tests"
upl.SaveAs "upload.out"
%>
Total Bytes Written: <%=upl.TotalBytes%><br>
Server Filename: <%=upl.ServerName%><br>
Total Bytes Transmitted by you: <%=Request.TotalBytes%>
<%set upl=nothing%>
</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.
● Some properties are Read Only such as TotalBytes, and some are Read/Write such as MaxBytes.
● The amount of information transmitted by the browser is always larger than the file because of addition encoding
information and form elements.
That completes our tutorial for now. Please see our many code samples for other examples of SA-FileUp functionality,
including:
● Uploading to a Database
● Secure download from the server to the browser
● Saving the upload in binary format
● Manipulating files on the web server.
Thank you for using our tutorial!
Please visit the Software Artisans' web
http://www.learnASP.com/learn/uploadmanyfiles.asp by Charles M. Carroll
Page 269
Upload Many Files by David 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
2
3
4
5
6
7
8
9
<HTML><HEAD>
<TITLE>uploadmanyfiles.asp by softartisans.com</TITLE>
</HEAD><body bgcolor="#FFFFFF">
<form enctype="multipart/form-data" method="post" action="uploadmanyfilesrespond.asp">
Enter first filename: <input type="file" name="f1"><br>
Enter second filename: <input type="file" name="f2"><br>
<input type="submit">
</form>
</BODY></HTML>
The responder to the form will look like this:
1
2
3
4
5
6
7
<HTML><HEAD>
<TITLE>Uploadmanyfilesrespond.asp by softartisans.com</TITLE>
</HEAD><BODY>
Thank you for uploading your files.<br>
<% Set upl = Server.CreateObject("SoftArtisans.FileUp")
upl.Path = server.mappath("\upload") & "/tests"
%>
8
9
10
11
12
<% upl.Form("f1").SaveAs "upload1.out" %><BR>
Total Bytes Written for file 1: <%=upl.Form("f1").TotalBytes%>
<% upl.Form("f2").SaveAs "upload2.out" %><BR>
Total Bytes Written for file 2: <%=upl.Form("f2").TotalBytes%>
</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.
● For each uploaded file, SA-FileUp creates a new SAFile object to represent the uploaded file.
Great - you've got lots of uploads working.
http://www.learnASP.com/learn/perfcounters.asp by Charles M. Carroll
Page 270
Performance Counter monitoring via a Web 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
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<%
' counters to watch
Dim arrFriendlyName,arrCounterPath
arrFriendlyName = Array("Total failed requests","Errors per second (current)",_
"Runtime errors (total)", "Script compiler errors (total)", _
"ASP preprocessor errors (total)")
arrCounterPath = Array("\\.\Active Server Pages\Requests Failed Total", _
"\\.\Active Server Pages\Errors/Sec", _
"\\.\Active Server Pages\Errors During Script Runtime",_
"\\.\Active Server Pages\Errors From Script Compilers", _
"\\.\Active Server Pages\Errors From ASP Preprocessor")
Dim objQPerfCnt, bResult, varResult, i
Set objQPerfCnt = CreateObject("Softwing.AspQPerfCounters")
bResult = objQPerfCnt.OpenQuery()
for i = 0 to UBound(arrCounterPath)
bResult = objQPerfCnt.AddCounter(arrCounterPath(i))
next
bResult = objQPerfCnt.CollectQueryData()
for i=0 to UBound(arrCounterPath)
varResult = objQPerfCnt.GetFormattedCounterVal(arrCounterPath(i), 0)
Response.Write "<b>" & arrFriendlyName(i) & "</b>: "
Response.Write varResult & "<br>" & vbCrLf
next
%>
</body>
</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
[email protected]
Related Links
http://www.learnASP.com/learn/new.asp by Charles M. Carroll
Page 271
New Lessons (new.asp) - Page 1
Global.asa Resources (globalmore.asp) - Page 2
Validation Resources (validationmore.asp) - Page 3
Graphic Size Detector (graphicdetect.asp) - Page 4
Database Display via GetRows (dbtablegetrows.asp) - Page 5
Database Display via GetString (dbtablegetstring.asp) - Page 6
ASPDB - Superb Database Component (aspdb.asp) - Page 7
Date/Time on ASP Pages by Tony Arguelles (datetime.asp) - Page 8
Time Tasks with Millisecond Accuracy (speedtimer.asp) - Page 9
Hidden Fields/Pass Data Among Pages (hidden.asp) - Page 10
Cookies/Pass Data Among Pages (cookies.asp) - Page 11
Remote Scripting Simple Example (remotescripting.asp) - Page 12
Remote Scripting/Microsoft Sample (remotescriptingms.asp) - Page 13
Database to ListBox Online Resources (dblistmore.asp) - Page 14
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
●
www.thawte.com
http://www.learnASP.com/learn/FAQCommerceCharge.asp by Charles M. Carroll
Page 276
[aspcommerce] listserv
FAQ #2: I want to process credit cards on my web site. Where do I start?
Many sites offer credit card processing but here is a list (you can search the archives for opinions and rates, etc.)
● www.anacom.com
●
www.cybercash.com
●
www.charge.com
●
ww.swreg.com
●
http://www.authorizenet.com/
●
http://www.securetrading.co.uk (may do just the UK)
●
http://www.worldpay.com
●
http://www.merchantservices.com
http://www.learnASP.com/learn/FAQCommerceCarts.asp by Charles M. Carroll
Page 277
[aspcommerce] listserv
FAQ #3: What ASP components and scripts work to charge online?
● ASPcharge from www.bluesquirell.com
●
IPCharge from www.gosoftinc.com
●
IISCart from http://www.iiscart.com
●
PCAuthX used with Tellan's PCAuthorize*Hub at http://www.active4.com/default.asp?PI=PCAUTHX
●
www.mercantec.com
●
http://www.storefront.net
●
http://www1.viaweb.com/softartisans/saxcheck.html
●
ActiveShopper at http://www.active4.com
http://www.learnASP.com/learn/FAQJscriptCleanUp.asp by Charles M. Carroll
Page 278
[aspJscript] listserv
FAQ #1: How do I close database connections?
Question: In VBScript, after you would close the recordset and connection objects, you would insure that the objects 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 [email protected]
MCSE, MCP+Internet Senior Consultant,
ARIS Corporation Inquire at http://www.aris.com
What do I need for connectivity for Oracle from ASP:
This question is a very valid question for most people beginning and experienced with Oracle from within ASP. Because of the variety of 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.
●
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.
●
Your DSN connection consists of an ODBC driver. Here are your most utilized choices:
●
Microsoft ODBC Driver for Oracle 2.00.00.6325 (Microsoft supplied driver)
●
Microsoft ODBC for Oracle 2.573.3513.00 (Microsoft supplied driver)
●
Oracle ODBC Driver 7.x or 8.x (Oracle supplied driver)
Most people prefer to use the Microsoft ODBC Driver for Oracle 2.0 for the reason that is seems to be more stable than the 2.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:
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.
●
The CONNECT_DATA string is made up of the Oracle SID. The SID is the name of the Oracle Instance.
●
The PORT parameter is defaulted to 1521 and 1526. These are the default installations where the listener listens for requests from the
machine where Oracle is installed.
What does a connection string to Oracle look like?
Set AUM = Server.CreateObject("ADODB.Connection")
AUM.Open Connect_String(DSN), USERNAME, PASSWORD
How do you configure the Oracle ODBC Driver?
To configure the ODBC driver, you will first need to :
1. open the "ODBC Data Sources" icon in the control panel applet.
2. 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").
3. Once selected, you will see the following screen minus everything below connect string. If you want the advanced configuration as shown
below select options.
* 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.
●
If you have successfully tested the statement against the database outside of ASP, make sure your statement is syntactically correct with
ADO.
●
Make sure all concatenated statements have the correct spaces in them.
sqlChk = "SELECT COUNT(NAME)"
sqlChk = sqlChk & " FROM MYAPP_USERS"
sqlChk = sqlChk & " WHERE NAME = UPPER('" & Request.Form("txtUserID") & "')"
* Note: Although eliminating the number of lines for interpretation can optimize your code, some prefer readability to the 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.
●
Make sure that you DO NOT have spaces in your table names.
I keep getting a TNS error while trying to connect.
Check the following:
● Insure that you can connect via SQL*PLUS. This will confirm that your TNSNAMES.ORA file is configured properly. If not, check the
following:
●
Verify the instance is running (i.e. Oracle is up).
●
Make sure you have a TNSNAMES.ORA entry. See "WHAT DO I NEED FOR CONNECTIVITY FOR ORACLE FROM ASP".
●
Check to see that the "TNS listener" service is running on the machine where Oracle resides.
●
Check to make sure that you have the correct ODBC driver. See "WHAT DO I NEED FOR CONNECTIVITY FOR ORACLE FROM
ASP".
●
If you can connect via SQL*PLUS, check the following:
●
Check to make sure that you have the correct ODBC driver. See "WHAT DO I NEED FOR CONNECTIVITY FOR ORACLE FROM
ASP".
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" [email protected]:
Not really about ASP... but... this is an excellent book and is a very good all around Oracle text. It includes detailed info on RDO,
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 <[email protected]>
This happens when the DLL is loaded in memory because it is in use or has been used by an application. The DLL needs to 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
●
http://www.activeserverpages.com/learn/buildregister.asp
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