M0194 Web-based Programming Lanjut Session 7 

advertisement
M0194
Web-based Programming Lanjut
Session 7
 2004 Tau Yenny, SI - Binus
2
Connection, Command dan Procedure





The Connection Object
The Command Object
Stored Procedure
Optimization
Data Shaping
 2004 Tau Yenny, SI - Binus
3
The Connection Object

Connection object


Gives us connection to the data store
Run the commands



action queries (updates, inserts, deletes)
return a recordset
Returning a Recordset
To return a recordset use the ‘Execute’ method
The syntax is:
Connection.Execute CommandText, [RecordsAffected], [Options]
 2004 Tau Yenny, SI - Binus
4
The Connection Object
Argument
Description
CommandText
The text of the command to execute. This is the same as the ‘Source’ of
the Recordset ‘Open’ method, and can also represent an existing
Command object.
RecordsAffected
A variable into which is placed the number of records affected by the
command.
Options
The command options, which can be one or more of the values from the
CommandTypeEnum or ExecuteOptionEnum constants, as detailed in
session 6.
Set conPubs = Server.CreateObject(“ADODB.Connection”)
conPubs.Open strConn
Set rsAuthors = conPubs.Execute (“Authors”)
The difference between Execute and Open method:
•
Open method have the ability to change the cursor type and lock type
•
Execute method always get a forward-only cursor and read-only recordset.
 2004 Tau Yenny, SI - Binus
5
The Connection Object

Action Commands
You can use the RecordsAffected argument to find out how many records
were affected by the command.
Dim strSQL as String
Dim lngRecs as Long
strSQL = “UPDATE Titles SET Price = Price * 1.10 WHERE Type=‘Business’”
conPubs.Execute strSQL, lngRecs, adCmdText
Response.Write lngRecs & “ records were updated.”

No Recordset Returned
If no recordset is being returned, then it’s also best to add another option to
the Execute statement :
conPubs.Execute strSQL, lngRecs, adCmdText + adExecuteNoRecords
 2004 Tau Yenny, SI - Binus
6
The Command Object

Command Object




Deal with commands of any sort, especially that require
parameters.
Can run both commands that return recordsets and not return
recordsets.
If your command doesn’t have parameters, then it doesn’t matter
whether you use a Connection, a Command, or a Recordset.
Returning Recordsets

use the Execute method and the CommandText property.
Set cmdAuthors = Server.CreateObject(“ADODB.Command”)
cmdAuthors.CommandText = “Authors”
Set rsAuthors = cmdAuthors.Execute
 2004 Tau Yenny, SI - Binus
7
The Command Object
The Execute method also has some optional arguments:
Argument
Description
RecordsAffected
A variable into which is placed the number of records affected by the
command.
Parameters
An array of parameter values.
Options
The command options. This is similar to the ‘Options’ of the Recordset
‘Open’ method.
Set cmdAuthors = Server.CreateObject(“ADODB.Command”)
cmdAuthors.CommandText = “Authors”
cmdAuthors.CommandType = adCmdTable
Set rsAuthors = cmdAuthors.Execute
Or
Set rsAuthors = cmdAuthors.Execute (, , adCmdTable)
 2004 Tau Yenny, SI - Binus
8
The Command Object

Changing the Cursor Type
If require a different cursor or lock type, use the Open method.
cmdAuthors.ActiveConnection = strConn
cmdAuthors.CommandText = “Authors”
cmdAuthors.CommandType = adCmdTable
rsAuthors.Open cmdAuthors, , adOpenDynamic, adLockOptimistic

Action Command
For action commands, such as update data without returning any records:
Set cmdUpdate = Server.CreateObject(“ADODB.Command”)
StrSQL = “UPDATE Titles SET Price = Proce * 1.10 WHERE Type = ‘Business’”
cmdUpdate.ActiveConnection = strConn
cmdUpdate.CommandText = strSQL
cmdUpdate.CommandType = adCmdText
cmdUpdate.Execute , , adExecuteNoRecords
 2004 Tau Yenny, SI - Binus
9
Stored Procedures

A stored procedures (stored query) is a predefined SQL query stored on
the database.

The reasons why we create and use a stored procedure:

