0% found this document useful (0 votes)
167 views4 pages

Delphi - Stored Procedures - Part 1 PDF

1) Stored procedures are SQL code and logic embedded within a database that can be invoked by applications. This extracts logic from applications and places it in the database. 2) The document demonstrates calculating a customer's available credit using SQL in an application versus using a stored procedure. Stored procedures encapsulate business rules in the database rather than applications. 3) Benefits of stored procedures include encapsulating logic so it only needs changed in one place, allowing for improved performance through caching and optimization, and enabling two-tier architectures with business rules separated from applications.

Uploaded by

nagat4r
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
167 views4 pages

Delphi - Stored Procedures - Part 1 PDF

1) Stored procedures are SQL code and logic embedded within a database that can be invoked by applications. This extracts logic from applications and places it in the database. 2) The document demonstrates calculating a customer's available credit using SQL in an application versus using a stored procedure. Stored procedures encapsulate business rules in the database rather than applications. 3) Benefits of stored procedures include encapsulating logic so it only needs changed in one place, allowing for improved performance through caching and optimization, and enabling two-tier architectures with business rules separated from applications.

Uploaded by

nagat4r
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 4

Surviving Client/Server:

Stored Procedures Part 1


by Steve Troxell

S tored procedures are a way of


extracting SQL statements and
logic from an application and
would simply be calls to invoke
those stored procedures.
You generally pass information
table, we get the amount of
available credit for the customer.
Listing 1 shows one way to
embedding them within the between the application and the approach this problem using SQL
database. Any application written stored procedure through parame- code embedded in the Delphi appli-
in any language which has the ters in the procedure (not unlike a cation. Query1 and Query2 are TQuery
facilities to execute SQL code can parameterized TQuery). Some back- components on the form. The SQL
run these stored procedures and end servers, like Sybase, can statements we’re executing each
manipulate their results. produce “implied results sets”, return a result set containing one
This month, we’re going to meaning their stored procedures value, so we use Open to execute
explore the pros and cons of stored can produce multi-row result sets them. After that, it’s a simple calcu-
procedures in general and how to indistinguishable from a result set lation using the values returned to
handle them in Delphi in particular. produced by a regular SQL query. determine the available credit. All
Next month, we’ll go into greater Delphi provides the TStoredProc currency amounts in this example
detail by exploring the various component to help you manage are assumed to be whole dollar
types of stored procedures, how to your stored procedures. This com- amounts, so we use integer types.
create them with Interbase and ponent has most of the functional- Listing 2 shows the definition of
how to manipulate them from ity you’ll find in TQuery, which is not an Interbase stored procedure to
Delphi. surprising since stored proce- do this same task. The stored
While the concepts of stored dures are just server-based SQL procedure accepts an input pa-
procedures are common across queries. In addition to TStoredProc, rameter, CustNo, defining the
many back-end servers, the syntax you can also call stored proce- customer we are interested in. It
and functionality varies widely dures through a TQuery with regular also returns two output parame-
from vendor to vendor. Stored SQL commands. ters, CreditLimit and CreditAvail,
procedures have not been a formal To illustrate how the use of returning the information we need.
part of the SQL standard, so stored procedures affects the We use a local variable, CreditUsed,
vendors have been free to imple- Delphi code you’ll write, we’ll take to temporarily hold the amount of
ment them however they see fit. a simple database task and solve it credit used.
You should view the material with SQL embedded within the Finally, Listing 3 shows the
presented here as an overview to application and with a stored Delphi code that we use to call this
stored procedures and consult procedure. stored procedure (this would
your SQL server’s reference The task is this: You have a table replace the code shown in Listing
manuals for specific information. called Customers from which you 1). StoredProc1 is a TStoredProc
can look up a particular customer component on the form.
What Is A Stored Procedure? by the CustomerNo field. Also in this OK, so the Delphi code is more
Whereas a table is a database table is a CreditLimit field showing concise, but all we’ve done is shift
object containing data, a stored the maximum amount of credit the load from one area to another.
procedure is a database object which has been authorized for the Also, you could argue that it takes
containing SQL code which usually customer. In addition, you have an more effort to develop the stored
manipulates the data in one or Extensions table with a one-to- procedure version. So why go to
more tables. It is really a server- many relationship to Customers the trouble of splitting the SQL
based SQL query, but may also (linked through CustomerNo). This code out into a stored procedure?
include flow control logic or data table contains one row for every
computations. In this way, some credit extension (loan) given to the Encapsulated Logic
portions of the system logic are customer. The BalanceDue column Since a calculation like this could
separated from the Delphi applica- shows how much of the loan easily be needed at many points in
tion and placed in the back-end remains to be paid (completely an application, or across multiple
database. It’s not out of the paid loans have a BalanceDue of applications in an integrated sys-
question that all SQL logic in a sys- zero). If we take the credit limit tem, we have encapsulated its logic
tem could be located in stored found in the Customers table and at a single point in the database
procedures and the only SQL state- subtract out all the outstanding itself. In so doing, we have removed
ments remaining in the application balances found in the Extensions a business rule from the software

