
Miscellaneous Tips from Bill Nigh
Over many years, I have worked as a developer and instructor who developed proficiency in HTML, Sybase, Unix (AIX),
Powerbuilder, AREV and Oracle, and have worked with business users and
other stakeholders to provide desired standards-based functionality. As a diligent supportive instructor, I
took it upon myself to write short notes and handouts for students. They sought to firm up understanding of concepts
covered that day, to give more examples of topics, to reinforce a novel concept or powerful feature we had seen that
class day. A representative selection of this content is provided here.
SQL Server and NULL handling in queries and procedures
In earlier releases of Sybase SQL Server (and its cousin MS SQL Server), you could actually code a statement
like:
IF @myvar = NULL as well as the correct IF @myvar IS NULL
(notice the equals sign in first example--this is not ANSI!)
With SQL Server 6.5 and later, an environmental setting will enforce ANSI syntax, meaning that '@myvar IS NULL'
would compile, whereas the earlier syntax will not!
AIX Shell Notes
How Transactions can torpedo an Application
One of the things which makes applications lose user acceptance is poorly constructed transactions. These usually
cause no problems when the database is small, but they will force more and more locking and contention as the
database grows in size and number of users. In order to address this problem: 1.) be sure to make transactions
span only as many update/delete/insert statements as logically belong together 2.) do not permit user interaction
from the client app while a transaction is pending 3.) try to put all update/delete/insert actions within stored
procedures, for faster performance.
Java ENUM types
For a handy set of constants, and built-in way to return an array of that set, for boilerplate iteration,
look at the enum class of Java. By convention, data members of that class have their names uppercased, as they
are equivalent to system constants; the 'values' method of the ENUM type feeds you an array of the data values
you assign to the enum object.
WebLogic Tips
The 't3' protocol that various processes listen on in WLS is a reference back to Tengah WebLogic before BEA
bought the small San Francisco based company. This is optimized http.
In order to fire up WLS, you need to have configured an instance of a server within a domain. A domain is an
administrative definition that relates to administering one or more servers on one or more machines. If only
one server is present, WLS assumes it is the admin server.
WebLogic Server is a Java class that is passed as the argument to the ‘java’ command, and therefore runs entirely
within a single JVM instance. Due to this behavior, it is legal to have multiple versions of it running on
one box; Prasanna has several versions on his, for example, in addition to JBoss, etc.
There are useful command prompts that are provided normally that you use to get to a command line, rather than
the vanilla ‘Run’ command on Windows. Using them causes all environmental vars like CLASSPATH to be set for
you.
Domains are useful administrative entities in WLS, with an Admin Server and several Managed Servers.
Each Server maintains its own log, with useful filtering options for recording the severity.
Username and password can be entered in plain text initially, then the file gets encrypted; WLS wants to always
be the agent that gets that info and encrypts it. This is why just copying a valid file from elsewhere does
not work, as it tries to encrypt something already encrypted.
The term ‘Managed Server’ can be misleading, as the only thing that they get from a so-called Admin Server
is the configuration at startup; once they are started, they can run indefinitely, even if the Admin Server
is down. The access to config info from the Managed Server end, however, is always read-only.
The Admin Server is a single point of administration for a given domain, but NEVER a single point of failure.
The start script for a particular instance has arguments that identify the URL of the admin server. This is
an optional argument.
Domain-level logging is available on the Admin server. Managed servers propagate (filtered) contents from their
local logs to the domain log. This is not queued in a hard queue; if the admin server is not running, the log
is incomplete. REMEMBER, however, that the complete logs are ALWAYS maintained locally for each server; diagnostics
would typically use that local log anyway.
Domains can be created from templates. Templates are created with a useful wizard, from config_builder.cmd
or .sh; one template is provided by default, since you need a template in order to create a template. You can
include resources, such as files, and Database scripts, in the domain (via the template you are building).
Unix Regular Expressions
A 'regular expression' is a Unix term for a fairly common concept, one seen in DOS and in Windows search programs,
namely the use of 'wildcard' characters to specify matches based on partial name or text line contents, and
to extend that with 'or' and 'and' capabilities. Regular expressions use characters such as '^' to indicate:
1.) 'starts with' at the beginning of a regular expression 2.) '(if within the '[ ]' characters, means 'not',
to negate a range of values, like the SQL NOT IN (SELECT...
How to create an empty Unix file most easily
If you use the touch command followed by a new filename, you will be able to create an empty file, in any directory
you specify. Otherwise, touch can be used to update file attributes.
Subtle 'Gotcha' in Dreamweaver
I love Dreamweaver, but like any development tool, it has some quirks. Here's one (a minor one admittedly):
If you are only modifying the title attribute of a page, the page will not be considered modified initially. You
need to click somewhere else after modifying it in the edit line.
Recent Dialogue on array basics and persistence in TrueBasic
Hi Bill, Thanks for offering to help! I'm taking a programming final for my Computer Science class in a
few days and I'm having trouble with arrays. I think I understand the point of using arrays but I'm not really
sure how to write them into a program. In the past, I've had trouble with actually getting the data to store
from one execution to the next. I've usually been using loops in conjunction with arrays, not sure if that
makes a difference. Any help on explaining this? I'd really, really appreciate it!
Thanks, Cat
Bill: I think it's important to understand what a 'session' is, as it is related to a particular login
at a moment in time, and implies 'statefulness'. This simply means that data in variables is reliable, but
ultimately any session ends, and the data, in whatever format, simple data type or array, either has to be
'persisted' or stored, or else it just evaporates. This is also what an 'instance' is like, namely the 'statefulness'
aspect. Keep asking me questions. I'm glad to help.
Cat: Ok, that makes sense. Now, in the actual writing of the program, I know I need a DIM statement, with
the variables and dimensions, but then how do you actually tell the program to associate a value or string
with one number within the dimensions set? How would you write that out?
Bill:This is where my actual syntax knowledge is lacking, but some things are the same across arrays in any
language I've seen. One common theme is addressing with a subscript. The actual way you automate the addressing
is the main difference, of course. The answer to me starts with identifying the source of the values. Is it
being keyboarded? Is it coming in from a file? From a database through a connection?
Cat: It's keyboarded.
Bill: You want to set up a variable and a loop. The variable is used to slide through the array using indexing.
Indexing syntax typically supports use of a variable to subscript/address the elements in an array.
Initialize the variable OUTSIDE loop, above it, and:
Prompt for input
Get the string
Increment the index var
Use var's value as subscript
Loop until some condition is met.
Outside the loop, you have the array. You can count the number of elements in the array and do a for..next
type loop and subscript to address one element at a time, show the element (if you want), loop until no more
elements
Cat: Oh! I get it! Awesome, that helped a lot! Thank you so much!
Bill: Good; glad I was able to break that down for you. Not sure if your language uses 0 as first index value,
or 1, but when you initialize that var, set it to one less than the desired starting value at top of loop.
Or, you can use the starting value set above the loop, and after the processing of input is done, increment
the var by one. Good luck!
Workload balancing
It is possible to perform the same work on either the client or the server in a client-server installation.
Those operations relating to sorting or filtering should ideally be done on the server, since it can be optimized
to do this work much more easily than the client application. For example, the query optimizer on RDBMS products
can inspect the incoming SQL query and determine the most efficient way to satisfy the query, using indexes.
Just because you do the initial sorting in the query doesn't mean the user wouldn't benefit from being able
to shuffle and temporarily ignore (filter) data records on the client application, so try to include this functionality
in the early versions of your application, and you will win user acceptance more readily.
Caution - Datatypes make cross-platform DDL problematic
If you are designing a database and you have not yet identified the datatypes available to you from that database
product, you'd better take a look. For example, I was surprised to discover that the datatype of 'date' did
not exist in SQL Server and Sybase! Rather, a compound 'datetime' datatype is the only choice. This can mess
you up if you are expecting to store effective date and effective time in separate columns. Overview discussions
of SQL are appropriate for those who are trying to design in a platform-independent style.
Shell programming can be easy to learn
The simplest type of shell program is a batch of commands typed into a text file. Shell programs are
not compiled, and are run by simply typing their name. In addition to standard interactive command sentences,
looping and conditional execution of blocks of code are available. Combining the various utilities of
Unix, the file expansion and the Regular Expression capabilities of the shell, and the procedural language,
you have a potent combination
Unix Files
In Unix, a file can be an executable program (which would comprise shell scripts), a log, or some type of text,
often comprised of 'records', or lines whose 'columns' are set off by tab or space delimiters. Using
grep and awk, you can process these files, doing powerful searching, filtering and modification operations. Note
that modifying the actual file is most typically and safely done by creating a minimum two-line script (shell
script) which will create a new file from the processed 'source' file, then use an 'mv' command as the next
'batch' instruction, to rename the new file to the old name. Files and directories are accorded 9 (actually
12 with some versions) permissions flags, for read/write/execute permissions on the owner, group and public
level, also known as user, group, others (ugo). Using the initial of the set, and the permission being
extended, initially granted or reduced, you use the 'chmod' program to accomplish your task, as:
chmod 777 myprog
to give all operations to all classes of users.
Files can be hidden by using the period as the first character in the name. Names can conceivably consist
of printing AND nonprinting, 'control' characters. Beware. Some commands such as AWK are not case
sensitive, but assume that something is case sensitive and you will not go wrong. Files can be created
by 'piping', where the output of a program can be sent to a file. Files such as those in the dev subdirectory
are actually devices, but you can read from them and write to them---pretty cool.
Copying or moving Unix files to the current directory
When you use the cp or mv commands, and you are already in the target directory, use the '.' (period) character
at the end. This is the way to say 'current directory'.
Timing a long-running job
You can use redirection and batching to note the start date and time for a process, run that process (with
suppress output option) and note the date and time when the process finished. Here is
a sample:
echo "Starting processing at:" > report.txt ; date >> report.txt ; myprog1 > /dev/null ; date >> report.txt
This single command line 'batch' runs the whole set of commands.
Note: If you use the 'batch' command, you can then put these commands (on separate lines) into a stream
which you terminate with Ctrl / D. The commands then get scheduled, and a likely time for batch completion
will be shown.
The Unix 'awk' utility
If you want to process a file (normally text, to include non-English character sets), then you should know
about awk, named from the initials of its creators. 'awk' expects to open and process, line by line,
as many files as you pass to it (see 'metacharacters' to have shell provide directory search returns). The
file(s) will be processed in a loop, where every line (as determined by a 'newline' character) is parsable
into columns, and can be searched using Regular Expressions. If a line meets the criteria fed to awk,
then you can print it in whole or part, with literals, to an output stream and capture that in another file,
or pass it to a pipeline. 'Pre' and 'Post' loop syntax options are found, as are built-in and user-defined
variables.
Outer Joins
Under fairly natural conditions, database joins can appear to 'lose' data. What happens is that if data in
one table does not match similar data in another table, even the existing data in the first table is suppressed,
because joins are based on matching data values in related tables. To show 'outliers', (but only in one direction
at a time), use an OUTER JOIN.
IIOP - a robust, stateful cousin to http, for object-to-object messaging
When an HTML page is requested and delivered, any connection between the browser and the server is ended. Each
request is a separate connection, so the server has no 'memory' of what you transacted with it last time. This
'stateless' nature of http is why it cannot support the 'memory' of who the current user is, (unless cookies
are used, which can be blocked). Enter Internet Inter-ORB Protocol. This utility provides persistent
connections between processes, and is one way that Jaguar CTS talks to its PowerBuilder, VB, or HTML clients
Frustration-saving vi tip
Getting a lot of beeps when you work with vi? The characters you are typing are not appropriate for the current
mode of operation of vi. Safest way to recover is to press the {Esc} key. This will take you out of any special
mode such as insert, and return you to the starting mode of vi, which is related to commands, rather than actual
text creation/editing. From there, you can use the hjkl characters for cursor movement, and aAiI for editing
initiation.
Three modes of operation within vi
There are three modes of operation within vi. The first is the command mode, which I find misleading,
because it also relates to cursor movement. This is how you start vi. The next mode of operation
is EX mode, when you can enter more powerful commands such as w, to write out changes from the buffer to a
filesystem file. From the EX mode you can properly exit the vi session. The insert mode is for
editing. Note the overwrite capabilities here, and the special significance of the '$' character.
Pipeline tips
You may think of a pipeline as an assembly line, with each piped utility call adding (or maybe not effecting)
the 'stream' of data passing down the pipeline. Utilities such as grep and awk may filter out lines of
data based on criteria you pass, while sort and pr adjust the display of the data set you're processing in
the pipeline. The assembly line metaphor helps us remember the 'additive' nature of the pipeline. This
additive behavior suggests the following tip: Use as many invocations of grep, awk, sed, tr and others
as needed. A close alternative to the pipeline is the batch of commands which uses temporary files
(see /tmp directory) to achieve the same effect. Use any combination of the two to maximize your possibilities
(see 'cron' processing).
AIX Command history
If you type ( or have in your .profile ) the command:
set -o vi
then you will be able to use vi commands to modify any previously typed sentence. Your 'command history', if
you will, is stored in the .sh_history file, and is therefore persistent beyond any given session. To invoke
the editing options, press {Esc} then type k. This will bring back the last command. Use k to move back, then
j to move forward through the 'stack'. Once you find a useful command, you may use the standard commands to
move along the line to edit the sentence. Press {Enter} from anywhere in the modified sentence to re-run the
command.
Command History editing/display
You may display your command history with the 'history' command, which is an alias for fc -l, the 'fix command'
with list option. If the word 'history' does not work, incidentally, type: history='/usr/bin/fc -l'.
Type man fc at the shell prompt to see full detail, including the 'r' command of history to re-run
a listed command string by its number. You may also try: set -o vi or set -o emacs or any editor program, to
modify your command history as well as recall and re-run it.
One advantage of Views
A view can cover over the complexity of a data structure, not just the complexity of syntax. For example, certain
types of expressions may not syntactically coexist under all circumstances, such as aggregates and scalars.
Create a view of a GROUP BY query, and the rows which appear to be in that 'flat' structure are themselves
summary data. This can then be used in a join to show such calculations as percent of the total, greater/less
than group average, others.
Select Into/ Bulk Copy option with SQL Server
A procedure which builds a table on the fly with 'insert into' may fail based on settings in the database. The
Insert Into/ Bulk Copy option must be on. (Later versions added a parallel sort option). No matter whether
its two or three choices, they are either all off or all on.
Search capabilities in Unix
In Unix, there are a number of powerful utilities which can be used to search for files, directories, or other
objects based on their name and external attributes such as last date updated, permission level, and owner,
and there are utilities for searching within files for specific content. A lot of these utilities are native
to Unix in general, because C programmers and shell programmers created these features largely for easier code
maintenance.
The 'find' command searches for files and directories which meet search conditions, and supports an AND/OR
capability for complex search conditions. Once you find any files/directories which meet your search conditions,
you have the ability to indicate an action which is to be performed on those items. Such actions can be automatic,
or you can ask your 'find' operation to prompt you, to permit selective application.
The 'grep' and 'awk' programs can comb through files for lines (always entire lines by default) within a file
which meet search conditions. 'awk' supports a powerful procedural and high-level programming language, with
print and extract operations, and is so powerful that some people have created compilers using awk. Both grep
and awk also can be put into a 'pipeline', (i.e., they can be 'fed' the streamed output from other utilities).
How to handle annoying duplicate characters in TELNET
If you are getting duplicate characters while you enter commands in a Telnet session, (example: user123
is displayed as uusseerr112233), then use the appropriate interrupt command to return to the Telnet prompt,
if necessary, then type unset LOCAL_ECHO.
Sybase SET SHOWPLAN Tips
When using SET SHOWPLAN ON, you can also use SET NOEXEC ON. (Despite the way the phrase reads, when NOEXEC
is 'on', then the actual query you are measuring will not execute). Sample: SET SHOWPLAN ON, NOEXEC
ON
If you are trying to see the query plan for a stored procedure, you cannot EXEC it and see any detail. Instead,
you need to copy the source code which created the sp (without the CREATE PROCEDURE and AS statements) and
paste it into the ISQL or whatever tool you are using as a client app. This may require that you trump up the
code to account for parameters in the signature of the procedure you are testing.
How to process large sets of files automatically
The Unix 'find' command supports the ability to do rich searches for directories and files. In
the files area, you can run a 'find' operation, much like what you get in MS Windows now. However, Unix
goes Windows one better by permitting you to take all files which meet a condition, then passing them through
some other process, such as awk or sed. Check it out.
Make your Sybase life easier with centralized, simplified ownership of database objects
Each time a stored procedure is executed, the objects which it references (other sp's, views, etc.) are checked
to see whether the user running the sp has permission to execute / select or otherwise use those referenced
objects. This can create a nightmare of 'surprises' as previously good triggers, procedures, etc. fail
when they are next referenced. Have a single individual (dbo) own all objects, and make good use of groups
and aliases to control this area of possible complexity.
Unix: Write, message blocking and WHO
The WRITE command lets you send messages to a specified user elsewhere on the Unix system to which
you've logged in. However, that recipient may have used the command mesg n to block messages. To
determine whether this is so, use the command who -T, which displays an additional column. If that column
has a minus sign, messages are blocked to that user. (Tip: use the H switch also to see column
headings, as: who -TH, remembering that these commands are case sensitive.
Unix: The 'at' command
To run jobs (commands) at a later time, use at. The at command lets you specify commands to
run, and when to run them. You may use 'pronouns' such as today and tomorrow, specific times of day, offsets
from current time, and lots of other temporal options. You may also specify which shell is to be used to run
the particular job, as c for csh, k for ksh. at can be used with piping too, as in this example:
echo uuclean | at 3:00 pm January 24
If a file named /var/adm/cron/at.allow exists, only users whose login names appear in it
can use at. A system administrator can explicitly stop a user from using the at command by
listing the user's login name in the /var/adm/cron/at.deny file. If only the at.deny file exists, any user
whose name does not appear in the file can use the at command
Autocommit attribute of a connection
If you understand that you can connect to a database with a login, and that you then have a session
which may have more than one connection, then: consider the fact that the session can have a flag set which
can mess up your day. Check the autocommit setting, if present. If it is 'on', or 'true', then you will not
be able to support a basic logical unit of work, or 'transaction'. This may be the default, then any insert/update/delete
actions you are doing are automatically committed. There is no syntax available to 'recover' modifications
to support 'undo'. You cannot use ROLLBACK; you never had the chance.Set it to false to 'clump'
DML, then turn it on when you're ready. You may use a COMMIT statement to apply pending changes in the transaction
(which also releases locks-be sure not to hold locks).
AutoCommit is found in TOAD, SQL*Plus, JDBC, PowerBuilder and no doubt many other developer tools/protocols.
Two main 'flavors' of the SQL language
The Structured Query Language (SQL) has gone through two major 'versions'. Despite its name, the SQL
92 version is the more recent of the two. The various software vendors who sell Relational Database Management
Systems (RDBMS) do not have entirely identical implementations of that standard, or its predecessor, SQL 89. If
you are shopping for specific features in an RDBMS, make sure you get enough detail.
Humongous join, or step-wise solution?
Because of locking, it is usually better to avoid having too many tables in a join. This is especially true
for very popular tables. It may be better to create a temporary table in a procedure from the larger tables,
where the WHERE clause is use to maximum effect. This first result can then be used in subsequent joins against
the smaller or less contentious tables.
How to get detail about the current Unix directory
When you want to get some good detail about the current directory, use:
ls -d .
(That's a period at the end). The period indicates 'current directory', and the -d option provides more detail.
Warning about Microsoft DTS
If you use the DTS feature to move/copy objects between databases, beware. Trying to overwrite
a view on a target machine will cause tables to be deleted if you choose to include dependent objects (the
checkbox, I mean.) I ended up deleting a number of production tables, before I got suspicious and cancelled
the job. I don't know if I saved any tables, but it was an unnecessary headache. In my opinion,
a table can NEVER be 'dependent' on a view, since the opposite it true, a view being a derived well, VIEW of
data in another view and/or table.
Java in the Server
To provide a dynamic way to generate HTML from an RDBMS, vendors are now weaving Java more tightly into their
engines. For example, Oracle permits the use of Java on the server side, which is not that revolutionary. What
is appealing is that the JVM runs in the same program space as the server, obviating the need for any
connection to the database server from the Java program. Developers can code stored procedures in either
PL/SQL or Java.
Chained and unchained Transactions
Sybase and Microsoft SQL Server support either chained or unchained transactions, which is not even a choice
with such RDBMS as Oracle. Sybase databases can use the SET command to permit chaining with SET
CHAINED ON. In later versions of Microsoft SQL Server, use SET IMPLICIT_TRANSACTIONS ON.
The ANSI standard does not recognize the syntax BEGIN TRANsaction; in fact, such a statement will not even
be accepted by Oracle. Rather, upon logon, a Transaction is deemed to begin upon issuance of any DML
statement, and from that point on a transaction is pending on that connection until a COMMIT, ROLLBACK or DISCONNECT
statement is sent to the server. What Oracle provides to give more of a finer-grained control over small transactions
(logging) within larger unit-of-work transactions is the pragma for AUTONOMOUS TRANSACTION.
What's in a name?
Can two objects with the same name exist in a SQL Server database? The answer is 'Yes or No', depending on
what you mean by 'name'. The 'normal' view of an object name is one-part, as seen in a simple query like 'SELECT
authors'. However, every name is finally fully-qualified. A fully-qualified name uses dot notation to define
a hierarchy of objects and an unambiguous name for any object on an installed copy of Microsoft SQL Server,
or its Sybase cousin, for any release, going back to at least version 4. Therefore 'authors' can mean the same
as 'pubs2.dbo.authors'.
The name of an object is fully qualified by putting the name of the database, name of the creator/owner of
the object, and actual object name. The special role of 'dbo' must be mentioned here, for, in a well-behaved
application (one without any unnecessary ambiguity), the dbo (database owner) is usually charged, or claims
for him/herself the right and responsibility for creating all objects. Here is a fairly typical isql session:
1> create view vw_titles_pubs ( title, publisher)
2> as select title, pub_name
3> from mytitles, mypublishers
4> where mytitles.pub_id = mypublishers.pub_id
5> end Msg 2714, Level 16, State 1: Server 'FTPAR1', Line 9:
There is already an object named 'vw_titles_pubs' in the database.
In such a case, you might want to run the query SELECT db_name() to see the current database context, which
can be determined two ways, and then run SELECT suser_name()
Applications in a Distributed Space
The Graphical User Interface (GUI) which is typically all the 'end user' sees, is an important part of any
application, no matter how ambitious or humble.
The ability to understand and navigate an application can be a deal breaker between users and developers, and
what are we getting paid for after all than creating useable apps to solve business problems?
Note that many design approaches will separate the retrieval of data from its presentation to the user. This
is where application servers come in. Taking advantage of resource optimization design features, they
can connect to 'back end' data sources such as relational databases, and store/maintain/update that data for
you.
Check out the MVC (Model View Controller) design pattern when considering Servlet or JSP/ASP design. If using
Jaguar and PowerBuilder, check out DataWindow synchronization with elements of an n-tier application, using
get- and setFullState methods.
Triggers in Oracle
In addition to the user exits called 'triggers' in Forms and Reports, more 'traditional' (is that word even
appropriate in this industry yet?) examples of trigger functionality are found in Oracle, and are more formally
known as 'database triggers' and 'Instead-of triggers'. The former is applied to the DML actions on tables,
like other RDBMS, but Oracle also supports row-level triggers vs. statement-level (set level) triggers, and
has a BEFORE and AFTER syntax requirement which specifies when the trigger fires. Business rules
regarding validation would be on the BEFORE side, whereas auditing / tracing / profiling stats would be written
out IFF the DML is permitted. A statement-level trigger on an UPDATE will precede any row-level processing,
giving you two shots at attempted changes, with the same capabilities for INSERT and DELETE, of course. All
in all, given all combinations, you get 12 trigger opportunities with Oracle.
UML, XML and SQL
The Structured Query Language is associated with the relational theory of databases, and its various vendor
implementations. It is based on a rigorous model. It provides an ANSI standard dialect which controls
all actions needed to maintain databases.
Using SQL you can do powerful things to data in database tables or views (views are updateable under certain
conditions, even though they are merely a reflection of data stored in underlying, 'base', tables.)
SQL seems to straddle a lot of generations of client/server, n-tier, distributed applications, and will continue
to be a useful career skill for decades to come, since it is available on and for essentially all platforms,
certainly business desktops, and laptops, but also phones, pagers, PIM's and email.
XML is a language which lets you define data entities, and have them interpreted by an unknown 'client' program;
they are presented in plain text, so could be bulky, but their hierarchical data structure and freeform nature
make it possible for cooperating organizations to pass data back and forth between their heterogeneous database
and application systems.
The Unified Modeling Language, which is an amalgam of several different OO notational systems, serves as an
intermediate language between business owners/users and IT architects/coders. Interaction diagrams are
documented in UML and show scope, method calls, and order in which objects should be instantiated in the application
program space. The UML is being taught in many univesities in the world, and since it fills a useful niche,
look for it to continue to grow in importance. It is relatively easy to get used to, and there are many
IDE's which help you build diagrams. Such IDE's often permit full round trip software engineering. Even
years ago, Rational Rose was able to produce interfaces, stubs and classes that fit into an architecture.
Useful intermediaries for migrating RDBMS data
Both PowerBuilder and Access provide easy ways to attach to multiple data sources, and move/copy data from
one database format to another. The ability to massage the data on the way to the new location is supported.
PowerBuilder uses both ODBC and native drivers (DBLib / SQLNet ) to talk to data sources. Access uses ODBC.
FOREIGN KEY Constraint in DDL
The FOREIGN KEY constraint is the most powerful declarative constraint there is, since it invokes so much automatic
functionality. It is used to maintain both referential integrity and domain integrity. INSERT or
UPDATE statements which try to alter or insert a value in the constrained column which does not match a primary
key are rejected.
Here's something you may not know about the FOREIGN KEY constraint, however: By default, the minimal
syntax for this constraint implies an ON DELETE RESTRICT clause, meaning that not only must the foreign key
value match a primary key in the parent table, but also no parent row can be deleted if there are child rows
present. Two other possibilities are available as well. ON DELETE SET NULL will actually
remove foreign key value when the parent row is deleted, effectively 'orphaning' the child row. (If the
foreign key column has a NOT NULL constraint, however, the attempt to set the child row value to null will
fail. ON DELETE CASCADE will actually delete child rows as well as parent rows, a cascading type of delete
across tables. Considering how the child table may be a parent to another table, this could be a profoundly
powerful design choice. There may be other options in the works, for example a possible ON DELETE SET
DEFAULT which will use the default value in the column-level DDL to replace the vacated value, this, of course
taking care of the NOT NULL conundrum mentioned above.
When NOT IN ( subquery ) fails
(Thanks to Kim Evangelista for this one: )
If you have a nested query which returns column contents from a table, be sure to eliminate nulls, or else
the subquery will return null.
Two ways of promoting Domain Integrity - Decoding values in a Data Domain
If you agree that storing a short code is efficient, then trying to turn a potentially cryptic code into a
more natural description ('Decoding') becomes a consideration. If you use the CHECK constraint to limit
what can be stored in a given column, you typically use the DECODE function to turn those codes into fuller
narrative values. If you have chosen to do your 'runtime lookup' against another table, then you can use two
ways, DECODE, and more typically, a runtime operation which uses the common stored value in a JOIN to get the
longer description. The ease and usefulness of Joins favors the use of separate tables for verification
and decoding.
Searching for the underscore or per cent sign using LIKE
Since the '_' and '%' symbols are used to indicate two types of search patterns when used with LIKE, what do
you do when you are actually LOOKING for one or both of those characters? What you would do is to extend
the LIKE operation and indicate any arbitrary character which is used to preceed the _ or %, as:
WHERE BOOK_TITLE LIKE '%7\%%' ESCAPE '\'
to mean, 'search for book titles which contain the actual string 7%'.
Notice how the other occurrences of the % sign play their usual role.
(Note for Unix folks: you must actually type the word ESCAPE and specify the escape character, which
is not limited to the backslash)
Business Rules, and where to apply them in the Oracle environment
In Oracle, you may install business rules right on the table level, using ANSI-compliant CONSTRAINTS. Among
these are constraints which do column-level checking, such as (must be a positive number, must be in this range,
must match this discrete set of values), validation of one column's data against other columns in the same
row, uniqueness enforcement (over and above the standard enforcement provided by a primary key), and more powerful
checking, such as cross-table verification and actions in triggers. You may also use declarative referential
integrity to do run-time lookups of a candidate value for a column in other tables, and to either restrict
or cascade deletes based on child data. I would argue that any business rules which can be reduced to
these forms should be implemented using these features, but I would also suggest that application programs
should do timely validation and error notification as well. Note that Oracle Forms has a lot of predefined
'hooks' for validation, both standard and programmatic.
More on the Oracle References Constraint
You should always try to use the built-in capabilities of the RDBMS server, and the use of declarative referential
integrity is probably among the most profound examples of how a little goes a long way. When you say
that a colunn in a table REFERENCES another table, you are requiring a 'run-time lookup' on that foreign table
which denies any INSERT/UPDATE which tries to change that column's value to one not found in the referenced
table.
You can add the on DELETE CASCADE phrase to cause a 'parent-child' delete if the referenced row is deleted
from the referenced table. You may also use the CASCADE CONSTRAINTS clause during table delete to clean
up reference constraints in child tables.
There are 4 possible variations on the ON DELETE operation from the 'parent': the implicit ON DELETE
RESTRICT, aforementioned CASCADE, then SET NULL and SET DEFAULT. Triggers can extend this functionality
beyond declarative to procedural, with remarkable ease of use and bulletproof applicability.
Using NVL with Aggregates
COUNT, SUM, AVG, STDDEV and VARIANCE provide the ability to operate on a column across multiple rows. Only
COUNT has the ability to operate on entire rows, not just specific columns or column-level expressions, with
its special COUNT(*) syntax.
With the exception of COUNT(*), all other forms of aggregate expressions need you to pass them a column name
or any expression of the appropriate datatype. For example, you can't do much with SUM(last_name), for
SUM of course wants to work with numeric values. Here's an example of doing a 'what if' calculation on the
fly, where we want to know what the impact of an across-the-board 12% pay raise would mean on the total payroll: SELECT
SUM( salary * 1.12 ) "Projected Payroll" FROM INSTRUCTOR. What about only those instructors
in Denver (DNV)? SELECT SUM( salary * 1.12) "Denver Projection" FROM INSTRUCTOR WHERE HOME_SITE_CODE='DNV'.
By default, all forms except the COUNT(*) will ignore null (missing) values in the column they are operating
on. Assume that the instructor table in your sample database has a lot of new rows, and due to
some issue with data entry at the time, none of the salaries has been filled in for the new instructors. Over
half of the rows in instructor have null in the salary column. If you type SELECT AVG( salary ) FROM
INSTRUCTOR, you will only get the average of the rows which have a value in that column. What if you
wanted to temporarily substitute a value to more appropriately 'pad' or adjust the salaries for the purpose
of doing a better average? You can use the NVL function to provide runtime substitution. Assume
that we generally believe that all the new instructors have an average of 50,000.
Therefore you can type SELECT AVG(NVL(salary, 50000)) FROM INSTRUCTOR. By default, all aggregate functions
use all values in that column (as of course determined by any WHERE clause in the query, which would limit
rows based on criteria).
Autonomous Transactions in Oracle
Oracle, with Release 8, provides a way to submit DDL and not have it disturb a transaction, to have triggers
write log entries even though the DML which caused the trigger to fire is itself is rolled back, and otherwise
have better control over the environment.
Use the PRAGMA AUTONOMOUS_TRANSACTION directive in your declaration section and you can then (and in fact must)
issue the COMMIT or ROLLBACK from within your program.
Anonymous blocks with nested blocks can only compile if the pragma is in the topmost block. If you do
not issue a ROLLBACK/COMMIT before your block goes out of scope, an exception will be raised and a ROLLBACK
implicitly issued by Oracle.
The value of roles in SQL Server
Logins to a SQL Server are associated with a default database at time of creation, and may also choose to log
in to other databases, assuming their login gets them access to SQL Server. Once logged in, you operate
as a user of a given database. Users may be assigned to groups, which can then be subjected to common
GRANT and REVOKE behavior. A User may have a role assigned to them, which also accords access to commands
and objects. Here is a typical listing from ASE 11.9:
sp_who output:
name
------------------------------
dbo
guest
navigator_role
oper_role
public
replication_role
sa_role
sso_role
sybase_ts_role
(9 rows affected)
Oracle Trigger Notes
In addition to schema-level and database-level triggers based on common events such as startup, login, connect
and various others, the Oracle developer can use numerous trigger events and scopes for tables, objects and
views, to great advantage. You can use a statement-level (set level) scope for pre-update to set a global
variable, then access that value in row-level trigger processing on that same DML statement. You can
do things both before and after any DML (except SELECT). You can do things conditionally based on what
column(s) is/are affected, you can inspect the attempted insert or update data, and enforce business
rules, do distributed calls, post to a message queue, operate on other tables, run stored programs, use cursors,
and other possibilities. Other RDBMS's I've worked with usually have one trigger per DML operation, not
before and after and different scope. Using the INSTEAD OF trigger option for a view, you could make
any DML attempted through the view get mapped to multiple table DML, to service the underlying tables/views.