Compiled by database. Produces an execution plan, so the database knows exactly
what it’s going to do. This makes the execution of the procedure faster.

Stored procedures are often cached by the database, thus making them faster to run.
Not all databases support this caching mechanism – Microsoft Access doesn’t, but SQL
Server does.

More secure by specifying that your database tables can be modified only by stored
procedures.

Avoid cluttering ASP code with lengthy SQL statements. This makes the ASP code
easier to maintain.

Keep all the SQL code together, on the server.

Can use output parameters, which allows to return both a recordset and other values.
 2004 Tau Yenny, SI - Binus
10
Stored Procedures
A stored procedure on SQL Server
CREATE PROCEDURE usp_UpdatePrices
AS
UPDATE Titles
SET Price = Price * 1.10
WHERE Type = ‘Business’
For a Microsoft Access database,
you can create a simple update
query to do the same task
 2004 Tau Yenny, SI - Binus
11
Stored Procedures

To run this stored procedure from an ASP page, you’d simply
use the following code:
Set cmdUpdate = Server.CreateObject (“ADODB.COmmand”)
cmdUpdate.ActiveConnection = strConn
cmdUpdate.CommandText = “usp_UpdatePrices”
cmdUpdate.CommandType = adCmdStoredProc
cmdUpdate.Execute , , adExecuteNoRecords
 2004 Tau Yenny, SI - Binus
12
Stored Procedures

Parameters
Must follow the naming convention for SQL variables, which
means they must start with an @ symbol.
CREATE PROCEDURE usp_UpdatePrices
@Type
Char(12),
@Percent
Money
AS
UPDATE Titles
SET Price = Price * ( 1 + @Percent / 100 )
WHERE Type = @Type
 2004 Tau Yenny, SI - Binus
13
Stored Procedures

The Parameters Collection
Set Parameter = Command.CreateParameter (Name, [Type], [Direction], [Size], [Value])
Argument
Description
Name
The name of the parameter. This isn’t the name of the parameter in the stored procedure,
but the name of the parameter in the Parameters collection. It is however, a good idea to
use the same names.
Type
The data type of the parameter. This can be one of the adDataType constants, which are
detailed in the appendices.
Direction
The direction of the parameter, indicating whether the parameter supplies information to
the stored procedure, or whether the procedure supplies the information back to ADO.
The value can be one of:
 adParamInput (1), is an input parameter, being sent to the stored procedure.
 adParamOutput (2), is an output parameter, being retrieved from the stored procedure.
 adParamInputOutput (3), is both an input and an output parameter.
 adParamReturnValue (4), holds the return status of the stored procedure.
Size
The size of the parameter. For fixed length types, such as numbers, this can be omitted.
Value
The value of the parameter.
 2004 Tau Yenny, SI - Binus
14
Stored Procedures

Once the parameter is created it can be appended to the
Parameters collection.
Set parValue = cmdUpdate.CreateParameter (“@Type”, adVarWChar, adParamInput, 12, “Business”)
cmdUpdate.Parameters.Append parValue
Set parValue = cmdUpdate.CreateParameter (“@Percent”, adCurrency, adParamInput, ,10)
cmdUpdate.Parameters.Append parValue
cmdUpdate.Parameters(“@Percent”) = 10
If you don’t want to create a variable, you can also take a shortcut :
cmdUpdate.Parameters.Append = _
cmdUpdate.CreateParameter (“@Type”, adVarWChar, adParamInput, 12, “Business”)
cmdUpdate.Parameters.Append = _
cmdUpdate.CreateParameter (“@Percent”, adCurrency, adParamInput, ,10)
cmdUpdate.Parameters(“@Percent”) = 10
The Parameters in the Parameters collection must match the order of the
parameters in the stored procedure.
 2004 Tau Yenny, SI - Binus