28 The Delphi Magazine Issue 6


function TForm1.GetCreditAvail(CustomerNum: LongInt): LongInt;
site. Let’s say you developed a sys-
begin tem containing the GetCreditInfo
Result := 0;
with Query1 do begin { Typically, the SQL code would be set through the property editor }
stored procedure and deployed it
SQL.Clear; for Customer A and Customer B,
SQL.Add(’SELECT CreditLimit FROM Customers’); but Customer B wants to include
SQL.Add(’ WHERE CustomerNo = :CustNo’);
ParamByName(’CustNo’).AsInteger := CustomerNum; more factors in determining avail-
Open; able credit than Customer A does.
try
with Query2 do begin
All you have to do is modify
SQL.Clear; Customer B’s stored procedure,
SQL.Add(’SELECT SUM(BalanceDue) FROM Extensions’);
SQL.Add(’ WHERE CustomerNo = :CustNo’);
none of the application software
ParamByName(’CustNo’).AsInteger := CustomerNum; needs to be modified.
Open; It is this concept of encapsulated
try
{ This check is needed in case there are no credit extensions on file for the customer } business rules in the database that
if Query2.FieldByName(’Sum’).IsNull then is commonly referred to as ‘two-
Result := Query1.FieldByName(’CreditLimit’).AsInteger
else
tier architecture’. The first tier is
Result := Query1.FieldByName(’CreditLimit’).AsInteger - the client application which
Query2.FieldByName(’Sum’).AsInteger;
finally
interacts with the user. The second
Close; { Close Query2 } tier is the business rule logic at the
end; server which interacts with the
end;
finally client application.
Close; { Close Query1 }
end;
end;
Improved Performance
end; A second advantage of this stored
procedure is that it executes more
quickly than if the individual SELECT
➤ Listing 1
statements were sent as queries
from the client. To understand why
this is so, we must look at how an
CREATE PROCEDURE GetCreditInfo(CustNo integer)
RETURNS(CreditLimit integer, CreditAvail integer) SQL query is processed.
AS When an SQL statement is re-
DECLARE VARIABLE CreditUsed integer;
BEGIN ceived from the client, the server
SELECT CreditLimit FROM Customers parses the statement and validates
WHERE CustomerNo = :CustNo
INTO :CreditLimit;
it, checking its syntax and database
SELECT SUM(BalanceDue) FROM Extensions object references. It then formu-
WHERE CustomerNo = :CustNo lates an execution plan for the
INTO :CreditUsed;
/* This check is needed in case there are no credit extensions on file for the customer */ query by deciding which, if any,
IF (CreditUsed IS NULL) THEN CreditUsed = 0; indexes it will use to process the
CreditAvail = CreditLimit - CreditUsed;
END request. Some servers may at-
tempt to reorganize the statement,
compare the execution costs of
➤ Listing 2
various strategies and select the
optimal approach. Finally the
function TForm1.GetCreditAvail(CustomerNum: LongInt): LongInt; query is compiled and executed.
begin However, with a stored proce-
{ Typically, this would be set through the property editor }
with StoredProc1 do begin dure, all the steps of parsing, vali-
StoredProcName := ’GetCreditInfo’; dating, optimizing, and compiling
ParamByName(’CustNo’).AsInteger := CustomerNum;
ExecProc;
are performed when the procedure
Result := ParamByName(’CreditAvail’).AsInteger; is created. When a client applica-
end;
end;
tion executes a stored procedure,
the server skips those steps since
they have already been done and
➤ Listing 3
simply executes the pre-compiled
SQL statements. This is the same
and centralized it in the database, change the logic in the stored reason why using Prepare and
where any application can use it. procedure and all affected applica- Unprepare with a TQuery improves
By extracting business rules like tions will automatically respond to performance for repetitive para-
this from the software, all applica- the new logic. meterized queries (see last
tions can instantly respond to logic By the same token, encapsulated month): Prepare takes care of all
changes without the need to business rules simplify the reus- the steps up through compilation.
re-code, re-compile, and redistrib- ability of the software when in- But, those steps must still be per-
ute EXEs or DLLs. We can simply stalled at more than one customer formed at least once at runtime.

