SQL Server 2000 Stored Procedures Handbook 1st Edition Tony Bain instant download
SQL Server 2000 Stored Procedures Handbook 1st Edition Tony Bain instant download
https://ebookgate.com/product/sql-server-2000-stored-procedures-
handbook-1st-edition-tony-bain/
https://ebookgate.com/product/beginning-sql-server-2000-for-visual-
basic-developers-1st-edition-thearon-willis-auth/
ebookgate.com
https://ebookgate.com/product/sql-server-t-sql-recipes-4th-edition-
jason-brimhall/
ebookgate.com
https://ebookgate.com/product/pro-sql-server-2012-practices-1st-
edition-bradley/
ebookgate.com
https://ebookgate.com/product/mastering-sql-server-2008-1st-edition-
michael-lee/
ebookgate.com
Professional SQL Server Reporting Services Paul Turley
https://ebookgate.com/product/professional-sql-server-reporting-
services-paul-turley/
ebookgate.com
https://ebookgate.com/product/microsoft-sql-server-2008-r2-unleashed-
rankins/
ebookgate.com
https://ebookgate.com/product/accelerated-sql-server-2008-1st-edition-
robert-e-walters/
ebookgate.com
https://ebookgate.com/product/beginning-microsoft-sql-
server-2008-programming-robert-vieira/
ebookgate.com
https://ebookgate.com/product/microsoft-sql-server-2008-bible-1st-ed-
edition-paul-nielsen/
ebookgate.com
SQL Server 2000 Stored
Procedures Handbook
This book is dedicated solely to stored procedures In SOL Server 2000. SOL Server 2000
administrators and designers will benefit from this book, but It IS also ideal for the experienced
SOL Server 2000 developer who is already familiar with the basic concepts of stored
procedures.
Summary of Contents
Introduction
Chapter 1: Stored Procedures Overview
Chapter 2: Optimizing and Debugging
Chapter 3: Concurrency, Cursors, and Transactions
Chapter 4: Common Practices with Stored Procedures
Chapter 5: System Stored Procedures
Chapter 6: User Defined Functions
Chapter 7: Triggers
Chapter 8: Security
Appendix A: Support, Errata, and forums.apress.com
Index
SQL Server 2000 Stored
Procedures Handbook
Tony Bain
Louis Davidson
Robin Dewson
Chuck Hawkins
Trademarked names may appear i n this book. Rather than use a trademark symbol w i t h
every occurrence of a trademarked name, w e use the names only i n an editorial fashion
and to the benefit of the trademark owner, w i t h no intention of infringement of the
trademark.
Distributed to the book trade i n the United States by Springer-Verlag New York, Inc., 175
Fifth Avenue, New York, NY, 10010 and outside the United States by Springer-Verlag
G m b H & Co. KG, Tiergartenstr. 17, 69112 Heidelberg, Germany.
For information o n translations, please contact Apress directly at 2560 Ninth Street, Suite
219, Berkeley, CA 94710. Phone 510-549-5930, fax 510-549-5939, email info@apress.com,
or visit http://www.apress.com.
The information i n this book is distributed o n an "as is" basis, without warranty. Although
every precaution has been taken i n the preparation of this w o r k , neither the author(s) nor
Apress shall have any liability to any person or entity w i t h respect to any loss or damage
caused or alleged to be caused directly or indirectly by the information contained in this
work.
Thanks to Linda, Laura, Stephanie, and William for their continued support
and thanks also to Craig Walker who is a .NET legend!
Louis Davidson
Louis Davidson has been in the
technology industly for ten years, as a
corporate database developer and
architect. Currently, he is serving as a
Database Administrator for Compass
Technology Management in their Nashville
Data Center supporting the Christian
Broadcasting Network and NorthStar
Studios in Nashville, TN.
The majority of his experience, with slight deviations into Visual Basic, has been spent
with Microsoft SQL Server from version 1.0 to the latest version that is in Beta. Louis'
primaty areas of expertise are in database architecture and coding in Transact-SQL, and he
has written numerous stored procedures and triggers throughout the years, though he
seldom has the need anymore with the code generation tools he has developed to
generate objects, with only a few procedures and triggers to code from the ground up.
Louis has published "Professional SQL Server 2000 Database Design," also by Apress. The
book follows the complete arc of developing a database through requirements, architecture,
and design. He has also been an active volunteer with SQL PASS as a presenter and a
chairperson in their special interest groups. It has been said that in his ridiculously small
amount of spare time, he tends to playa lot of Nintendo (got to save that dam Princess, she
went off and was captured by the silly dragon, again!) and watch a great deal of television.
Most notably, his favorites are old English programs (the Avengers, The Saint, Monty Python,
and Blackadder to name a few). Quite often, this spare time is also spent with his notebook
computer writing something pertaining to SQL.
Robin Dewson
Robin has come a long way since the early heady
days of the Sinclair ZX8O/81 and Spectrum. He was
ftrst introduced to computers at an exhibition in
Glasgow where he saw a Commodore Pet
manipulate a robot and he knew instantly that
computers was the route for him. Unfortunately
that route initially took him into IBM mainframes.
However, he feels that this is a crucial keystone in his overall approach to computing and
without this he would not be where he is today. Well, that, Scottish College of Textiles,
his family and of course many, many bottles of 1m Bru (who needs caffeine?). Robin
moved to working with PCs nearly 10 years ago with FoxBASE and has moved from there
through Visual FoxPro, Visual Basic, Sybase, and of course SQL Server.. Robin can be
contacted at robin@fat-belly.com.
There are many people once again that I UXJU!d like to thank for different
reasons. All those at Wrux throughout the yea~ but especially Cilmara,
Douglas, Cath, Helen, James, and Chris for different reasons, but thanks!
Andy at Pinball Mania for keeping my pinball machines working, Charlie
and Debbie at Sea Palling in Noifolk for being two greatfriends and
brilliant with my children in their arcade, Philljupitus, Phil (2112 rules/)
Wilding, Gideon Cae, Liz K~haw, and Andrew Collins at the BBG's 6Music,
(v.ww.bbc.co.uk/6music) for the e:xcellent music and humor to keep me going
at work, all my traders at Lehmans but especially Anthony 'Jock"Jawad for
his staunch support, and my good.friendJack Mason. Of cou~ speCial
thanks though to my mum and dad for sorting out this great life for me, nry
sister Carol and herfamily, Eleanor, Erin, and Lucas out in Australia but
most ofall my wifeJulie who goes through hell with each book I write. I am
afraid this was "not another one". But you can now go and enjoy the Donny
Osmond concert. Also my 3 long suffering kids, Scott, Cameron, and Ellen.
Let's go and see a movie.
Chuck has spoken at professional Association for SQL Server conferences in Chicago,
London, Denver, and Seattle. He has contributed columns to several magazines and was a
contributing author for Louis Davidson's "Professional SQL Server 2000 Database Design,"
now published by Apress. Prior to his life as a computing professional, Chuck taught
English in Japan for five years.
Chuck is happily married to Kathy and adopted Kristina from Russia five years ago on
Christmas Day. When not working with databases, he likes to play with Kristina, run long
distances, and read "First Things" journal. You can get in touch with Chuck at
chuck@sqlserver.cc.
Table of Contents
Introduction 1
Who Is This Book For? 1
Book Outline 2
Returning Values 28
RETURN 28
OUTPUT 29
Single Row of Data 30
When an Error Occurs 30
Other Issues with Returning Values 30
Common Mistakes 48
Batches and GO 48
Dynamic SQL in Procedures 50
Security 51
Error Handling 52
@@ERROR 53
RAISERROR & Return Parameters 55
Summary 62
ii
Table of Contents
Uses of Cursors 73
Formatting a Result Set 73
Batch Operations 78
Best Practices 80
Transactions 81
Syntax 82
Simple Transactions 82
Savepoints 86
Distributed Transactions 87
Explicit versus Implicit Transactions 88
Compiled SQL Server Code 88
Best Practices 90
Concurrency 91
OS and Hardware Issues 92
Concurrency Controls 92
SQL Server 93
Coding for Integrity and Concurrency 99
Best Practices 108
Summary 109
Summary 133
iii
Table of Contents
Summary 176
iv
Table of Contents
V
Table of Contents
Summary 245
Index 251
vi
Introd uction
As well as being used for fundamental database administration, stored procedures are the
cornerstone of any kind of database solution. Mastery of stored procedures is imperative
to access and modify your data in the most effective way, as well as to keep your
database secure and performing well. This book is a must on your road to that mastery.
This book is dedicated to stored procedures and the surrounding aspects of SQL Server
2000 that affect their operation. In here you will find many useful tips, facts, and
techniques that will help you to get the most from your stored procedures. Whether
you are accessing data from a client application, performing database administration
with system stored procedures, or even using extended stored procedures to work with
other parts of the operating system, you will hopefully find information that will make
you review your own dealings with stored procedures, and ensure the continuous
improvement of your database solutions.
Book Outline
Below is a detailed outline of what this book covers, chapter by chapter.
2
Book Outline
If you manage a SQL Server as a part of your day-to-day tasks, you will find this
chapter helpful. There's a section on mining system stored procedures that will be
especially useful to those involved in T-SQL coding.
UDFs have some features that are common to stored procedures but there are a
number of restrictions, as well. In this chapter, we will begin by looking at what a UDF
actually is, and then move onto look at the different types of UDFs, building and
calling functions that return different types of data, using schema binding with UDFs,
and how UDFs differ from stored procedures.
Chapter 7 - Triggers
Triggers are best used for enforcing business rules as well as performing validation or
data modifications, when other methods are not sufficient. Triggers are typically used
in two areas: creating audit records and reflecting changes to crucial business tables,
and validating changes against a set of business rules coded in T-SQL. In this chapter
we will look at performance considerations when working with triggers, the different
types of triggers, transactions and triggers, and recursive triggers.
Chapter 8 - Security
In this chapter we will first analyze security threats and the core security requirement
of SQL Server - allowing data access only to explicitly authorized users. Then, we will
look at the proper implementation of stored procedures for adequately countering
these threats. Finally, we will examine some general methods for securing our SQL
Server implementation, giving special emphasis on SQL Server stored procedures and
the system stored procedures that Microsoft ships with SQL Server.
3
Stored Procedures Overview
Welcome to the SQL Server 2000 Stored Procedures handbook. Here, we will cover the
different types of stored procedures used in SQL Server 2000 and their usage. We will
also examine the working of stored procedures, the potentially tricky areas, and how to
avoid them.
o The difference between system stored procedures and user stored procedures
o Creating and designing stored procedures
o Using parameters and best practices
o Flow control statements
o Recursion
o Return values
Chapter 1: Stored Procedures Overview
You may have executed some ad-hoc queries for tasks like inserting data, querying
information in other systems, or creating new database objects such as tables. All these
tasks can be placed within a stored procedure, so that any developer can run the same
code without having to recreate the T-SQL commands. Also, generalising the code for
all values makes it generic and reusable.
Stored procedures are more than just tools for performing repetitive tasks. They can
ensure the integrity of data (through standalone stored procedures or triggers), behave as
subroutines for performing part of a task that can be called from several routines (known
as user-defined functions), or even act as SQL Server routines for everyone to use.
There are two main types of stored procedure - system stored procedures and
user-defined stored procedures. We will see how these differ, in the next section. We
also have extended stored procedures that can reside as either system or user-defined
types. Extended stored procedures give functionality that is not necessarily contained
within SQL Server, like allowing DOS commands to run and working with e-mail. It is
also possible to create your own extended stored procedures. This book doesn't cover
building extended stored procedures, as these are written using C++ libraries.
6
What is a Stored Procedure?
Every time we add or modify a table, make a backup plan, or perform any other
administrative function from within Enterprise Manager, we actually call a stored
procedure specifically written to complete the desired action. These stored procedures
are known as system stored procedures, which are functions that enhance the basic
functionality of SQL Server itself, either by extending the functionality of an existing
system stored procedure or by creating new functionality that enhances the basics of
what is already there.
For example, the sp_who system stored procedure will list connections to SQL Server,
including all the system running processes, but if you do not want to see those system
processes, you can write a new sp_whouser system stored procedure based on
sp_who by taking sp_who as a basis, and create the new procedure from that.
System stored procedures are prefixed by sp_, so it is not advisable to use sp_ for any
of the stored procedures that we create, unless they form a part of our SQL Server
installation. Creating a stored procedure prefixed with sp_ and placing it in the
master database will make it available to any database without the need to prefix the
stored procedure with the name of the database.
Lets clarify this with an example. If we take the sp_who stored procedure, call it
sp_mywho, store it in the master database, and move to another database such as
northwind, we can still execute sp_mywho, rather than having to specify the
procedure in the fully qualified manner as master.dbo.sp_mywho.
Although SQL Server comes with many useful and relevant system stored procedures
built in, there is always room for improvement. We will discuss how we can harness
the full capablities of SQL Server by inspecting these and improve the usability of SQL
Server by creating our own, in Chapter 5.
If we create our own system stored procedure then we will need to place them within all
installations of SQL Server (an instance of SQL Server is a separate installation, and hence
a separate entity) in our organization, to ensure consistency. There are several reasons for
doing this. For example, it is possible to create development, testing, and production
installations as completely separate entities. We may find the development and test
instance on one machine, and the production instance on a different one.
We can see that there are three instances defined in the follOWing screenshot-
a Development instance, a Live instance, and a Local instance. The Development and Local
instances reside on the same computer, while the Live instance is on a remote
computer. Therefore, each instance would have its own stored procedures to perform
the administrative tasks:
7
Chapter 1: Stored Procedures Overview
8 ~COnsoie~
I~Rloot• •1IIJ!II
DeveIopmoN: Servo<
8 live
9
Dot_.
195.224.19.9 (W'ndows NT)
System stored procedures reside in the master database or the model database for
each instance installed. Every stored procedure residing in the model database will be
placed into any database that we create within our SQL Server instance, by default.
When we create a new database, it is based on the model database. Therefore, any
new system or user stored procedures added to the model database will also be placed
into each new database that we create.
It is rare to create system procedures that are specific to one database. Generally, they
are implemented as user stored procedures. Now, let's take a look at them and see
how these differ from system stored procedures.
8
What is a Stored Procedure?
Now let's take a look at the syntax for creating a stored procedure:
END
An example of a simple stored procedure follows, where two numbers are passed in
and the midpoint of the two numbers is listed:
SELECT @Mid
END
9
Chapter 1: Stored Procedures Overview
At the time of creation, SQL Server takes our code and parses it for any syntactical
errors. Column names and variables are checked for existence at compilation. Even if
they don't exist, any temporary tables created within the stored procedure will also
pass the compilation stage. This is known as deferred name resolution. It can be an
asset or a drawback, as we can create temporary tables that exist for the lifetime of the
stored procedure execution only, which is desirable, but if we define a temporary table
and get something wrong later on, such as a column name, then the compilation will
not pick up this error.
While executing the CREATE PROCEDURE statement, errors will be reported. Once it is
compiled, the details of the stored procedure are stored in three system tables in the
concerned database:
o sysobj ects
This table contains a row for each object that is created within the
database. If you want to track an object in the database, you can use this as
the main root. Apart from the object name and type, this table also keeps
track of the object's owner and time of creation. This can be useful in
crosschecking the contents of our source control system with our database.
o sysdepends
This table stores dependency information about objects. For example, when
a stored procedure, view, or trigger is created, there can be references to
other tables, views, or procedures within it. These references are known as
dependencies. If one of the dependent objects alters, we may need to
recompile the stored procedure. For example, if we alter an index on a
table, we should recompile every dependent object.
o syscomments
This holds the original SQL definition statements of the stored procedure. It
also holds details of views, rules, defaults, triggers, CHECK constraints, and
DEFAULT constraints.
These tables are safe only for interrogation, although details within them can always
change between SQL Server releases. One of the best methods to ensure that the code
stored in your source control system matches that within your database is to check if
the dates and times match or are within a few seconds of each other.
!Although we have mentioned these tables, we strongly advise that you should
never alter any information in these tables directly.
10
Why Use Stored Procedures?
Performance Consideration
When a stored procedure is created, it passes through several steps. First of all, the T-
SQL is parsed and resolved, saved to the disk, and stored in SQL Server. The first time
the procedure is executed, the procedure is retrieved and optimized, on the basis of
any data queries and values passed through parameters. SQL Server will inspect the
code and try to use the best indexes on the tables, which are referenced by checking
the statistics that are held for those tables.
The query plan is then cached within SQL Server, ready for any further executions.
SQL Server will always use this plan, providing it doesn't retire the plan. Thus, the
performance gain of stored procedures comes from compiled cached plans.
Network Consideration
You may consider passing T-SQL statements to insert a row into a table, with very few
characters. However, creating a stored procedure and passing only the name of the
stored procedure, parameters, and their values reduces the characters needed. We can
see the extra overhead imposed by the T-SQL statements on our network by
multiplying this difference by the number of calls being made. This can be a significant
issue, especially if we are using it over the Internet.
Ins_Emp1oyeeTerritories @empId=3,@terrId=12345
The first statement has 74 characters, while the second has 46 characters, differing by a
mere 28 characters. However, if this was a more column-intensive insert, with 10,000 of
these in a day, for example, this amounts to almost 280k of wasted bandwidth! What if
an image data type was being uploaded or downloaded? Anything that is of binary data
type, such as images or sounds, and so on, is sent as binary values. These are
converted to character strings, and this will double the size of the ad-hoc query that we
are sending, when using T-SQL inline.
11
Chapter 1: Stored Procedures Overview
Another gain from using stored procedures is that they are much simpler to maintain,
as compared to raw T-SQL code. Since the stored procedure is held centrally within the
database, any required bug fix, upgrade, or modification can be completed centrally,
thus reducing the downtime. If the code is embedded within a program, as in VB.NET,
we have to not only change the code in one central place but also distribute it to every
client running the software. Modification of web sites also brings in its own set of
problems, and rolling out a new ASP .NET client can prove problematic. This can be
settled by using stored procedures.
The code in a stored procedure is executed in a single batch of work. This means that
it is not necessary to include a GO command while writing code for procedures. SQL
Server will take any of those statements and implicitly execute them, as a batch.
Perhaps, the greatest reason to create a stored procedure rather than use inline T-SQL,
is security. As we will discuss in Chapter 8, we have several security options at our
fingertips while using a stored procedure. Along with other security measures, it helps
to ensure that we can lock down our database from prying eyes.
Stored procedures are rarely used for creating other database objects with
the exception of temporary tables, which are special tables created to
complete a task within a stored procedure. There is more on temporary
tables in Chapter 4.
Replication
Stored procedures can also be used to work with databases involved in replication. By
creating a specialized custom stored procedure, which is placed on each pUblishing
database, it is possible to resolve any row UPDATE conflicts that may occur. Stored
procedures can aid in replication processing, and also ensure that a replicated database
is optimized. We won't be teaching you about replication in this book, but we bring up
the subject to ensure that you are aware of potential problems that can arise with
stored procedures in a replication scenario.
For example, the publisher places each update into the log reader for publication to each
subscriber of the database. The Distribution Agent takes one row at a time, distributes
them to the subscriber, and updates the subscriber database. If there is more than one
subscriber, or if there is a delay due to connection speed or network traffic, the
subscriber can lag behind, if there is no break in processing at the publisher's side.
12
Designing Good Stored Procedures
In a real life scenario, at one installation, we had a very fast publisher and subscriber
link (between London and New York). Traffic on one table was relatively light, but due
to stock market conditions an update had to take place. The developer in question
didn't realise that they had to update 100,000 rows, so off they went, and altered the
data. The publisher updated fairly quickly, but the subscriber took 3 hours to catch up.
How does replication, and problems like this fit into this book? In the above example,
if the developer had placed the updates in a stored procedure and made it a
procedure execution article, then SQL Server would have replicated the execution of
the stored procedure and not the updates that took place.
! You have to be 100% sure that the data in the publisher and the subscriber
databases are consistent. If not, you can have a failure on one of the
databases, but a success on another, thus compounding the data
inconsistency. This can come about as a result of other transactions and data
modifications being successful on the publisher, but not yet applied by the
log reader on the subscriber.
If we have an isolation level that can allow dirty reads, then we can insert data into a
table before a previous modification has been committed.
1. AB with any other programming language - keep it simple. Don't make your
procedure complex to read and understand if it is only going to save a few
microseconds of processing time. If a stored procedure is complex to
understand, then applying bug fixes or upgrading will need a formidable effort.
2. Document your code, especially if you have to create a complex section of
code. Throughout the stored procedure, place comments with a description of
the stored procedure and any changes made at the top. This is even more
crucial if the source control system that you are using doesn't have this ability.
13
Chapter 1: Stored Procedures Overview
3. At processing time, T-SQL works well with a set. Therefore, avoid cursors
wherever possible; even if it means using two or three steps or maybe even
a temporary table. This rule will be covered in detail in Chapter 3.
Don't rule out cursors totally, though. There will be times, although
relatively rare, when they will be more beneficial to the overall processing.
4. If you pass parameters, then ensure that the values are within an acceptable
range, especially if the parameter is optional and a value of NULL is
permissible. If this is the case, then keep results in mind when this
parameter forms part of a WHERE filter or a JOIN criterion.
5. Always clean up. If you have used a cursor, close and deallocate it, so that
memory and resources are freed up. Similarly, if you are using temporary
tables, ensure that you explicitly drop them. A temporary table defined
within a stored procedure can exist only for the lifetime of that process.
However, if the stored procedure has been called from a parent process,
and if it is an iterative process, then the temporary table may exist beyond
the lifetime of the process.
By dropping the temporary table explicitly, even if the code is moved from
the stored procedure and run as standalone code within Query Analyzer, it
will ensure that the table is cleared up. If you do not do this, then the
temporary table will remain until the Query Analyzer session is closed, the
temporary table is dropped through T-SQL code from within that Query
Analyzer session, or SQL Server is recycled.
6. When a stored procedure is complete either through an error or a successful
process, ensure that you return a value. This is a simple method of checking
that the stored procedure has terminated as you were expecting, and if not,
then you can then deal with the problem within the calling procedure.
Data integrity
Within a database, there are three different levels of integrity - domain, entity,
and referential
o Domain integrity
Domain integrity ensures that the values for a specific column are valid and
meet the relevant business rules. This is enforced through CHECK
constraints, DEFAULT values, and FOREIGN KEY constraints.
o Entity integrity
Entity integrity ensures that every row within a table is unique. This
integrity is enforced through UNIQUE constraints and PRIMARY KEYS.
14
Data integrity
o Referential integrity
Referential integrity ensures that relationships between tables are maintained.
It can be enforced through FOREIGN KEYS as well as cascading updates.
This is the only type of integrity that is enforced by stored procedures.
We will examine data integrity in Chapter 7, when we look at triggers, which are ideal
to ensure referential integrity.
Every night on our production server, once the overnight processing and backups have
been done, special stored procedures execute T-SQL commands to check if everything
is in order. These are mainly DBCC (Database Console Commands) statements, which
run when system usage is low (as they can be quite CPU and process-intensive).
The system procedures, which run these commands, are usually placed in jobs. If an
error occurs, these procedures will fail, and hence the job fails too. It will then produce
a page or e-mail, so that DBAs can check and fix the error manually. These DBCC
commands are usually run to list errors, but it is also possible to set them up to
automatically correct the errors. This needs extreme care, however.
We can also expand this by building stored procedures to be executed when SQL
Server starts up, known as recycled procedures, which can be used for checking the
integrity of the database. For example, we can set up auto reboot when the server
gives the 'blue screen of death', so that when the server reboots, SQL Server also
reboots, and is available for use again. By building a stored procedure that checks the
tables and data, or maybe even automatically fixes problems found, so that we are
back to a stable scenario after the crash.
If you meet the 'blue screen of death', it is advisable to carry lots of checks on the data
as well as the transaction log. Many corporations include their overnight checks as part
of the startup check. Thus, you can really gain by having stored procedures that run
when the SQL Server automatically starts up.
By executing the following system stored procedure, it's possible to check if this option
is set for the database:
15
Chapter 1: Stored Procedures Overview
If you receive the following message, the configuration option' scan for startup
procs' does not exist:
Then you need to run the following. This message indicates that advanced options are
not set to be displayed, and the advanced option setting is:
mllll@
The first column is the name of the option, the next two are the minimum and maximum
values that the option can have, confi!Lvalue is what the option is currently set to by
sp_configure, whereas run_value is the setting when the option is actually used by
SQL Server.
If a value of 1 is returned, then you can create and set up procedures to run
automatically. To set this option you will execute:
If we wanted a stored procedure to run when SQL Server starts up, we can do this
through the sp-procoption system stored procedure. I won't give a specific example,
as stored procedures designed to run at startup need a great deal of consideration.
However, once you have your procedure, the syntax is demonstrated here:
Note the case on the parameters. On most installations this is not vital, but if
you use a collation that is case sensitive you will need to use the above case.
!If SQL Server refuses to start and the problem can be an auto start procedure,
then you can start SQL Server from a DOS prompt with minimal configuration
to allow you to remove any problem, by using the -f option as shown below
>sqlservr -c -f
16
Calling a Stored Procedure
You can skip EXEC(UTE), but you will need it if you run one stored procedure
within another.
However, this is not the most efficient way to call a stored procedure. When such a
command is processed, SQL Server has a hierarchical method of finding a stored
procedure and executing it. First of all, it will take the login ID of the user who wants
to execute the procedure and see if a stored procedure of that name exists. If it
doesn't, then SQL Server will look for the stored procedure under the DBO login.
Hence, always fully qualify your stored procedure with the owner.
You will find stored procedures within SQL Server that start with sp_ but these
are resewed for system stored procedures. We will look at them in Chapter 6.
So how do we name our stored procedures? There are different naming standards and
methods that we can employ. However, a commonly followed one is to prefix the
stored procedure with what it does. If a stored procedure inserts data, then it will be
prefixed with ins_, if it's returning rows of data then we will use sel_, and so on.
This naming convention is for main stored procedures that are used as part of the
system. When it comes to writing procedures to be used for supporting the system,
then we may prefix the procedure with util_ for utility, or sup_ for support. Note
that following this convention, triggers would be prefixed with tr_, and user defined
functions with fn_.
17
Chapter 1: Stored Procedures Overview
If you are using a common database for several applications, then prefix stored
procedures for common functionality with the name of the database, and ones specific
to a separate system with a pseudonym for that system. For example, if northwind
has a procedure that accesses pubs, then we will name it as pub_sel_Authors.
Other rules include not using spaces in the name, or any 'specialized' characters such
as %, &, and so on. Underscores, _, are allowed, and are the preferred method of
naming tables and columns rather than using spaces. If you do wish to use a space
instead, then while working with the object you will need to surround the name with
square brackets.
Most procedures have parameters passed to them. It is vital that every parameter is
tested to ensure that its value is within a valid range, especially in stored procedures
for updation, where a parameter is used as part of the WHERE row filter criteria, if an
invalid value is submitted we can end up updating every row in the table. Of course, it
is impossible to check for a wrong value that unfortunately fits in the range.
One of the problems with stored procedures is the lack of comments within them.
Even the simplest of stored procedures should have comments. Every stored procedure
should also contain a quick description of itself, at the top. A more complex code
should be properly commented throughout and the comments should be up to date.
Ifyou use the source control software, ensure that it resides on a drive that
is backed up nightly.
The source control system may also be capable of automatically updating comments
defining the version, the date and time of the last check-in. This can prevent rogue
updates to the stored procedure code, which hasn't gone through the source control
system, but it is not foolproof. It is possible to create a system stored procedure
capable of checking this comment value, with a value entered within a system table
when the stored procedure was created.
18
Modifying Stored Procedures
The ALTER PROCEDURE statement will also reset the QUOTED_IDENTIFIER and
ANSI_NULL parameters, just as a DROP and CREATE will, so take care to maintain the
same settings, as there were before, when working on a stored procedure.
It is best to have these as company standards so that problems don 't exist
upon any alteration.
The system stored procedure sp_depends will list all the objects dependent
on the object name that is passed to it.
Recompiling
When a stored procedure is created and placed in SQL Server, it will sit in the database
until it is executed for the first time. At that point, SQL Server compiles the procedure
optimising it based on current statistics on the tables used. If it is a subsequent
execution, then there are two possible scenarios:
If an index or even columns are added to a table, and if they are likely to alter the
query plan that has been built up for the set of tables used, then we should recompile
all the dependent stored procedures, otherwise our stored procedure may not utilize
the best method for accessing the data.
19
Chapter 1: Stored Procedures Overview
In all these situations, performance gains can be obtained if the stored procedure was
recompiled before each execution. Keep in mind that these are stored procedures that
process a heavy workload, but run very infrequently.
Use this option with care and only if it totally necessary for
your solution. Using this option will slow down the
execution of the stored procedure, as there will be a
recompilation with each execution.
You can also manually recompile a stored procedure using the sp_recompile
command. You will use this if you alter indexes on a table and do not expect a SQL
Server recycle prior to the stored procedure being used. More on this subject will be
covered in Chapter 2.
Parameter Usage
Data will be passed in and out of a stored procedure, even when the purpose of the
procedure is not to return information. All variables defined as parameters have to be
prefixed with an @ sign. The normal practice is to define input parameters before any
output parameters.
As with any column in a database, use the data type that is most appropriate for the
parameter and if the parameter has to match with a column in the table, then ensure
that both the data types match exactly.
20
Flow control
If the parameter does not match a column but will be still used, for example, as a join
condition or a filter condition, then use a data type and size appropriate to the type of
data, rather than have everything as character data type. Also, wherever possible, use
varchar or nvarchar rather than char, just as you will in your inline T-SQL, which
will avoid unnecessary spaces being passed across networks.
Flow control
This section will deal with ensuring that our stored procedure flows correctly. Although
we will cover some T-SQL statements here, as we have indicated earlier, it is not within
the scope of the book to teach you how these statements should be coded.
In the following snippet, we have two similar stored procedures. The difference is in the
use of the BEGIN ... END code block. Executing the first one will execute the second
PRINT statement, as the IF statement will take only the first line as part of the decision:
Compare it with the following snippet. Here, neither of the PRINT statements will
be executed:
21
Chapter 1: Stored Procedures Overview
BEGIN
PRINT @var1
PRINT @var2
END
END
Now that we know how to demarcate blocks in our code, we can look at the IF
statement in more detail.
Decisions
There are two main ways to make decision in SQL Server. The first one makes
decisions throughout our code, whereas the second one bases decisions on data
returned in specific columns from the returned rows. There are other statements, such
as NULLIF, which will return a NULL value if two expressions are similar, but this isn't
decision processing and is more of a comparison. Let's start with the first IF statement.
IF ... ELSE
This is a simple Boolean decision processing strategy, where a statement is evaluated
as either TRUE or FALSE. If the statement is TRUE, it will process the statements
immediately following the IF. If the statement is FALSE, then it will process the
statements following the ELSE statement, if there is one defined. If there is no ELSE
statement, then processing will continue after the END of that statement block.
The first statement works faster, as a simple SELECT statement takes the table and
processes the data.
IF @AvgFound < 10
Print 'Less than 10'
ELSE
Print 'More than 10'
Here's the execution plan of the above (we will have a more detailed explanation of
the execution plan in the next chapter):
22
Flow control
}I: . ,. . ,_ ......
St.-ream Agqregat .. ,Ord~r Deea11s.p ...
Con: 0\ Con: 100\
i
cw.
<----
COtllPut.e: Scalar
mI ;,
NI!-st@'d LooP:l/ln...
II]
Const.ant Scan
COl!llt: 0,"
Co.t: O' Co.. : O. Lo.t: 0._---
_01_
""--..,,...--
lOQlcol _ _ _
Row""""
EsUrnat~""' Mk:
I/O cost:
CPU cost:
~teeCoA;
&t::Jmat:~ row count:
~esc.
eon,..;.SC.....
o.oooroc
0.000216
I
IS
t
Q.04<Il
t
By letting the cursor hover over some of the details, you can see the underlying processing.
CASE
Unlike the IF statement that is placed in code as part of a decision-making process, CASE
can be found within any of the SELECT, UPDATE, and INSERT T-SQL data statements.
CASE statements won't work for DELETEs. To implement the CASE statement, two
different methods can be employed. The first method is known as the simple CASE
function. Here, an expression, which is to be tested, is the same throughout the
possible options available. Let's look at its syntax:
CASE input_expression
WHEN when_expression THEN result_expression
[ ... n)
23
Chapter 1: Stored Procedures Overview
This will be used, for example, when we have a column containing several values and
we want to translate this value into something more meaningful, such as the output in
the column. We can also include other SELECT statements. We can see this in action in
the following code:
END
There is a problem concerning the NULL values. In the following T-SQL, the Fax column
contains either a fax number or NULL. Here, we test the column to check whether it's
equal to another value however, we can't do this for NULL, where the test is ignored:
END
However, by using the second type of CASE statement, we can search for NULL values.
Again, let's begin by looking at its syntax:
CASE
WHEN Boolean_expression THEN true_result_expression
(..n]
(ELSE el se_result_express ion]
END
To solve the problem in our previous example, we can code the example as:
24
Flow control
CASE
WHEN FAX Is NULL THEN 'No Fax'
ELSE Fax
END AS Fax
FROM Customers
END
GOTO label
As with programming languages, labels are frowned on and it is better to avoid using
them. However, there is one exception - it is advisable to use them when you are
branching to the end of a procedure for doing some cleanup or error coding. At times,
even this can get messy, as you may have to code a GOTO around a GOTO label to
avoid error processing. To clarify this, let'S examine the following code:
IF @@ERROR > 0
GOTO Error
GOTO ProcEnd
Error:
ProcEnd:
RETURN
It is necessary to use GOTO ProcEnd for avoiding normal processing from slipping into
the Error: labelled routine. In this instance it is not too confusing, but it can be, in
complex stored procedures.
Loops
At this point, we will not look at looping through a cursor, as cursors are covered in
Chapter 3, which leaves us with one method for looping around a set of code.
WHILE Boolean_expression
{ sql_statement I statement_block
[ BREAK l
{sql_statement statement_block
[ CONTINUE l
25
Chapter 1: Stored Procedures Overview
BREAK breaks the loop and passes the control to the statements outside the code block,
while the CONTINUE statement will resume processing from the beginning of the loop.
SET @var1 = 1
SET @var2 = 1
WHILE @var1 < 10
BEGIN
IF @var2 > 100
BREAK
SET @var2 @var2 + @var2
SET @var1 @var1 + 1
END
PRINT 'Var1=' + CONVERT(CHAR(3).@var1) + ' and Var2=' +
CONVERT(CHAR(3),@var2)
END
As with the IF statement, its common to see a WHILE statement working with a
SELECT criterion.
There is a more efficient and controlled method to achieve this and also make the
environment more secure, and that is to use SQL Server Agent and create a job. Here, you
can proVide various functionalities, such as e-mail notification of any failures, a more
controlled start and end timings, as well as logging of the success or failure of the task. You
can pause a stored procedure in multiples of a minute within a job in SQL Server Agent.
! Be extremely careful in your use ofWAI'l'FOR ( ) . It will stop the processing of any
stored procedure containing this statement until the time is reached or until the
delay as expired. Any locks in this stored procedure will obviously stop any other
stored procedure until the locks in the WAI'l'FOR () procedure are released.
Although it's a useful command, you can easily put your system in trouble if you
get it wrong, for example, when you get the delay calculation wrong.
26
Nesting in Stored Procedures
SQL Server puts a limit of 32 on the number of times that a stored procedure can be
called by itself. However, things can go wrong even in that time frame, so it's always
advisable to have a good 'drop out' scenario. One method is to check the recursion
level that we are at by using the @@NESTLEVEL system configuration function. To
demonstrate nesting levels through recursion, check the following system function that
we have to add to SQL Server. This example calculates the factorial of a number:
IF @ValIn != 1
BEGIN
SET @WorkValln = @Valln - 1
PRINT @@NESTLEVEL
EXEC ut_Factorial @WorkValIn, @WorkValOut OUTPUT
SET @ValOut = @WorkValOut * @Valln
END
ELSE
SET @ValOut 1
END
Cannot add rows to sysdepends for the current stored procedure because it depends on the
missing object 'utJactorial'. The stored procedure will still be created.
We know that the maximum nesting level will be the first value passed through
@ValIn, as it reduces by one on each call to the procedure. We also have to check
that we do not have more than a 20 level recursion invoked by the test at the top of
the procedure.
27
Chapter 1: Stored Procedures Overview
We can see this in action with the following T-SQL code. The first digits listed will be
the PRINT statement on the @@NESTLEVEL, which will show our current nesting level.
We have to drop out here, if we have nested too many times:
ifyou execute a stored procedure that calls another stored procedure, the
called stored procedure can access all objects created by the first stored
procedure, including temporary tables, but cannot access values in the
variables defined in the first procedure. Variable scope is local to that 'call'.
Returning Values
In most of our stored procedures, we will either modify or return a set of data. You
may also wish to return some value that signifies a successful or failure. In the
remaining stored procedures, we will perform some business functionality, where we
may return values calculated during that time.
There are different ways to return this sort of information and it depends on the
number of values we wish to return and also how we wish to handle these within
either other stored procedures or calling programs. Let's look at each method now.
RETURN
This is either implicit or explicit within a stored procedure, and will execute as the last
statement of a stored procedure. This statement terminates the stored procedure
immediately, with no further statements executing after this statement.
If RETURN is specified, then a value of 0 is returned, however, we can also return our
own integer value. The normal practice is that a negative number returned indicates that
an error has occurred. Apositive number indicates some other reason, but it is often used
to return the number of rows that have been returned or modified within a statement.
28
Another Random Document on
Scribd Without Any Related Topics
saw on the faces of every one of his companions. “The next time we
try to toll a flock of canvas-backs, remember what I told you about
their sharp eyes, and be careful to keep out of sight. Look at Bogus!
He thinks he was to blame for it, and he expects a whipping.”
The boys glanced toward the beach, and there was the dog which
had done his part of the work so faithfully, going through all sorts of
antics, and saying, as plainly as a dumb brute could say it, that he
was very sorry the flock had gone off without giving the young
hunters a chance for a shot, and that, if it were his fault, he would be
careful to do better next time. First, he would sit up and beg, and
then he would lie down and hold up both his paws imploringly, as if
he were trying to ward off the blows of a switch; but a friendly word
from Egan dispelled all his fears, and made a happy, light-hearted
dog of him again.
“You didn’t do it, old fellow,” said the boy, as Bogus came
bounding to his side; “and I can’t think what did do it, unless one of
these careless friends of mine—— Hold on! I take it all back. There’s
the cause of the trouble,” added Egan, nodding his head toward the
upper end of the bay.
The others looked in the direction indicated, and saw Enoch
Williams’ schooner coming down under full sail. Whether or not her
crew knew that Egan and his companions were trying to toll the
ducks within gun-shot, was a question; but they knew it a moment
after they hove in sight, for the young hunters arose from their places
of concealment, and stood out in full view of the schooner, which ran
down as far as the foot of the island, and then came about, and
started back up the bay.
“That move seems to indicate that they knew we were here, and
that they came down on purpose to frighten the ducks away,” said
Hopkins, with no little indignation in his tones.
“What else could you expect of such fellows as they are?”
demanded Egan. “Never mind. There is more than one flock of
canvas-backs on the bay, and they can’t drive them all away from us,
no matter how hard they try. Now, we will take a short sail, and then
we will run back to Eph’s, and get our terrapin.”
As it happened, Hopkins and Egan were both mistaken in their
opinions regarding the object the schooner’s company had in view
when they followed the Sallie down to Powell’s Island. Enoch and
Jones had an idea in their heads, but they did not know that Egan
and his friends were after the ducks until they saw them rise from
their hiding-places. They were acting as volunteer spies upon the
movements of Egan and his guests, and if we step aboard the
schooner, and listen to some of the conversation that took place
between Enoch and his two companions, we may be able to
understand why they did it.
It will be remembered that Egan and his guests had got into the
way of spending a portion of their vacations at one another’s homes,
the first being spent in Mississippi. When Lester Brigham saw how
they enjoyed themselves at Don Gordon’s Shooting box, he
proposed to his friends, Enoch and Jones, that they should pass their
vacations in the same way; and so it came about that while Egan,
Hopkins, and Don and Bert Gordon were hunting and fishing with
Curtis in the wilds of Maine, Lester’s Maryland friends were visiting
with him at his home near Rochdale. It was not accident that had
brought them all together in Maryland during this particular
vacation. Lester had come there with a fully developed plan in his
head, and Enoch and Jones were ready and eager to help him carry it
out. Lester and Jones had been at Enoch’s home two weeks,
impatiently awaiting the arrival of Egan’s guests, who, as we have
said, were sojourning with Hopkins, enjoying themselves in shooting
quails and snipes. On the morning of which we write they went out
for a sail on the bay before breakfast, and it was while they were on
their way home that their eyes were gladdened by the sight of the
Sallie under sail.
“There they are at last!” exclaimed Enoch, who was the first to
discover Egan’s boat as she moved gracefully away from her
anchorage. He was standing at the helm of his schooner, the Firefly,
and Lester and Jones were sitting near him in the cock-pit.
“They? Who?” inquired the former, who, for a wonder, happened
to be thinking about something besides his contemplated revenge on
the boys who had unintentionally excited his jealousy.
“Why, your particular friends, the Gordon boys.”
“Good!” exclaimed Lester. “I wonder if they are all there.”
“If you will run down and get the spy-glass you can soon find out,”
was the reply.
The glass was brought, passed rapidly from hand to hand, and
then the three plotters looked at one another while a smile of
triumph lighted up their faces. They saw the Sallie frighten away the
ducks that were about to swing to the decoys that were anchored
around the sink-boat, and Enoch and Jones were so delighted when
they saw the occupant of the boat rise up and flourish his fists in the
air, that they could scarcely refrain from shouting.
“They have got themselves into trouble already,” said Enoch, as he
brought the glass to bear upon the angry gunner. “That man in the
sink-boat is Amos Barr. They have made him mad by scaring away
his ducks, and I am glad of it, for he is one of the most vindictive men
on the bay.”
We have already told how the two yachts passed each other
without any exchange of courtesies between the crews. The Firefly
ran between the decoys and the shore and was thrown up into the
wind, so that her skipper could talk to the man in the sink-boat.
“Good morning, Mr. Barr,” said Enoch, pleasantly. “Egan came
along just at the wrong time, didn’t he?”
“He is always around when he ain’t wanted, and I told him so,” was
the gruff response.
“Do you believe it is all unintentional on his part?” asked Jones, in
a significant tone. “Don’t you think that he does it on purpose—that
he is just snooping around to see what he can find that is worth
looking at?”
“I know it,” answered Barr, shaking his clenched hand at the
rapidly receding cutter. “When he told that detective that I was a
duck-shooter, and that I and my partners had a big gun hid
somewhere about the bay, didn’t he do it a purpose? Of course he
did. He wanted to get me into trouble; but he wasn’t by no means as
smart as he thought he was. We had more’n one big gun, me and my
partners did, and—by the way, did you know that we had got our best
gun back?”
“No!” replied Enoch, who was surprised to hear it.
“Well, we’ve got it safe and sound, and if one of them detectives
ever gets a chance to put an ugly hand on it again, I’m a Dutchman.
Simpson, he—but I don’t reckon I had best say any more,” said Barr,
with a hasty, suspicious glance at Lester.
“O, you need not be afraid of my friend Brigham,” exclaimed
Enoch. “He is true blue, and he hates Egan and all his crowd as
cordially as Jones and I do. What about Simpson?”
“Mebbe I will tell you all about it some other time,” answered Barr,
cautiously. “’Tain’t best to say too much to nobody these times.”
“I know that. Those ‘gentlemen sportsmen’ (Enoch sneered as he
uttered the words), who live up north, and rent some of our
shooting-points, are bound to break up your business if they can.”
“And how would they feel if we-uns should go up where they live,
and set about breaking up their business—should try to take the
bread out of the mouths of their children?” exclaimed Barr, in savage
tones. “The birds we shoot bring we-uns in our grub and clothes.
Being wild, they don’t belong to nobody; but they belong to we-uns
who live here, more’n they do to folks who don’t live here, and we
have a right to get ’em in any way we can. Them fellers up north can’t
break up our business, for we won’t let ’em; an’ as for the folks who
live round here and tries to help ’em do it—”
“Fellows like Gus Egan, for instance,” interrupted Enoch.
“Yes, he is one of the worst in the lot of the mean fellers that won’t
let us shoot the ducks because they want to shoot them theirselves,”
assented Barr. “As for him, and others like him, that I could call by
name if I wanted to, they are getting theirselves deeper and deeper
into a furse every day. Something’s going to happen if them
detectives comes down here this season. You hear me speaking to
you?”
As Barr said this, he played with the lock of his heavy duck-gun,
and looked very fierce indeed.
CHAPTER III.
BARR’S BIG GUN.
“I don’t blame you for being angry,” said Jones, after a few
minutes’ pause. “I hold as you do, Mr. Barr—that the wild fowl
which come into this bay are the property of any one who can bring
them to bag; and that men who live hundreds of miles away, who
come here only once a year, and for a few days at a time, are taking a
good deal upon themselves when they presume to tell us how these
wild birds shall be killed. Those ‘gentlemen sportsmen,’ as Enoch
calls them, have no right to make laws for my government, and I
shall pay no attention to them.”
“No more will I,” said Barr, emphatically. “But I bet you I will pay
some attention to the fellers about here who are mean enough to side
with them and the detectives.”
“Was that you shooting last night?” asked Enoch, suddenly.
“I didn’t hear no shooting last night,” answered Barr, with another
sidelong glance at Lester.
“You have grown very suspicious since I saw you last,” said Enoch,
with some impatience in his tones. “But I tell you that you need not
be afraid to trust me or any one whom I endorse. We all heard a big
gun shortly after midnight, and I’ll bet my schooner against your
sink-boat, that if I were to look along the shores of Powell’s Island, I
could find the gun.”
Barr grinned, but made no reply.
“When are you going out again?” continued Enoch.
“Well, that depends,” said the gunner, hesitatingly. “If I see
nothing suspicious, I may go out the fore part of next week.”
“When you go, remember that we three want to go with you,”
added Enoch. “This fellow”—jerking his thumb over his shoulder
towards Lester Brigham—“is my chum and Jones’s. He lives way
down in Mississippi, and has never seen a big gun. We passed a
portion of our last vacation at his father’s house, and as Lester took
pains to show us every thing of interest there was to be seen in that
part of the country, we desire to reciprocate his kindness. You will let
us know when you are going out, won’t you? Hallo! What is the Sallie
doing back here? I thought she went on down the bay.”
So she did; but when Bert discovered that immense bed of canvas-
backs off Powell’s island, the skipper ran back to old Eph’s cabin
after his dog to entice the wild fowl within range. When Enoch saw
her, she was just rounding to in readiness to start down the bay
again. He and the rest watched her until she disappeared in the cove
at the head of the island, and then to quote from Lester Brigham,
Barr swore until every thing around him turned blue.
“Aha!” cried Enoch, and there was a triumphant ring in his voice.
“Didn’t I say that that big gun we heard last night was somewhere
around the island? If you think I can be of any service to you, I will
run down there and keep an eye on them. Of course they don’t know
that the gun is there, but if you go down, they will suspect it.”
“All right,” said Barr, in tones that were husky with passion. “Go
on, and I will do you a friendly act the first chance I get.”
“Will you let us go out with you the next time you use the big gun?”
inquired Enoch, as he put the helm down and motioned to Jones to
haul in a little on the jib sheets.
“Yes, I will; honor bright,” answered Barr, eagerly. “Say, Enoch,
the gun is hid in the bushes on the banks of that little cove on the
other side of the island. You just hang around and see whether or not
they stumble on to it, and if they do, let me know it at once. I will put
it in a safer place before I go home to-night. I see one of my partners
down there in his canoe. I wish you would hail him as you go by and
tell him to come up here. I may need him.”
The Firefly ran up the bay until she cleared the decoys, and then
rounding to, filled away for Powell’s Island. Her captain seemed to be
in a very jovial mood.
“Didn’t we promise that we would help you square yards with
those fellows?” said he, addressing himself to Lester. “I wouldn’t like
to be in their boots if they find that gun; would you, Jones?”
“No, indeed,” was the quick reply. “Barr is just on the point of
boiling over already, and he won’t stand much more interference
with his business.”
“What do you think he would do to Egan if he and his crowd
should find that big gun and take possession of it?” asked Lester.
“O, Egan would not dare do that,” answered Jones. “He has no
more right to touch that big gun than he has to take charge of this
schooner. The most he could do would be to tell an officer where the
gun was hidden, and if he did that, Barr would improve the very first
opportunity he got to destroy some property for him or his father.”
“But how would that help me square yards with Don and Bert?”
inquired Lester. “I don’t like Egan, because he is Don’s friend; but
still I don’t care to see him injured.”
“Well, I do,” said Enoch, spitefully. “I haven’t forgotten how
squarely he went back on me during my first day at the academy.
There I was, a stranger in a strange place, and he wouldn’t introduce
me to a single student; and when he walked off toward the gate with
some of his chums, he told me to stay behind because he did not
want me along. Do you think I shall ever forget that? Not much.”
“It seems that Barr has got his big gun back again,” said Jones. “I
mean the one the detectives found on information furnished them by
Gus Egan.”
“I am not at all surprised to hear it,” replied Enoch. “You see,” he
added, turning to Lester, “this man Simpson, of whom Barr spoke, is
a local detective, who has long been suspected of being in sympathy
with the big-gunners; and you know Barr hinted that it was through
him that he got his big gun back. The detectives often play into one
another’s hands, and I believe that for a hundred dollars Simpson
could be bribed to do almost anything. Look there, Brigham! Did you
ever see such a sight before?”
Up to this time the Firefly had been kept behind the island, so that
her approach would not be detected by the boys whom Enoch
intended to watch; but now she was obliged to stand out into the bay,
and, as she rounded the headland, Enoch caught sight of the flock of
canvas-backs which old Eph’s dog was tolling in toward the beach.
“No, I never saw so many ducks in one flock before,” replied
Lester, as soon as he had somewhat recovered from his surprise.
“Why, Diamond Lake would hardly hold them. Don’t those look like
heads over there in the grass?” he added, directing Enoch’s attention
toward the cove where the young wild fowlers were concealed.
“They are heads,” said Jones, after he had taken a look at the
objects through the spy-glass. “They were tolling that flock, and we
came up just in time to spoil their sport for them.”
“If I could have my way, they would never have the pleasure of
shooting a wild duck or anything else as long as they live,” snapped
Lester.
“We have found them,” said Enoch. “Now we will sail around, far
enough from the shore to avoid arousing their suspicions, and keep
an eye on their movements through the glass. Barr’s big gun is
hidden somewhere near that cove, you know.”
Enoch kept on down the bay without one word of apology to the
boys on shore for frightening away the ducks, while Jones, at his
suggestion, settled himself down on a cushion in the cock-pit to
observe and report upon the actions of Egan and his party. The
latter, all unconscious of the fact that they were being closely
watched, strolled leisurely along the shore of the cove in the hope of
picking up a few brace of snipes for their next morning’s breakfast;
and although they did not find the game for which they were looking,
they found something else for which they were not looking. Jones,
through the glass, saw them stop all on a sudden, and bend down
until their heads disappeared from view. They were out of sight for a
long time, and when they again arose to an upright position, three of
them were tugging and lifting at something which seemed to be
about as heavy as they could manage with their united strength.
When Jones saw that, he uttered a loud ejaculation of astonishment.
“Enoch,” he exclaimed, “give me the tiller and you take the glass—
quick. Those fellows have found it, or else I am very much mistaken.”
Enoch seized the glass, and one look was all that was needed to
show him that the sharp-eyed young hunters had unearthed the
poacher’s hidden treasure.
“It is Barr’s big gun, sure enough,” said he. “They are trying to
stand it up on end so that they can take a good look at it.”
“One would think, from the way you talk, that you were glad of it,”
observed Lester.
“And so I am,” answered Enoch, gleefully, as he passed the glass
over to Lester and resumed his place at the tiller. “Do you not see
that Barr will be awful mad when we tell him of it, and that he will do
something to pay Egan for snooping around in this way? Now we will
run up to his sink-boat and see what he is going to do about it.”
“By gracious, Enoch!” exclaimed Jones, suddenly. “Just look at
that, will you?”
“Whew!” whistled the skipper. “It is all up with the big gun now.
Barr has seen it for the last time.”
Lester looked down the bay in the direction in which his two
companions were gazing, but could discover nothing to call forth that
long-drawn whistle of surprise from Enoch. All he could see were a
few oyster and pleasure boats, and a neat little steamer, which was
coming up with a heavy bone in her teeth.
“That is a police-boat,” explained Enoch, noticing the inquiring
look on Lester’s face. “They run around night and day searching for
illegal duck-shooters and oyster-dredgers. What is the matter now,
Jones?” he added, as his companion uttered another exclamation of
surprise.
Jones did not reply until he had snatched the glass from Lester’s
hand and taken a long look at the boys on shore; then he said slowly:
“Egan is signaling to the police-boat to come in and get the gun, as
sure as I’m a foot high.”
“No!” cried Enoch, who thought the news too good to be true. He
wanted Egan and his friends to do all the mischief they could, so that
he would have an exasperating report to make to Barr when he went
back to the sink-boat.
“But I say he is,” insisted Jones. “I can see him waving his hat.
There! do you believe it now?” he continued, as the steamer gave one
short, quick toot on her whistle to show that Egan’s signal was seen
and understood.
Yes, Enoch believed it now; especially, when he saw the police-
boat turn her bow toward the cove. She ran as close to the shore as
the depth of the water would permit, then rang her stopping bell, and
presently Jones announced that the crew were putting one of the
small boats into the water.
“I tell you Barr has seen that big gun for the last time,” repeated
Enoch. “He may be able to bribe a private detective; but the State
authorities, as a general thing, don’t do business that way. Won’t
Barr be hopping when he finds it out? We can’t do any thing to save
the gun, and neither can he; so we might as well run down there and
look on.”
The Firefly came about and bore down toward the cove, running in
between the steamer and the shore so that her crew could make a
note of every thing that was done by the police, and perhaps overhear
some of the conversation that took place between them and the
young wild fowlers; but in this last hope they were disappointed.
More than that, they had the satisfaction of discovering that they
were suspected of something themselves. For, when one of the
officers who went off in the small boat began talking in rather a loud
voice, Egan said a word or two to him in a low tone; whereupon the
officers faced about, and stared so fixedly at the schooner’s crew, that
the latter began to feel uneasy. But they saw the big gun put into the
boat, and then the Firefly filled away and stood up the bay again.
“Great Scott!” exclaimed Lester, when they were fairly under way;
“I never saw a gun like that before. How long is it, and how much do
you suppose it weighs?”
“It is ten feet long, and weighs a hundred and sixty pounds,”
snarled Enoch, who was fully as angry as he expected Barr to be
when he heard the report they had to make. “Say, Jones, did you
notice how quickly those officers stopped talking, and how hard they
looked at us when Egan spoke to them?”
“I did,” was the reply; “and it struck me at once that he was telling
them something that he would not dare say to our faces.”
“That was, and still is, my opinion,” continued Enoch. “Now, the
only way we can get even with him for that is to make out as bad a
case against him as we can when we report to Barr.”
“Why can’t you take his punishment into your own hands?”
inquired Lester. “You can do as much damage as you please, and
unless you are surprised and caught in the act, it will all be laid to
Barr’s account.”
“I say,” exclaimed Enoch, gazing admiringly at Lester, “your head
is level yet, isn’t it? That is a proposition worth thinking and talking
about at some future time. Now, then, here we are.”
The Firefly was by this time almost within hailing distance of the
sink-boat. She had two occupants now, for the “partner” of whom
Barr had spoken, and who had been hailed by Enoch and sent up to
the sink-boat, had pushed his canoe through the decoys, and was
talking earnestly with his companion in guilt, while waiting for the
captain of the schooner to come back and make his report.
“Now, then,” exclaimed Barr, as soon as he could make himself
heard, “is your news good or bad?”
“Bad enough,” was Enoch’s reply. “The Magpie sent a boat ashore
and gobbled up that big gun of yours.”
The “partner” looked incredulous, but Barr saw no reason to doubt
the truth of the report. He jumped to his feet with so sudden and
strong an impulse that he came within a hair’s breadth of losing his
balance and going headlong out of the sink-boat; and when he had
recovered his perpendicular, he found relief for his feelings in a
volley of the heaviest kind of oaths. If swearwords could have sunk
the Magpie (that was the name of the police-boat), the officers who
captured his big gun never would have seen Baltimore again.
“You needn’t bear down so heavy on the police,” said Enoch, as
soon as he saw a chance to crowd a word in edgewise, “for they
would not have known that the big gun was there, if it had not been
for that meddlesome fellow who took it upon himself to play the spy
upon your actions last season.”
“You mean Gus Egan?” said Barr, inquiringly.
“He is the very chap,” replied Enoch. “We found him and his party,
which is made up of boys as mean as he is, in the cove, trying to toll
in a flock of ducks with old Eph’s dog; but that was only a blind.
When we came up and frightened the ducks away, they went down
the beach and found the gun as easy as falling off a log. Just then the
police-boat came up and they signaled to her, and she went in and
brought away the gun.”
Upon hearing this, Barr went off into another paroxysm of rage,
flourishing his fists in the air and dancing about in the sink-boat,
while the “partner” clung to the sides to keep from being thrown out
by his companion’s wild antics, and swore softly to himself.
“We ran alongside the police-boat, thinking that we might hear
something that would be of use to us, but Egan put the officers on
their guard, talking to them in a tone so low that we could not hear
what he said,” chimed in Jones. “We owe him one for that.”
“I am afraid you will never get any more ducks with that gun,” said
Enoch, consolingly.
“I know I never shall,” growled Barr, who, having worked off a
little of his rage, was now seated quietly on the bottom of the sink-
boat. “Let’s pick up the decoys, Pete. I don’t feel like doing any more
shooting to-day.”
“I shouldn’t think he would,” said Enoch, in a low tone. “If I were
in his place I should feel much more like hunting up that Gus Egan
and giving him a good thrashing.” Then raising his voice, he
continued: “You won’t forget your promise, will you, Mr. Barr? You
will let us know when you are ready to make another night excursion,
won’t you?”
But Barr was too angry, or too busy with his decoys to reply. Enoch
did not dare press the matter just then, for fear of defeating the
object he had in view; and as he could not think of anything that he
cared to add to his report, he bade the big-gunners good-by, and filed
away for home. On the way the Firefly passed Mr. Egan’s house, and
Jones pointed out to Lester the berth the Sallie always occupied
when she was not in use. Lester saw at a glance that it was a lonely
and retired spot, and so far from the dwelling that a tramp or
anybody else who wanted to go down the bay, and who thought it
easier to ride than to walk, could steal Egan’s yacht, or his father’s
oyster-boat, with little fear of detection.
“Well, then, suppose we try it to-night,” said Enoch, when Lester
had given utterance to the thoughts that were passing through his
mind. “Suppose we steal the cutter?”
“What shall we do with her after we get her?” inquired Jones.
“We’ll not do anything with her,” answered Enoch, glancing up at
the sky. “We will let the elements take care of her. There is wind in
those clouds, and plenty of it, too. It will be the easiest thing in the
world to come down here in a small boat after dark and slip the
chain, and I’ll bet there won’t be much left of the Sallie by the time
morning comes.”
Jones was prompt to say that he would gladly lend a hand, but
Lester, although he had often talked very glibly about doing
something of this kind, in order to be revenged upon Egan for
ignoring him and paying so much attention to Don and Bert Gordon,
did not seem to be very enthusiastic. He felt a good deal as he did on
the night he and the rest of the deserters from the academy ran away
in the Sylph. It was easy enough to sit down and talk about such
things, but when the time for action arrived, Lester was the first one
to stand back and let somebody else do the work and take all the
chances of detection and punishment.
“What do you say, Brigham?” demanded Enoch, after a little
pause. “Are you in for it?”
“O, yes; of course; certainly,” answered Lester, with great apparent
earnestness. “You can count on me every time. Didn’t I help you
rescue those people from the Mystery at the time she was wrecked?
Well, I will help you turn Egan’s cutter adrift this very night. I would
like much to see his face, and hear what he will have to say when he
comes out in the morning and finds his boat gone.”
“But you would not like to be within reach of his arm, if he thought
you had anything to do with helping that boat to get adrift, would
you?” asked Jones. “I know I wouldn’t, for a fellow who can knock
down three or four men and boys, as Egan did during that fight with
the rioters at Hamilton Creek bridge, is a good fellow to keep out of
the way of.”
Enoch and Lester had no reply to make to these words of praise,
bestowed upon the boy they so cordially hated; but they told
themselves, as they had often done before, that they would give
almost anything they possessed if they had showed a little more
pluck during those troublous times.
The Firefly ran on to her moorings, and her captain proceeded to
make everything snug in anticipation of the storm he had predicted.
They went ashore in the canoe which they had left tied to the anchor
buoy when they started out in the morning, and sat down to their
late breakfast with appetites that enabled them to do full justice to it.
They passed a few hours in roaming about the fields with their guns
in their hands, popping away at everything in the shape of a bird that
showed itself, and when the wind came up, driving before it blinding
sheets of rain and sleet, they retreated to Enoch’s room, where they
passed the time in reading and talking and watching the angry white-
caps on the bay.
Although the force of the gale decreased when the sun went down,
the white-caps still rolled wildly; but that did not in the least dampen
the ardor of Enoch and his friend Jones, who were fully resolved that
Gus Egan and his guests should not see any more pleasure in
cruising about in the Sallie, if it were in their power to prevent it.
They could scarcely restrain their impatience, so slowly did the hours
drag themselves along; but darkness came at last, and Enoch gave
the signal for action by picking up his hat and starting for the door.
“We could not have chosen a better night for the work,” said he,
holding fast to his hat, which the wind seemed determined to tear
from his head, in spite of all his efforts to keep it on. “Just let this
breeze get a good grip on the Sallie, and she is a gone cutter. Gus
thought he was seeing lots of fun to-day while he was helping those
officers steal Barr’s gun, and now he will learn, by experience, how
the loss of property affects a fellow.”
“But there is this difference,” added Jones, turning his back to the
wind so that he could catch his breath. “Barr was in a measure
dependent upon that big gun for his living, while Egan is dependent
upon his yacht for nothing but his pleasure-rides. He is able to buy
another boat if he loses this one, but poor Barr can’t replace that
gun.”
“I am glad he’s got another that the officers know nothing about,”
replied Enoch, as he unlocked the boat-house, and hung the lighted
lantern he had brought with him upon a convenient hook. “Now
catch hold, all of us, and shove her in.”
Lester Brigham, whose experience on the day he so rashly
volunteered to assist in rescuing the crew of the Mystery, had made
him very much afraid of rough water, was greatly relieved to find that
the craft, in which Enoch purposed braving the white-caps, was not a
canoe, but a staunch row-boat, with plenty of sheer, and roomy
enough to hold ten or a dozen men. Being mounted on rollers she
was easily managed, in spite of her size and weight. Lester assisted in
putting her in the water, and in five minutes more she was being
rowed rapidly toward the Sallie’s anchorage.
As they passed Mr. Egan’s residence Enoch took note of the fact
that there was a bright light in the ex-sergeant’s room. He and his
guests were doubtless having a “high old time” in there, and Enoch
told himself that Gus had deliberately insulted him by not asking him
and his guests over to help them enjoy it.
“Every body likes that boy—every body except Barr and his crowd
of loafers and ruffians—and no one seems to care a cent for me,”
thought Enoch, with no little bitterness in his heart. “I don’t believe
that even those low-down fellows, the big-gunners, would
countenance me, if it were not for the fact that I have showed that I
can be of use to them. They are a pretty gang for a gentleman like
myself to associate with, I must say! Well, the fault lies at Egan’s
door, and he is going to suffer for it this very night.”
Guided by Enoch, who pulled the bow-oar, and acted as look-out
and coxswain at the same time, the row-boat dashed past Mr. Egan’s
oyster-sloop, and drew up alongside the Sallie. There were no signs
of life on board either of the little vessels. Jones fastened into the
fore-chains as soon as he could reach them with his boat-hook, and
Enoch, after carefully laying down his oar, placed his hands on the
rail, and sprang lightly to the yacht’s deck. Groping his way to the
windlass he found, to his gratification, that Egan had been
accommodating enough to leave the anchor-chain in such shape that
it could be slipped in an instant. Seizing the rope with both hands he
was about to lay out all his strength upon it in one vigorous jerk,
which would have released the chain, and allowed it to run overboard
through the hawse-hole, thus giving the yawl up to the mercy of the
elements, when suddenly there was a glare of light and a deafening
report on the deck of the oyster-boat, not more than a dozen yards
away, and a bullet whistled through the air in close proximity to the
boy’s head. This was followed by a chorus of barks and growls that
made Enoch’s blood run cold, and a voice he had often heard before
shouted at him through the darkness:
“You-uns mighty smart ober da’—you is so; but ole Sam wide
awake, an’ he done seed ye when ye go pas’. Look out da’; Ise gettin’
ready to shoot agin, an’ the nex’ bullet come closter, I tell ye.”
Enoch waited to hear no more. He made a headlong rush for the
side, and tumbled into his boat, which was at once pushed off into
the darkness by its frightened crew. The Sallie was not destined to be
given up to the tender mercies of the elements that night.
CHAPTER IV.
AT SCHOOL AGAIN.
T he last time we saw Don and Bert Gordon, they had just returned
to Mississippi after having spent a few weeks with their friend
Curtis in his far northern home. They had come back with more
honors as students, soldiers and hunters than they had ever hoped to
win. Eight months’ hard study, combined with strict attention to
their duties, had made Don major of the academy battalion and Bert
first lieutenant of his company. The latter had barely escaped
mutilation from the teeth and claws of a wounded lucivee, while Don
had smelled powder, heard the whistle of bullets, seen a murderous-
looking bowie-knife flourished before his eyes by a ruffian who tried
his best to use it on his person, and those who were with him during
that trying ordeal declared, as one boy, that he never flinched. More
than that, he had performed a feat during his sojourn in Maine of
which any veteran hunter would have been proud to boast. He had
killed a full-grown moose, whose antlers had been given an honored
place in his mother’s dining-room.
“I don’t believe Don shot that moose himself,” said Lester
Brigham, when he heard of it. “Some old hunter shot it for him, and
he comes home and palms it off as a trophy of his own skill with the
rifle. He tried hard to get up a reputation on the strength of that fight
with the rioters, which really did not amount to any thing; but after
Williams and I risked our lives to save the crew of the Mystery, Don
and his crowd had not another word to say. There was danger in that
undertaking, I beg you to remember, and if Don and his brother had
been the heroes of it, they never would leave off talking about it.”
Lester was standing in the Rochdale post-office waiting for his
mail when he said this, and Enoch Williams and Jones were with
him. Around them was a crowd of boys, who had so often heard them
tell of the wonderful exploits they had performed during their
runaway expedition, that they were tired of listening to them.
Knowing these three fellows as well as we do, it is hardly necessary to
say that, while magnifying their own achievements, they did not
scruple to speak in the most contemptuous terms of what Don
Gordon had done, and to declare, in so many words, that his
promotion and Bert’s was owing entirely to favoritism. They wore
their uniforms on all occasions, carried themselves very stiffly when
they walked, and tried in every way to impress the Rochdale boys
with a sense of their importance. They succeeded with some, while
others, who were civil enough to their faces, laughed at them behind
their backs. The Mississippi boys were not lacking in common sense
if they did live in the country. Williams and Jones were getting ready
to go home now, their preparations being somewhat hastened by the
arrival of Don and his brother, whom, for reasons of their own, they
did not care to meet.
“We heard down here that that fight with the rioters was a pretty
severe one,” observed Fred Packard.
“We don’t doubt it,” answered Jones. “It is very natural for some
people to praise themselves when there is no one to do it for them. I
would be perfectly willing to go through one just like it, and take my
chances.”
“So would I,” exclaimed Enoch.
“Here too,” chimed in Lester, puffing out his cheeks and looking
very brave and warlike indeed. “And I wouldn’t brag about it after I
got home, either.”
“Well, then, why did you not go to Hamilton with Don and the
rest?” inquired Fred.
“Because I couldn’t. The third company went, and I belonged to
the fourth. I volunteered to go, and so did my two friends here, but
the superintendent has his favorites among the students, and of
course they had to go, no matter if they were the biggest cowards in
the academy.”
“I conclude that you were just spoiling for a fight,” said Joe
Packard, with a smile that was highly exasperating to Lester and his
two friends. “If that was the case, what made you pull your head
under the bed-clothes and pretend that you were ill when the bugle
sounded that false alarm?”
“I didn’t do any thing of the kind; did I, boys?” cried Lester,
appealing to his guests who were prompt to sustain him in his denial
of the humiliating charge. “If Don Gordon told you any story of that
sort, he is a mean, sneaking——”
“Hold on!” interrupted Fred. “Don is a friend of mine, and
somehow I can’t bear to hear him abused. Besides——”
Here Fred stopped and jerked his thumb over his shoulder toward
the open door. The boys looked, and saw Don and Bert in the act of
hitching their ponies to a tree on the opposite side of the road. They
were dressed in citizens’ clothes, and although they did not walk with
the regulation step, nor turn square corners, any one could see at a
glance that they had been under military training, and that they had
paid some attention to it.
Lester took just one look at them, and then leaned his elbow on the
show-case and rested his head on his hand. He had evidently
forgotten what he was going to say about Don.
“Another thing, Gordon has never said a word to my brother or me
about you since he came home,” continued Fred. “He isn’t that sort.
He is much too manly to try to build himself up by pulling others
down, and that is more than I can say for some lads with whom I
happen to be acquainted.”
“Then who told you that ridiculous tale about me?” demanded
Lester, wincing a little under the covert rebuke contained in Fred’s
last words.
“Our information came from a very reliable source,” was the rather
unsatisfactory reply. “I know we live a good many miles from
Bridgeport; but we manage to keep pretty well posted in some things
that happen there.”
“His uncle told him all about it,” said Enoch, turning his back
toward Fred, and speaking in a low voice. “No one else could have
done it, if Don or Bert didn’t.”
The “uncle” referred to was the Mr. Packard who owned the Sylph
—the yacht in which Enoch and his band of deserters made their
runaway voyage. He was an old man with all a boy’s love of fun. He
was very fond of his nephews, Fred and Joe, with whom he
corresponded regularly, and it is reasonable to suppose that if
anything amusing or exciting happened at the academy, he did not
neglect to speak of it in his letters.
“And we took Mr. Packard’s relatives off the Mystery and saved
them from going to the bottom of the bay with her!” exclaimed
Lester, in deep disgust.
“But that was after the fight, you know,” whispered Enoch. “He
wouldn’t say anything against our courage now, I’ll bet you.”
“No matter. He has talked about us, and told things that his good
sense, if he had any, ought to have led him to conceal, and I’ll never
go near his house again. I think Fred and Joe might treat us with a
little more respect after what we did for their relatives when the
Mystery was wrecked.”
As it is possible the reader may think so too, we hasten to assure
him that it was not Fred’s fault nor Joe’s that they could not be
friends with Lester and Enoch. These two had a faculty of driving
every decent boy away from them. When they arrived in Rochdale,
Fred and Joe lost no time in calling upon them, to tell them how
grateful they were for what they had done for their friends when
their lives were in peril, but Lester showed them very plainly, by his
actions, that he did not thank them for the visit. They wouldn’t have
anything to do with him when he was plain Lester Brigham, he said;
but now that he was Lester Brigham the hero, they were anxious to
cultivate his acquaintance. That was something to which he could not
consent; and so he, and Enoch and Jones following his example,
snubbed Fred and Joe most royally as often as the opportunity was
presented. If the high-spirited Packard boys grew tired of such
treatment after a while, and showed Lester and his boastful guests up
in their true colors, can anybody blame them?
“Here comes Don,” said Jones, in a suppressed voice. “Don’t salute
him.”
“Of course not!” exclaimed Lester, who seemed to grow angry at
the mere mention of such a thing. “We are not at the academy now,
and we are just as good as he is.”
“Hallo, major!” cried all the Rochdale boys, as Don and his brother
came into the store. “Glad to see you back safe and sound, and none
the worse for your fight with the rioters. You don’t act a bit stuck up
if you are a big officer.”
“Just listen to ’em!” whispered Lester, who could not conceal his
indignation. “The world is full of toadies.”
“And always will be,” answered Jones, who was equally angry and
disgusted. “Whenever some fortunate accident raises a chap a round
or two, you will always find plenty who are willing to bow to him.”
“Well, major,” said Fred Packard, “I hear that—”
“O, for goodness sake, drop that,” interrupted Don. “Drop it, I say,
or I’ll not talk to you. I am at home now, and I want to forget school
and every thing connected with it until the time comes to go back.”
Don’s friends knew very well that he cared nothing for his military
title, except in so far as it marked his standing at the academy, and
that was the reason they addressed him by it—simply to bother him.
They gathered in a group about him and Bert, and Lester and his two
friends being left to themselves, secured their mail as soon as the
window was opened, and left the post-office, looking straight before
them as they passed out at the door, and giving the brothers no
chance to salute them, even if it had been their place to do so.
“Now, Don,” said one of the boys, who had not an opportunity to
speak to him before, “is it true that Lester and Williams took the
crew off Mr. Packard’s yacht at the risk of their own lives?”
“It is,” answered Don, readily. “Bert and I were there and saw it all.
It was a brave act, and everybody who knows the circumstances says
so.”
“But still Lester pulled the quilts over his head and feigned illness
when the bugle sounded; and Jones, who belonged to your company,
was left behind because he hid in one of the coal-bins,” said Joe
Packard.
As Don could not deny this, he said nothing about it. He took his
mail as soon as he could get it, and then he and Bert mounted their
ponies and rode homeward, accompanied by the Packard boys.
The two brothers spent this vacation in much the same way they
spent the first one after their northern friends, Hopkins, Curtis, and
Egan had gone home. Bert studied hard in the hope of being able to
exchange his single bar for a captain’s shoulder-strap at the next
examination, but Don never looked into the book. He had earned a
Welcome to Our Bookstore - The Ultimate Destination for Book Lovers
Are you passionate about books and eager to explore new worlds of
knowledge? At our website, we offer a vast collection of books that
cater to every interest and age group. From classic literature to
specialized publications, self-help books, and children’s stories, we
have it all! Each book is a gateway to new adventures, helping you
expand your knowledge and nourish your soul
Experience Convenient and Enjoyable Book Shopping Our website is more
than just an online bookstore—it’s a bridge connecting readers to the
timeless values of culture and wisdom. With a sleek and user-friendly
interface and a smart search system, you can find your favorite books
quickly and easily. Enjoy special promotions, fast home delivery, and
a seamless shopping experience that saves you time and enhances your
love for reading.
Let us accompany you on the journey of exploring knowledge and
personal growth!
ebookgate.com