Active Server Pages/Print version


Active Server Pages

The current, editable version of this book is available in Wikibooks, the open-content textbooks collection, at
https://en.wikibooks.org/wiki/Active_Server_Pages

Permission is granted to copy, distribute, and/or modify this document under the terms of the Creative Commons Attribution-ShareAlike 3.0 License.

Prerequisites

ASP (or Active Server Pages) is a scripting tool for dynamic webpages. It is a technology that can be compared to Cold Fusion, JSP, and PHP. While primarily made for the Microsoft Windows platform, there are implementations of ASP technology on other environments.

ASP is the technology that powers the dynamic websites, not the language that the pages are scripted in. There are a number of languages that can be used to script or program a dynamic website. However, most people assume that ASP and vbscript (one of the languages used) are the same.

With the release of the .Net platform, Microsoft also updated ASP to ASP.Net. There are a number of improvements to ASP that ASP.Net provides, but that would be a book unto itself. This textbook focuses on what is now called "classic" ASP. One important difference is that ASP.Net pages are named *.aspx and ASP 3.0 pages are named *.asp, and ASP 3.0 pages are interpreted and ASP.Net pages are compiled thus ASP.net pages work faster. ASP.Net uses the Microsoft .Net framework and can use any language that .Net supports. ASP 3.0 is limited to VBScript and JScript (Microsoft's version of Javascript).

Do I need to know HTML? edit

Yes and No... The output of ASP is usually HTML, so it is strongly recommended that you are familiar with at least HTML 4.01. While many programmers prefer visual editors like Macromedia's Dreamweaver and Ultradev, Microsoft's Frontpage and Visual InterDev, beginners will benefit more from using a plain text editor until comfortable with the basic concepts.

Do I need to know a programming language? edit

You should be familiar with at least one object-oriented programming language. This book will teach you how to program in ASP, but it will not teach you how to program. You should understand the following concepts:

  • variables
    • global variables, and how they differ from local variables
  • functions, and
    • how to pass parameters to functions
  • decision-making statements such as if-then and if-then-else
  • looping statements such as the for loop and the while loop

Do I need to install web server software on my computer? edit

There are sites such as 1asphost.com that provide free web sites with ASP capabilities. You can upload your ASP files, and the server will do all the ASP processing for you.

Find similar services by doing a Google search for "free asp hosting".

You may also install software on your computer to process ASP files locally. Internet Information Services will come in handy for users of Microsoft Windows operating system. And there are Apache webservers available for most of today's operating systems.

In order to execute ASP 3.0 locally, you will need Windows 2000 Professional or higher. All versions of Windows from 2000 include Internet Information Services with the exception of Windows XP Home. Installation is simple, just go to Add/Remove programs and then the Add/Remove Windows components section. Just keep in mind that just because you have IIS installed that does not mean that ASP files will execute.


Differences between ASP 3.0 and ASP.NET

Previous: Prerequisites Index Next: Your first page

The most important difference between ASP and ASP.Net is that ASP uses interpreted VBScript or JScript, and ASP.net uses any .Net language (including VB.Net, C#, J#, etc.) compiled.

ASP 3.0 left all its code in the front of the application. There was no way for a programmer to "hide" the sensitive code which he or she may not want anybody to see. The fact that the code was interpreted also slowed performance. ASP.NET allows the programmer to create dynamic link libraries containing the sensitive code. This may be a disadvantage from an open-source perspective but compiling code into dll's greatly improves performance.

ASP.NET is firmly rooted in XML. Customarily, the dlls that ASP.NET creates start out as namespaces. All of the classes in the namespaces are then compiled into a single dll binary.

  1. ASP is mostly written using VB Script and HTML intermixed. Presentation and business logic is intermixed while ASP.NET can be written in several .NET compliant languages such as C# or VB.NET.
  2. ASP has maximum of 4 built in classes like Request, Response, Session and Application whereas ASP.NET using .NET framework classes which has more than 2000 built-in classes.
  3. ASP does not have any server based components whereas ASP.NET offers several server based components like Button, TextBox etc. and event driven processing can be done at server.
  4. ASP doesn't support Page level transactions whereas ASP.NET supports Page level transactions.
  5. ASP.NET offers web development for mobile devices which alters the content type (wml or chtml etc.) based on the device.
  6. ASP.NET allows separation of business and presentation logic because the code need not be included directly in the *.aspx page.
  7. ASP.NET uses languages which are fully object oriented languages like C# and also supports cross language support.
  8. ASP.NET offers support for Web Services and rich data structures like DataSet which allows disconnected data processing.
Previous: Prerequisites Index Next: Your first page


Your first page

Previous: Differences between ASP 3.0 and ASP.NET Index Next: Basic ASP Syntax

Objectives edit

  • Embed ASP scripting code into a web page.
  • Upload your ASP page to a server.
  • Test your page by viewing it in a web browser.

Content edit

ASP is delimited with "<%" and "%>"
within these delimiters is your custom code that is executed in the server.

Here is a small fragment of an ASP code (it outputs "My First ASP" on your browser):

<%
Response.Write "My First ASP"
%>

Or you could put the text into a pre-defined variable:

<%
Dim MyText

MyText = "My First ASP Page"
Response.Write MyText
%>

Here is a way to separate your code from your page layout.

<%@LANGUAGE="VBSCRIPT" CODEPAGE="1252"%>
<%

Dim MyText

MyText = "My First ASP"

%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>My First ASP</title>
</head>

<body>
<%=(MyText)%>
</body>
</html>

Summary edit

Review Questions edit

Exercises edit

Previous: Differences between ASP 3.0 and ASP.NET Index Next: Basic ASP Syntax


Basic ASP Syntax

Previous: Your first page Index Next: Variable Types

Objectives edit

In this section you will learn about the different parts of Active Server Pages scripting. We don't want to get too deep in discussion of how to write ASP scripts, but instead just want to introduce the different elements of ASP scripting.

Content edit

Active Server Pages or ASP is a scripted language which means that it doesn't have to be compiled in order to run. Instead, the program code is parsed, interpreted and evaluated in real-time. This means that you do not have to compile code in order to execute it.

Code is executed by placing it within a web page on a Web server. ASP was developed by Microsoft and because of this, is only completely reliable on Microsoft's IIS (Internet Information Server.) We encourage you to use Microsoft IIS to develop Active Server Page code.

Statements edit

A statement is like a sentence in English, it describes one task for the ASP interpreter to perform. A block of code is made up of multiple statements strung together on a web page.

There are various types of statements which we will talk about in the future including: "(flow) control, output, assignment, and HTTP processing.

In Active Server Pages, it is important to realize that each statement must appear on a line by itself. There is no special delimiter that indicates the end of an ASP statement. Unless you consider the carriage-return as the delimiter, which you really shouldn't.

You can use the colon character ":" within a program block to place multiple statements on the same line such as:

<%
Response.Write "Error" : Response.End
%>

In practice, it is best to avoid such programming constructs since it will make your code harder to read and maintain.

Another way to include more than one statement on a line is by using multiple code blocks like in the following:

<% If I < 0 Then %>Negative<% End If %>

Here, you have two different statements (even though they look like one statement) broken into two different code blocks. Active Server Pages allows this construct on your web pages since it is sometimes necessary to write code like this to eliminate white space that appears on your web page.

Variables edit

One of the hallmarks of a good scripting language is that the variables in the language are loosely typed. This means that there is minimal type-checking done on the values of the variables your program code uses. Active Server Pages was built correctly as a scripting language to be loosely typed. This allows you, as the programmer, to worry less about what type a variable is which frees you from a lot of work converting values and testing for the correct type.

You are not required to declare your variables before you use them (or even at all if you so wish). The one exception to this rule is when the page directive "Option Explicit" is in effect. If you place the following at the top of your ASP page, you will be required to declare all variables:

 <% Option Explicit %>

If you don't want this requirement in all your scripts, you can leave it out. It is a useful tool to throw onto a page to check for mis-spelled or mis-used variable names. If you mis-spelled a variable, you will likely see "variable not defined".

Variables are declared with a Dim statement and can include a single variable at-a-time or a comma-delimited list of variable names like shown in the following example:

 <%
 Dim sPhoneNo
 Dim sFirstName, sMidleInitial, sLastName
 %>

There is no such thing as a global variable in the ASP language. All variables are specific to the web page they are processed in. Once the page is done processing the values are lost. One exception to this is the Application object. It can hold a number of different values, each of which is associated with a string value. Another way is to pass variables in a web form or part of the URL in the Request object. More information on these topics will be covered later.

Comments edit

Comments are notations you can make on your web page within an ASP script block that will not be output on the web page. For all intents and purposes, they are hidden from your site visitors since they cannot view the ASP source code for your web pages. This allows you to make comments about what your code is doing.

Active Server Pages uses the quote character (') to define comments. This comment is a "line comment" meaning that it will comment out everything following it up until the end of the line. There is no multi line comment in ASP. In order to comment multiple lines, each line must be preceded by a quote (').

 <%
 ' example comment - show the current date
 Response.Write Now()
 %>

Server-Side Includes (SSI) edit

Server-Side Includes allow you to retrieve code from one web page and insert it into another page. This allows you to create common pieces of code and HTML which only need to be maintained in one place. Other web pages can include this content within their pages using this server directive.

If you are using server-side include directives, you cannot place ASP code within the directive. This is because the directive is evaluated before the ASP code is interpreted. So trying to do something like the following is illegal:

<!-- #include virtual="/lib/<%= sLibName %>" -->

But this doesn't mean that you can't place ASP code inside an included file. So if you include a file called /lib/common.asp, you can place ASP code inside that file (just like you would a normal ASP page) and it will be evaluated by IIS and the results will be placed in the calling page.

An interesting note is that your main page can use a ".html" extension and include (via SSI) an ASP page and the included file will be interpreted and processed as ASP and included in the HTML page.

The two different types of Server-Side includes allow you to retrieve and include files based on the absolute path (based on the Web site root) or relative to the calling page as shown below;

<%' absolute path - based on web site root %>
<!-- #include virtual="/pathtoinclude/include.asp" -->
<%' relative path - based on folder of calling page  %>
<!-- #include file="../../folder1/include.asp" -->

There are benefits to using both. A good rule of thumb is this: if you expect you will be moving entire folders (or trees) of your web application then relative paths are more appropriate. If you expect things to stay pretty much where you created them then you should use absolute paths.

Please note: When using IIS6 (Windows 2003 Server), relative paths are not enabled by default, which will cause any Server-Side includes using relative paths to cease functioning.

Review Questions edit

  • What are the three different types of script delimiters?
  • What file extension must be used when writing an ASP web page?
  • Which web server must be used to interpret ASP web pages?
  • How do you declare a variable?
  • How do you enforce the rule that all variables must be declared?
  • What are the benefits of server-side includes?
  • When should you use absolute server-side includes (SSI)?
  • How do you terminate a statement in ASP?
  • What is an "interpreted" scripting language?
  • How do you write comments in Active Server Pages?
  • How do you make "block comments" in ASP?
  • Which database works best with ASP?

Exercises edit

Previous: Your first page Index Next: Variable Types

Career Fair or Exhibition

External Links edit


Variable Types

Previous: Basic ASP Syntax Index Next: Expressions

Objectives edit

In this section you will learn about variables in Active Server Pages. This includes naming conventions, how they are declared, different primitive types and naming conventions. After studying this section, you should have a firm grasp of the types of variables available to you and how to work with different types in a web application.

Content edit

All variables in ASP are loosely typed. This means that you don't need to declare variables with a type. It also means that you can assign the value of any variable to any other variable. There are a few exceptions to this rule as we will see.

Basically, every variable in ASP has the major type of Variant. It is "variant" meaning that the type of value it holds can vary. Basically, the ASP interpreter will handle all conversion between types automatically when you group more than one variable or type together in a single expression.

Variable Scope edit

There are three different scopes for variables used in ASP. The first is page scope meaning that the variable is available for the entire duration. These are typically declared at the top of the page. The second type of variables are procedure scoped variables which are declared inside a procedure or function declaration. The third type of variables are scoped with a class definition which is used for object-oriented programming.

 <%
 Dim sStr1      ' page-scoped variable
 ....

 Procedure DoSomething
     Dim mStr2     ' procedure-scoped variable
 End Procedure

 Function DoSomething
     Dim mStr2     ' function-scoped variable
 End Function

 Class clsTest
     Private msStr4   ' class-scoped variable
     Public msStr5    ' class-scoped variable
 End Class
 %>

Page-scoped variables will be visible to all code included on your web page including procedures and functions. You can even access page-scoped variables within a class although good object-oriented design would strongly discourage this practice.

Procedure-scoped variables will only be visible within the procedure in which they are defined. It is perfectly acceptable to use the same variable name for a page-scoped variable and a procedure-scoped variable. Keep in mind, that when you do this, you will hide the page-scoped variable and will have no way to access it within the procedure.

Class-scoped variables can only be accessed through an instance of the class. There is no notion of static variables or static methods in the simplified ASP scripting language. You will need to use the ObjectName.VariableName syntax in order to access member variables directly. Only variable declared Public can be accessed in this way. Private class variables can only be accessed by code defined within the class. More information about using classes in Active Server Pages will be discussed later.

Valid Variable Names edit

To be valid, an ASP variable name must follow the following rules:

  • Must begin with an alphabetic character
  • All other characters must be alphanumeric or underscore ("_")
  • Name must not exceed 255 characters in length
  • Name must be unique within the scope it is defined
  • Name must not be the same as a reserved word of built in functions, procedures, and objects.

Variable names, just like statements are case-insensitive. This means that if you declare a variable with the name "myVar", you can access it using "MYVAR" or "myvar" or even "MyVaR".

One way to avoid using reserved words and make it easier to identify what type of variables you are using is to use a naming convention. Usually the first letter or few letters of the variable names what information it holds.

Examples:

  • nCount n for integer or number, holds a value that is used to count something, like for control loops.
  • sName s for string, holds a value that represents a name.
  • bIsActive b for boolean, holds true or false values, in this case true if something is active, false if it is not.

Following a naming convention can help avoid messy code, and leads to good programming habits. It also allows somebody else to work with your code and help debug it or modify it. Along with a naming convention, use comments as well to document what the variable is to be used for in the ASP page.

Examples:

  • Dim nCount 'Used to count values in control loops.
  • Dim sName 'Used to store the user's name that they enter in a web form.
  • Dim bIsActive 'Used to test if the user's account is active.

You will learn more on naming conventions later on in this document.

Declaring Variables edit

To declare a variable, you use the Dim statement for page and procedure-scoped variables. After the Dim statement, you can put a comma-separated list of variable names. If you prefer, you can just put one variable on each line. This allows you to add comments about each variable you declare.

 <%
 Dim sAction     ' form action
 Dim sQuery      ' database query
 Dim I, J, K
 %>

You should place your variables in a consistent location on the page or within your procedures. Typically, most people place the declarations at the very top (beginning) of the page or the top of the procedure. Others think it makes more sense to place the variable declarations right above the location where they are first used.

Primitive Types edit

When we talk about primitive types, we are talking about low-level variables types that cannot be broken down into smaller primitive types. Basically, these are the "built-in" variables that Active Server Pages understands.

These are sometimes referred to the "sub-type" of the variable since the major type of the variable is "variant". Each variable may have one of the sub-types shown in the following table. If you have used other programming languages, then these primitive types will be very familiar to you.

Type Name Values Memory Example
Boolean True or False 2 Bytes? true
Byte 0 to 255 1 Byte 127
String Any unicode characters Unlimited "unicode: ê"
Int -32,768 to 32,767 2 Bytes 147
Long -2,147,483,648 to 2,147,483,647 4 Bytes 3458972
Single 1.401298E-45 to 3.402823E38 (pos)
-3.402823E38 to -1.401298E-45 (neg)
4 Bytes 23.546234
Double 4.94065645841247E-324 to 1.79769313486232E308 (pos)
-1.79769313486232E308 to -4.94065645841247E-324 (neg)
8 Bytes 43872452.23445
Currency -922,337,203,685,477.5808 and 922,337,203,685,477.5807 8 Bytes 132412.34
Datetime 01/01/100 to 12/31/9999 8 Bytes '09/23/2004 12:34 AM'
Object An object reference 8 Bytes? Server.CreateObject("...")

Special Values edit

In addition to the values shown above, the following special values may also be assigned to Active Server Page variables:

Type Name Values Memory Example
Empty vbEmpty 2 Bytes? vbEmpty
Null null 2 Bytes? null

The empty value is the default value for newly declared variables (never assigned any value.) If tested in a boolean context, it is equivalent to "false" or tested in a string context it is equivalent to the empty string ("")

Conversion and Verification edit

You don't need to concern yourself much with setting the type of the variable. This is done pretty much automatically for you. In the event that you want to set the type that is assigned to a variable, you can use the ASP conversion function that corresponds to each type.

Also, there are verification functions available to make sure a variable is compatible with the specified type. This doesn't mean that the variable has that sub-type. Rather, it means that the variable can successfully be converted to the type.

Type Name Convert Verify
Boolean CBool n/a
Byte CByte IsNumeric
String CStr n/a
Int CInt IsNumeric
Long CLng IsNumeric
Single CSng IsNumeric
Double CDbl IsNumeric
Currency CCur IsNumeric
Datetime CDate IsDate
Object n/a IsObject
Empty n/a IsEmpty
Null n/a IsNull

Literal Values edit

Literal values are values you insert into your ASP code and use in expressions. By itself, a literal value has no use, but when used in a statement such as an assignment or output statement

 <%
 ' examples of literal values
 Dim sString, nInt, fFloat, dDate, bBool

 sString = "Hello There"
 nInt = 1234
 fFloat = -25.324
 dDate = DateSerial(2004, 10, 28)
 bBool = True
 %>

You will notice that there is no way to specify a date literal in ASP. Therefore, you need to use a function call to build a date value using DateSerial or you can use Now() to get the current date and time.

The value for a literal value is bound by the limits specified in the table for primitive types above. If you attempt to use a value that is outside the acceptable range for any of the types, you will receive an error message indicating this fact and your ASP page will terminate execution.

Constant Definitions edit

In some cases, you might want to create "named constants" instead of using literal values all of the time. This is particularly useful if you create a common include file that will be used in multiple scripts on your site. You define constants using the Const keyword like so:

 <%
 Const PI = 3.141592654
 Const RECS_PER_PAGE = 25
 Const FSO_FORREADING = 1
 Const FSO_FORWRITING = 0
 %>

It is common practice to use all uppercase variables for your constant definitions although this is not required. It simply makes your code easier to read and maintain.

Naming Conventions edit

A naming convention is a standard way of naming all of the variables used on your site. There are various different methods used for naming variables and a whole chapter could be devoted to this subject. One of the most popular is Hungarian notation where the first letter of the variable name indicates the dominant sub-type for the variable.

Type Name Letter Example
Boolean b bIsMale
Byte z zAge
String s sFirstname
Int n nAge
Long l lPageHits
Single f fScore
Double d dMass
Currency m mBalance
Datetime d dExpiration
Object o oFSO

The Microsoft standard proposed for Visual Basic is to use a 3-letter naming convention for their variables. This is a little more clear for reading and maintaining code. Some would consider this overkill for a light-weight scripting language.

Type Name Letter Example
Boolean bln blnIsMale
Byte byt bytAge
String str strFirstname
Int int intAge
Long lng lngPageHits
Single sng sngScore
Double dbl dblMass
Currency cur curBalance
Datetime dat datExpiration
Object obj objFSO

Summary edit

Exercises edit

Previous: Basic ASP Syntax Index Next: Expressions


Expressions

Previous: Variable Types Index Next: Conditionals and Looping

Objectives edit

In this section, you will learn how to build expressions in Active Server Pages. After studying this section, you will learn how to build an expression and learn how to combine variables and string literals in combination to manipulate data.

Content edit

An expression is a group of literal and variables which are organized in a structured format using operators. The best example of an expression is a mathematical expression such as x + 3.

Expressions are made up of a collection of mathematical, comparison, bit-wise and logical operators as well as literal values and ASP variables which are placed together for evaluation by the ASP Interpreter. Once an expression is evaluated, it can be assigned to a variable, used as the argument to an ASP procedure or output on an ASP page.

Assignment edit

One of the most basic statements you can make in ASP is an assignment. This basically evaluates an expression and places the result into a variable. The equals sign (=) separates the variable that gets the result (on the left side) and the expression to build the result (on the right side).

 <%
 Dim nX, dX, sName, bIsAdmin

 ' assign literal values
 nX = 13
 dX = 7645.34
 sName = "Barney Google"
 bIsAdmin = True

 ' or you can assign complex expressions like
 Dim dDateTime

 dDateTime = Now()
 nX = 13 + 23 - 10
 dx = (5 * nX) / 2.0
 sName = "Barney is " & CStr(nX)
 %>

Don't worry too much about some of the more complicated expressions found in this example. All of this will be explained later in this chapter. You should note that the left side of the expression is always a variable. You are only allowed to put a single ASP variable on the left side of the equals sign.

Evaluation Order edit

The way an expression is evaluated, depends on the operator precedence. Precedence is kind of an importance assigned to an operator. Operators that have the highest precedence are evaluated first and those that have the lowest are evaluated last. When two operators exist that have the same precedence, the operators are evaluated from left-to-right.

Take for example the following expression:

dX = 6 - 3 * 4 + 2

In this example, you will see we have three different operators. The "+" and the "-" operator have the same precedence while the multiplication operator (*) has a higher precedence. In this case, the multiplication takes place first reducing the expression to:

dX = 6 - 12 + 2

Now there are two expressions that have the same precedence. In this case, we evaluate the left-most expression first. After two more reductions we get the final result:

 dX = -6 + 2
 dx = -4

You should note also that if we had evaluated the expression from the other direction we would get a completely different result. This order of evaluation follows the same method used in mathematics (if you remember your basic algebra.)

Grouping Sub-Expressions edit

If you want to over-ride the default order-of-evaluation (precedence) for evaluating an expression, you can group expressions that should be evaluated first in parentheses. You can think of it as an expression embedded in another expression or a "sub-expression".

If you remember the example from the previous section, we can modify it to change the order-of-evaluation like so:

dX = (6 - 3) * 4 + 2

And just like in Algebra, we know that we have to evaluate these sub-expressions first. So the first step in reducing this type of expression is to evaluate the sub-expression:

dX = 3 * 4 + 2

The final reduction will yield a result of 14 which is a completely different result than we got before. Be careful about how you group your expressions. It can cause a lot of problems and increase the complexity of your code. If you want to keep your code simpler, you can always create new variables to store the results of sub-expressions.

 ' Using variables to evaluate sub-expressions
 Dim dX, dY
 dY = 6 - 3
 dX = dY * 4 + 2

Mathematical Expressions edit

The following table lists all of the binary mathematical operators. They are "binary" because they require two arguments. The first argument is on the left-side and the second argument is on the right-side. So the operator "+" in the expression "5 + 6" has the binary arguments "5" and "6".

Symbol Operator Example
+ Addition nX + 5
- Subtraction nX - 5
* Multiplication dX * 1.5
/ Division dX / -1.5
\ Integer Division dX \ 6
% Modulus (remainder) nX % 6

The following table lists all of the unary mathematical operators. A unary operator only has a single argument to act on.

Symbol Operator Example
- Negation -nX

Of course you can combine binary and unary operators in one expression. The results of one binary operation might serve as the argument to your unary operation.

 ' combining the binary "+" with the unary "-"
 dX = -(nX + nY)

There are many advanced mathematical functions that can be used to do complex arithmetic which we will talk about later. These will not be covered in this chapter.

String Operators edit

When working with strings, Active Server Pages provides a wealth of functions for manipulating strings. But since we are only talking about operators that may be used in an expression, we will only be dealing with the one string operator here: the string concatenation operator.

String concatenation means that you want to append one string to another. This operation is a binary operation meaning that it takes two arguments: the left-side is the string you want to append to and the right-side is the string that you want to append.

 Dim sFirst, sLast, sFullName
 sFirst = "Bill"
 sLast = "Gates"
 sFullName = sFirst & " " & sLast

As you can see in the example above, we are using the string concatenation operator to append three string values together: "Bill", " ", and "Gates". Two of the strings are stored in variables while the space character is just a string literal.

You may concatenate as many variables as you want together using the string concatenation operator. It has been shown that string concatenation under Active Server Pages is very inefficient. So if your page is performing slowly and you have a lot of string concatenations, you should look for ways to eliminate them.

Comparison Operators edit

Comparison operators, as you might have guessed, are used to compare two different expressions and return a value of "true" or "false". In most cases the two expressions being comparted will evaluate to a number, but it is possible to compare string values, dates and booleans.

The following table lists the binary comparison operators. These operators require two expression arguments: one on the left-side of the operator and one on the right-side. Just like mathematical expressions, you may combine two-or-more of these expressions together. In the next section we will explain how to these are combined using logical operators.

Symbol Operator Example
= Equality nX = 5
<> Inequality (Not Equal) nX <> nY
< Less Than nX < 5
> Greater Than nX > -5
<= Less Than or Equal nX <= 5 + nY
>= Greater Than or Equal nX >= dY * 5.0 - 2

These operators are most commonly used in an If Then statement which will take an action based on the boolean result of an expression. Unless you already have a boolean value stored in an ASP variable, you will need to write an expression like the following:

 If nX >= 60 Then Response.Write "You Passed!"
 If nX < 60 Then Response.Write "You Failed"

Of course, your expression can be as complicated as you want as long as it evaluates to a boolean value.

Logical Operators edit

Whereas mathematical expressions are used to manipulate numbers, logical operators are used to work with the two boolean values "true" and "false". These operators are always used to combine two expressions that result in boolean values.

Symbol Meaning Example
And True only if both arguments are true, otherwise false nX > 5 And nX < 10
Or True if either argument is true, false only when both arguments are false nX < 5 Or nX > 10

In addition to these binary operators, there is also one unary operator:

Symbol Meaning Example
Not Negation, true becomes false and false becomes true Not (nX > 5)

The negation operator basically will give you the opposite value of the expression. So if the expression evaluates to "true" and you perform the Not operation on it, it becomes "false". Conversely, "false" will become "true" when Not is applied.

So using these logical operators, we can group many comparison expressions together to create a very complex expression like so:

 ' example of a complex expression with four comparisons)
 If (nX = 2) Or (nX < 10 And nX < 20) And Not (nY * 5.0 - 2 <= 17.0) Then
     Response.Write "Yes"
 End If

The first comparison (nX = 2) looks just like an assignment. You can never put an assignment in an expression like this. Assignment only occurs at the start of an expression, where the first symbol is an ASP variable which is followed by the assignement (=) operator.

You will notice that we used parentheses to group the expressions. Even in some cases where parentheses are not required, it sometimes makes your expressions easier to read when you put them in there.

Bit-Wise Operators edit

For advanced programming, Active Server Pages has operators for working with individual "bits". A "bit" is the digit used in the binary number system and was formed from a contraction of the words "binary digit". It can only have one of two different values: "0" and "1".

In the old days of computer, programmers were severely limited in storage and had to make the most of the available storage. One way they did this was by combining multiple variables into a single "byte". This has carried through to modern-day computer systems and this is why we need bit-wise operators.

In computer terms, we talk about "bytes". A byte is composed of 8 "bits" and therefore can have 2 ^ (raised-to-the-power) 8 or 256 possible values. An integer is composed of two bytes so it can have a value of 256 ^ 2 or 65536 possible values.

 The 8 bits from a byte and their integer equivalents

 +-------------------------------------------------------+
 | Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1 | Bit0 |
 +------+------+------+------+------+------+------+------+
 |  128 |   64 |   32 |   16 |    8 |    4 |    2 |    1 |
 +-------------------------------------------------------+

For all of the bits that are set (equal to 1) above, you need to add their integer equivalent to determine the resulting byte value. So If bits 6, 4, 1 and 0 were set, the equivalent byte value would be: 64 + 16 + 2 + 1 = 83.

Going the other way around, we can convert an integer to binary. We just take the integer value and subtract the biggest binary value we can and note the corresponding bit. We continue to do this subtracting binary values until we come up with the resulting bit string:

 ' convert integer value (221) to binary
 221 - 128 = 93 (binary 0x10000000)
 93 - 64 = 29 (binary 0x11000000)
 29 - 16 = 13 (binary 0x11010000)
 13 - 8 = 5 (binary 0x11011000)
 5 - 4 = 1 (binary 0x11011100)
 1 - 1 = 0 (binary 0x11011101)

When working with the bit-wise operators, we sometimes have to convert between binary and integer like this and vice-versa.

In Active Server Pages, bit-wise operators are only used on numeric expressions to manipulate individual bits. The numberic expression can evaluate to integers, longs, single or double-precision numbers. After evaluating the bit-wise operation, the resulting value will be compatible with the original arguments.

The following bit-wise operators require two arguments: one on the left-side of the operator and one on the right-side.

Symbol Meaning Example
& Bit-wise And nX & 5
| Bit-wise Or nX | 48
^ Bit-wise Exclusive Or nX ^ 48
<< Shift Bits Left nX << 2
>> Shift Bits Right nX >> 1

The following operators are "unary" operators meaning they only require one argument. The single expression argument must be to the right-side of this operator.

Symbol Meaning Example
~ Bit-wise Negation ~ nX

Truth Tables edit

Truth tables display the results of the binary operators on a bit-by-bit basis. You can think of each bit in the arguments being evaluated one-by-one. Bits are matched up based on their position in the bytes. So for a 16-bit integer, each bit would be operated on individually and the resulting bits would be strung together in the same order to generate the resulting number.

When viewing these tables, think to yourself "When performing a bit-wise and (&), bit 0 from argument 1 and bit 0 from argument 2 are anded together and the result is X. Next bit 1 from argument 1 and bit 1 from argument 2 are anded together and the result is Y". And continuing on for all the bits in the arguments.

And (&) Operator Truth Table
Arg #1 Arg #2 Result
0 0 0
0 1 0
1 0 0
1 1 1
Or (|) Operator Truth Table
Arg #1 Arg #2 Result
0 0 0
0 1 1
1 0 1
1 1 1
Exclusive Or (^) Operator Truth Table
Arg #1 Arg #2 Result
0 0 0
0 1 1
1 0 1
1 1 0
Negation (~) Operator Truth Table
Arg #1 Result
1 0
0 1

Manipulating Date and Time Values edit

ASP has some built-in functions to manipulate datetime values. Thought technically not operators, we mention them here for completeness since datetime is a valid data type and it is often necessary to calculate dates and times.

Date and Time Functions
Function Purpose
Date Get the current date according to the local machine
dNow = Date()
Time() Get the current time as a datetime value according to the local machine
dTime = Time()
Now() Get the current date AND time according to the local machine
dNow = Now()
DateAdd(Interval, Number, Date Add a specific Number of Interval to the supplied date
DateAdd("d", 3, Now())
DateDiff(Interval, Date1, Date2) Calculate the number of Interval difference between Date1 and Date2
dDaysLeft = DateDiff("d", Now(), dBirthDay)
DatePart(Interval, Number, Date) Retrieve a specific part of a date such as the hour or month
DatePart("yyyy", Now())
DateSerial(Year, Month, Day) Construct a datetime value from the year, month and day components
dBirthday = DateSerial(1998, 12, 23)
TimeSerial(Hour, Minute, Second) Construct a datetime value reflecting the time components.
dNapTime = TimeSerial(14, 0, 0)
DateValue(DateTime) Convert a date string into a datetime value.
DateValue("12/23/1998")
TimeValue() Convert a time string into a valid datetime object.
dTime = TimeValue("10:51:43 PM)
Day(Date) Retrieve the day-of-the-month (0-31) for a specific datetime value
Day(Now())
Month(Date) Retrieve the month (1-12) for a specific datetime value
nMonth = Month(dBirthDay)
Year(Date) Retrieve the year for a specific datetime value.
Year(Now())
Hour(Datetime) Retrieve the hour (in 24-hour military time format [0-23]) for the datetime value
Hour(Now())
Minute(Datetime) Retrieve the minute (0-59) component for a specific datetime value
nMinute = Minute(dBirthDay)
Second(Datetime) Retrieve the seconds (0-59) for a specific datetime value.
Second(Now())
FormatDateTime(Datetime) Format the specified datetime value in a standardized format
FormatDateTime(Now(), vbLongDate)

Information about optional arguments for these functions and valid interval types will be discussed in a later chapter. You should note that none of the mathematical operators apply to datetime values. You must use the various conversion and calculation functions above to manipulate dates.

Line Continuation Operator edit

If you have a really long line in ASP that you would like to split into two lines, you can use the line continuation operator. This is an underscore (_) placed at the end of the line that tells the ASP interpreter that statement or expression continues on the next line.

 if ((bDaysLeft < DateDiff("d", Now(), dBirthDay)) Or _
   (bDaysLeft > DateDiff("d", Now(), dChristMas)) Then
 	Response.Write "Hooray!"
 End If

In the example above, we use the line continuation to continue a boolean expression. You may use it to continue any type of expression or statement. It makes sense to split up long lines for readability. Just be careful how you split lines so that you don't make the line more confusing to read.

Summary edit

There are eight different types of operators in ASP:

  • Assignment Operators
  • Mathematical Operators
  • String Operators
  • Comparison Operators
  • Logical Operators
  • Bit-wise Operators
  • Grouping Operators
  • Line Continuation Operator

All but the assignement operators can be used for building expressions. Operators are evaluated based on precedence and the grouping operators. If two operators have the same precedence, then the operators are evaluated from left-to-right.

All date and time values must be manipulated using functions. The mathematical operators are invalid on datetime values.

Review Questions edit

  • What must be on the left-side of the assignment operator?
  • What must be on the right-side of the assignment operator?
  • What are the eight major types of operators?
  • What is meant by operator precedence?
  • Which operator is used to group expressions?
  • How are datetime values used in expressions?

Exercises edit

  • Write the conditional expression to test a variable (nSpeed) is less than or equal to the speed limit (nSpeedLimit)
  • Write an expression to convert a temperature in Fahrenheit to degrees and vice-versa
  • Create a function that calculates the number of days from now until Christmas.
  • Create a page that inputs a user's birthday and then calculates how old that person is.
Previous: Variable Types Index Next: Conditionals and Looping


Conditionals and Looping

Previous: Expressions Index Next: Functions and Subroutines

Objectives edit

In this section we will introduce the basic program flow-control statements available to you in Active Server Pages. This includes conditional statement and looping constructs. After studying this section, you should have a good understanding of how to use Active Server Pages to make decisions based on expressions. You should also understand how to repeat a block of program code based on conditions you define.

Content edit

Conditional statements are used by your program to make decisions and decide what the program should do next. An example of this would be deciding whether a user has entered the correct password for your site by comparing the password entered with the correct password. If the user passes the test, they are sent to their account management Web page. If they fail, they are sent back to the login screen with an error indicating the "password is invalid".

This kind of decision making is common in all programming languages. You need to master this aspect of Active Server Pages in order to write dynamic web applications.

Another important concept is looping. Looping simply means that you repeat the same block of code multiple times. Since you are going through the code once, going back to the beginning and repeating it again, the direction of program execution looks like a loop (or a circle) which is why we call it looping. We will introduce you to all of the looping methods available to you in this chapter.

Program Flow edit

In general, program flow starts at the very top of the page and continues all the way down the page in the same way that you read a book. All pages are executed this way in ASP and it makes the code very easy to follow until you get to conditional statements and looping constructs.

Because of the logical flow of the program, it is easy to trace through your program code and output debugging information to see what your script is doing as it gets processed by the ASP interpreter. Through use of the Response.End statement, you can place breakpoints in your script to stop execution at specific points. More about this will be discussed later.

One topic that will not be covered in this section is procedure and object method calls. We will talk about these in later sections.

Conditionals edit

A conditional statement is one where an expression is evaluated and based on the result one or more actions may be taken. This allows you to check for a certain condition and take a specific action that is required when the condition is or is not met.

If-Then Statement edit

The "If-Then" statement is the most basic conditional statement. When put on a single line, this statement says "If the condition is met, then do this." For example, we could test to see if someone is old enough to vote with:

 If nAge > 18 Then Response.Write "Yes, you can vote!"

You may optionally, create an If-Then statement that encloses a block of statements. A block of statements means more than one statement grouped together. In this case, the entire block of statements will be executed only when the condition is met. We use indenting in this case to help us read the code and determine where the block starts and ends.

 If nAge > 18 Then
     Response.Write "Yes, you can vote!"
     bCanVote = true
 End If

As you can see in this program block, the If Then statement defines the start of the program block while the End If statement defines the end of the program block. The program block is indented to make it easier to match the start and end of the block. All of the statements in this program block will only be executed if the conditional statement is met (nAge > 18). When it is not, nothing will be done.

If-Then-Else edit

The If Then statement is great, but what if you want to perform two different actions. One action to be taken when the condition is met and one action to be taken when the condition is not met. That is what the If Then Else statement was create to handle. It basically says: "If the condition is met, then do this, otherwise do this".

 If nAge > 18 Then bCanVote = true Else bCanVote = False

As you can see from the example above, you can put the entire If Then Else statement in one line. In many cases, you will want to avoid this since it tends to make the length of the line very long. Instead, you will probably want to use the program block form like so:

 If nAge > 18 Then
     Response.Write "Yes, you can vote!"
     bCanVote = true
 Else
     Response.Write "No, you can not vote."
     bCanVote = false
 End If

In this case, only one of the two program blocks will be executed. The first will be executed when the condition is met. The second will be executed when the condition is not met. So you can think of the If Then Else statement as saying "one or the other but not both".

Although we are using more than one statement in the program blocks shown above, you could also put a single statement within each program block. For debugging purposes, you can even have no statements at all within a program block. This allows you to comment out all the statements in a program block and your script will still run no problem.

You will notice that in the conditional expression for the If Then statement, we did not have to enclose the condition with parentheses "(" and ")". You can always use parentheses for grouping expressions together but they are not required to enclose conditional statements.

Select Case edit

The If Then statements are great if you are just evaluating a "true" or "false" condition. But if you want to evaluate an expression other than a boolean and take some action based on the result, you will need another mechanism. This is why the ASP language includes the Select Case statement. This allows you to basically "select" from a list of many cases, the action to perform.

The cases for a Select Case are all literal primitive values. You must have an "exact match" in order to match a "case". You may include more than one value to match, but you may not define ranges of values to match, nor may you define a pattern to match.

 Select Case nAge
     Case 15, 16
         Response.Write "You are almost old enough to vote"
     Case 17
         Response.Write "You might want to register to vote"
     Case 18 
         Response.Write "Yes, you can vote!"
     Case Default
         Response.Write "Catch-all for all other ages"
 End Select

This select statement is a little deceiving, because it will only tell you that you can vote if the age is 18 and only 18. If the age is greater than 18, then none of the specific cases will be matched. Instead, the optional catch-all case (Case Default) will be executed when the age is greater than 18.

Of course, you don't need to include the Case Default if you don't need it. By leaving it off, you are basically saying "do nothing if an exact match for a case is not found".

You can use any expression for the Select Case as long as it evaluates to a primitive type. You can not use an object expression because there is no such thing as an object literal to compare it to. However, you can call an object method that returns a primitive type and use this as the expression.

In the example shown above, you can see that we are using the carriage return to separate the Case from the block to be executed. There is no need to terminate this type of program block. It is terminated by the instance of the next case or the End Select. You may also put the case and the action to perform on the same line by using the colon (:) as a statement separator:

 Select Case nAge
     Case 15, 16 : Response.Write "You are almost old enough to vote"
     Case 17 : Response.Write "You might want to register to vote"
     Case 18 : Response.Write "Yes, you can vote!"
     Case Default : Response.Write "Catch-all for all other ages"
 End Select

Looping Constructs edit

Looping constructs are used for repeating the same step over-and-over again. There may be many reasons to use a loop. In database-driven web applications, you will often use a loop to iterate over each record returned from a recordset.

For Next Loop edit

The "for next" loop allows you to repeat a block of code using an incremental counter. The counter is initialized at the start of the loop and then incremented at the end of the loop. At the start of each repetition, the counter is checked to see if it has exceeded the ending value. This is best explained by using an example:

 For I = 1 To 10
     Response.Write "I = " & I & "<br>"
 Next

In this example, we have created a loop that is repeated 10 times. We know it executes exactly ten times because you can read the statement as "for every whole integer from 1 to 10, do this".

The variable "I" is initialized with a value of 1 and the first repetition of the program block (indented) is executed. The output will be "I = 1". Don't worry about the "<br>" part, this is just HTML code to create a line break on the web page.

The second time through the loop, the counter (I) is incremented and takes on a value of 2. So the second line output by this block is "I = 2". This process repeats as I is incremented one at a time until the counter exceeds the end value. So in this case, the last line printed will be "I = 10".

In a more advanced case, we can change the way in which the index is incremented. If we wanted the counter to increment by 2, we would write the For Next loop as follows:

 For I = 1 To 10 Step 2
     Response.Write "I = " & I & "&lt;br&gt;"
 Next

The output of this code will be:

 I = 1
 I = 3
 I = 5
 I = 7
 I = 9

This time we only get five values output by the loop. This is because we are incrementing the counter by 2 instead of by 1 (the default.) Notice that we do not have to finish on the ending value (10). After incrementing the counter from 9 to 11, the loop checks to see if we have exceeded the ending value (10) and exits the loop.

You can also count backwards like this:

 For I = 10 To 1 Step -1
     Response.Write "I = " & I & "&lt;br&gt;"
 Next

And of course, you can substitute expressions and variables for the starting and ending values and even the amount to "step through" the loop:

 For I = nX + nY To YourFunc(nZ) Step nStep
     Response.Write "I = " & I & "&lt;br&gt;"
 Next

Do While edit

Another looping construct is the Do While loop which will repeat a block of program code as long as the condition is met. This is kind of like the If Then conditional statement in that it expects a boolean expression. Here is what it looks like:

 I = 1
 bFound = False
 Do While I < 10
     Response.Write "I = " & I & "&lt;br&gt;"
     I = I + 1
 Loop

What we have here is a loop that does exactly the same thing as the For Next example shown in the previous section. Why would you want to use this construct instead of a "for next"? The problem becomes obvious when it is not easy to determine how many repetitions of the loop you need to do.

 X = 239821.33
 Do While X > 1
     Response.Write "X = " & X & "&lt;br&gt;"
     X = X / 2
 Loop

In this case, we do not know how many times we will have to divide the value of X by two until we end up with a value less than or equal to 1. So we just use the Do While loop to handle the logic for us.

Do Until edit

Almost identical to the Do While looping construct is the Do Until. It works exactly the same way except that it repeats the program block until the condition evaluates to "true". You could basically do the same thing with "Do While" by enclosing your expression with Not (expr), but the creators of ASP realized that the code would be cleaner using this more logical statement.

 X = 239821.33
 Do Until X <= 1
     Response.Write "X = " & X & "&lt;br&gt;"
     X = X / 2
 Loop

Here, we have created a loop that does exactly the same thing as our "do while". We just reversed the logic of the conditional statement and changed the keywords to Do Until. In this case, it doesn't make the code that much cleaner to read. But as we will see later, there are definite cases where you will want to use Do Until.

While edit

The While loop works exactly the same as the Do While except that it has a little shorter construct. Please read the section on "Do While" to understand how this looping construct works.

 X = 239821.33
 While X > 1
     Response.Write "X = " & X & "&lt;br&gt;"
     X = X / 2
 Wend

Unlike the "Do" loops, the While loop program block is terminated by the Wend statement.

Summary edit

Active Server Pages has many different control flow statements to handle the execution of your ASP page. The conditional statements are: If Then, If Then Else and Select Case. The looping constructs are For Next, Do While, Do Until and While. Conditional expressions in ASP do not need to be enclosed in parentheses ("(" and ")").

For Next loops manipulate a counter and repeat the program block until the counter exceeds the ending value. Do While, Do Until and While loops repeat based on the evaluation of a boolean expression (meaning an expression resulting in the value of "true" or "false").

Review Questions edit

  • What types of conditional statements are available in ASP?
  • What types of looping constructs are available in ASP?
  • What are the three parameters for a For Next loop.
  • How do you count backwards using a For Next loop.
  • What loop would you use to repeat until a condition is satisfied?
  • What loop would you use to repeat while a condition is satisfied?
  • How do you terminate a program block for a Do While loop?
  • How do you terminate a program block for a While loop?

Exercises edit

  • Create a For Next loop that outputs integers from 10 to 100 that are evenly divisible by 10
Previous: Expressions Index Next: Functions and Subroutines


Functions and Subroutines

Previous: Conditionals and Looping Index Next: Database Access Using ADO

Objectives edit

In this chapter we will introduce the concepts of creating procedures. A procedure may be a function or subroutine definition. Once defined, a procedure can be called from anywhere in your code. After reading this chapter, you should understand how to write your own procedure and then call that from another point in your code.

Content edit

One of the most powerful features of the Active Server Pages is the ability to create powerful procedures that can extend the scripting language. If you are new to procedural programming, you can think of a procedure as a macro that performs a complex task. Once defined and included in your web page, you can reference the macro in any code block you define.

For example, if you created a function to display the current date and time you could call this function with something like:

 <%= TodaysDate() %>

What is a Function? edit

A function is a procedure that returns a value to the caller. By "caller", we mean the place in the ASP code where you invoke the procedure through a "function call". Functions are declared using the Function statement and terminated with an End Function statement.

 ' a totally useless function to get the current date and time
 Function TodaysDate
 	TodaysDate = Now()
 End Function

Above, we have an example of a function definition that will return the current date and time using the built-in function Now. By assigning a value to a variable which has the same name as the function (TodaysDate), we return a value to the calling process. There is no return statement like the PHP scripting language or in C programming.

This function can be declared anywhere in your web page and it will be made available for you to call from within anywhere in the page. As we will see later, you can even place commonly used procedures within a Server-Side Include page so that you don't have to write duplicate procedures on multiple pages from your web site.

This function is totally useless because it's easier to just call the built-in function Now.

It is important to note that a procedure declaration like this will not do anything meaningful until it is actually called. It simply declares a procedure which will do work when it is called.

What is a Subroutine? edit

A subroutine is a procedure that does not return a value to the caller. Subroutines are declared using the Sub statement and terminated with an End Sub statement.

 ' a subroutine to output today's date
 Sub ShowDate
 	Response.Write("Today's Date is: ")
 	Response.Write(Now())
 End Sub

The subroutine call above will output text that looks like "Today's Date is: Jan, 23 2004 06:43:12AM" when it is called. The location in the web page where this is output depends on where the subroutine is called. You should call the subroutine at the exact point where you would like it to output the text.

Unlike a function declaration, you are not allowed to assign a return value to the procedure name (ShowDate). If you attempt to use a subroutine as a function, you will receive a runtime error. The same is true when you try to use a function as a subroutine.

Procedure Parameters edit

Thus far, we have only looked at procedures which have no parameters. A parameter is an ASP value which is passed to the procedure for the purpose of completing a task. An optional parameter list is declared along with the function or subroutine by appending a comma-separated list of parameter names and enclosing this within parentheses.

 ' a subroutine to say hello
 Sub SayHello(sName)
 	Response.Write "Hello "
 	Response.Write sName
 	Response.Write ", Nice to Meet You!"
 End Sub

Above we have a very simple subroutine which takes a single argument. This argument is the name of the person you want to say hello to. When you invoke this subroutine with a call such as:

 <% SayHello("Bill Gates") %>

Your ASP page will output "Hello Bill Gates, Nice to Meet You!". In this case we pass a string literal as the argument to the subroutine. You may also pass an ASP variable or a complex expression.

 ' a subroutine to convert hours/minutes to seconds
 Function HoursToSeconds(nHours, nMinutes)
 	 HoursToSeconds = nHours * 3600 + nMinutes * 60
 End Function

Finally, this example shows how multiple parameters are declared for a function. These two values are used to compute the number of seconds from the hours and minutes. You can see that multiple parameters are separated by a comma. If you want to place a long list of parameters on multiple lines, you will have to use the "line continuation" operator which is the underscore character (_).

Passing by Reference edit

By default, all procedure parameters are passed by reference. This means that when you use a variable as your procedure argument, any changes to the parameter within the procedure, will be reflected in the original argument. If you want to explicitly declare your parameter as "by reference", you may use the ByRef keyword:

 ' explicitly pass by reference
 Sub HelloInformal(ByRef sFullName)
 	If InStr(1, sFullName, " ") > 0 Then
 		sFullName = Left(sFullName, InStr(1, sFullName, " ")-1)
 	End If
 	Response.Write "Hello "
 	Response.Write(sFullName)
 End Sub

You need to be careful when writing and invoking procedures like these. This procedure will actually modify the calling argument by removing everything except the first word in the argument.

Passing by reference is the default calling method. So even if the ByRef keyword is not present, the parameter is defined as "by reference" by default. It is important to remember this so that you don't fall into the trap mentioned above.

Passing by Value edit

The other way to pass values into your procedure is "by value". This means that a copy of the value is taken when the procedure is called. The parameter holds a copy of the value so that any modifications to this parameter will not affect any arguments that were used by the calling process.

Parameters which should be "passed by value" should be declared using the ByVal prefix. By default, all parameters are passed "by reference". If you need to pass a value "by value", you need to prefix the parameter declaration with ByVal.

 ' explicitly pass by value
 Sub HelloInformal(ByVal sFullName)
 	If InStr(1, sFullName, " ") > 0 Then
 		sFullName = Left(sFullName, InStr(1, sFullName, " ")-1)
 	End If
 	Response.Write "Hello "
 	Response.Write(sFullName)
 End Sub

When invoking this subroutine call, you will be guaranteed that the original argument will not be modified. You won't have that same guarantee with the previous declaration which declares the parameter ByRef.

You should only use ByVal when it is absolutely necessary. It is more efficient to pass parameters "by reference" than it is to pass them "by value". In typical use, most parameters are used as "read only", so you will probably only use the ByVal keyword occasionally.

Of course, you can mix the ByRef and ByVal prefixes together on a list of multiple parameters. Each parameter in your list can have one prefix modifying it (or none at all).

Calling Conventions edit

When invoking a subroutine or function, you need to be aware of the different calling conventions used for each. If you fail to follow these guidelines, you will receive a syntax error when loading the page in your browser.

Calling a function will always require you to enclose the arguments within parentheses. Unlike subroutines, a function can be used within expressions or as an argument to another function.

 ' call a function
 nSeconds = ToSeconds(2, 35)

 ' use a function call within an expression
 nSeconds = 3600 + ToSeconds(2, 35)

 ' use a function as an argument to another function
 sTime = MyFormatTime(ToSeconds(2, 35))

 ' ignore the return value for a function call
 ToSeconds(2, 35)

In the last example above, you will notice we call the function but ignore the return result. This is only useful when your function has some side effect on a global variable, or modifies a variable passed "by reference".

Calling subroutines, on the other hand, requires that you do not enclose the arguments within parentheses. The one exception to this rule is when you precede your function call with the Call keyword. The two different invocations are shown below

 ' call a subroutine (parentheses forbidden...)
 SayHello "Bill Gates"

 ' parentheses allowed for subroutine call using "Call"
 Call SayHello("Bill Gates")

Local Variables edit

Just as you can declare variables using the Dim statement in your web page, you can also declare variables for use within your procedures. These are typically referred to as "local variables" because they are only available "locally" within the procedure declaration. The variables declared outside of the procedures can be thought of as "global variables".

You declare local variables within a procedure block just as you would a regular variable:

 ' example of local variables as loop iterator
 Sub CountTo(nFinal)
 	Dim I

 	For I = 1 To nFinal
 		Response.Write "count = " & I & "&lt;br&gt;"
 	Next
 End Sub

The scope of the variable I is strictly within the procedure declaration. You won't be able to reference I outside of the procedure. It is created when the function is called and disappears when the function finishes.

Active Server Pages allows you to reference global variables within your procedures. Although this is not recommended because it makes your procedures less portable, there are some instances where this proves useful.

Variable Hiding edit

A variable may be declared "locally" and "globally" using the same name. This is perfectly legal in ASP. When you do this, the local variable will "hide" the global variable within the context of the procedure.

 ' I declared globally and locally
 Dim I
 I = 5
 Response.Write "I = " & I & "&lt;br&gt;"
 CountTo 10
 Response.Write "I = " & I & "&lt;br&gt;"

 Sub CountTo(nFinal)
 	Dim I
 
 	For I = 1 To nFinal
 		Response.Write "count = " & I & "&lt;br&gt;"
 	Next
 End Sub

In the example above, we have the variable I declared globally (actually the scope is the life of the web page) and locally. When you run this sample code, you will notice that the global variable I remains unchanged after the call to CountTo. This is because the local variable is completely separate from the global. Changes to the local variable have no effect on global I.

Because you declared a local variable with the same name as a global one, you effectively hide the reference to the global variable. Within the procedure CountTo, there is no way to reference the global I. While other languages provide a mechanism to access such variables, ASP does not. One way to get around this is to either: change the name of your local variable or pass the global variable as a parameter (using a different name).

Recursion edit

Recursion refers to the practice of having a function "call itself" in order to perform a repetitive task. Creating a recursive function is as simple as declaring a function that contains a call to itself.

 ' A simple bubble-sort routine
 Sub BubbleSort(arrList, nSpan)
 	Dim I, vTemp

 	If nSpan = 0 Then nSpan = UBound(arrList)
 	For I = 0 To UBound(arrList) - nSpan
 		If arrList(I) > arrList(I + nSpan) Then
 			vTemp = arrList(I + nSpan)
 			arrList(I + nSpan) = arrList(I)
 			arrList(I) = vTemp
 		End If
 	Next
 	If nSpan > 1 Then BubbleSort arrList, nSpan-1
 End Sub

As you can see on the last line of the subroutine, the bubble sort routine will call itself recursively as the span decreases by one each time. The function will stop calling itself once the span distance reaches one. The "depth" or "level of recursion" depends on the size of the array passed. If you have seven elements, the procedure will call itself 6 times.

Shown below is some ASP code which will test the bubble sort routine be creating an array of seven numbers and invoking the BubbleSort procedure:

 Response.Write "<p>"
 Dim arrTest, I
 arrTest = Array(8753, 5234, 434, 5234, 34, 1, 65, 123)
 For I = 0 To UBound(arrTest)
 	Response.Write "arr("&I&") = " & arrTest(I) & "<br>"
 Next
 	BubbleSort arrTest, 0
 Response.Write "</p>"
 
 Response.Write "<p>"
 For I = 0 To UBound(arrTest)
 	Response.Write "arr("&I&") = " & arrTest(I) & "<br>"
 Next
 Response.Write "</p>"

You should notice, that we first call the procedure with a span of zero. Code in the procedure will recognize this as a signal to initialize the span parameter with for sorting.

You should also be aware, that the bubble sort routine outlined above could easily be re-written to use no recursion at all. A good rule-of-thumb is: if the procedure is much easier to write and maintain using recursion then go ahead and do so.

Summary edit

Procedures allow you to create reusable code "macros" that perform a specific task. Functions are procedures which return a value, whereas subroutines do not. Procedures may be declared anywhere within a page and referenced from anywhere on your page. Output from a subroutine or function will be placed at the location where the sent to the location where the procedure is invoked.

Each procedure declaration may have an optional list of parameters. Parameters may be declared as being passed "by reference" or "by value". The default parameter passing convention is "by reference". Use ByVal or ByRef to explicitly declare your procedure parameters.

Review Questions edit

  • Procedures may be subroutines or functions.
  • Only functions may return a value to the caller.
  • Function declares a function, Sub declares a subroutine.
  • Procedures may be placed anywhere on the page from which they are called.
  • Commonly-used procedures may be placed in a Server-Side Include file.
  • An optional parameter list may be declared after the procedure name.
  • The parameter list must be enclosed in parentheses.
  • Multiple parameters are separated by a comma.
  • The default parameter passing convention is "by reference".
  • ASP variables passed "by reference" to a procedure may be modified.
  • The default parameter passing convention is "by reference".
  • When calling functions, enclose the arguments in parentheses
  • When calling subroutines, use no parentheses around the arguments
  • Functions may be used in expressions and as arguments to functions
  • Local variables may be declared inside of a procedure block.
  • Local variables hide references to global (page-scoped) ones.

Exercises edit

  • Write a function to compute the diameter of a circle (2 * pi * radius) with the single parameter being the radius.
  • Write a function to compute the area of a rectangle (length * width) having two parameters.
  • Write a subroutine to output a greeting such as: "Good Morning", "Good Afternoon" or "Good Evening" based on the time-of-day.
  • Re-write the bubble-sort procedure as a non-recursive function.
Previous: Conditionals and Looping Index Next: Database Access Using ADO


Database Access Using ADO

Previous: Functions and Subroutines Index Next: Server-Side Includes

Objectives edit

This describes database connectivity with ADO (ActiveX Data Objects) and how you can use this to communicate and manage a database server. You will learn how to open a connection to a database, run INSERT, UPDATE, DELETE, and SELECT statements as well as execute a stored procedure.

Content edit

Active Server Pages, being a scripted language, is a stateless language. By this, we mean that it doesn't preserve the state of the application between page loads. Nearly all ASP hosting solutions will include some sort of database hosting. Most common is MySQL, followed by Microsoft SQL Server. No matter what database you are using, ADO will allow you to manage the database through Active Server Pages.

While it's true that you can store persistant data in the Application object. This is basically just stored in a memory cache that will be flushed whenever IIS or the server is restarted. It also causes problems when trying to create an application which will be used in a server cluster (where each cluster has its own version of the Application cache.)

Connecting to a Database edit

Here is a sample showing how to open a connection to a database. To do this, we call the Server.CreateObject to create an instance of the built-in ADODB Connection object. Not only is this used to create the initial connection to the database, it will also be used to create the Recordset and Command Objects later.

You will need to replace the text mysqluser, mysqlpass, and mysqldbname with the correct values for your database. Note that this is accessing a MySQL server on the local server (localhost) using ODBC.

' create a connection object
Set oConnection = Server.CreateObject("ADODB.Connection")

' open a connection to a data source
oConnection.Open "Driver={MySQL ODBC 3.51 Driver};server=localhost;port=3306;uid=mysqluser;pwd=mysqlpass;database=mysqldbname;Option=16384"

Note that you could wrap this statement with an On Error block to trap any exceptions that may occur.

INSERT, UPDATE, and DELETE edit

The following will use the ADODB.Connection object to run an INSERT query on the database. The code is the same whether you are doing INSERT, UPDATE, or DELETE. You only need to change the sQuery variable with your modified query.

' build the query to run
sQuery ="INSERT INTO Company VALUES ("Microsoft")"

' execute the insert statement
oConnection.Execute sQuery, nRecordsAffected, adCmdText + adExecuteNoRecords

Response.Write "Records Affected: " & nRecordsAffected

The constants adCmdText and adExecuteNoRecords are described in the section ADO Constants.

SELECT edit

The following code can be used to run a SELECT statement against a database. You must first open a connection to a database using the code described in the section Connecting to a Database.

sQuery = "SELECT companyid, companyname FROM tblCompany"

' create the recordset object to hold the result sets
Set rs = Server.CreateObject("ADODB.Recordset")

' set the number of records to fetch into memory at once (performance)
rs.CacheSize = 256

' execute the query and populate the recordset 
rs.Open sQuery, oConnection, adOpenKeySet, adLockReadOnly, adCmdText

'More examples of SELECT (based on criteria) are:
'*example 1.
sQuery = "SELECT companyid, companyname FROM tblCompany WHERE companyid = 1" '1. See details below
  • 1. When sQuery in above code snippet is set as example 1. it will fetch records with companyid having value 1, in this SQL statement WHERE clause is used to define that criteria.

The constants adOpenKeySet, adLockReadOnly, and adCmdText are described in the section ADO Constants. Now that you have opened a recordset, what can you do with it?

Retrieving the Recordset edit

The following code will show you how to use the recordset object (rs) described in the SELECT section to retrieve values from your database query.

' EOF checks for the end of a recordset
If Not rs.EOF Then
	' The Fields collection accesses fields from a single record
	sFirstName = rs.Fields("firstname").Value
	
	' You can enumerate all fields in the record
	For Each oFld In rs.fields
		Response.Write "Field = " & oFld.Name & "<br>"
		Response.Write "Value = " & oFld.Value & "<br>"
	Next
End If
		
' You can also loop through all records
Do Until rs.EOF
	Response.Write "Name = " & rs.Fields("firstname").Value & "<br>"
	' make sure you don't forget this next step
	' MoveNext will move to the next record in the resultset
	rs.MoveNext
Loop

' following is always a good idea to clean up resources ASAP
rs.Close : rs = 0

Closing a Database Connection edit

You should always close your database connection when you are done accessing the database. It is not required, but it is always a good idea.

' it's a good idea to close your recordset first (if necessary)
rs.Close : rs = 0

' this will close the database connection 
oConnection.Close

ADO Constants edit

Variable Purpose
'adOpenKeySet Open a keyset
Const adOpenKeySet = 1
adLockReadOnly Create a database lock for read only access to a table. This is a forward-only cursor which provides the most efficient method for retrieving results.
Const adLockReadOnly = 1
adLockPessimistic This locking method will lock a database record as soon as edits have been made to the database. (Not really used in Active Server Pages)
Const adLockPessimistic = 2
adLockOptimistic Use optimistic record locking on the database records. Meaning a record will only be locked when records have been modified and edits are committed back to the database. (Not really used in Active Server Pages)
Const adLockOptimistic = 3
adCmdText Indicates the SQL command being passed is text (an SQL statement)
Const adCmdText = 1
adCmdTable Indicates the SQL command being passed is the name of a database table to open (all rows and fields)
Const adCmdTable = 2
adCmdStoredProc Indicates the SQL command being passed is the name of a stored procedure to execute. When using this call, the parameters must be defined separately.
Const adCmdStoredProc = 4
adCmdUnknown Indicates the SQL command being passed is unknown - the ADO library will do it's best to interpret what type of command was intended.
Const adCmdUnknown = 8
adStateOpen Indicates the current state of the result set. This indicates the recordset is open and data retrieval operations can be performed.
Const adStateOpen = 1
adStateClosed Indicates the current state of the result set. This indicates the recordset is closed and data retrieval are forbidden.
Const adStateClosed = 0
adExecuteNoRecords Indicate that no recordset is returned. SQL command is stored procedure call, INSERT, UPDATE, or DELETE statement.
Const adExecuteNoRecords = 128
adParamInput Stored procedure parameter is an input (this is the default) meaning we are just passing data into the procedure.
Const adParamInput = 1
adParamOutput Stored procedure parameter is an output meaning that data will be returned by the procedure.
Const adParamOutput = 2
adParamInputOutput Stored procedure parameter is both an input and an output. Data is passed into the procedure and then returned after execution is complete.
Const adParamInputOutput = 3
adParamReturnValue Indicates that the variable holds the return value from a procedure
Const adParamReturnValue = 4
adVarChar Variable character (string) SQL data type
Const adVarChar = 200
adChar Fixed length character SQL data type
Const adChar = 129
adInteger Integer SQL data type
Const adInteger = 3
adCurrency Currency SQL data type
Const adCurrency = 6

Summary edit

Using ADODB is the ideal way to connect to a database through Active Server Pages. ADODB utilizes ODBC or OLE DB technologies to connect to a database depending on the connection string you use when using the ADODB.Connection::Open method. The most efficient method of access is OLE DB.

You may choose to create a database library code to simplify the task of working with a database. You can create a database class which manages all the tasks of communicating with a database. Combine this with database configuration settings stored in a global.asa file, and you will have a quick yet powerful way of executing database queries.

Make sure to make use of the ADO Constants to make the most efficient use of the ADO methods and your database server. The examples above should give you everything you need to work with a database.

Review Questions edit

  • What does ADO stand for?
  • Which object is used to connect to a database?
  • What method do you use to connect to a database?
  • Which object do you need to retrieve results from SELECT?
  • How do you retrieve the value of a field from the current record?
  • How do you enumerate all fields from a record
  • How do you close a connection to a database

Exercises edit

  • Write the code to run an INSERT, UPDATE, or DELETE query
  • Write the code to execute a stored procedure?
  • Write the code to execute a SELECT statement and read its results
Previous: Functions and Subroutines Index Next: Server-Side Includes


Server-Side Includes

Previous: Database Access Using ADO Index Next: Appendix A: Language_Reference

Objectives edit

In this chapter we will discuss the use of server-side includes (SSI) to simplify the process of building and maintaining a website. For maximum flexibility, I use SSI for both site templates and common code modules (libraries).

Content edit

Server-side includes have been around long before Active Server Pages was ever conceived. Basically, it was designed as a web server extension that looked for special macros contained inside of HTML comments. Nearly all webservers support at least some subset of server-side includes. The most useful of these macros is the "server-side include".

So when a web page is accessed, the web server would first scan the source file (or resource) that the visitor requested. If no processing macros were found, then this file is simply delivered to the user without modification. When a macro is found, the web server will do the appropriate processing of the macro (completely replacing the HTML comment with the appropriate results). All of this is done before the content gets delivered to the user (or the remote host).

What it Does edit

The specific processing directive we are interested in here is the server-side include. This allows you to import the contents of another document into the current one. This is extremely useful for reusing common blocks of ASP code and HTML. One of the most common uses of this is for creating a website template.

Another popular use is for creating code libraries that can be included in the web pages where you need them. I typically create a generic site-wide library that all pages must include, a header and footer template, a database library, an e-mail library and a form processing library. By reusing common code, you can eliminate the errors that may occur when you copy code from one page to another.

There are two different types of server-side includes we will discuss here: "virtual includes" and "file includes". The only difference is in the way that they access the directory structure for the website.

Virtual Includes edit

A virtual include will import the contents of another file based on the document root of the webserver. The path to the file should begin with a slash (/) which represents the root of the website (not the root of the filesystem).

Internet Information Server (the default webserver for Microsoft Windows) may be configured so that you cannot use a File Include to import the contents of a file from a parent directory. In this case, you will need to use the Virtual Include to accomplish this task.

Shown below is an example of two virtual includes used to pull in a header and footer template into the current page. Contained within an HTML comment (delimitted by <!-- and -->), you will see the processing directive (#include virtual). The path and filename inside the quotes is the resource we want to bring into the current document.

<!-- #include virtual="/lib/header.asp" -->

<h1>Hello World</h1>

<!-- #include virtual="/lib/footer.asp" -->

It is important to note that you can import many different types of files into the current document. You should realize that the webserver simply replaces the contents of the included file directly into your HTML document. Also, you cannot embed any preprocessing macros inside an ASP code block (delimitted by <% and %>).

The include process works recursively, so that if you include one file that //also contains// server-side include directives, then those will be included recursively so that all macros are processed.

File Includes edit

Another type of include statement is #include file. This statement works just like the virtual include except that the path to the file must be relative to the directory where the current page resides. In other words, you cannot access the directory structure starting from the document root (meaning the root of the website.)

Below is the same example as before with the virtual includes replaced with file includes. When running this script under IIS, you may get an error when trying to access a parent directory in this manner. For this reason, I prefer to use virtual includes whenever possible.

<!-- #include file="../lib/header.asp" -->

<h1>Hello World</h1>

<!-- #include file="../lib/footer.asp" -->

Alternatives to Server-Side Includes edit

Active Server Pages contains a couple of statements that work similar to server-side includes. These are also useful for the same purposes as server-side includes. However, none is a substitute for the other. They all have their different purposes and you should know when to use each.

Server.Execute edit

This will execute another Active Server Page file from the website. You can do this conditionally using the If Then ... End If syntax. This is different from the server-side include statement which will be executed wherever it appears.

Another difference between this statement and a server-side include is that all variables, functions and classes defined in the calling script will not be accessible in the executed script. This is a huge barrier to using this as an include and it is the main reason why I prefer server-side include to this statement.

If Application("ShowForum") Then
	Server.Execute("/module/forum.asp")
End If

I have used this to build a modular web portal application with good success. Through a control panel, the user can configure which modules they would like to display on their website. The template engine checks this configuration and pulls in only the modules that we need to display and arranges the layout accordingly.

Server.Transfer edit

The Server.Transfer statement is similar to Execute in that it executes an external ASP file on the webserver. However, unlike Execute, this function does not return control to the calling script. Instead, control is transferred to the script and, when the script finishes execution, the processing of the request terminates.

This is useful for use as a redirect. Basically, you test for certain conditions in your script and transfer control to another script based on which condition is met. So maybe you could have a login page that contains a form which posts to itself. If the user login is authenticated, you can transfer processing to a member control panel.

If bIsLoggedIn Then
	Server.Transfer("/account/index.asp")
End If

You should note that if any HTML is output to the browser before the Server.Transfer statement is reached, the output of the new ASP file will be appended to the HTML that has already been output. While you could do a standard redirect using the ASP built-in statement Response.Redirect, that would discard any HTML that has already been output and rebuild the response from the beginning.

Summary edit

Server-side includes provide a powerful mechanism to reuse code in Active Server Pages. You can use it to create a website template, code libraries, and HTML modules which may be reused throughout your site.

The two types of include statements are the virtual include and the file include. Use the virtual include to include ASP or HTML files using a path specifier that begins with a slash (/) denoting the document root of your website. The file include includes the content of a file with a path specifier that is relative to the directory of the calling script. The contents of the external file will be imported into the original document before any ASP code is processed.

Alternatives to server-side include the Server.Execute statement which executes the external file as a stand-alone script and then combines this output with the output of the calling script. The other is the Server.Transfer statement which passes control over to the external script permanently (control never returns).

Review Questions edit

  • What does a server-side include do?
  • What are the two types of server-side includes?
  • What happens if you include a file which contains server-side includes?
  • What are some alternatives to the server-side include?
  • Explain how these alternatives work to execute external ASP code

Exercises edit

  • Create the include files (header and footer) for a real simple HTML template
  • Write a virtual server-side include to import the HTML template files.
  • Write some ASP code to call Server.Execute to display a weather module
  • Write some ASP code to call Server.Transfer to log off a user from a member area.
Previous: Database Access Using ADO Index Next: Appendix A: Language_Reference


Debugging

Dumping a variable edit

Variables are easily dumped in asp using the following idiom:

Response.write Var
Response.end


Appendix A: Language Reference

Previous: Server-Side Includes Index  

Objectives edit

A reference for all of the keywords and statements used in Active Server Pages. Items are grouped by function and contain a short description and example of their usage.

Content edit

This contains a quick reference of all of the language elements in Active Server Pages.

Array Functions edit

Statement Purpose
Array This function creates an instance of an array. The arguments to this function are the elements you want to see the array with. It is possible to have no arguments at all.
aOption = Array("yes", "no", "unknown")
Erase Subroutine which clears all of the elements of the array. If the elements are numeric values, then they will all be set to zero. If the elements are strings then they will all be made empty.
Erase(aYear)
Filter Selectively include or exclude elements from an array. The optional third argument is a boolean which indicates whether items are included.
Filter(aArray, "remove", False)
Join Build a string by joining all of the elements in the array. A "glue string" is inserted between each element.
sCSV = Join(aArray, ",")
LBound Return the lower bound of an array meaning the smallest possible array index that may be used for the array. All arrays in ASP start with the index 0, so you shouldn't need to use this.
nStart = LBound(aArray)
ReDim Use this to re-dimension (or resize an array) after it has already been declared. If the Preserve keyword is used, existing elements will not be destroyed in the process.
ReDim Preserve aField(nCount + 10)
Split Takes a string argument and creates an array by "splitting" the string into multiple elements. Strings are split based on a "delimitter" which is passed as the second argument.
aName = Split("joe,bill,john", ",")
UBound Return the upper bound of the array meaning the last possible array index. This is often used to get the size of an array (which in turn can be used in For...Next loops to iterate over the elements)
nLast = UBound(aArray)

Variable and Procedure Declarations edit

Statement Purpose
Const Used to declare a constant value (a value that will never change over the course of the program)
Const PI = 3.1415926
Dim Used to declare a variable in your program. Variables can be declared as "global" meaning available to the entire script or as local variables (inside a procedure)
Dim I, J, K
Function Used to declare a function in your script. A function is a procedure that should return a value but this is not enforced in Active Server Pages.
 Function YearsOld(dBirthDate)
 	YearsOld = DateDiff("y", dBirthDate, Now())
 End Function
Sub Used to declare a subroutine in your script. A subroutine cannot return a value to the caller. You don't have to declare a function or subroutine before calling it.
 Sub HelloWorld(sName)
 	Response.Write "Hello " & sName
 End Sub

Control Flow Statements edit

Statement Purpose
Call Invoke a procedure (either a subroutine or a function). If used to invoke a function, the return value cannot be assigned (leave the Call keyword off if you want to do something with the return value)
 Call SayHello("Bill Gates")
 ' alternative way to call a subroutine (notice no parentheses necessary)
 SayHello "Bill Gates"
Eval Evaluate Active Server Pages code that is built dynamically. In other words, if you build a string (at runtime) containing ASP code, you can execute that code using Eval.
fArea = Eval("3.14159 * fRadius * fRadius")
Execute Execute an ASP script programatically. Allows you to execute an ASP page during runtime. Most normal methods of doing this (like using a server-side include) will process the script regardless of whether it is used or not. With Execute, you can conditionally process ASP scripts.
 if (nThemeNo = 1) then
   Execute("/theme/fantasy/header.asp")
 Else
   Execute("/theme/modern/header.asp")
 End If
Exit Used to break execution out of a function, subroutine, or many of the looping constructs.
 Exit Function
 Exit Sub
 Exit For
 Exit Do
 Exit While
Select Case This allows you to create a multi-branched conditional construct similar to a sequence of If Then ... Else If ... Else If ... Else ... End If.
 Select Case nDayOfWeek
   Case vbSunday : Response.Write "Day of Rest"
   Case vbSaturday : Response.Write "Shopping Day"
   Case vbMonday : 
   Case vbThursday : Response.Write "Dance Class"
   Case Else : Response.Write "Work is Fun!"
 End Select

Loop Statements edit

Statement Purpose
Do Loop There are two different variations of the do loop. Do While repeats a block of statements while a condition is true and Do Until repeats while a condition is false. You can exit out of a Do ... Loop statement by using the Exit Do statement.
Do While I < 0
  I = I + 1
Loop
Do Until rs.EOF
  rs.MoveNext
Loop
For Each When working with a collection, you can use this function to iterate over each item.
For Each sKey In oHash.Keys
Next
For Next Iterate over a sequence of numbers with a known start and end value and an optional increment value. You can force execution to break out of a For ... Next loop by using the Exit For statement.
For I = 1 To 10
  Response.Write " I = " & I
Next
For I = 10 To 1 Step -1
  Response.Write " I = " & I
Next
While Loop Repeat a block of statements while a condition is true. You can force execution to break out of a While loop by using the Exit While statement.
While I < 10
  Response.Write "I = " & I & "&lt;br&gt;"
  I = I + 1
  If I = 6 Then Exit While
Wend

Math Functions edit

Statement Purpose
Abs Calculate the absolute value of an expression (makes a negative result into a positive one)
x = Abs(y)
Atn Trigonometry function to calculate the arc-tangent of a value
x = Atn(y)
Cos Trigonometry function to calculate the cosine of a value
x = Cos(y)
Exp Calculates the value of the expression e ^ y where e is a constant representing the base of the natural logarithm (otherwise known as napier's constant).
x = Exp(y)
Fix Converts a number to an integer. Negative numbers are rounded up (instead of down which is how Int works). So a number like -5.99235 would result in a value of -5.
x = Fix(-5.66663)
Int Converts a numeric value into an integer value. It effectively does the same thing as the "Floor" function in that it truncates any fractional part of the number (not performing any rounding).
x = Int(y)
Log Calculate the natural logarithm of a number. This is often expressed in mathematics as ln(y)
x = Log(y)
Mod Calculate the modulus (or remainder) between two numbers. This is a boolean operator just like + or /. The result of 10 Mod 3 is 1, because 3 goes into 10 at most 3 times with 1 left over (3 * 3 = 9 and 10 - 9 = 1)
nRem = 10 Mod 3
Randomize Seed the random number generator. Doesn't return a value but prepares the script to produce truly random numbers via the Rnd function.
Randomize
Rnd A function which returns a random number that is greater than or equal to zero and less than 1. You shoud always call Randomize before calling this function.
x = Int(Rnd() * 100)
Round A function which rounds a number to the closest integer. So if the fractional part of the number is < 0.5, the number will be rounded down, otherwise the number will be rounded up.
x = Round(3.5)
Sgn Performs the sign function which returns only three possible values. -1 if the argument is a negative number, 1 if the number is positive, or 0 if the argument is exactly zero.
x = Sgn(-245.444)
Sin Trigonetry function which returns the sine function. The argument is the angle of degrees in radians.
x = Sin(90)
Sqr Calculates the square root of a number. The argument must be a positive number greater than or equal to zero.
x = Sqr(16)
Tan Trigonometry function to calculate the tangent of a value. The argument is the angle of degrees in radians.
x = Tan(1.331)

String Functions edit

Statement Purpose
Asc Return the ASCII code for a character (the first character of a string since there is no character subtype in ASP)
nAsciiH = Asc("Hello")
AscB Returns the first byte of a sequence of binary data. Binary data is typically used when manipulating files.
nByte = AscB(sInput)
AscW Returns the 32-bit wide (unicode) character code for the first character in a string
nAsciiH = AscW("Hello")
Chr Builds a single string (character) based on the ASCII code argument. This is how you can build a string containing non-printable characters. ASP contains many built-in constants which also serve this purpose (such as vbCr, vbLf and even vbCrLf).
sStr = "Hello World!" & Chr(13) & Chr(10)
FormatCurrency Formats a numeric value as currency according to the locale settings. The optional second argument indicates the number of places after the decimal point. In the United States, the default is two.
 sGasPrice = FormatCurrency(3.00)
 sNatlDebt = FormatCurrency(9065368997351, 0)
FormatNumber Formats a numeric value according the locale settings for the server. It may insert digit separator (like the comma in 3,932) or pad the number with zeros. An optional second argument indicates the number of digits to show after the decimal point.
 sPopulation = FormatNumber(9065368997351)
 sPI = FormatNumber(3.1415926, 4)
FormatPercent Format a number as a percentage value. Actually it converts a probability number from 0 to 1 into a percentage between 0% and 100%. An optional second argument indicates the number of digits shown after the decimal point.
 nPct = FormatPercent(0.5442)
 nPct2 = FormatPercent(0.5442542, 3)
InStr Find the first occurrence of one string within another. By default the search will do a case sensitive comparison. The first argument is the character index to start the search from. The second argument is the text to be searched (haystack) and the third argument is what you are looking for (the needle). The optional fourth argument allows you to specify the comparison type (like vbTextCompare or vbBinaryCompare)
nBeginPos = InStr(1, sText, "Begin", vbTextCompare)
InStrRev Find the first occurrence of one string within another starting from the end of the string and searching to the left. Unlike InStr, the optional position to start the search from is the third argument (instead of the first). The optional fourth argument allows you to specify the comparison type (like vbTextCompare or vbBinaryCompare)
 nScriptPos = InStrRev(sURL, "/")
 nProtocolPos = InStrRev(sURL, "http://", 100, vbTextCompare)
LCase Convert all alphabetic characters in a string to lowercase.
sUsername = LCase("WaCkYcAsEuSeR")
Left Return a substring starting from the left side (first character) of the base string.
sFirst = Left(sFullName, 10)
Len Given a string as the argument, returns the length of the string in characters.
nLen = Len("ASP")
LTrim Trim any whitespace that exists on the left side of the string. So if you give the function an argument of " Hi! ", it would return the value "Hi! ".
sFirst = LTrim("   Will")
Mid Get a subtring from a string. The first argument is the base string to extract the substring from. The second argument indicates the character index to start from. The last argument indicates the number of characters to extract. You may omit the last argument to retrieve all characters up to the end of the string.
 sMiddle = Mid(sFullname, nMidStart, nMidEnd - nMidStart + 1)
 sLast = Mid(sFullName, nLastStart)
Replace Replace all occurrences of the search string (argument 2) with the replacement string (argument 3) in the base string (argument 1) and return it.
sEscape = Replace(sSQL, "'", "''")
Right Return a substring starting from the right side (last character) of the base string.
sLast = Right(sFullName, 13)
RTrim Trim any whitespace that exists on the right side of the string. So if you give the function an argument of " Hi! ", it would return the value " Hi!".
sClean = RTrim("  Hi!  ")
Space Build a string with a repeated number of spaces. When displayed as HTML, the browser will compress all whitespace unless the text is preformatted (in a <PRE>...</PRE> block) or the content is delivered in plain text.
Response.Write Space(30 - Len(sFirst)) & sFirst
StrComp Compare two strings to see if they are equal or not. You may perform a binary (case sensitive) comparison (the default) or you can do a textual (case insensitive) comparison by passing the optional third parameter as vbTextCompare
if (StrComp(sFirst1, sFirst2, vbTextCompare)) Then Response.Write "EQUAL!"
String Creates a string by repeating a specified character a certain number of times. The first argument is the number of repetitions and the second argument is the string (character) to repeat.
 sLine = String(80, "-")
 sDblLine = String(80, "=")
StrReverse Take a string and reverse the order of the characters. In other words, given a string like "012345789", this function would return "9876543210".
sReverse = StrReverse("0123456789")
Trim Trim any whitespace that exists on either the right or left side of the string. So if you give the function an argument of " Hi! ", it would return the value "Hi!".
sClean = Trim("  Hi!  ")
UCase Convert all alphabetic characters in a string to uppercase.
sUsername = UCase("WaCkYcAsEuSeR")

Logic Statements edit

Statement Purpose
And Logical "AND" operations. Result is true only if both of the expressions evaluate to true, otherwise the result is False
If nScore > 80 And nScore < 90 Then sGrade = "B"
Eqv Test a pair of boolean expressions and return true only when both of the expressions evaluate with the same result (both are true or both are false).
If nScore > 60 Eqv False Then
If Then This evaluates an expression (resulting in a boolean true or false) and conditionally executes ASP code based on the resulting
 ' example of a single-line If...Then
 If nScore < 60 Then sGrade = "F"

 ' example of a multi-line If.. Then
 If nScore < 60 Then
   Response.Write "Sorry, You Failed"
 Else
   Response.Write "Congratulations, You Passed"
 End If
Imp The "implication" operator is used to determine whether A implies B. The result is always true unless A is true and B is false.
If bCondA Imp bCondB Then Response.Write "It Implies"
Is Use the is operator on variables containing objects to test if one object is the same as another (refers to the same instance). You can also use is to see if an object variable is set to nothing.
If oFile is nothing Then Response.Write "Nothing"
IsArray This function determines if a variable contains an array. Returns true to indicate it does, or false meaning it does not.
If IsArray(aVar) Then nCount = UBound(aVar) + 1
IsDate Test to see if the expression contains a valid date (either as a string which may be converted to a date using CDate or as date subtype)
If IsDate(dBirth) Then sBirthDay = FormatDateTime(dBirth)
IsEmpty Check to see if a variable (or an expression) contains an empty value. An empty value is the default value for variables which have been declared but never assigned.
If IsEmpty(sVar) Then Response.Write "You forgot to define the variable ""sVar"""
IsNull Check to see if a variable or an expression evaluates to null. This is particularly useful for database values retrievied using the ADODB component.
If IsNull(rs.Fields("lastname").value) Then bError = True
IsNumeric Check to see if a variable or expression contains a numeric value or can be converted to a numeric value using CLng, CInt, CFlt, or CDbl.
If IsNumeric(sAmount) Then nAmount = CInt(sAmount)
IsObject Test to see if a variable or expression refers to a valid object. An object can be created by calling the Server.CreatObject method.
If IsObject(oFile) Then oFile.Close
Not Perform a negation operation on a boolean expression. Gives you the opposite of either true or false.
bSad = Not bHappy
Or Boolean "or" operation takes two arguments which must be boolean expressions. Returns true if either expression evaluates to true, otherwise returns false.
 If bLovesSchool Or bLovesBoooks Then bIsSmart = true
 bIsSmart = (bLovesSchool Or bLovesBoooks)
Xor The exclusive or operator only returns true when exactly one of the boolean expression arguments is true. Returns false when both arguments are false OR both arguments are true.
 If (bLikesYankees Xor bLikesMets) Then bIsRealPerson = true
 bGiveCake = (bJoeWantsCake Xor bJuneWantsCake)

Date and Time Functions edit

Statement Purpose
Date Return the date according the local system clock. Does not return any time information, just the date.
dToday = Date()
DateAdd Add a specific number of time units to the supplied date.
dTomorrow = DateAdd("d", 1, Now())
DateDiff Calculate the number of time units between two date arguments.
Response.Write "Hours = " & DateDiff("h", dTomorrow, Now())
DatePart Extract a specific part of the datetime expression and return it. First argument may be "d" (day), "m" (month), "yyyy" (year), "q" (quarter), "w" (weekday), "ww" (week of year), "h" (hour), "n" (minute), or "s" (second).
nDay = DatePart("d", Now())
DateSerial Construct a date value from its individual components. The components are year (argument 1), month (argument 2) and day (argument 3).
dChristmas = DateSerial(2008, 12, 25)
DateValue Attempt to convert a string containing a date value into a variable with subtype date. If the date is not formatted properly, the script will fail with an error.
dChristmas = DateValue("12/25/2008")
Day Extract the day portion of a date expression. Shortcut for DatePart("d", dDate).
Response.Write "Christmas is on day " & Day(dChristmas)
FormatDateTime Format a datetime expression into human readable format. Format specifier (argument 2) may be one of: vbGeneralDate, vbLongDate, vbShortDate, vbLongTime, or vbShortTime.
sModified = FormatDateTime(dModified, vbGeneralDate)
Hour Extract the hour portion of a date expression. Shortcut for DatePart("h", dDate).
nHour = Hour(dChristmas)
Minute Extract the minute portion of a date expression. Shortcut for DatePart("n", dDate).
nMinute = Minute(dDate)
Month Extract the month portion of a date expression. Shortcut for DatePart("m", dDate).
nMonth = Month(dDate)
MonthName Returns the name of a month corresponding to a month number (1 to 12). The second argument is an optional boolean indicating whether the month name should be abbreviated (true) or not (false).
 sMonth = MonthName(Month(dDate))
 sMonth2 = MonthName(DateValue("12/25/2008"), true)
Now Returns a datetime value which corresponds to the current server time.
Response.Write "Today is: " & Now()
Second Extract the second portion of a date expression. Shortcut for DatePart("s", dDate).
nSecond = Second(Now())
Time Returns a time value using the current server time. The date is not included in this value (for that you should use Now).
Response.Write "Time Right Now: " & Time()
Timer Returns a floating point value with the integer portion indicating whole seconds (since Jan 1, 1970) and the fractional part indicating milliseconds.
 fStart = Timer()
 ' do some work here
 fEnd = Timer()
 fElapsed = fEnd - fStart
TimeSerial Construct a variable with a subtype of time using the supplied arguments. Arguments are: hour, minute, and second.
dTime = TimeSerial(23, 59, 0)
TimeValue Attempt to convert a string (representing a valid time value) into a variable with subtype time. Throws an exception of the string is not properly formatted (and unable to convert).
dTime = TimeValue("23:59:00")
Weekday Extract the day of the week (as an integer) for a datetime expression. The first day of the week is Sunday which is returned as 1. The last day of the week is Saturday which is returned as 7.
nWeekday = Weekday(DateValue("12/25/2008"))
WeekdayName Extracts the day of the week (as a string) for a datetime expression.
sWeekday = WeekdayName(DateValue("12/25/2008"))
Year Extract the year portion of a date or datetime expression. This is a shortcut for DatePart("yyyy", dDate).
nYear = Year(dChristmas)

Data Type Conversions edit

Every variable in ASP is a variant (meaning the language is not strongly typed), so when we talk about type conversions, we're talking about the subtype of a variant value.

Statement Purpose
CBool Convert a variable into a boolean type (which can only hold true or false)
bDone = CBool("true")
CByte Convert a variable into a byte type (integer from 0 to 255)
bByte = CByte("127")
CCur Convert a variable into a currency type. This is just like a decimal number in that extra care is taken to ensure that nothing is lost in rounding).
fMoney = CCur(Request.Form("LoanAmount"))
CDate Convert a variable into a datetime value. The expression may be a date, a time, or a datetime expression.
dBirthday = CDate(Request.Form("BirthDay"))
CDbl Convert a variable into a double type which is a double precision floating point number.
dVal = CDbl("23.3452e+04")
CInt Convert a variable into an integer type. An integer is a 2-byte signed value that is restricted to values between -32,768 to 32,767. Note that CInt() performs "Banker's Rounding"—it does not truncate the fractional portion. Use Int() to truncate variables to integers.
nIntVal = CInt(Request.Form("SATScore"))
CLng Convert a variable into a long integer type. A long integer is a 4-byte signed value that is restricted to values between -2,147,483,648 to 2,147,483,647. Note that CLng() performs "Banker's Rounding"—it does not truncate the fractional portion.
nLngVal = CLng(Request.Form("SerialNo"))
CSng Convert a variable into a floating point number (basically a float) which is also known as a single precision floating point number. Positive numbers are restricted to values between 1.401298E-45 to 3.402823E+38 and negative numbers are restricted to values between -3.402823E+38 to -1.401298E-45.
fTemp = CSng(Request.Form("Temperature")
CStr Convert a variable into a string value. This is often necessary when comparing two values where one is a different type.
if (CStr(nAge) = Request.Form("Age")) Then Response.Write "You're " & nAge
Hex Convert an integer number to hexadecimal equivalent. Hexadecimal is a "base 16" number with digits ranging from 0 to 9 and A to F. Hexagonal numbers are restricted to four-byte values so that converting a value of -1 results in the value FFFF.
sEnc = Hex(Asc("%"))
Oct Convert an integer number to its octal equivalent. An octal number is a "base 8" number meaning the digits range from 0 to 7.
sOct = Oct(123)

Object-Oriented Programming edit

Statement Purpose
Class Declare a new instance of a class by enclosing it between Class ... End Class. Contained inside the class may be member variable definitions, method definitions, and property definitions.
 Class Month
  Private String sName
  Private String nDays
 	
  ' constructor
  Sub Class_Initialize()
    sName = "Unknown"
  End Sub
  
  ' Abbreviation method
   Public Function Abbreviation
     Abbreviation = Left(sName, 3)
   End Function
  
   ' retrieve the number of days
   Property Get Days
     Days = nDays
   End Property
  
   ' assign the name for this month
   Property Let Name
     sName = Name
   End Property
 End Class
New Use this statement to declare a new instance of a class. The built-in class RegExp may be used to declare an instance of a regular expression object. You must use the Set statement when instantiating a new object.
 Set oRE = New RegExp
 oRE.Pattern = "\w+"
Private This is an access modifier which may appear before a member variable, method, or properety. Any entity marked private may only be accessed within the class definition itself.
Private String sName
Public This access modifer makes an entity public. So a public variable can be accessed using the "dot notation" from the instance of a class. Likewise for methods and properties. Note that Public is the default access modifier and you don't have to include an access modifier on all entities.
Public Function Abbreviation
Property Get The Property Get statement allows you to declare a read-only property to your class. This is similar to a function in that it returns a value. If you try to do assignment using this property (oMonth.Days = 31), the parser will throw an exception.
Property Get Days
Property Let Use this property definition to define an assignor method. This allows you to assign a value to a class property. How the assignor method is implemented is up to you, but it usually modifies one of the member variables.
Property Let Name
Property Set If you need to define a property which assigns the value of an object, you should define a Property Set method. To define a property which retrieves an object value, you can simply use Property Get.
 Property Set RegularExp
 
 Set oRE = New RegExp
 Set oMonth.RegularExp = oRE
Set Assign an instance of an object to a variable.
Set oRE = New RegExp
TypeName Use this function to retrieve the type of an object as a string. When used with a regular variable, it returns the subtype ("Date", "Double", "Integer", "String", "Boolean", etc.)
 ' another built-in object - Dictionary COM+ object
 Set oHash = Server.CreateObject("Scripting.Dictionary")
 ' this will return the string "Dictionary"
 Response.Write "Hash Type = " & TypeName(oHash)
With The With statement will save you some typing and allow you to access one instance of an object repeatedly by using a notation like .Write for the Response object. So instead of repeatedly typing Response.Write, you could do:
 With Response
   .Write x
   .Write " x "
   .Write y
   .Write " = "
   .Write z
 End With

Comments edit

Statement Purpose
' A line comment which commenting out all text up to the end of the line (or the end of the script block whichever comes first)
' This procedure does something
Rem Old style of making comments in visual basic. I believe this is only part of the language for backwards compatibility. It does the same thing as a single quote (') meaning that it does a line comment (commenting out all text up to the end of the line)
Rem This procedure does something

Error Handling edit

Statement Purpose
On Error The On Error statement is used to trap errors thus preventing the throwing of an exception. On Error must be terminated with an On Error Goto 0 to stop error trapping.
' trap all division error (overflow or divide-by-zero)
On Error Resume Next
f = x / y
If Err.Number <> 0 Then
   sError = Err.Number & " - " & Err.Description
End If
On Error Goto 0

Built-in Literals edit

Statement Purpose
Empty The default value of a variable before it has been assigned a value. You never explicitly assign this value to a variable but you can test for its existence using IsEmpty
IsEmpty(sFullname)
False Boolean value with a negative connotation. Similar to "No".
bIsCool = false
Nothing A special value that an object variable can be set to. Used to clear an object variable.
Set oFile = nothing
Null A null value is used to indicate that a variable holds no valid data. Primarily used when accessing the value of database fields.
If IsNull(rs.Fields("firstname").Value) Then ...
True Boolean value with a positive (or affirmative) connotation. Similar to "Yes".
bIsFun = true
Previous: Server-Side Includes Index  


Protecting against user-input (XSS attacks)

To protect your users from Cross-site scripting (XSS) and similar attacks, you should escape both URLs and user-submitted text. In ASP this is done with two functions Server.HTMLEncode, and Server.URLEncode.

Server.HTMLEncode edit

Don't ever output non-escaped user data:

Response.write user_data 'not safe

Instead do the following:

Response.write Server.HTMLEncode( user_data )

This method should also be used for all data that comes from SQL. Better safe than sorry.

Server.URLEncode edit

To encode URLs that you insert into the href attribute of A tags, use the Server.URLEncode function, like this:

<a href="http://foobar.com?<%= Server.URLEncode( "foo=bar" + "&baz=quz" ) %>">