15
Stored Procedures
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
<HTML><HEAD><TITLE>Stored Procedure with Parameter</TITLE></HEAD><!-- UpdatePrices.asp -->
<BODY>
<!-- #include file="dataconn.inc" -->
<FORM NAME="UpdatePrices" Method="Post" ACTION="StoredProcedure.asp">
<TABLE>
<TR><TD>Book Type:</TD>
<TD><SELECT NAME="lstTypes">
<%
Dim rsTypes
Dim strSQL
Dim strQuote
12.
13.
14.
15.
strQuote = Chr(34)
'Predefined the quote character
Set rsTypes = Server.CreateObject("ADODB.Recordset")
strSQL = "SELECT DISTINCT type FROM titles"
rsTypes.Open strSQL, Conn
16.
17.
18.
19.
While Not rsTypes.EOF
Response.Write "<OPTION VALUE=" & strQuote & rsTypes("Type") & strQuote & ">" & rsTypes("Type")
rsTypes.MoveNext
Wend
20.
21.
22.
23.
24.
25.
26.
27.
rsTypes.Close
Set rsTypes = Nothing
%></SELECT></TD></TR>
<TR><TD>Percent Value</TD>
<TD><INPUT NAME="txtPercent" TYPE="TEXT"></TD></TR>
</TABLE>
<P><INPUT TYPE="Submit" VALUE="Run Query">
</FORM></BODY></HTML>
 2004 Tau Yenny, SI - Binus
16
Stored Procedures
1.
2.
3.
4.
5.
6.
7.
<!-- #include file="dataconn.inc" -->
<!-- StoredProcedure.asp -->
<%
Dim cmdUpdate
Dim lngRecs
Dim strType
Dim curPercent
8.
9.
10.
'get from the values
strType = Request.Form("lstTypes")
curPercent = Request.Form("txtPercent")
11.
12.
'Tell the user what's being done
Response.Write "Updating all books of type <B>" & strType & "</B> by " & curPercent & "%<P>"
13.
Set cmdUpdate = Server.CreateObject("ADODB.Command")
14.
15.
16.
17.
18.
19.
20.
21.
22.
' Set the properties of the command
With cmdUpdate
.ActiveConnection = conn
.CommandText = "usp_UpdatePrices"
.CommandType = 4
‘adCmdStoredProc = 4
.Parameters.Append .CreateParameter("@Type", 202, 1, 12, strType) ‘adVarWChar = 202, adParamInput=1
.Parameters.Append .CreateParameter("@Percent", 6, 1,, curPercent) ‘adCurrency = 6
.Execute lngRecs,,128
‘adExecuteNoRecords=128
End With
23.
24.
25.
26.
'And finally tell the user what's happened
Response.Write "Procedure complete. " & lngRecs & " records were updated."
Set cmdUpdate = Nothing
%>
 2004 Tau Yenny, SI - Binus
17
Stored Procedures
 2004 Tau Yenny, SI - Binus
18
Stored Procedures

Passing Parameters as an Array
Utilizes the Array function, which turns individual variables into an
array, suitable for passing into this method call.
Some disadvantages to this method:


You can only use input parameters.
This method is slower if you intend to call the stored procedure
several times, since ADO will ask the data store what parameters
are, and what data types they use.
Set cmdUpdate = Server.CreateObject(“ADODB.Command”)
With cmdUpdate
.ActiveConnection = conn
.CommandText = “usp_UpdatePrices”
.CommandType = adCmdStoredProc
‘Execute the command
.Execute lngRecs, Array(strType, curPercent), adExecuteNoRecords
End With
 2004 Tau Yenny, SI - Binus
19
Stored Procedures

Output Parameters
If you want more information, but still don’t want to return a
recordset, you can define a parameter as an output
parameter.
CREATE PROCEDURE usp_UpdatePricesMax
@Type
Char(12),
@Percent Money,
@Max
Money OUTPUT
AS
UPDATE Titles
SET Price = Price * ( 1 + @Percent / 100 )
WHERE Type = @Type
SELECT @Max = MAX(Price)
FROM Titles
 2004 Tau Yenny, SI - Binus