February 1996 The Delphi Magazine 29


With a stored procedure, those However, a stored procedure component is bound to a database
steps are all handled in advance can read or modify a table inde- through the DatabaseName property,
and are not needed at runtime. pendent of any permissions the you simply select the stored proce-
Another way in which stored user might have. While at first dure from the drop-down list in the
procedures can improve perform- glance this may seem to be a design StoredProcName property editor.
ance is by reducing network traffic. flaw in the security of the database, With Interbase, Delphi automat-
For example, if your application it’s actually an intentional feature ically populates the stored proce-
needed to manipulate several rows to permit even tighter control over dure’s parameter names, types
of data to arrive at a decision and data access. A user might only be (whether they are input or output
that manipulation could be encap- granted read access to a particular parameters) and data types in the
sulated within a stored procedure, table, but be able to execute a Params property. However, with
then only the decision arrived at stored procedure to update the some other SQL back-ends, like
needs to be sent back to the client. same table. The user can modify Sybase and Microsoft, the Borland
The rows never need to leave the the table only by running the Database Engine is unable to deter-
server in order to arrive at the de- stored procedure. This allows mine the stored procedure’s
cision. Thus, network congestion users to modify database tables parameter types (input or output),
for this activity is greatly reduced. under the control of an application so you have to assign them manu-
For example, suppose a stored written around the stored proce- ally through the Params property
procedure runs several SELECT dures, but prevents them from editor. If you fail to do this, Delphi
statements to gather values from altering the data with independent raises the exception ‘No parameter
several different tables into local third-party software. type for parameter xxx’ when you
variables. It then does some calcu- In addition, stored procedures, try to execute the procedure.
lations and comparisons of these like all database objects, generally Once these connections are
values to arrive at a simple yes/no can only be altered by the user who defined, you use the TStoredProc
decision. In this case, all the opera- owns them, or the system adminis- component very much the same
tions are performed at the server trator. So if you include stored way you use the TQuery component.
and only the yes/no answer is sent procedures in your database, you You assign input values to or read
back to the client. If this task were aren’t exposing critical parts of output values from the proce-
done using SQL embedded in the your application to unauthorized dure’s parameters through the
application, the results of all the modification. Params or ParamByName methods. To
SELECT statements would be sent execute the procedure, you call the
back to the client, which would Drawbacks Open method if the procedure
examine the values and arrive at The principal drawback of stored returns a result set, or the ExecProc
the yes/no decision. procedures is reduced flexibility. method if it does not. A common
Since the SQL code in the proce- error in working with stored proce-
Enhanced Data Security dure is fixed, you lose the power of dures (or TQueries for that matter)
Client/server databases enforce dynamically constructing SQL is to confuse these two methods of
system security by granting or statements at runtime in response execution. If you get the exception
revoking data access privileges to user actions (see Dynamic SQL ‘Error creating cursor handle’ when
(select, insert, update, delete) for last month). Also, there is slightly executing a stored procedure, the
each table to specific users or more development overhead since procedure most likely does not
groups of users. Normally, if the the stored procedures are inher- return a result set and it should be
application you are developing ently separated from the applica- executed with ExecProc.
allows the user to modify a particu- tion and a certain amount of
lar table, that user must be granted interface scaffolding is necessary. TQuery
the appropriate permissions. How- On the other hand, it wouldn’t be TStoredProc isn’t the only mecha-
ever, since client/server systems unusual for a large project to have nism you have to run stored proce-
are inherently ‘open’ to any ODBC a dedicated SQL developer respon- dures from Delphi. All client/server
application, this also allows a par- sible for all the stored procedures databases which support stored
ticularly devious user to log into in the system. The Delphi develop- procedures also provide SQL
the database using an external ers can then concentrate on the commands to execute them. Using
application to modify the table user interface and not concern SQL syntax, you could always
directly, outside the control of your themselves with database access execute any stored procedure from
application. So, a knowledgeable, other than the task of interfacing to a TQuery. For example, to run an
unscrupulous user could generate the stored procedures. Interbase stored procedure which
transactions to gain some benefit deletes a record (does not return a
for themselves or someone they TStoredProc result set), you would use the
know and promptly remove all Stored procedures are most com- following SQL statement:
trace of accountability for those monly accessed in a Delphi appli-
transactions, through some cation through the TStoredProc EXECUTE PROCEDURE
external program. component. Once the TStoredProc DeleteCustomer(:CustomerNo)

