Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
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
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
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!
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"> The webserver file
Today is <%=now%> and all is well<br>
<%if hour(now())>13 THEN%>
Good Morning
<%ELSE%> <<<<<<<
Good Day!
<%END IF%>
</body></html>
ASP compiler grabs page
Interprets all the <% %> markers
before browser sees page!
<html><head>
<TITLE>hi.asp</TITLE> Before 12pm the user at the browser receives
</head>
<body bgcolor="#FFFFFF">
Today is Tue 10:30am and all is well<br>
Good Morning <<<<<<<
</body></html>
<html><head>
<TITLE>hi.asp</TITLE> After 12pm the user at the browser receives
</head>
<body bgcolor="#FFFFFF">
Today is Tue 02:00pm and all is well<br>
Good Day! <<<<<<<
</body></html>
IIS4 Docs
NT4 Option Pak /iishelp
ASP objects reference /iishelp/iis/htm/asp/intr1orp.htm
Ex Air /IISSamples/ExAir/default.asp
Installable Components for ASP /iishelp/iis/htm/asp/comp275c.htm
JScript Language Reference /iishelp/JScript/htm/JStoc.htm
VBScript Language Reference /iishelp/VBScript/htm/VBStoc.htm
Server Side Include Reference /iishelp/iis/htm/asp/iissiref.htm
ASP Quick reference card /iishelp/iis/htm/asp/iiwaref.htm
ASP Tutorial* click here
IIS3 Docs
Roadmap / Official IIS3 Docs /iasdocs/aspdocs/roadmap.asp
IIS3 Code Samples /aspsamp/samples/samples.htm
AdventureWorks /AdvWorks/default.asp
● 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 <html><head>
2 <title>response.asp</title>&
3 <body color="#FFFFFF">
4 <%
5 when=now()
6 tommorow=dateadd("d",1,when)
7 twoweekslater=dateadd("ww",2,when)
8 fourteenweekdayslater=dateadd("w",14,when)
9 monthlater=dateadd("m",1,when)
10
11 sixminuteslater=dateadd("n",6,when)
12 sixhourslater=dateadd("h",6,when)
13 fortysecslater=dateadd("s",40,when)
14
15 response.write "Now <b>" & when & "</b><br>"
16 response.write "tommorow <b>" & tommorow & "</b><br>"
17 response.write "2 weeks from Now <b>" & twoweekslater & "</b><br>"
18 response.write "fourteen working days from Now <b>" & fourteenweekdayslater & "</b><br>"
19 response.write "1 month from Now <b>" & monthlater & "</b><br>"
20 %>
21 six minutes from now <b> <%=sixminuteslater%> </b><br>
22 six hours from now <b> <%=sixhourslater%> </b><br>
23 fourty seconds later <b> <%=fortysecslater%> </b><br>
24 </body></html>
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 the fixed page that will NOT display the error:
1 <%response.buffer=true%>
2 <html><head>
3 <title>dailystuff.asp</title>
4 </head>
5 <body>
6 <%
7 whatweekday=Weekday(now())
8 select case whatweekday
9 case vbSunday
10 response.redirect "http://www.cnn.com"
11 case vbMonday
12 response.redirect "http://www.activeserverpages.com"
13 case vbTuesday
14 response.redirect "http://www.aspalliance.com"
15 case vbWednesday
16 response.redirect "http://www.aspconvention.com"
17 case vbThursday
18 response.redirect "http://www.aspmagazine.com"
19 case vbFriday
20 response.redirect "http://www.dilbert.com"
21 case vbSaturday
22 response.redirect "http://www.movielink.com"
23 end select
24 %>
25 </body>
26 </html>
<!--#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.
<%SELECT CASE
CASE 1 %>
<!--#include virtual="whatever1.asp"-->
CASE 2 %>
<!--#include virtual="whatever2.asp"-->
CASE 3 %>
<!--#include virtual="whatever3.asp"-->
<%END SELECT%>
Three includes are performed before any ASP code is executed.
YOU CANNOT DO:
<%
whichfile="1"%>
<!--#include virtual="whatever<%=whichfil%>.asp"-->
Though this is a reasonable idea.
<!--#include virtual="whatever.asp"-->
The alternative is:
1 <html><head>
2 <TITLE>includedynamic.asp</TITLE>
3 </head><body bgcolor="#FFFFFF">
4 <%
5 whichfile="bookscifi.asp"
6 Call ReadDisplayFile(whichfile)
7 response.write "<hr>"
8
9 whichfile="bookhorror.asp"
10 Call ReadDisplayFile(whichfile)
11 response.write "<hr>"
12
13
14 whichfile="/learn/test/bookmarketing.asp"
15 Call ReadDisplayFile(whichfile)
16 response.write "<hr>"
17 %>
18
19 </body></html>
20 <%
21 SUB ReadDisplayFile(FileToRead)
22 whichfile=server.mappath(FileToRead)
23 Set fs = CreateObject("Scripting.FileSystemObject")
24 Set thisfile = fs.OpenTextFile(whichfile, 1, False)
25 tempSTR=thisfile.readall
26 response.write tempSTR
27 thisfile.Close
28 set thisfile=nothing
29 set fs=nothing
30 END SUB
31 %>
The only downside to this method is no ASP Code ( i.e. anything in <% %> ) will be parsed or executed in the included file.
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.
Microsoft provides a ton of predefined VBScript functions designed to reduce coding time. The FormatDateTime() function is one of
those powerful functions and is really easy to use, too. This function uses the following format:
FormatDateTime(date, format)
There are two arguments the function accepts: date and format. Table 1-1 below describes these arguments in greater detail:
Table 1-1: The FormatDateTime() function and its arguments
Argument Argument Description
date This argument is required and can be any valid date expression
such as Date or Now
format This format constant or format value specifies how the date
and/or time will be displayed on your ASP page.
When specifying the format argument, you can either type the
Visual Basic constant name (name in left column), or the
constant's corresponding value (0 - 4, from the middle column).
They do the same thing, it's just less typing if you use the value.
Constant Format Value Format Description
vbGeneralDate 0 This is the default. Not
specifying a value or
specifying 0 will produce a
date in the format of
mm/dd/yy.
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:
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) %>)
If you would like to return the current time, here are a couple of ways to do that:
If you would like to return the current date and time together, here's how to do just that:
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) %> <%= FormatDateTime(Now, 3)%> returns:
Tuesday, January 25, 2000 9:55:29 PM
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>
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:
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.
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
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 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.
Think of the displayed date or time as a "snap shot" of when the page was requested by the visitor. You cant use this function to
display a "clock" that updates every second, or automatically update the date on the page when one day turns to the next.
If you wanted to display a dynamic clock on your page, you would need to use client side JavaScript, or VBScript (IE only) to handle
that task.
I hope you've enjoyed this article on the FormatDateTime() function. I'll be back soon with more date and time related ASP fun! If you
have any questions or comments, send me an Email at: tony@southbaywebdesigns.com
http://www.learnASP.com/learn/DoLoop.asp by Charles M. Carroll
Page 19
Do Loop Part #1 by Charles Carroll
To execute a code sequence more than once ASP provides:
● DO, LOOP
● 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
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.
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
● skipping the variables ALL_HTTP and ALL-RAW since they are just a "glob" of all the other vars
● place blank variables at the end
● display code to retrieve that variable so you can cut and paste into script
1 <html><head>
2 <TITLE>serverall.asp</TITLE>&
3 <body bgcolor="#FFFFFF">
4 <%
5 Response.Write("<P><B>Server Variables</b><br>")
6 BlankVars="<P><B>Blank Server Variables</b><br>" & vbcrlf
7 quote=chr(34)
8 For Each Key in Request.ServerVariables
9 If instr(Key,"_ALL")+instr(key,"ALL_")=0 then
10 tempvalue=trim(request.servervariables(Key))
11 If len(tempvalue)=0 then
12 BlankVars=BlankVars & Key & ", "
13 Else
14 response.write "request.servervariables(" & quote
15 response.write Key & quote & ") "
16 response.write " =<br><B>" & tempvalue & "</b><p>" & vbcrlf
17 End If
18 end if
19 Next
20 response.write mid(BlankVars,1,len(BlankVars)-2)
21 %>
22 </body></html>
If the server has been secured with https:// then the following script will display some additional variables:
https://secure.activeserverpages.com/learn/test/serverall.asp
● RND function
● INT function
● SELECT CASE
The script randomadvice.asp shows different advice every time the pge is refreshed:
1 <html><head>
2 <TITLE>randomadvice.asp</TITLE>
3 </head>
4 <body bgcolor="#FFFFFF">
5 <%
6 ' generate a random number 1-6
7 randomize
8 randomnum=int(rnd*6)+1
9 SELECT CASE randomnum
10 CASE 1,2,3%>
11 Plant your crops early this year<br>
12 No frost expected<br>
13 <%CASE 4%>
14 Never play cards<br>with a man named after a city<br>
15 <%CASE 5%>
16 You can never be too rich, too thin or backup too often<br>
17 <%CASE 6%>
18 A swallow keeps away the stork<br>
19 <%END SELECT%>
20 </body></html>
Browser Capabilites
The script below demonstrates the most commonly used property of the Browser Capabilites component.
1 <html><head>
2 <TITLE>bc.asp</TITLE>
3 </head><body bgcolor="#FFFFFF">
4 <% Set bc = Server.CreateObject("MSWC.BrowserType") %>
5 Browser Name: <%=bc.browser %><p>
6 Browser Version: <%=bc.version%><p>
7 <% if (bc.frames = TRUE) then %>
8 I noticed you do frames<p>
9 <% else %>
10 I noticed you are frame challenged<p>
11 <% end if %>
12 <% if (bc.tables = TRUE) then %>
13 I noticed you do tables<p>
14 <% else %>
15 I noticed you can't do tables<p>
16 <% end if %>
17 <% if (bc.BackgroundSounds = TRUE)then %>
18 I noticed you allow me to play music<p>
19 <% else %>
20 I noticed you aren't a music listener<p>
21 <% end if %>
22
23 <% if (bc.vbscript = TRUE) then %>
24 I noticed you are VBscript capable<p>
25 <% else %>
26 I noticed you can't understand VB Script<p>
27 <% end if %>
28
29 <% if (bc.javascript = TRUE) then %>
30 I noticed you understand JScript<p>
31 <% else %>
32 I noticed you don't understand JScript<p>
33 <%
34 end if
35 set bc=nothing
36 %>
37 </body></html>
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
Remember that the response.redirect code should go before any of the HTML content on the page. You can keep
this check script in a separate file, and include it at the top of all pages within an application.
Another example is the title attribute for HTML elements which, currently, is only supported by IE 4 or greater.
While the title attribute degrades fine in other browsers, it is sometimes desirable to limit the amount of
superfluous code being sent to the browser... regardless of how insignificant it may seem. This example will show
you a quick and easy way to let BrowserHawk decide for you whether or not to use that title attribute.
Here is an example of the title attribute. Since you are using IE4 or greater, if you hold your mouse over the
following link for a few seconds, you will see a tooltip, similar to the kind you see when you hold your mouse over
a button on an application's toolbar. This allows you to include a lot more information in a small space, such as a
navigation frame or a slim table cell.
Hover here
Using two methods of BrowserHawk, we can quickly and easily check if the visitor is using a browser which
supports the title element (namely, that it is Internet Explorer AND that it is version 4 or greater). Here is what the
code looks like:
1 <%
2 set bh = server.createobject("cyScape.browserObj")
3 if bh.version>=4 and bh.browser="IE" then
4 %>
5 <a href='x.asp' title=' This is the alternate text. '>
6 <% else %>
7 </a>
8 <a href='x.asp'>
9 <%
10 end if
11 set bh = nothing
12 %>
13 <p>
14 Hover here</a>
15
This logic could be used for any feature that you know is only supported by certain browser versions. Sometimes
it is worth it to prevent the waste of bandwidth caused by adding elements and features to a page when they can't
be viewed anyway. But more likely then not, you'll use this approach to avoid inconsistencies with layout and
scripting across browsers.
Need a copy of BrowserHawk? See our section on Getting Started.
Copyright (c) 1999 cyScape, Inc. All rights reserved. This material may not be published, distributed, or reprinted without written consent from cyScape.
http://www.learnASP.com/learn/bhaol.asp by Charles M. Carroll
Page 30
Similarly, you can also obtain the host name for any given IP address as well. You simply call the ResolveIP method and
pass in the IP address to be resolved as a parameter to the method. This is demonstrated in the example below:
1 <html>
2
3 <head>
4 <title>Resolve IP</title>
5 </head>
6
7 <body>
8 <%
9 ipToLookup = "198.137.240.91"
10 %>
11
12 <p>The host name for <%=ipToLookup%> is <%
13 set bh = Server.CreateObject("cyScape.browserObj")
14 hostname = bh.ResolveIP(ipToLookup)
15 if hostname <> "" then
16 response.write hostname
17 else
18 response.write "Unknown"
19 end if
20 %> </p>
21
22 <p>%></p>
23 </body>
24 </html>
Copyright (c) 1999 cyScape, Inc. All rights reserved. This material may not be published, distributed, or reprinted without written consent from cyScape.
Now even though all the syntax in the script is correct, since one of the numbers has the effect of creating a "division by zero" error
the script fails.
1 <TITLE>errordivide2.asp</TITLE>
2 <body bgcolor="#FFFFFF">
3 <%
4 ' ASP program that works if numbers are legit
5 x=7
6 y=2 ' if changed to 0 this will crash
7 z=x/y
8 response.write z & "<br>"
9 %>
10 </body></html>
Now we use the VBScript error trapping to present a message instead of a catastrophic script error.
1 <TITLE>errordivide3.asp</TITLE>
2 <body bgcolor="#FFFFFF">
3 <%
4 ' ASP program that works if numbers are legit
5 on error resume next
6 x=7
7 y=0
8 z=x/y
9 response.write z & "<br>"
10
11 If err.number=0 then
12 response.end
13 end if
14 pad=" "
15 response.write "<b>VBScript Errors Occured!<br>"
16 response.write parm_msg & "</b><br>"
17 response.write pad & "Error Number= #<b>" & err.number & "</b><br>"
18 response.write pad & "Error Desc.= <b>" & err.description & "</b><br>"
19 response.write pad & "Help Context= <b>" & err.HelpContext & "</b><br>"
20 response.write pad & "Help File Path=<b>" & err.helpfile & "</b><br>"
21 response.write pad & "Error Source= <b>" & err.source & "</b><br><hr>"
22 %>
23 </body></html>
Here are our guidelines for getting to the heart of the matter. First add some error code to the script to display the messages and bad
SQL that causes the problem, for example:
1 <html><head>
2 <title>dbtroubleshoot.asp</title>&
3 <body>
4 <!--#include file="lib_errors.asp"-->
5 <%
6 on error resume next
7 Set Conn = Server.CreateObject("ADODB.Connection")
8 conn.open "DSN=student;uid=student;password=magic"
9
10 SQLstmt = "INSERT INTO junk (city,state,zip) VALUES ('Rockville','MD','20849')"
11 Set RS = Conn.Execute(SQLStmt)
12
13 Call ErrorVBScriptReport("Insert Statement")
14 Call ErrorADOReport(SQLstmt,conn)
15
16 rs.close
17 set rs=nothing
18 Conn.Close
19 set conn=nothing%>
20
21 </body></html>
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.
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)
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.
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.
....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.
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.
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.
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
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.
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
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
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
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
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
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
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
This component.ini file contains a list of typical server components, grouped by type. Type is indicated within [ ] codes. Here is the
contents of the current component.ini:
1 [standard]
2 mswc.browsertype
3 mswc.nextlink
4 scripting.dictionary
5 scripting.filesystemobject
6
7 [ado]
8 adodb.recordset
9 adodb.connection
10 adodb.command
11
12 [cdo]
13 CDONTS.NewMail
14
15 [cyscape]
16 cyScape.browserObj
17
18 [indexserver]
19 ixsso.Query
20 ixsso.Util
21
22 [Lyris]
23 Lyris.LCP
24
25 [http://msdn.microsoft.com/scripting]
26 Wscript.Shell
27
28 [msfreebies]
29 iissample.asp2htm
30 iissample.contentrotator
31 iissample.registry
32 iissample.summaryinfos
33 iissample.tracer
34 mswc.adrotator
35 mswc.counters
36 mswc.myinfo
37 MSWC.PageCounter
38 MSWC.PermissionChecker
39 mswc.tools
40 mswc.loadbalance
41
42 [msXML]
43 microsoft.XMLHTTP
44 microsoft.XMLDOM
45
46 [www.aspdb.com]
47 ASPdb.Free
48 ASPdb.View
49 ASPdb.Pro
50 ASPdb.EP
51
52 [www.serverobjects.com]
53 ASPChart.Chart
54 AspConv.Expert
55 AspDNS.Lookup
56 AspFile.FileObj
57 AspHTTP.Conn
58 AspImage.Image
59 AspInet.FTP
60 AspMX.Lookup
61 AspNNTP.Conn
62 AspPager.Pager
63 SMTPsvg.Mailer
64
65 [www.softartisans.com]
66 SoftArtisans.FileUp
67 SoftArtisans.SACheck
68 SoftArtisans.SASessionPro
69 SoftArtisans.FileManager
70 EZsite.Calender
71 EZsite.CalendarManager
72 EZsite.WebNotes
73
74 [www.active4.com]
75 ActiveLaunch.Control
76 ActiveSAR.SearchAndReplace
77 ActiveShopper.Cart
78 ActiveShopper.BasketItem
79 FileTouch.Control
80 PCAuthX.Authorizer
81 Prt2Disk.Control
82 SemClient.Control
83 SPrinterPro.Object
84 TimeSpan.Control
85 WWWPrint.Client
86
87 [Zaks Software]
88 ZaksPop3.Server
89 JavaPop3.Mailer
90
91 [www.persits.com]
92 Persits.MailSender
93
94 [www.oceantek.com]
95 ASPL.Login
96
97 [www.able-consulting.com]
98 ACI.WhoIs
99
100 [www.softwing.com]
101 Softwing.EventLogReader
102 Softwing.OdbcRegTool
103 w3info.w3info.1
104 InetCtls.Inet.1
105 Softwing.AspQPerfCounters
106 SQLOLE.SQLServer
107 SOFTWING.ASPEventlog
108 SOFTWING.ASPtear
109 SOFTWING.EDConverter
110 SOFTWING.EventLogReader
111 SOFTWING.FileCache.1
112 SOFTWING.OdbcRegTool
113 SOFTWING.LocaleFormatter
114 SOFTWING.Profiler
115
116 [www.dougdean.com]
117 EZsite.EZuploadLite
118
119 [www.algonet.se/~jekman]
120 lightcom.xBrowser
121 lightcom.xContent
122 lightcom.xPop3
123 lightcom.xSMTP
124 lightcom.xTree
125 lightcom.xBrowser
126 JESoftware.xContent
127 JESoftware.xPop3
128 JESoftware.xSMTP
129 JESoftware.xTree
130
131 [tech.dimac.net]
132 Socket.TCP
133
134 [www.de-info.com]
135 checkemail.maccheckemail
136
137 [www.pstruh.cz]
138 TCPIP.Trace
139 TCPIP.DNS
140
141 [www.dana-net.com/products/aspcomponents/magicregistry]
142 MagicRegistry.Tricks
If you want to know what drivers and other vital details are being used for a DSN, here is some code to the rescue.
1 <html><head>
2 <title>connectioninfo.asp by Christophe Wille http://www.softwing.com</title>
3 </head>
4 <!--#include file="lib_connectioninfo.asp"-->
5 <body>
6 <%
7 response.write "<hr>SQL Server Connection"
8 Call DSNinfo("DSN=student;uid=student;pwd=magic")
9 response.write "<hr>Access Connection Connection"
10 theDSN="DRIVER={Microsoft Access Driver (*.mdb)};DBQ="
11 theDSN=theDSN & server.mappath("/learn/test/biblio.mdb")
12 Call DSNInfo(theDSN)
13 %>
14 </body>
15 </html>
http://127.0.0.1
It has other aliases, like http://localhost but it true reliable name is the one above.
Tips:
Tip #1: If using response.redirect to simulate a GET don't forget to encode:
/learn/encode.asp
Tip #2: a text link to post above form would look like this:
<a href="javascript:submitform(document.forms['whatever'])">
whatever</a>
thanks to Remko van der Vossen <R.vanderVossen@chello.nl> for this tip I looked high and low for.
http://www.learnASP.com/learn/formtextbox.asp by Charles M. Carroll
Page 53
1 <html><head>
2 <title>FormTextBox.asp</title>
3 </head><body bgcolor="#FFFFFF">
4 <Form action = "FormTextBoxRespond.asp" method="get">
5 Fill Out This Form For Us:<p>
6 Last Name -> <Input NAME="NameLast" size ="10"><br>
7 Country -> <Input NAME="Country" value="USA" size=10><br>
8 State -> <Input NAME="State" MaxLength="2" size=2><br>
9 <Input type="submit" value="Give me your data!">
10 <hr></form>
11 </body></html>
1 <html><head>
2 <title>FormTextBoxRespond.asp</title>
3 </head><body bgcolor="#FFFFFF">
4 <%
5 lname=request.querystring("namelast")
6 cty=request.querystring("country")
7 st=request.querystring("state")
8
9 response.write lname & "<br>"
10 response.write cty & "<br>"
11 response.write st & "<br>"%>
12 </body></html>
Here is the select case that will determine what the form input means.
1 <html><head>
2 <TITLE>caserespond.asp</TITLE>
3 </head><body bgcolor="#FFFFFF">
4 <%
5 fname=request.querystring("Firstname")
6 lname=request.querystring("Lastname")
7 %>
8 Nice to Meet You <%=fname%> <%=lname%><p>
9 <%If fname="" then%>
10 Sorry we are not on a first name basis...<p>
11 <%end if
12 select case lcase(lname)
13 case "washington","adams"
14 response.write "The first president has same last name<p>"
15 case "jefferson"
16 response.write "The third president has same last name<p>"
17 case "lincoln"
18 response.write "The sixteenth president has same last name<p>"
19 end select%>
20 </body></html>
Here is the select case that will determine what the form input means.
1 <html><head>
2 <TITLE>case2respond.asp</TITLE>
3 </head><body bgcolor="#FFFFFF">
4 <%
5 fname=request.querystring("Firstname")
6 lname=request.querystring("Lastname")
7 title=request.querystring("title")
8 response.write "Nice to Hire You " & fname & " " & lname & "<p>"
9 Select Case lcase(Title)
10 case "employee","temp"
11 response.write("The washroom is in the hall")
12 case "manager","executive"
13 response.write("Here is your key to the Executive washroom")
14 case "ceo", "vice-prez"
15 response.write("The maid will attend to your private washroom")
16 End Select%>
17 </body></html>
Now we make a asp file that examines their first name and last name after the form is submitted.
1 <html><head>
2 <TITLE>ifrespond.asp</TITLE>
3 </head><body bgcolor="#FFFFFF">
4 <%fname=request.querystring("Firstname")
5 lname=request.querystring("Lastname")
6 If fname="George" and lname="Washington" then%>
7 Hi.<p>You must be the first president!
8 <%else%>
9 Hi!<p>Nice to Meet You
10 <%end if%>
11 </body></html>
Now we make a asp file that examines their first name and last name after the form is submitted. As contrasted to the previous
example this time we are checking multiple conditions utilizing elseif and we are dealing with entries no matter whether they were
typed in upper or lower case.
1 <html><head>
2 <TITLE>if2respond.asp</TITLE>
3 </head><body bgcolor="#FFFFFF">
4 <%
5 fname=lcase(request.querystring("Firstname"))
6 lname=lcase(request.querystring("Lastname"))
7 If fname="george" and lname="washington" then%>
8 Hi.<p>You must be the first president!
9 <%elseIf fname="ronald" and lname="reagan" then%>
10 Hi.<p>You must be the actor president!
11 <%elseIf fname="jimmy" and lname="carter" then%>
12 Hi.<p>You must be the peanut farmer president!
13 <%elseIf fname="naoko" or fname="charles" then%>
14 Hi.<p>Your name reminds me of someone<p>
15 but I am not sure who!
16 <%else%>
17 Hi!<p>Nice to Meet You
18 <%end if%>
19 </body></html>
http://www.learnASP.com/learn/if3.asp by Charles M. Carroll
Page 62
IF statement Part3 (by John Kauffman & Charles Carroll)
Very often you must determine what to do next based on user input. This is one of the roles of the IF statement. First we make a
form that will ask a user for their first name, last name and salary.
1 <html><head>
2 <TITLE>if3.asp</TITLE>
3 </head><body bgcolor="#FFFFFF">
4 <form action="if3respond.asp" method=get>
5 Your First Name<INPUT NAME="FirstName" MaxLength=20><p>
6 Your Last Name<INPUT NAME="LastName" MaxLength=20><p>
7 Your Salary <INPUT NAME="Salary" MaxLength=7><p>
8 <INPUT TYPE=submit><p><INPUT TYPE=reset>
9 </form></body></html>
This example shows how IF can deal with ranges and use various other boolean operators.
1 <html><head>
2 <TITLE>if3respond.asp</TITLE>
3 </head><body bgcolor="#FFFFFF">
4 <%
5 fname=request.querystring("Firstname")
6 lname=request.querystring("Lastname")
7 salary=request.querystring("Salary")
8 response.write "Nice to Meet You " & fname & " " & lname & "<p>"
9 if salary>100000 then%>
10 Would you like to loan me some money?<p>
11 <%
12 sstaxMarginal=15
13 else
14 SSTaxMarginal=15
15 end if
16 If salary>6700 and salary<30000 then
17 SSTaxMarginal=0%>
18 Would you like me to loan you some money?<p>
19 <%end if
20 If salary<6700 then
21 SSTaxMarginal=0
22 end if
23 %>
24 By the way your marginal tax rate is <%=sstaxmarginal%>
25 </body></html>
This example shows how IF can deal with ranges but this example illustrates the critical factor of ordering. If you were to re-arrange
these IFs they would not accurately report your salary grade.
1 <html><head>
2 <TITLE>if4respond.asp</TITLE>
3 </head><body bgcolor="#FFFFFF">
4 <%fname=request.querystring("Firstname")
5 lname=request.querystring("Lastname")
6 salary=request.querystring("Salary")
7 response.write "Nice to Meet You " & fname & " " & lname & "<p>"
8 if salary>80000 then
9 salarygrade=4
10 end if
11 if salary <=80000 then
12 salarygrade=3
13 end if
14 If salary <=60000 then
15 salarygrade=2
16 end if
17 if salary <=40000 then
18 salarygrade=1
19 end if
20 response.write ("Your Salary is $" & salary)
21 response.write (", your Grade is " & salarygrade & ".<p>")
22 %>
23 </body></html>
1 <html><head>
2 <TITLE>monthlyFormRespond.asp</TITLE>
3 </head><body bgcolor="#FFFFFF">
4 <%
5 daysworked=0
6 for each whatever in request.form
7 thisvalue=request.form(whatever)
8 If thisvalue="on" then
9 daysworked=daysworked+1
10 end if
11 next
12 response.write "Thanks for working <b>" & daysworked & "</b> days"
13 %>
14 </body></html>
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 the generic form responder that can be used with this or any form:
1 <html><head>
2 <title>serverobjectsmailrespond.asp</title>
3 </head><body bgcolor="#FFFFFF">
4 <%
5 ' ASPMail(tm) from http://www.serverobjects.com
6 ' is not part of ASP per se,
7 ' but a excellent third party component
8
9 my_from=request("mail-fromName")
10 my_fromAddress=request("mail-fromaddress")
11 my_to=request("mail-toName")
12 my_toAddress=request("mail-toaddress")
13 my_subject=request("mail-subject")
14 my_relay=request("mail-relay")
15
16 Set Mailer = Server.CreateObject("SMTPsvg.Mailer")
17 Mailer.RemoteHost = my_relay
18
19 Mailer.FromName = my_from
20 Mailer.FromAddress = my_fromAddress
21 Mailer.AddRecipient my_to, my_toaddress
22 Mailer.Subject = my_subject
23
24 for each whatever in request.querystring
25 If instr(whatever,"mail-")=0 then
26 Mailer.BodyText = whatever & "=" & vbcrlf
27 Mailer.BodyText = request.querystring(whatever) & vbcrlf & vbcrlf
28 end if
29 next
30
31 for each whatever in request.form
32 If instr(whatever,"mail-")=0 then
33 Mailer.BodyText = whatever & "=" & vbcrlf
34 Mailer.BodyText = request.form(whatever) & vbcrlf & vbcrlf
35 end if
36 next
37
38 my_emailcopy=request("emailcopy")
39 If my_emailcopy="" then
40 else
41 Mailer.AddRecipient "form filler",my_emailcopy
42 end if
43
44 If Mailer.SendMail then
45 Msg = "mail sent sucessfully!"
46 Else
47 Msg = "mail was not sent sucessfully"
48 End If
49 response.write Msg
50 %>
51 </body></html>
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
● 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]
%>
Everything you wanted to know about global.asa but were afraid to ask @
http://www.4guysfromrolla.com/webtech/113098-1.shtml
http://www.aspalliance.com/stevesmith/samples/sitestats.asp
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
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.
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/
Here Eli Robillard has done a lot of work for you. You modify one ASP file that specifies your database and query specs and his ASP
scripts magically do the rest.
Here is an example where I make a pubs.asp designed to plug into his ASP scripts.
1 <%
2 ' Generic interface to the Northwinds Employee table.
3 Session("dbGenericPath") = "/learn/test/genericdb/"
4 Session("dbExitPage") = "http://www.activeserverpages.com"
5 Session("dbTitle") = "Pubs"
6 Session("dbType") = "SQL"
7 Session("dbConn") = "DSN=student;uid=student;pwd=magic"
8 Session("dbRs") = "Publishers"
9 Session("dbKey") = 1
10 Session("dbOrder") = 2
11 Session("dbRecsPerPage") = 10
12 Session("dbFooter") = 1
13 Session("dbDispList") = "011101000000100010"
14 Session("dbDispView") = "111111111111111111"
15 Session("dbDispEdit") = "011111111111111111"
16 Session("dbSearchFields") = "011100010010001000"
17 Session("dbDefault6") = Date()
18 Session("dbCombo11") = "LIST, ??, Unknown, CA, Canada, US, United States, DE, Denmark"
19 Session("dbDefault17") = 10
20 Session("dbWhere") = ""
21 Session("dbDebug") = 1
22 Session("dbCanEdit") = 1
23 Session("dbCanAdd") = 1
24 Session("dbCanDelete") = 1
25 Session("dbConfirmDelete") = 1
26 Session("dbViewPage") = Request.ServerVariables("PATH_INFO")
27 Response.Redirect Session("dbGenericPath") & "GenericList.asp"
28 %>
There is even a listserve supporting this great FREE script collection. It is not a general database troubleshooting list, instead
only questions concerning these wonderful scripts are allowed.
aspgenericdb Listserver
Related Links
Generic DB Main Page @
http://www.ofifc.org/Eli/asp/
Use the lightning fast Getstring function to retrieve a recordset into a string:
/learn/dbtablegetstring.asp
Displaying a Table with many records as quick as possible is documented in depth at:
/learn/speedtables.asp
/learn/speedtablesall.asp
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.
DSNless connections demand that that you know the name of the file (i.e. file based databases like Access, Paradox, FoxPro, etc.)
or the address of the data server (SQLserver for example). Armed with appropriate information you could open a data source without
a DSN!
Note that you must know the actual filepath on the server, i.e. nwind.mdb is not good enough it needs to be
"C:\thatserver\account17\nwind.mdb". Fortunately the server.mappath function can turn a filename into the proper fully qualified
filename with path on the server.
Here is a sample nwind.asp connecting to an access database named "nwind.mdb" in the root of the web site with a DSNless
connection.
1 <HTML><HEAD>
2 <TITLE>nwind.asp</TITLE>
3 <body bgcolor="#FFFFFF"></HEAD>
4 <%
5 accessdb="nwind.mdb"
6 myDSN="DRIVER={Microsoft Access Driver (*.mdb)};"
7 myDSN=myDSN & "DBQ=" & server.mappath(accessdb)
8 mySQL="select * from customers"
9
10 call query2table(mySQL,myDSN)
11 %>
12 <!--#include virtual="/learn/test/lib_dbtable.asp"-->
13 </BODY>
14 </HTML>
15
Here is a sample sqldsn.asp connecting to an access database named "nwind.mdb" in the root of the web site with a DSNless
connection.
1 <HTML><HEAD>
2 <TITLE>sqldsn.asp</TITLE>
3 <body bgcolor="#FFFFFF"></HEAD>
4 <%
5 accessdb="nwind.mdb"
6 myDSN="DSN=student;uid=student;pwd=magic"
7 mySQL="select * from publishers where state='NY'"
8
9 call query2table(mySQL,myDSN)
10 %>
11 <!--#include virtual="/learn/test/lib_dbtable.asp"-->
12 </BODY>
13 </HTML>
14
Here is a sample sqldsnless.asp connecting to an access database named "nwind.mdb" in the root of the web site with a DSNless
connection.
1 <HTML><HEAD>
2 <TITLE>sqlDSNless.asp</TITLE>
3 <body bgcolor="#FFFFFF"></HEAD>
4 <%
5
6 mydb="PROVIDER=MSDASQL;DRIVER={SQL Server};"
7 mydb=mydb & "SERVER=sql2.datareturn.com;DATABASE=;"
8 mydb=mydb & "UID=student;PWD=magic;"
9
10 mySQL="select * from publishers where state='NY'"
11
12 call query2table(mySQL,mydb)
13 %>
14 <!--#include virtual="/learn/test/lib_dbtable.asp"-->
15 </BODY>
16 </HTML>
17
18
I began my development using Microsoft Access as I already had a copy, and it would help me to learn
SQL syntax that would later be of use in larger projects. For this reason, I will choose the MS Access
Database driver from this screen. If you are setting up a DSN for a different database format, select the
associated driver here.
http://www.learnASP.com/learn/dsn4.asp by Charles M. Carroll
Page 93
Setting up a system DSN Part 4
©1998, 1999 by Rob Martinson rob.martinson@directionsmag.com
Here we will name our DSN. For web development, I generally setup a single DSN (depending on the project of course) and then
just modify the database as needed. Because of that, I almost always name mine "tables.dsn". Name it whatever you like, just
remember the name. From this screen you are also able to setup various options with your DSN including default authorization (click
advanced), page timeout, database location, etc. For now we will leave the default options and move on to the next screen by
choosing "Ok".
http://www.learnASP.com/learn/dsn5.asp by Charles M. Carroll
Page 94
Setting up a system DSN Part 5
©1998, 1999 by Rob Martinson rob.martinson@directionsmag.com
If we have not specified the location of the database associated with our DSN on the previous screen, we will be prompted to
do so now. This is self explanatory I believe.
Here is a script that will add a bunch of records with the AU_ID of 200:
1 <TITLE>dbaddmany.asp</TITLE>
2 <body bgcolor="#FFFFFF">
3 <HTML>
4 <!--#include file="lib_errors.asp"-->
5 <%
6 on error resume next
7 myDSN = "DSN=Student;uid=student;pwd=magic"
8 mySQL = "INSERT INTO authors (AU_ID,author,year_born) "
9 mySQL = mySQL & "VALUES (200,'Charles M. Carroll',1964)"
10
11 Set Conn = Server.CreateObject("ADODB.Connection")
12 conn.open myDSN
13
14 for counter=1 to 200
15 thistask="Task #" & counter & "<br>"
16 response.write thistask
17 Conn.Execute(mySQL)
18 Call ErrorVBScriptReport(thistask)
19 Call ErrorADOReport(mySQL,conn)
20 next
21 Conn.Close
22 set conn=nothing
23 %>
24 </BODY>
25 </HTML>
Now here is a script that will delete all the records the above script added:
1 <TITLE>dbdeletemany.asp</TITLE>
2 <body bgcolor="#FFFFFF">
3 <HTML>
4 <!--#include file="lib_errors.asp"-->
5 <%
6 on error resume next
7 myDSN = "DSN=Student;uid=student;pwd=magic"
8 mySQL = "DELETE FROM authors WHERE au_id=200"
9
10 Set Conn = Server.CreateObject("ADODB.Connection")
11 conn.open myDSN
12
13 Conn.Execute mySQL,howmany
14 response.write "The statement " & mySQL & "<b> deleted " & howmany & " records</b><br>"
15 Call ErrorVBScriptReport("Deleting...")
16 Call ErrorADOReport(mySQL,conn)
17
18 Conn.Close
19 set conn=nothing
20 %>
21 </BODY>
22 </HTML>
If you have integrating Oracle with your ASP sites, we run a listserv/newgroup called [aspOracle] where that is the only topic
allowed you can join to get help from your colleagues worldwide.
aspOracle Listserver
JOIN, QUIT or Search ARCHIVES:
http://www.asplists.com/asplists/oracle.asp
Send Listserver Questions to
aspOracle@ls.asplists.com
Related Links
The Hottest Set of Oracle sites/listserves @
http://www.doug.org
How to Connect/Troubleshoot Oracle Connection by Bret H. Grade @
/learn/FAQOracleconnect.asp
How to Call Oracle Stored Procedure by Surya Rao @
/learn/FAQOraclestoredproc.asp
Returning Recordsets via ADO by John Kilgo @
/asplists/asporacleFAQ4.asp
Know any good Oracle Books? @
/asplists/asporacleFAQ2.asp
Does this approach matter for small data sets for example 9 rows x 2 columns of data? YES!!!!!!!!
My site has SQLserver scripts that run like lightning. I once needed to fill a 9 item listbox from Access and got 90 sec script timeouts
with movenext. Getstring never timed out. So in a real production situation it makes weak databases feasible and of course reduces
the load on more industrial back-ends so maybe the SQLserver doesn't need as many indexes or RAM upgrades.
This example does require ADO 2.0 or greater which can be downloaded from:
http://www.microsoft.com/data
If you are unsure which ADO version your server has now this code will allow you to identify the version on your server:
http://www.learnasp.com/learn/versioncheck.asp
1 <TITLE>dbtablegetstring.asp</TITLE>
2 <body bgcolor="#FFFFFF">
3 <%
4 whichDSN="DSN=Student;uid=student;pwd=magic"
5 mySQL="select * from publishers where state='NY'"
6
7 ' ASP program that displays a database in table form
8 set conntemp=server.createobject("adodb.connection")
9 conntemp.open whichDSN
10 set rstemp=conntemp.execute(mySQL)
11 If rstemp.eof then
12 response.write "No records matched<br>"
13 response.write mySQL & "<br>So cannot make table..."
14 rstemp.close
15 set rstemp=nothing
16 conntemp.close
17 set conntemp=nothing
18 response.end
19 end if
20 response.write "<table border='1'><tr>"
21
22 'Put Headings On The Table of Field Names
23 for each whatever in rstemp.fields
24 response.write "<td><b>" & whatever.name & "</B></TD>"
25 next
26 response.write "</tr><tr><td>"
27 response.write rstemp.getstring(,, "</td><td>", "</td></tr><TR><TD>", "-null-")
28 response.write "</td></tr></table>"
29
30 rstemp.close
31 set rstemp=nothing
32 conntemp.close
33 set conntemp=nothing
34 %>
35 </body></html>
36
37
38
39
40
41
42
http://www.learnasp.com/learn/dbtablegetstring.asp
rips getrows to shreds speed-wise as the backend transfers one big string instead of a complex array structure but formatting is
SOOOOO limited (unless you know Regexps like the back of your hand....)
Since this code relies heavily on arrays you may want to read up on them at:
● http://www.learnasp.com/learn/arrays.asp
● http://www.learnasp.com/learn/arrays2.asp
● http://www.learnasp.com/learn/arrays3.asp
1 <%@enablesessionstate=false%>
2 <%response.buffer=true%>
3 <html><head>
4 <TITLE>dbtablegetrows.asp</TITLE>
5 </head>
6 <body bgcolor="#FFFFFF">
7 <%
8 ' displays a database in table form via GetRows
9 myDSN="DSN=Student;uid=student;pwd=magic"
10 mySQL="select * from publishers where state='NY'"
11 showblank=" "
12 shownull="-null-"
13
14 set conntemp=server.createobject("adodb.connection")
15 conntemp.open myDSN
16 set rstemp=conntemp.execute(mySQL)
17 If rstemp.eof then
18 response.write "No records matched<br>"
19 response.write mySQL & "<br>So cannot make table..."
20 rstemp.close
21 set rstemp=nothing
22 conntemp.close
23 set conntemp=nothing
24 response.end
25 end if
26
27 response.write "<table border='1'><tr>"
28 'Put Headings On The Table of Field Names
29 for each whatever in rstemp.fields
30 response.write "<td><b>" & whatever.name & "</B></TD>"
31 next
32 response.write "</tr>"
33
34 ' Now lets grab all the records
35 alldata=rstemp.getrows
36 rstemp.close
37 set rstemp=nothing
38 conntemp.close
39 set conntemp=nothing
40
41 numcols=ubound(alldata,1)
42 numrows=ubound(alldata,2)
43 FOR rowcounter= 0 TO numrows
44 FOR colcounter=0 to numcols
45 thisfield=alldata(colcounter,rowcounter)
46 if isnull(thisfield) then
47 thisfield=shownull
48 end if
49 if trim(thisfield)="" then
50 thisfield=showblank
51 end if
52 response.write "<td valign=top>"
53 response.write thisfield
54 response.write "</td>"
55 NEXT
56 response.write "</tr>" & vbcrlf
57 NEXT
58 response.write "</table>"
59 %>
60 </body></html>
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.
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.
Legend:
R/W = Read/Write
R/O = Read-Only
N/A = Not Available or Supported
Yes = Available/Supported
Access allows you to list tables like this (assuming you allow system objects to be visible within the database on
the Access side):
1 <HEAD><TITLE>accesstablelist.asp</TITLE></HEAD>
2 <HTML><body bgcolor="#FFFFFF">
3 <%
4 whichDSN="DRIVER={Microsoft Access Driver (*.mdb)}; "
5 whichDSN=whichDSN & "DBQ=" & server.mappath("/learn/test/biblio.mdb")
6 call query2table("select * from MsysObjects WHERE type = 1",whichDSN)
7 %>
8 <!--#include virtual="/learn/test/lib_dbtable.asp"-->
9 </BODY></HTML>
Here is the contents of lib_fieldtypes.asp which is included to make this example work:
1 <%
2 FUNCTION fieldtypename(parm1)
3 SELECT CASE Parm1
4 CASE 0
5 fieldtypename="adEmpty"
6 CASE 16
7 fieldtypename="adTinyInt"
8 CASE 2
9 fieldtypename="adSmallInt"
10 CASE 3
11 fieldtypename="adInteger"
12 CASE 20
13 fieldtypename="adBigInt"
14 CASE 17
15 fieldtypename="adUnsignedTinyInt"
16 CASE 18
17 fieldtypename="adUnsignedSmallInt"
18 CASE 19
19 fieldtypename="adUnsignedInt"
20 CASE 21
21 fieldtypename="adUnsignedBigInt"
22 CASE 4
23 fieldtypename="adSingle"
24 CASE 5
25 fieldtypename="adDouble"
26 CASE 6
27 fieldtypename="adCurrency"
28 CASE 14
29 fieldtypename="adDecimal"
30 CASE 131
31 fieldtypename="adNumeric"
32 CASE 11
33 fieldtypename="adBoolean"
34 CASE 10
35 fieldtypename="adError"
36 CASE 132
37 fieldtypename="adUserDefined"
38 CASE 12
39 fieldtypename="adVariant"
40 CASE 9
41 fieldtypename="adIDispatch"
42 CASE 13
43 fieldtypename="adIUnknown"
44 CASE 72
45 fieldtypename="adGUID"
46 CASE 7
47 fieldtypename="adDate"
48 CASE 133
49 fieldtypename="adDBDate"
50 CASE 134
51 fieldtypename="adDBTime"
52 CASE 135
53 fieldtypename="adDBTimeStamp"
54 CASE 8
55 fieldtypename="adBSTR"
56 CASE 129
57 fieldtypename="adChar"
58 CASE 200
59 fieldtypename="adVarChar"
60 CASE 201
61 fieldtypename="adLongVarChar"
62 CASE 130
63 fieldtypename="adWChar"
64 CASE 202
65 fieldtypename="adVarWChar"
66 CASE 203
67 fieldtypename="adLongVarWChar"
68 CASE 128
69 fieldtypename="adBinary"
70 CASE 204
71 fieldtypename="adVarBinary"
72 CASE 205
73 fieldtypename="adLongVarBinary"
74 CASE ELSE
75 fieldtypename="Undefined by ADO"
76 END SELECT
77 END FUNCTION
78 %>
● Now try:
Test This -->/learn/test/dbupdate.asp?name=NewPerson&id=9000&year=1964
aspsqlhowto Listserver
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
1 <HEAD><TITLE>SQLwhere2.asp</TITLE></HEAD>
2 <HTML><body bgcolor="#FFFFFF">
3 <%
4 call query2table("select * from titles where Year_Published >= 1994")
5 %>
6 <!--#include virtual="/learn/test/subdbtable.inc"-->
7 </BODY></HTML>
1 <HEAD><TITLE>SQLwhere3.asp</TITLE></HEAD>
2 <HTML><body bgcolor="#FFFFFF">
3 <%
4 call query2table("select * from publishers where fax like '212%%'")
5 %>
6 <!--#include virtual="/learn/test/subdbtable.inc"-->
7 </BODY></HTML>
1 <HEAD><TITLE>sqlwhere4.asp</TITLE></HEAD>
2 <HTML><body bgcolor="#FFFFFF">
3 <%
4 call query2table("select * from publishers where state<> 'NY'")
5 %>
6 <!--#include virtual="/learn/test/subdbtable.inc"-->
7 </BODY></HTML>
1 <HEAD><TITLE>sqlwhereform1respond.asp</TITLE></HEAD>
2 <HTML><body bgcolor="#FFFFFF">
3 <%
4 myDSN="DSN=student;uid=student;pwd=magic"
5
6 mystate=request.querystring("st")
7 SQLtemp="select * from publishers where state='"
8 SQLtemp=SQLtemp & mystate & "'"
9
10 call query2table(SQLtemp,myDSN)
11 %>
12 <!--#include virtual="/learn/test/lib_dbtable.asp"-->
13 </BODY></HTML>
1 <html><head><TITLE>sqlwhereform3respond.asp</TITLE></head>
2 <body bgcolor="#FFFFFF">
3 <%
4 myDSN="DSN=student;uid=student;pwd=magic"
5 mycity=request.querystring("cy")
6 myexactsearch=request.querystring("exactsearch")
7 SQLtemp="select * from publishers where city"
8 If myexactsearch="on" then
9 SQLtemp=SQLtemp & " ='"
10 Else
11 SQLtemp=SQLtemp & " LIKE '"
12 End If
13 SQLtemp=SQLtemp & mycity & "'"
14 'response.write SQLtemp
15 call query2table(SQLtemp,myDSN)
16 %>
17 <!--#include virtual="/learn/test/lib_dbtable.asp"-->
18 </body></html>
If your goal is that several if conditions must ALL BE TRUE to suceed, this is the Role of the AND within a WHERE clause, i.e.
"select * from publishers where state='MD' and city='Rockville'
"select * from authors where Year_Born>1960 and Year_Born<1970'
If several conditions can indivually be true this is the Role of an OR within a WHERE clause, i.e.
"select * from publishers where state='MD' OR state='NY'
1 <HEAD><TITLE>SQLcities.asp</TITLE></HEAD>
2 <HTML><body bgcolor="#FFFFFF">
3 <Form action = "SQLcitiesrespond.asp" method="POST">
4 Choose City (or Cities):<p>
5 <%
6 call query2listm("select distinct city from publishers", _
7 "cy","DSN=student;uid=student;pwd=magic")
8 %>
9 <P>
10 <Input type="submit" value="Get Data"> <Input type="reset" value="Clear City"></form>
11 </BODY></HTML>
12 <!--#include virtual="/learn/test/lib_dblistm.asp"-->
13
1 <HEAD><TITLE>SQLcount3.asp</TITLE></HEAD>
2 <HTML><body bgcolor="#FFFFFF">
3 <%
4 call query2table("select count(city) as howmany,city from publishers group by city")
5 %>
6 <!--#include virtual="/learn/test/subdbtable.inc"-->
7 </BODY></HTML>
1 <HEAD><TITLE>SQLcount4.asp</TITLE></HEAD>
2 <HTML><body bgcolor="#FFFFFF">
3 <%
4 call query2table("select count(*),city,state from publishers group by city,state")
5 %>
6 <!--#include virtual="/learn/test/subdbtable.inc"-->
7 </BODY></HTML>
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.
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.
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
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:
$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
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
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.
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
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
IIS NT Challenge Response
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
● you can require the use of a compatible browser (Internet Explorer is the only browser which supports NTCR).
Definitions
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.
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
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
● 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.
Definitions
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.
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 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
● 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).
● 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 the login screen where someone can enter username/password and confirm
securityloginrespond.asp security level. It is a form that submits to securityloginrespond.asp
securitylogout.asp the screen to abandon someone's username/password and security level
securitylevel1required.asp which can be included on individual pages to limit access to people with that
securitylevel2required.asp security level, i.e/:
securitylevel3required.asp <!--#include file="securitylevel1required.asp"-->
securitytestlevel1.asp
which demonstrate how security is implemented. These scripts cannot be
securitytestlevel2.asp
seen unless you login.
securitytestlevel3.asp
which anyone attempting to access a page without appropriate security level
securitynotallowed.asp
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
Download Database user=chaz3, password=chaz3, securitylevel=3
In a production application, this database would be located OUTSIDE
of the web structure (and accessed by DSN) so it could never be
downloaded by a user.
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
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.
The user can enter a state or multiple states. We write the program utilizing SPLIT to demonstrate how this can be used.
statesplit.asp
1 <html><head>
2 <title>states.asp</title>
3 </head><body bgcolor="#FFFFFF">
4 <form action="statesplitrespond.asp" method="post">
5 Enter State (or many states separated by <b>,<b><p>
6 <input NAME="states" size="40"><p>
7 <input type="submit" value="Get The Publishers!">
8 </form>
9 </body></html>
statesplitrespond.asp
1 <!--#include virtual="/learn/test/lib_dbtable.asp"-->
2 <html><head>
3 <title>statesrespond.asp</title>&
4 <body>
5 <%
6 mySQL="select * from publishers " & whereclause
7 myDSN="DSN=student;uid=student;pwd=magic"
8 public allstates
9 tempinput=request("states")
10 allstates=split(tempinput,",")
11
12 maxcounter=ubound(allstates)
13
14 whereclause=" where state='" & allstates(0) & "'"
15 FOR counter=1 TO maxcounter
16 thisstate=allstates(counter)
17 whereclause=whereclause & " OR state='" & thisstate & "'"
18 NEXT
19 mySQL=mySQL & whereclause
20 Call Query2Table(mySQL,myDSN)
21 %>
22 </body></html>
The user can enter a state or multiple states. We write the program utilizing REPLACE to demonstrate how this function can
be used.
statereplace.asp
1 <html><head>
2 <title>statereplace.asp</title>
3 </head><body bgcolor="#FFFFFF">
4 <form action="statereplacerespond.asp" method="post">
5 Enter State (or many states separated by <b>,<b><p>
6 <input NAME="states" size="40"><p>
7 <input type="submit" value="Get The Publishers!">
8 </form>
9 </body></html>
statereplacerespond.asp
1 <!--#include virtual="/learn/test/lib_dbtable.asp"-->
2 <html><head>
3 <title>statesrespond.asp</title>&
4 <body>
5 <%
6 mySQL="select * from publishers " & whereclause
7 myDSN="DSN=student;uid=student;pwd=magic"
8
9 tempinput=request("states")
10
11 whereclause=" where state='" & tempinput
12 whereclause=replace(whereclause, ",","' OR state='")
13 whereclause=whereclause & "'"
14
15 mySQL=mySQL & whereclause
16 response.write mySQL
17 Call Query2Table(mySQL,myDSN)
18 %>
19 </body></html>
The user can enter a state or multiple states. We write the program using the JOIN function to demonstrate how this function
can be used.
statejoin.asp
1 <html><head>
2 <title>statejoin.asp</title>
3 </head><body bgcolor="#FFFFFF">
4 <form action="statejoinrespond.asp" method="post">
5 Enter State (or many states separated by <b>,<b><p>
6 <input NAME="states" size="40"><p>
7 <input type="submit" value="Get The Publishers!">
8 </form>
9 </body></html>
statejoinrespond.asp
1 <!--#include virtual="/learn/test/lib_dbtable.asp"-->
2 <html><head>
3 <title>statejoinrespond.asp</title>&
4 <body>
5 <%
6 mySQL="select * from publishers "
7 myDSN="DSN=student;uid=student;pwd=magic"
8 public allstates
9 tempinput=request("states")
10 allstates=split(tempinput,",")
11
12 whereclause=" where state='" & JOIN(allstates, "' OR state='") & "'"
13
14 mySQL=mySQL & whereclause
15 response.write mySQL
16 Call Query2Table(mySQL,myDSN)
17 %>
18 </body></html>
http://www.activeserverpages.com/learn/subdates.asp
has a good example of arrays in a practical context.
Assigning an array size with a variable produces an error unless the Redim command is used.
1 <html><head>
2 <title>arraysredimcorrect.asp</title>
3 </head><body bgcolor="#FFFFFF">
4 <%
5 dim my_array()
6 x=100
7 redim preserve my_array(x)
8 my_array(20)="Hi!"
9 my_array(40)="How are You"
10
11 lowcount=lbound(my_array)
12 highcount=ubound(my_array)
13 response.write "lowcount=" & lowcount & ";highcount=" & highcount & "<p>"
14 for counter=lowcount to highcount
15 response.write counter & " "
16 response.write my_array(counter) & "<br>"
17 next
18
19 %>
20 </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.
1 <HEAD><TITLE>subdbtable2.asp</TITLE></HEAD>
2 <HTML><body bgcolor="#FFFFFF">
3 <%
4 myDSN="DSN=student;uid=student;pwd=magic"
5 mySQL="select * from titles"
6 call query2table(mySQL,myDSN)
7 %>
8 <!--#include virtual="/learn/test/lib_dbtable.asp"-->
9 </BODY></HTML>
1 <HEAD><TITLE>subdbtable3.asp</TITLE></HEAD>
2 <HTML><body bgcolor="#FFFFFF">
3 <%
4 myDSN="DSN=student;uid=student;pwd=magic"
5 mySQL="select * from authors"
6 call query2table(mySQL,myDSN)
7 %>
8 <!--#include virtual="/learn/test/lib_dbtable.asp"-->
9 </BODY></HTML>
1 <HEAD><TITLE>subdbtable4.asp</TITLE></HEAD>
2 <HTML><body bgcolor="#FFFFFF">
3 <%
4 myDSN="DSN=student;uid=student;pwd=magic"
5 mySQL= "SELECT Publishers.Name, Titles.Title "
6 mySQL= mySQL & "FROM Publishers "
7 mySQL= mySQL & "INNER JOIN Titles ON Publishers.PubID = Titles.PubID "
8 mySQL= mySQL & "order by Name"
9
10 call query2table(mySQL,myDSN)
11 %>
12 <!--#include virtual="/learn/test/lib_dbtable.asp"-->
13 </BODY></HTML>
1 <HEAD><TITLE>subdbtable5.asp</TITLE></HEAD>
2 <HTML><body bgcolor="#FFFFFF">
3 <%
4 myDSN="DSN=student;uid=student;pwd=magic"
5 mySQL="select * from title_author"
6 call query2table(mySQL, myDSN)
7 %>
8 <!--#include virtual="/learn/test/lib_dbtable.asp"-->
9 </BODY></HTML>
1 <HEAD><TITLE>subdbtable6.asp</TITLE></HEAD>
2 <HTML><body bgcolor="#FFFFFF">
3 <%
4 myDSN="DSN=student;uid=student;pwd=magic"
5 mySQL="select name,type from sysobjects"
6 call query2table(mySQL,myDSN)
7 %>
8 <!--#include virtual="/learn/test/lib_dbtable.asp"-->
9 </BODY></HTML>
1 <HEAD><TITLE>subreusabledatalist.asp</TITLE></HEAD>
2 <HTML><body bgcolor="#FFFFFF">
3 <!--#include virtual="/learn/test/lib_subflexible.asp"-->
4 <%
5 call query2list("select distinct state from publishers","thestate")
6 call query2list("select distinct city from publishers","thecity")
7 call query2list("select distinct zip from publishers","thezip")
8 %>
9 </BODY></HTML>
10
1 <HEAD><TITLE>subreusabledatatable.asp</TITLE></HEAD>
2 <HTML><body bgcolor="#FFFFFF">
3 <!--#include virtual="/learn/test/subflexible.asp"-->
4 <%
5 call query2table("select * from publishers")
6 %>
7 </BODY></HTML>
1 <HEAD><TITLE>subreusableform.asp</TITLE></HEAD>
2 <HTML><body bgcolor="#FFFFFF">
3 <!--#include virtual="/learn/test/subflexible.asp"-->
4 <%
5 call query2form("select * from publishers")
6 %>
7 </BODY></HTML>
Eval function
1 <html><head>
2 <title>vbs5eval.asp</title>
3 </head>
4 <body>
5 <%
6 x="2+2*3"
7 response.write eval(x)
8 %>
9 </body>
10 </html>
Classes:
1 <html><head>
2 <title>vb5classes.asp</title>
3 </head>
4 <body>
5 <%
6 ' Create a myCustomer variable
7 Dim myCustomer
8 ' Create a new instance of the Customer Class
9 ' and set the value of myCustomer to be that instance
10 set myCustomer = new Customer
11 ' Add a new customer
12 myCustomer.Add "Charles","Carroll"
13 ' Set their Email address
14 myCustomer.EmailName = "charlescarroll@aspalliance.com"
15 ' Set their credit limit
16 myCustomer.CreditLimit = 5000
17 ' Display the customers fullname
18 response.write myCustomer.FullName
19
20 Class Customer
21 Public FirstName, LastName
22 Private nCreditLimit
23 Private strEmailName
24 Property Get EmailName
25 EmailName = strEmailName
26 End Property
27 Property Let EmailName ( strName)
28 StrEmailName = strName
29 End Property
30 Property Get FullName
31 FullName= FirstName & " " & LastName
32 End Property
33 Property Let CreditLimit ( s )
34 if s >= 0 then
35 nSalary = s
36 End If
37 End Property
38 Property Get CreditLimit
39 Salary = nSalary
40 End Property
41 Sub Add( First, Last )
42 FirstName = First
43 LastName = Last
44 End Sub
45 Function RaiseCreditLimit( Amount )
46 nCreditLimit = nCreditLimit + Amount
47 RaiseSalary = nSalary
48 End Function
49 End Class
50 %>
51 </body>
52 </html>
Execute Function:
1 <html><head>
2 <title>vbs5execute.asp</title>
3 </head>
4 <body>
5 <%
6 S = "Sub Hi" & vbCrLf
7 S = S & " Response.write ""Hi""" & vbCrLf
8 S = S & "End Sub"
9 Execute S
10 Call Hi()
11 %>
12 </body>
13 </html>
Regular Expressions
1 <html><head>
2 <title>vbs5reg.asp</title>&
3 <body>
4 <%
5
6 address="joe@aol.com"
7 validmail=checkemail(address)
8 IF validmail THEN
9 response.write address & " is good!"
10 ELSE
11 response.write address & " is bad!"
12 END IF
13
14 address="sallyaol.com"
15 validmail=checkemail(address)
16 IF validmail THEN
17 response.write address & " is good!"
18 ELSE
19 response.write address & " is bad!"
20 END IF
21
22
23 FUNCTION CheckEmail(parmaddress)
24 set myRegExp = new RegExp
25 ' Set the pattern to check for a word followed by
26 ' an @ followed by a word
27 myRegExp.pattern = "\w+\@[.\w]+"
28 if myRegExp.Test(parmaddress) then
29 CheckEmail=True
30 else
31 CheckEmail=false
32 end if
33 END FUNCTION
34 %>
35 </body>
36 </html>
With
1 <html><head>
2 <title>vbs5with.asp</title>
3 </head>
4 <body>
5 <%
6 with response
7 .write "Hi<br>"
8 .write "how are you doing?<br>"
9 .write "see you around"
10 end with
11 %>
12 </body>
13 </html>
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.
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.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.
Application values are visible to every user. But since, unlike session data, any web page could change the application's data there
is a potential concurrency issue. The lock and unlock method of the application object eliminate concurrency issues. Once an
application is locked, no other updates to the application object can occur until the unlock is executed.
One use for an application variable would be to store variables most scripts on a site needed to access or even HTML cached from
databases like in
The Worlds Fastest Listbox Example @
http://www.learnasp.com/learn/speedappdata.asp
One example I use to illustrate the conceptual use for each type of data would be a website that simulated a casino. Player's
individual winnings make perfect sense to maintain in session variables. However, the total number of players at each "virtual table"
(blackjack, roulette, etc.) would be application data as the would be the same regardless of an individual player's status.
Here is a file called appblackjackarrive.asp that could be included in any script where someone arrived at the blackjack table!
1 <%
2 response.write "Welcome to the BlackJack Table<br>"
3 application.lock
4 application("bjplayers")=application("bjplayers")+1
5 application.unlock
6 response.write "There are " & application("bjplayers") & " players here!<br>"
7 %>
Here is a file called appblackjacklook.asp that displays how many people are at the table.
1 <%
2 response.write "Over at the BlackJack Table<br>"
3 response.write "There are " & application("bjplayers") & " players there!<br>"
4 %>
Here is a file called appblackjackleave.asp that could be included in any script where someone left the blackjack table!
1 <%
2 response.write "Thanks for playing BlackJack!<br>"
3 application.lock
4 application("bjplayers")=application("bjplayers")-1
5 IF application("bjplayers")<0 THEN
6 application("bjplayers")=0
7 END IF
8 application.unlock
9 response.write "There are " & application("bjplayers") & " players still at the table!<br>"
10 %>
The listbox could be placed in an application variable, ala a "generator" script we will call listmake.asp.
1 <HTML>
2 <TITLE>listmake.asp</TITLE>
3 <body bgcolor="#FFFFFF">
4 </BODY>
5 <%
6 myDSN="DSN=student;uid=student;pwd=magic"
7
8 mySQL="select distinct city from publishers"
9 application("citylist")=query2htmlist(mySQL,"cities",myDSN)
10
11 mySQL="select distinct state from publishers"
12 application("statelist")=query2htmlist(mySQL,"state",myDSN)
13
14 mySQL="select distinct zip from publishers"
15 application("ziplist")=query2htmlist(mySQL,"zip",myDSN)
16 %>
17 </HTML>
18
19 <%function query2htmList(myquery,myname,myDSN)
20 dim conntemp, rstemp
21 set conntemp=server.createobject("adodb.connection")
22 conntemp.open myDSN
23 set rstemp=conntemp.execute(myquery)
24 query2HTMlist="<Select name='" & myname & "'>"
25 do until rstemp.eof
26 thisfield=trim(RStemp(0))
27 if isnull(thisfield) or thisfield="" then
28 ' ignore
29 else
30 query2HTMlist=query2HTMlist & "<option>" & thisfield & "</option>"
31 end if
32 rstemp.movenext
33 loop
34 query2HTMlist=query2HTMlist & "</select>"
35 rstemp.close
36 set rstemp=nothing
37 conntemp.close
38 set conntemp=nothing
39 end function%>
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]
%>
● 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.
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 #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.
If the task could be accomplished with hidden fields instead of session variables, then those limitations are not in effect -- and most
tasks can.
session_onstart
session("dbname")="DSN=employees;"
session("dbuser")="whoever"
session("dbpass")="majic"
end sub
and the script that goes with it looks like this:
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:
<%
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 ....
Everything you wanted to know about global.asa but were afraid to ask @
http://www.4guysfromrolla.com/webtech/113098-1.shtml
http://www.aspalliance.com/stevesmith/samples/sitestats.asp
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
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:
Backstage at Microsoft.com
http://www.microsoft.com/backstage/whitepaper.htm
Much ASP coding tips and advice related to scalability can be found at:
http://www.learnasp.com/advice
fastcode Listserver
Related Links
Niblacks Excellent ListBox/DB Speed Page @
http://niblack.com/kbase/listbox_x.asp
Timing Tasks to Millisecond accuracy @
http://www.learnasp.com/learn/speedtimer.asp
Web Application Stress Tool @
http://homer.rte.microsoft.com
Caprocks FREE Scalable Dictionary Object Replacement @
http://www.caprockconsulting.com/comsoftware.htm
Study up on Performance Counters @
http://msdn.microsoft.com/workshop/server/iis/usingWCAT.asp
monitor PerfCounters from ASP via a nifty component @
http://www.alphasierrapapa.com/IisDev/Components/
Speed Percieved Table Display @
http://www.learnasp.com/learn/speedtables.asp
Speeding Table Display - All Techniques @
http://www.learnasp.com/learn/speedtablesall.asp
Worlds Fastest ListBox @
http://www.learnasp.com/learn/speedappdata.asp
Charles Carroll's ASP Quick Lessons @
http://www.learnasp.com/learn/speedscale.asp
http://www.learnASP.com/learn/speedtimer.asp by Charles M. Carroll
Page 180
Speed: Measuring Code Speed
by Richard A. Lowe drahcir@home.com
with help from Jonathan McGuire jmcguire@solutionsatimpact.com
Gregory Lybanon glybanon@sbcsystems.com
Charles Carroll charlescarroll@learnasp.com
Measuring speed to the millisecond was considered impossible with ASP. People built COM components that wrapped up API calls!
So we called a COM component that called an API and then we distorted the measurement with overhead. Scripting has a few tricks
up its sleeves yet as Richard demonstrates with the nifty Library implemented in Jscript. We will use it to time retrieving and
displaying identical data three different ways:
● traditional loop and movenext
● 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.
1 <html><head>
2 <TITLE>timedbtable.asp</TITLE>
3 </head>
4 <body bgcolor="#FFFFFF">
5 <!--#include file="lib_timethis.asp"-->
6 <%
7 Set HttpObj = Server.CreateObject("AspHTTP.Conn")
8 HttpObj.Url = "http://www.learnasp.com/learn/test/dbtable.asp"
9 timeThen = milliDif()
10 strResult = HttpObj.GetURL
11 timeNow = milliDif()
12 SET HTTPobj = nothing
13 elapsed=timeNow-timeThen
14 msg="<br>Process time in ms: " & elapsed & "<br>" & elapsedpretty(elapsed)
15 bodytag="<body bgcolor=""#FFFFFF"">"
16 STRresult=replace(STRResult,bodytag,bodytag & msg)
17
18 response.write STRresult
19
20 %>
21 </body></html>
Here we retrieve data by fetching all the data into an array in one "gulp" (/learn/dbtablegetrows.asp):
1 <html><head>
2 <TITLE>timedbtablegetrows.asp</TITLE>
3 </head>
4 <body bgcolor="#FFFFFF">
5 <!--#include file="lib_timethis.asp"-->
6 <%
7 Set HttpObj = Server.CreateObject("AspHTTP.Conn")
8 HttpObj.Url = "http://www.learnasp.com/learn/test/dbtablegetrows.asp"
9 timeThen = milliDif()
10 strResult = HttpObj.GetURL
11 timeNow = milliDif()
12 SET HTTPobj = nothing
13 elapsed=timeNow-timeThen
14 msg="<br>Process time in ms: " & elapsed & "<br>" & elapsedpretty(elapsed)
15 bodytag="<body bgcolor=""#FFFFFF"">"
16 STRresult=replace(STRResult,bodytag,bodytag & msg)
17
18 response.write STRresult
19
20 %>
21 </body></html>
Here we retrieve data by asking the backend to combine the data into a custom string and not even bring fields and rows, just
produce 1 string (/learn/dbtablegetstring.asp):
1 <html><head>
2 <TITLE>timedbtablegetstring.asp</TITLE>
3 </head>
4 <body bgcolor="#FFFFFF">
5 <!--#include file="lib_timethis.asp"-->
6 <%
7 Set HttpObj = Server.CreateObject("AspHTTP.Conn")
8 HttpObj.Url = "http://www.learnasp.com/learn/test/dbtablegetstring.asp"
9 timeThen = milliDif()
10 strResult = HttpObj.GetURL
11 timeNow = milliDif()
12 SET HTTPobj = nothing
13 elapsed=timeNow-timeThen
14 msg="<br>Process time in ms: " & elapsed & "<br>" & elapsedpretty(elapsed)
15 bodytag="<body bgcolor=""#FFFFFF"">"
16 STRresult=replace(STRResult,bodytag,bodytag & msg)
17
18 response.write STRresult
19
20 %>
21 </body></html>
#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.
#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.
#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.
Side note: If anyone you know believes Access queries are done asynchronously, running a couple of these scripts will prove them
wrong. Access queries execute one web user at a time sequentially.
After Optimization
Here is a very fast table display going against an identical huge SQL Server Table:
1 <%response.buffer=true%>
2 <HEAD><TITLE>dbtablefast.asp</TITLE></HEAD>
3 <HTML><body bgcolor="#FFFFFF">
4 <%
5 myDSN = "DSN=student;UID=student;pwd=magic"
6
7 mySQL="select * from authors order by author"
8 call query2table(mySQL,myDSN)
9 %>
10 <!--#include virtual="/learn/test/lib_dbtablefast.asp"-->
11 </BODY></HTML>
12
13
Before Optimization
Here is the original slow script which basically demonstrates techniques that may work if your data and concurrency load is light, but
the script above demonstrates the typical changes made to speed up a script when it becomes needed or you just want to wring
every ounce of speed from your site. This script will probably timeout before it's completion!
1 <HEAD><TITLE>dbtableslow.asp</TITLE></HEAD>
2 <HTML><body bgcolor="#FFFFFF">
3 <%
4 myDSN = "DSN=student;uid=student;pwd=magic"
5
6 mySQL= "SELECT * from authors order by Author"
7 call query2table(mySQL,myDSN)
8 %>
9 <!--#include virtual="/learn/test/lib_dbtableslow.asp"-->
10 </BODY></HTML>
Method: GetRows command with no LOOP + movenext but loop through the array with periodic response flushes.
Method: GetRows command of a fixed row count (say 500 record clusters for example) with a reponse.flush after each
array is read!
Method: Displaying a portion of the data (say the first 500 records) only.
Now here is the code that was used to gather all the data.
Here is a table display with a simple LOOP:
1 <%response.buffer=true%>
2 <HEAD><TITLE>dbtableLoopAll.asp</TITLE></HEAD>
3 <HTML><body bgcolor="#FFFFFF">
4 <!--#include virtual="/adovbs.inc"-->
5 <!--#include virtual="/learn/test/lib_dbtablefastv2.asp"-->
6 <%
7 server.scripttimeout=240
8 optimize=optimize_LoopAll
9
10 myDSN = "DSN=student;UID=student;pwd=magic"
11 'mySQL="select * from authors order by author "
12 mySQL="select * from authors order by author "
13
14 Call TimerStart
15 call query2table(mySQL,myDSN,optimize,howmany)
16 Call TimerEnd
17 %>
18 </BODY></HTML>
This loop could tie up the CPU for quite a while, even though the user hit the "stop" button the task would still be
"spinning/executing" on the server even though the user was long gone. This is particularly true in database
tasks.
1 <%server.scripttimeout=20
2 ' this times out the script in 20 seconds whether done or
3 ' the user hit the STOP button
4 %>
5 <TITLE>infiniteloopfixed.asp</TITLE>
6 <body bgcolor="#FFFFFF">
7 <%
8 DO
9 x=x+1
10 response.write x & "<br>"
11 If x=10000 then
12 x=1
13 end if
14 LOOP WHILE response.isclientconnected()
15 %>
16 </body></html>
this code will stop when user hits the stop button.
I recommend that all loops through database recordsets incorporate this so that they don't execute invisibly
wasting CPU and database server resources. So here is a database table listing script that incorporates this
functionality:
1 <TITLE>dbtableisclientconnected.asp</TITLE>
2 <body bgcolor="#FFFFFF">
3 <%
4 ' ASP program that displays a database in table form
5 myDSN="DSN=Student;uid=student;pwd=magic"
6 mySQL="select * from publishers"
7
8 set conntemp=server.createobject("adodb.connection")
9 conntemp.open myDSN
10 set rstemp=conntemp.execute(mySQL)
11 howmanyfields=rstemp.fields.count -1
12 %>
13 <table border=1><tr>
14 <% 'Put Headings On The Table of Field Names
15 for i=0 to howmanyfields %>
16 <td><b><%=rstemp(i).name %></B></TD>
17 <% next %>
18 </tr>
19 <% ' Now lets grab all the records
20 do until (rstemp.eof or response.isclientconnected=false)%>
21 <tr>
22 <% for i = 0 to howmanyfields%>
23 <td valign=top><%=rstemp(i)%></td>
24 <% next %>
25 </tr>
26 <%rstemp.movenext
27 loop
28 %>
29 </table>
30
31 <%
32 rstemp.close
33 set rstemp=nothing
34 conntemp.close
35 set conntemp=nothing
36 %>
37 </body></html>
Scenario #1:
set x=server.createobject("whatever.whatever")
....
set x=nothing
Scenario #2
set x=server.createobject("whatever.whatever")
....
● exactly the line of code where the object is removed from memory
● 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.
and 1,000 users do this simultaneously. It is not quite simultaneous, let us say that what happens when eight users access a script
and create, close and destroy eight connections.
User Open conn. time Process Start time Close time
#1 1:00am .001 1:00am .002 1:00am .012
#2 1:00am .002 1:00am .003 1:00am .013
#3 1:00am .003 1:00am .004 1:00am .009
#4 1:00am .003 1:00am .004 1:00am .015
#5 1:00am .007 1:00am .008 1:00am .014
#6 1:00am .009 1:00am .010 1:00am .021
#7 1:00am .016 1:00am .017 1:00am .028
#8 1:00am .017 1:00am .018 1:00am .026
Time - open conns Open conns Pool to be reused Being Re-used
1:00am .001 - 1 #1 0
1:00am .002 - 2 #1, #2 0
1:00am .010 - 4 #1, #2, #4, #5, #6 #3
1:00am .013 - 4 #2, #4, #5, #6 #1 #6 using #3
1:00am .014 - 3 #4, #5, #6 #1, #2
1:00am .016 - 2 #6, #7 #2, #4 #7 using #1
1:00am .022 - #7, #8 #1, #3, #4, #5 #8 using #2
1:00am .027 - #7 #1, #3, #4, #5
1:00am .029 - #1, #3, #4, #5 waiting
Because of connection pooling they will use MUCH less than 1,000 brand new connections as conn.open statements will be
provided with already existing connections invisibly PROVIDING they were closed and thus guaranteed available for re-use.
The pool connections can only be re-used if they are closed. They expire in sixty seconds by default. This is all explained in:
http://msdn.microsoft.com/library/techart/pooling2.htm
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.
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.
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.
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.
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
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/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.
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.
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
People having trouble with ASP can sign up for the [ecommerce] listserv:
ecommerce Listserver
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
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
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
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
http://www.atgconsulting.com/doublelist.asp
http://www.atgconsulting.com/triplelist.asp
http://webreference.com/dev/menus/
http://www.amerirus.com/tutor.html
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 %>
It is a language preferred by a small percentage of ASP programmers, but most use VBScript as it is easier.
If you have using Perlscript to program your ASP sites, we run a listserv/newgroup called [Perlscript] where that is the only topic
allowed you can join to get help.
aspperlscript Listserver
JOIN, QUIT or Search ARCHIVES:
http://www.asplists.com/asplists/perlscript.asp
Send Listserver Questions to
aspperlscript@ls.asplists.com
Related Links
ActiveState - Perl Suppliers @
http://www.activestate.com
Tobias Martinsson's Site @
http://www.perlscripters.com
Matt's Perl Pages @
http://www.fastnetltd.ndirect.co.uk/Perl/
Roth Consulting @
http://www.roth.net/
O'Reilly's Perl Conference @
http://conference.oreilly.com/perl3/
Perl Reference Sites & Newsgroups @
http://www.activestate.com/reference/related_sites.htm
● dynamic page construction via Javascript that could be for example fetching database data for a page without reloading the
page.
● It doesn't work on IE Mac (thanks to "Brad Rhoads" <brad@data-science.com> 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).
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
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.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
http://www.15seconds.com/focus/ADSI.htm
has everything about ADSI you would want to know and is running a well managed, low-noise list-serve devoted to ADSI.
http://www.netfokus.dk/vbadmincode/
is a great source for FREE Visual Basic code to manage NT servers that easily adapts to ASP or can be used in a VB/ASP
Component.
ADSI listserv by 15seconds.com
to: -> LISTSERV@LISTSERV.15SECONDS.COM
body (not subject) -> SUBSCRIBE ADSI Your Name
http://www.jfkdesigns.com/default.asp?go=ADSI
has some FREE ADSI scripts
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
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.
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
● 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.
1 <html><head>
2 <title>websafe.asp</title>&
3 <body>
4 <%
5 spacer=" "
6 response.write "<strong><font size='2'><table border=1>"
7 for counter=1 to 6
8 safecolor1=websafe(counter)
9 for counter2=1 to 6
10 safecolor2=websafe(counter2)
11 for counter3= 1 to 6
12 safecolor3=websafe(counter3)
13 hexcolor=convertToHex(safecolor1,safecolor2,safecolor3)
14 response.write "<tr><td>" & hexcolor & "</td>"
15 response.write "<td bgcolor='" & hexcolor & "'>"
16 response.write "Black Text</td>"
17 response.write "<td bgcolor='" & hexcolor & "'>" & spacer & "</td>"
18 response.write "<td bgcolor='" & hexcolor & "'><font color='white'>"
19 response.write "White Text</td>"
20 response.write "<td bgcolor='" & white & "'><font color='" & hexcolor & "'>"
21 response.write "Colored Text</font></td></tr>"
22 next
23 next
24 next
25 response.write "</strong></font></table>"
26 %>
27 </body></html>
28 <%
29 function websafe(mynumber)
30 SELECT CASE mynumber
31 CASE 1
32 websafe=0
33 CASE 2
34 websafe=51
35 CASE 3
36 websafe=102
37 CASE 4
38 websafe=153
39 CASE 5
40 websafe=204
41 CASE 6
42 websafe=255
43 END SELECT
44 end function
45 %>
46
47 <script language=jscript runat=server>
48 function convertToHex(R, G, B) {
49
50 var n = B;
51 n += G << 8;
52 n += R << 16;
53 return convertBase(n);
54 }
55
56 // turns decimal integer into hexadecimal string
57 function convertBase(num) {
58 var i = 0; var j = 20;
59 var str = "#";
60
61 while(j >= 0) {
62 i = (num >> j)%16;
63 if(i >= 10) {
64 if(i == 10) str += "A";
65 else if(i == 11) str += "B";
66 else if(i == 12) str += "C";
67 else if(i == 13) str += "D";
68 else if(i == 14) str += "E";
69 else str += "F";
70 } else
71 str += i;
72 j -= 4;
73 }
74
75 return str;
76 }
77 </script>
BUY IT http://bn.bfast.com/booklink/click?sourceid=10446528&ISBN=1565924460
http://www.oreilly.com/catalog/devaspcom/
INFO ONLINE
http://www.yasd.com
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
Shopping Cart @
http://www.asp101.com/samples/shopping.asp
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
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
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.
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
%>
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
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
%>
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
%>
+ 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: Scenario 2: objects created/destroyed on a page per
object in session_onstart page basis
End Result: End Result:
450 sessions/objects in memory 50 objects in memory
with 50 people on your site. And dozens or hundred of with 50 people on your site. No unused threads must
threads that can't be reclaimed for a while 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.
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.
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
Related Links
Security Issues from www.learnasp.com @
http://www.learnasp.com/security
The library files/includes that make all these tasks one step are detailed at:
/learn/qualitycode.asp
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.
The script named cljumprespond.asp that implements the jump looks like this:
1 <%
2 response.redirect request.querystring("whichtopic")
3 %>
This ingenious piece of code demonstrates how to read a file using the file system object and extract bytes that contain the height
and width.
1 <!--#include virtual="/learn/test/lib_graphicdetect.asp"-->
2 <html><head>
3 <TITLE>dbtable.asp</TITLE>
4 </head>
5 <body bgcolor="#FFFFFF">
6 <%
7 graphic="images/learnaspiconmain.gif"
8 HW = ReadImg(graphic)
9 Response.Write graphic & " Dimensions: " & HW(0) & "x" & HW(1) & "<br>"
10 response.write "<img src=""/" & graphic & """"
11 response.write height=""" & HW(0) & """
12 response.write width=""" & HW(0) & "">"
13 %>
14 </body></html>
15
● 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".
If you are updating a component (i.e. registering a component that replaces another component) instead:
● 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".
● start and stop web service to purge old component from memory
This example will not compile unless you go to the "Project; References" menu and check/turn on the following libraries:
● Microsoft "Active Data Objects" object library
● Microsoft "Active Server Pages" object library
14 ' projectname =charlescarroll
15 ' classname =dbhelperver001
16 Private ASPresponse As Response
17 Private ASPserver As Server
18 Private htmlstart, htmlend, rowstart, rowend
19 Private fieldstart, fieldend, namestart, nameend
20 Public Sub onstartpage(sc As ScriptingContext)
21 Set ASPresponse = sc.Response()
22 Set ASPserver = sc.Server()
23 End Sub
24 Public Property Let connect(temp As Variant)
25 myconnect = temp
26 End Property
27 Public Property Get connect() As Variant
28 connectme = myconnect
29 End Property
30 Public Property Get fieldnames() As Variant
31 fieldnames = myfieldnames
32 End Property
33
34 Public Property Let fieldnames(temp As Variant)
35 myfieldnames = temp
36 End Property
37
38 Public Property Let query(temp As Variant)
39 myquery = temp
40 End Property
41 Public Property Get query() As Variant
42 query = myquery
43 End Property
44
45 Public Property Let selectdefault(temp As Variant)
46 myselectdefault = temp
47 End Property
48 Public Property Get selectdefault() As Variant
49 selectdefault = myselectdefault
50 End Property
51 Public Property Let selectname(temp As Variant)
52 myselectname = temp
53 End Property
54 Public Property Get selectname() As Variant
55 selectname = myselectname
56 End Property
57
58 Public Sub query2list()
59 htmlstart = "<select name='" & selectname & "'>"
60 htmlend = "</select>"
61 rowstart = "<option>"
62 rowend = "</option>"
63 fieldstart = ""
64 fieldend = ""
65 Call query2html
66 End Sub
67
68 Public Sub query2table()
69 htmlstart = "<table border=1>"
70 htmlend = "</table>"
71 rowstart = "<tr>"
72 rowend = "</tr>"
73 fieldstart = "<td valign=top>"
74 fieldend = "</td>"
75 Call query2html
76 End Sub
77
78 Public Sub query2form()
79 htmlstart = ""
80 htmlend = ""
81 rowstart = ""
82 rowend = "<hr>"
83 fieldstart = ""
84 fieldend = "<br>"
85 fieldnames = True
86 namestart = ""
87 nameend = " = "
88 Call query2html
89 End Sub
90
91 Public Sub query2entryform()
92 htmlstart = ""
93 htmlend = ""
94 rowstart = ""
95 rowend = ""
96 fieldstart = "%name% = <input type='text name='%name%' value='"
97 fieldend = "' size='%size%'><br>"
98 fieldnames = False
99 namestart = ""
100 nameend = " ="
101 Call query2html
102 End Sub
103
104 Public Sub CustomDisplay(PARMhtmlstart, PARMhtmlend, PARMrowstart, PARMrowend, _
105 PARMfieldstart, PARMfieldend, PARMfieldnames, _
106 PARMnamestart, PARMnameend)
107 htmlstart = PARMhtmlstart
108 htmlend = PARMhtmlend
109 rowstart = PARMrowstart
110 rowend = PARMrowend
111 fieldstart = PARMfieldstart
112 fieldend = PARMfieldend
113 fieldnames = PARMfieldnames
114 namestart = PARMnamestart
115 nameend = PARMnameend
116 Call query2html
117 End Sub
118
119
120 Private Sub query2html()
121 On Error GoTo Badnews
122 attempt = "creating connection"
123 Set conntemp = ASPserver.CreateObject("adodb.connection")
124
125 attempt = "opening connection"
126 conntemp.Open myconnect
127
128 attempt = "making recordset"
129 Set rstemp = conntemp.Execute(myquery)
130 howmanyfields = rstemp.Fields.Count - 1
131 ReDim fsa(howmanyfields)
132 ReDim fea(howmanyfields)
133 For i = 0 To howmanyfields
134 tempstart = Replace(fieldstart, "%name%", rstemp(i).Name)
135 tempend = Replace(fieldend, "%name%", rstemp(i).Name)
136 tempstart = Replace(tempstart, "%size%", rstemp(i).ActualSize)
137 tempend = Replace(tempend, "%size%", rstemp(i).ActualSize)
138 fsa(i) = myfieldstart
139 fea(i) = myfieldend
140 Next
141 ASPresponse.Write htmlstart & vbCrLf
142 Counter = 0
143 Do While Not rstemp.EOF
144 ASPresponse.Write rowstart & vbCrLf
145 For i = 0 To howmanyfields
146 If fieldnames = True Then
147 ASPresponse.Write namestart & rstemp(i).Name & nameend
148 End If
149 ASPresponse.Write fsa(i) & rstemp(i) & fea(i) & vbCrLf
150 Next
151 ASPresponse.Write rowend & vbCrLf
152 Counter = Counter + 1
153 rstemp.MoveNext
154 Loop
155 rstemp.Close
156 Set rstemp = Nothing
157 conntemp.Close
158 Set conntemp = Nothing
159 ASPresponse.Write htmlend
160 Exit Sub
161 Badnews:
162 temp = "Error: " & attempt & "<br>"
163 temp = temp & Err.Description & "<br>"
164 temp = temp & Err.Number
165 ASPresponse.Write temp
166 End Sub
167
http://www.learnASP.com/learn/buildvbguidelines.asp by Charles M. Carroll
Page 251
VB ASP Component Building Guidelines by Charles Carroll
Component written in Visual Basic can be written using programming techniques that will cause them to be unstable in a web server
environment. Commands, Functions and Objects that are fine in most standalone or client/server VB programs may not be
appropriate in a web server component. We offer the following major guidelines:
● Do not use DAO or RDO for data access. Use ADO only. DAO and RDO do not scale to the concurrency issues a website
faces well.
● Do not use traditional file access methods (Open #, Close #). Instead use the scripting FileSystemObject.
● 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:
● 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
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
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!
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.
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
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
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
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 private mycntxt as ObjectContext
managed components set mycntxt= GetObjectContext()
The traditional wisdom is that a robust transaction must pass the ACID test or the transaction procesing has flaws:
Durable: All transactions must store their results on a permanent or durable device before reporting success.
Of course the ASP page must include code to address both committing and aborting the transaction:
<%
SUB OnTransactionCommit()
...
END SUB
SUB OnTransactionAbort()
...
END SUB
%>
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
● 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.activeserverpages.com/learn/test/serverobjectsmail.asp
is the page you can test this at.
1 <html><head>
2 <title>serverobjectsmail.asp</title>
3 </head><body bgcolor="#FFFFFF">
4 <%
5 ' ASPMail(tm) from www.serverobjects.com
6 ' is not part of ASP per se,
7 ' but a third party utility from serverobjects.com
8 Set Mailer = Server.CreateObject("SMTPsvg.Mailer")
9 Mailer.RemoteHost = "relay.datareturn.com"
10
11 Mailer.FromName = "Some Student"
12 Mailer.FromAddress = "somestudent@activeserverpages.com"
13 Mailer.AddRecipient "Charles Carroll","cc@thebestweb.com"
14 Mailer.AddBCC "Charles Carroll","charles@activeserverpages.com"
15 Mailer.Subject = "ASPMail Tutorial"
16
17 Mailer.BodyText = "Hi. Just trying the mail example" & vbCrLf
18 Mailer.BodyText = "Line 2"
19 Mailer.BodyText = "Line 3"
20 If Mailer.SendMail then
21 Msg = "mail sent sucessfully!"
22 Else
23 Msg = "mail was not sent sucessfully"
24 End If
25 response.write Msg
26 %>
27 </body></html>
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"> </TD>
14 <TD ALIGN="LEFT"><INPUT TYPE="SUBMIT" NAME="SUB1" VALUE="Upload File"></TD>
15 </TR>
16 <TR>
17 <TD ALIGN="RIGHT"> </TD>
18 <TD ALIGN="LEFT">
19 <B><I><SMALL>Note: if a button labeled "Browse..." does not appear, then your
20 browser does not support File Upload. For Internet Explorer 3.02 users, a
21 free add-on is available from Microsoft. If you <b>do not see a Browse... button</b>
22 <A HREF="http://www.microsoft.com/msdownload/ieplatform/iewin95/iewin95.asp"
TARGET="_new">click here to go to Microsoft's Site and get your free file upload add-on</A>.
23 Select "Internet Explorer 3.02 File Upload Add-On for Windows 95 & NT".
24 </SMALL></I></B>
25 </TD>
26 </TR>
27 </TABLE>
28 </form>
29 </BODY></HTML>
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. The FORM must have a tag of ENCTYPE="multipart/form-data".
2. 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.
SA-FileUp provides a Form object that provides identical functionality to the ASP Request.Form object, but can understand the
encoding type that is specific to file uploads.
1 <HTML><HEAD>
2 <TITLE>uploadmultipart.asp by softwareartisans.com</TITLE>
3 </HEAD><body bgcolor="#FFFFFF">
4 <form enctype="multipart/form-data" method="post" action="uploadmultipartrespond.asp">
5 Enter description: <input type="text" name="descrip"><br>
6 Enter filename to upload: <input type="file" name="f1"><br>
7 <input type="submit">
8 </form>
9 </BODY></HTML>
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")
The previous example showed how to upload multiple files and access each of their individual properties. Previously we've
seen how to read properties of the file, such as the TotalBytes of the upload.
There are several properties that can be set. One very useful property is called MaxBytes. MaxBytes allows you to set a firm
limit on the size of the uploaded file, ensuring that malicious users do not fill up your server's hard disk with huge files.
When you set the MaxBytes property (before saving the file!), SA-FileUp will write up to the number you specify and then
stop. Any additional data will be discarded. You can set MaxBytes once and it will apply to all files in the current upload,
limiting each of them to the value that you specify.
The maximum file size that SA-FileUp can process is 2 GB. If set MaxBytes equal to zero (0), SA-FileUp will revert to the
default maximum, which is 2 GB.
Time for an example. We'll use the same simple form as in the very first upload:
1 <HTML><HEAD>
2 <TITLE>uploadlimitsize.asp by softartisans.com</TITLE>
3 </HEAD><body bgcolor="#FFFFFF">
4 <form enctype="multipart/form-data" method="post" action="uploadlimitsizerespond.asp">
5 Enter a big file to upload: <input type="file" name="f1"><br>
6 <input type="submit">
7 </form>
8 </BODY></HTML>
● 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
Even though the Internet Standard specification for HTTP Upload (RFC 1867) permits wildcarded filenames ("*.doc"), neither
Netscape Navigator or Microsoft Internet Explorer support wildcarded names at this time. When they do, the current version of
SA-FileUp will be able to process wildcarded filenames. For now, it is necessary to have an additional input tag for every file you
want to upload.
1 <HTML><HEAD>
2 <TITLE>uploadmanyfiles.asp by softartisans.com</TITLE>
3 </HEAD><body bgcolor="#FFFFFF">
4 <form enctype="multipart/form-data" method="post" action="uploadmanyfilesrespond.asp">
5 Enter first filename: <input type="file" name="f1"><br>
6 Enter second filename: <input type="file" name="f2"><br>
7 <input type="submit">
8 </form>
9 </BODY></HTML>
● For each uploaded file, SA-FileUp creates a new SAFile object to represent the uploaded file.
Related Links
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
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
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;
● 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.
* 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.
* 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.
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
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
Out_1 = comm("Output")
'and so on...
%>
Thats it!
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.
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
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