20
Stored Procedures
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
<!-- #include file="dataconn.inc" --> <!-- StoredProcedureMax.asp -->
<%
Dim cmdUpdate
Dim lngRecs
Dim strType
Dim curPercent
Dim curMax
'get from the values
strType = Request.Form("lstTypes")
curPercent = Request.Form("txtPercent")
11.
12.
'Tell the user what's being done
Response.Write "Updating all books of type <B>" & strType & "</B> by " & curPercent & "%<P>"
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
Set cmdUpdate = Server.CreateObject("ADODB.Command")
' Set the properties of the command
With cmdUpdate
.ActiveConnection = conn
.CommandText = "usp_UpdatePricesMax"
.CommandType = 4
‘adCmdStoredProc = 4
.Parameters.Append .CreateParameter("@Type", 202, 1, 12, strType) ‘adVarWChar = 202, adParamInput=1
.Parameters.Append .CreateParameter("@Percent", 6, 1,, curPercent) ‘adCurrency = 6
.Parameters.Append .CreateParameter("@Max", 6, 2)
‘adCurrency = 6, adParamOutput=2
.Execute lngRecs,,128
‘adExecuteNoRecords=128
curmax = .Parameters(“@Max”)
‘Extract the OUTPUT parameter
End With
'And finally tell the user what's happened
Response.Write "Procedure complete. " & lngRecs & " records were updated.“
Response.Write "The highest price book is now " & FormatCurrency(curMax)
Set cmdUpdate = Nothing
%>
 2004 Tau Yenny, SI - Binus
21
Stored Procedures
 2004 Tau Yenny, SI - Binus
22
Stored Procedures

Return Values



Return values from functions are handled differently from the way
return values from stored procedures.
In user functions, we often return a Boolean value to indicate the
success or failure of a function
When calling a stored procedure though, we can’t use the same
method. The stored procedure are run using the Execute method,
and this returns a recordset.
For example, consider adding a new employee to the employee
table. You don’t want to stop two people with the same name
being added, but you might want this situation flagged. Here we
can use a return value, to indicate whether an employee wuth the
same name already exists.
 2004 Tau Yenny, SI - Binus
23
Stored Procedures
CREATE PROCEDURE usp_AddEmployee
@Emp_ID Char(9),
@FName
Varchar(20),
@MInit
Char(1),
@LName
Varchar(30),
@Job_Id
SmallInt,
@Job_Lvl TinyInt,
@Pub_ID
Char(4),
@Hire_Date Datetime
AS
BEGIN
DECLARE @Exists
Int
-- Return Value
-- See if an employee with the same name exists
IF EXISTS (SELECT *
FROM Employee
WHERE FName = @FName
AND MInit = @MInit
AND LName = @LName)
SELECT @Exists = 1
ELSE
SELECT @Exists = 0
INSERT INTO Employee (emp_id, fname, minit, lname, job_id, job_lvl, pub_id, hire_date)
VALUES (@Emp_ID, @FName, @MInit, @LName, @Job_Id, @Job_Lvl, @Pub_ID, @Hire_Date)
RETURN @Exists
END
GO
 2004 Tau Yenny, SI - Binus
24
Stored Procedures
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
<HTML><HEAD><TITLE>Stored Procedure with Return Values</TITLE></HEAD><!-- ReturnValues.asp -->
<BODY><!-- #include file="dataconn.inc" -->
<H1>Retuen Values from stored procedures<HR></H1>
<FORM NAME="ReturnValues" Method="Post" ACTION="StoredProcedureAdd.asp">
<TABLE>
<TR><TD>Employee ID:</TD> <TD><INPUT NAME="txtEmp_ID" TYPE="TEXT"></TD></TR>
<TR><TD>First Name:</TD> <TD><INPUT NAME="txtFName" TYPE="TEXT"></TD></TR>
<TR><TD>Initial:</TD> <TD><INPUT NAME="txtMInit" TYPE="TEXT"></TD></TR>
<TR><TD>Last Name:</TD> <TD><INPUT NAME="txtLName" TYPE="TEXT"></TD></TR>
<TR><TD>Job:</TD><TD>
<SELECT NAME="lstJob">
<%
Dim rsJobs
Dim strSQL
Dim strQuote
15.
16.
17.
18.
strQuote = Chr(34)
'Predefined the quote character
Set rsJobs = Server.CreateObject("ADODB.Recordset")
strSQL = "SELECT DISTINCT job_id, job_desc FROM jobs"
rsJobs.Open strSQL, Conn
19.
20.
21.
22.
23.
While Not rsJobs.EOF
Response.Write "<OPTION VALUE=" & strQuote & _
rsJobs("job_id") & strQuote & ">" & rsJobs("job_desc")
rsJobs.MoveNext
Wend
24.
25.
26.
rsJobs.Close
Set rsJobs = Nothing
%></SELECT></TD></TR>
 2004 Tau Yenny, SI - Binus