30 The Delphi Magazine Issue 6


If we have the TStoredProc com- CREATE TRIGGER Save_Salary_Change FOR Employee
ponent why would we need to use AFTER UPDATE
AS
a TQuery to run a stored procedure? BEGIN
First, as we’ll see next month, there IF (Old.Salary <> New.Salary) THEN
are certain kinds of stored proce- INSERT INTO Salary_History
(Emp_No, Change_Date, Updater_ID, Old_Salary, Percent_Change)
dures that simply cannot be VALUES (
executed with TStoredProc. Second, Old.Emp_No,
’Now’,
TStoredProc is very closely bound User,
to the Borland Database Engine. As Old.Salary,
(New.Salary - Old.Salary) * 100 / Old.Salary);
new releases of back-end servers END
appear, the BDE may not be up-to-
date with any changes made in the
➤ Listing 4
stored procedure functionality.
Since TQuery provides direct access
to the stored procedures through trail record so that a history is purview by the trigger, Delphi
the vendor’s own SQL command maintained of all changes to a loses track of the record and raises
set, you can bypass any shortcom- table, auto-generating a unique a ‘Record/Key Deleted’ exception.
ings in TStoredProc’s connectivity. primary key value for new records, To avoid this, rather than use a
Third, in the early releases of posting a time stamp of record trigger to assign the key value, you
Delphi, the BDE and SQL Links modification, or cascading may want to use a regular stored
drivers had several bugs in com- changes across related tables. procedure to return the auto-incre-
municating with some back-end Listing 4 shows a typical trigger ment value, have Delphi use this to
servers that could be avoided by for an Interbase table. This exam- obtain the key value, and assign it
calling the stored procedure ple comes directly from Delphi’s to the record’s primary key field in
directly through TQuery. sample employee database, file TTable’s OnNewRecord event handler.
EMPLOYEE.GDB. Whenever the
Triggers Salary field in the Employee table is Summary
Triggers are a special form of changed, this trigger adds a record A client/server system can benefit
stored procedure. Whereas stored to the Salary_History table. from stored procedures by encap-
procedures are executed on This code creates a trigger called sulating business rules, improving
demand by an explicit call from the Save_Salary_Change which is performance and enhancing data
application, triggers are bound to executed whenever a record in the security. However, they reduce
specific data events on a table and Employee table is updated. Like a your ability to dynamically create
are executed automatically by the stored procedure, the actual trig- queries at runtime and may compli-
server when those events occur. ger code is defined within the AS cate the development process.
Generally, a trigger can be assigned BEGIN END block. Interbase supplies Since there are many variations
to execute whenever a record is two ‘virtual’ tables, Old and New, to among SQL server vendors, do
added, changed, or deleted in a hold the record’s contents before make sure you check your own
given table. An application cannot and after the update respectively. vendor’s reference manuals.
explicitly execute a trigger and can- These virtual tables are available Next month we’ll continue our
not prevent a trigger from being only within triggers. We use them look at stored procedures by roll-
executed if the proper data event here to determine if the Salary field ing up our sleeves and walking
has occurred. Triggers act some- has changed and, if so, to insert a through several Interbase exam-
what like event-handlers in Delphi. record into the Salary_History ta- ples, digging into both the SQL and
Just as you can assign a Delphi pro- ble. The INSERT statement uses the Delphi ends of the business. We’ll
cedure to execute when certain ap- Interbase literal Now to provide the also take a look at some Microsoft
plication events (like OnClick) current date and time and the lit- SQL Server examples to illustrate
occur, you can assign database eral User to capture the username just how different stored proce-
triggers to execute when certain of the user making the change. dures can be from server to server.
database events occur. Unlike A common technique in the
Delphi event handlers, triggers client/server world is to use a
have no input or output parame- trigger tied to the record insert Steve Troxell is a Software
ters. As they are controlled purely event to assign an auto-increment- Engineer with TurboPower
through database events, there is ing numeric value to the primary Software where he is developing
no direct communication between key of the record. In Delphi, at least Delphi Client/Server applications
an application and a trigger. with data-aware controls and using InterBase and Microsoft SQL
Triggers can contain essentially TTable, this poses a bit of a prob- Server for parent company Casino
the same SQL statements and logic lem. Delphi uses the primary key to Data Systems. Steve can be
which can be used within a stored keep track of the records. Since the reached on the internet at
procedure. Some example uses of primary key for the inserted record stevet@tpower.com and also on
triggers would be: posting an audit is assigned outside of Delphi’s CompuServe at 74071,2207

February 1996 The Delphi Magazine 31

You might also like