25
Stored Procedures
27. <TR><TD>Job Level: </TD><TD><INPUT NAME="txtJob_Lvl" TYPE="TEXT"></TD></TR>
28. <TR><TD>Publisher: </TD><TD><SELECT NAME="lstPub">
29.
<%
30.
Dim rsPub
31.
32.
33.
Set rsPub = Server.CreateObject("ADODB.Recordset")
strSQL = "SELECT DISTINCT pub_id, pub_name FROM publishers"
rsPub.Open strSQL, Conn
34.
35.
36.
37.
38.
While Not rsPub.EOF
Response.Write "<OPTION VALUE=" & strQuote & _
rsPub("pub_id") & strQuote & ">" & rsPub("pub_name")
rsPub.MoveNext
Wend
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
rsPub.Close
Set rsPub = Nothing
%></SELECT></TD></TR>
<TR><TD>Hire Date: </TD>
<TD><INPUT NAME="txtHire_Date" TYPE="TEXT" Value="<%= FormatDateTime(date()) %>"></TD>
</TR>
</TABLE>
<P>
<INPUT TYPE="Submit" VALUE="Run Query">
</FORM>
</BODY>
</HTML>
 2004 Tau Yenny, SI - Binus
26
Stored Procedures
 2004 Tau Yenny, SI - Binus
1.
2.
3.
4.
5.
6.
7.
8.
9.
27
<!-- #include file="dataconn.inc" --><!-- StoredProcedureAdd.asp -->
<%
Dim cmdEmployee
Dim lngRecs
Dim lngAdded
Set cmdEmployee = Server.CreateObject("ADODB.Command")
With cmdEmployee
.ActiveConnection = conn
.CommandText = "usp_AddEmployee"
.CommandType = 4
10.
11.
12.
13.
14.
15.
16.
17.
18.
.Parameters.Append .CreateParameter("RETURN_VALUE", 3, 4)
.Parameters.Append .CreateParameter("@Emp_ID", 129, 1, 9)
.Parameters.Append .CreateParameter("@FName", 202, 1,20)
.Parameters.Append .CreateParameter("@MInit", 129, 1, 1)
.Parameters.Append .CreateParameter("@LName", 202, 1,30)
.Parameters.Append .CreateParameter("@Job_Id", 2, 1)
.Parameters.Append .CreateParameter("@Job_Lvl", 17, 1)
.Parameters.Append .CreateParameter("@Pub_ID", 129, 1, 4)
.Parameters.Append .CreateParameter("@Hire_Date", 135, 1,8)
19.
20.
21.
22.
23.
24.
25.
26.
.Parameters("@Emp_ID") = Request.Form("txtEmp_ID")
.Parameters("@FName") = Request.Form("txtFName")
.Parameters("@MInit") = Request.Form("txtMInit")
.Parameters("@LName") = Request.Form("txtLName")
.Parameters("@Job_Id") = Request.Form("lstJob")
.Parameters("@Job_Lvl") = Request.Form("txtJob_Lvl")
.Parameters("@Pub_ID") = Request.Form("lstPub")
.Parameters("@Hire_Date") = Request.Form("txtHire_Date")
27.
28.
29.
30.
31.
32.
33.
34.
35. %>
.Execute lngRecs,,128
lngAdded = .Parameters("RETURN_VALUE")
End With
Response.Write "New Employee added.<P> "
If lngAdded = 1 Then
Response.Write "An Employee with the same name already exists."
End If
Set cmdEmployee = Nothing
 2004 Tau Yenny, SI - Binus
28
Stored Procedures
 2004 Tau Yenny, SI - Binus
29
Stored Procedures

Refreshing Parameters
Instead of typing in all of the parameter details yourself, ADO can do it for
you, simply by calling the Refresh method .
But be aware that it imposes a performance penalty, since ADO must query
the provider for the details of the parameters for the stored procedure.
1.
2.
3.
4.
With cmdEmployee
.ActiveConnection = conn
.CommandText = "usp_AddEmployee"
.CommandType = 4
5.
.Parameters.Refresh
6.
7.
8.
9.
10.
11.
12.
13.
.Parameters("@Emp_ID") = Request.Form("txtEmp_ID")
.Parameters("@FName") = Request.Form("txtFName")
.Parameters("@MInit") = Request.Form("txtMInit")
.Parameters("@LName") = Request.Form("txtLName")
.Parameters("@Job_Id") = Request.Form("lstJob")
.Parameters("@Job_Lvl") = Request.Form("txtJob_Lvl")
.Parameters("@Pub_ID") = Request.Form("lstPub")
.Parameters("@Hire_Date") = Request.Form("txtHire_Date")
14.
15.
16.
.Execute lngRecs,,128
lngAdded = .Parameters("RETURN_VALUE")
End With
 2004 Tau Yenny, SI - Binus
30
Optimization

General ADO Tips






Pick only the columns you need
Use stored procedures as much as possible
Use stored procedures for data changes
Don’t create a recordset unless it’s required
Use the appropriate cursor and lock modes
Object Variables

One guaranteed way to improve performance whilst
looping through recordset is to use object variables
 2004 Tau Yenny, SI - Binus
31
Optimization

Cache Size

Cache size is the number of records that ADO reads at a
time from the data sore, and it defaults to 1.

The size 1 means, every time you move to another record,
the record must be fetched from the data store.

Increasing the size of the cache to 10, for example, would
mean that records are read into the ADO buffer 10 at a
time.

Set the size of the cache by using the CacheSize property :
rsAuthors.CacheSize = 10
 2004 Tau Yenny, SI - Binus
32
Data Shaping

Allows to represent a tree-like structure or related
recordset.

Reasons why this is useful:



Performance : When used correctly, data shaping can
improve performance
Convenience : It’s extremely easy to map the parent/child
relationship in data shaping.
Using data shaping


Use the MSDataShape OLEDB Provider
Use a special Shape language, a superset of SQL, that
allows you to construct the hierarchies
 2004 Tau Yenny, SI - Binus
33
Data Shaping

The Connection String
Provider=MSDataShape; Data Provider = SQLOLEDB; Data Source=…

The Shape Language
SHAPE {parent command} [AS parent alias]
APPEND ({child command} [AS child alias]
RELATE parent_column TO child_column) [AS parent_column_name]
For Example:
SHAPE {SELECT * FROM Publishers }
APPEND ({SELECT * FROM Titles}
RELATE Pub_ID TO Pub_ID) AS rsTitles
 2004 Tau Yenny, SI - Binus
1.
2.
3.
4.
5.
6.
34
<!-- #include file="dataconn.inc" --><!-- DataShape.asp -->
<%
Dim rsPublishers
Dim rsTitles
Dim strShapeConn
Dim strShape
Data Shaping
7.
Set rsPublishers = Server.CreateObject("ADODB.Recordset")
8.
9.
strShapeConn = "Provider = MSDataShape; Data Provider = SQLOLEDB; Data Source= Hogwartz; " & _
" Initial Catalog= pubs; User ID= sa; Password= letmein"
10.
11.
strShape = "SHAPE {SELECT * FROM Publishers } APPEND ({SELECT * FROM Titles} " & _
" RELATE Pub_ID TO Pub_ID) AS rsTitles "
12.
rsPublishers.Open strShape, strShapeConn
13.
14.
15.
16.
'Loop through the publishers
Response.Write "<UL>"
While Not rsPublishers.EOF
Response.Write "<LI>" & rsPublishers("Pub_Name")
17.
18.
19.
'Now the titles
Response.Write "<UL>"
Set RsTitles = rsPublishers("rsTitles").Value
20.
21.
22.
23.
24.
25.
'Loop through the titles
While Not rsTitles.EOF
Response.Write "<LI>" & rsTitles("title")
rsTitles.MoveNext
Wend
Response.Write "</UL>"
26.
27.
28.
29.
'Move to the next publishers
rsPublishers.MoveNext
30.
31.
32.
33.
Wend
Response.Write "</UL>"
rsPublishers.Close
Set rsPublishers = Nothing
Set rsTitles = Nothing
%>
 2004 Tau Yenny, SI - Binus
35
Data Shaping
 2004 Tau Yenny, SI - Binus
Download