• Aucun résultat trouvé

Creating a Table

Dans le document SQL Server (Page 159-164)

All right, we’ve seen plenty; we’re ready for some action, so let’s build a few tables.

When we started this section, we looked at our standard CREATEsyntax of:

CREATE <object type> <object name>

And then we moved on to a more specific start (indeed, it’s the first line of our statement that will create the table) on creating a table called Customers:

CREATE TABLE Customers

Our Customerstable is going to be the first table in a database we will be putting together to track our company’s accounting. We’ll be looking at designing a database in a couple of chapters, but we’ll go ahead and get started on our database by building a couple of tables to learn our CREATE TABLE state-ment. We’ll look at most of the concepts of table construction in this section, but we’ll save a few for later on in the book. That being said, let’s get started building the first of several tables.

I’m going to add in a USE <database name>line prior to my CREATEcode so that I’m sure that, when I run the script, the table is created in the proper database. We’ll then follow up that first line that we’ve already seen with a few columns.

Any script you create for regular use with a particular database should include a USEcommand with the name of that database. This ensures that you really are creating, altering, and dropping the objects in the database you intend. More than once have I been the victim of my own stupidity when I blindly opened up a script and executed it only to find that the wrong database was current, and any tables with the same name had been dropped (thus losing all data) and replaced by a new layout. You can also tell when other people have done this by taking a look around the masterdatabase — you’ll often find several extraneous tables in that database from people running CREATEscripts that were meant to go somewhere else.

There can be some serious performance increases to be had by splitting your database up into multiple files, and then storing those files on separate physical disks. When you do this, it means you get the I/O from both drives. Major discussion of this is out-side the scope of this book, but keep this in mind as something to gather more infor-mation on should you run into I/O performance issues.

FedIDNo varchar(9) NOT NULL, DateInSystem smalldatetime NOT NULL )

This is a somewhat simplified table vs. what we would probably use in real life, but there’s plenty of time to change it later (and we will).

Once we’ve built the table, we want to verify that it was indeed created, and that it has all the columns and types that we expect. To do this, we can make use of several commands, but perhaps the best is one that will seem like an old friend before you’re done with this book: sp_help. The syntax is simple:

EXEC sp_help <object name>

To specify the table object that we just created, try executing the following code:

EXEC sp_help Customers

The EXECcommand is used in two different ways. This rendition is used to execute a stored procedure — in this case, a system stored procedure. We’ll see the second version later when we are dealing with advanced query topics and stored procedures.

Try executing the command, and you’ll find that you get back several result sets one after another. The information retrieved includes separate result sets for:

❑ Table name, schema, type of table (system vs. user), and creation date

❑ Column names, datatypes, nullability, size, and collation

The identity column (if one exists) including the initial seed and increment values

❑ The RowGUIDCol (if one exists)

❑ Filegroup information

❑ Index names (if any exist), types, and included columns

❑ Constraint names (if any), types, and included columns

❑ Foreign key (if any) names and columns

❑ The names of any schema-bound views (more on this in Chapter 10) that depend on the table Now that we’re certain that we have our table created, let’s take a look at creating yet another table — the Employeestable. This time, let’s talk about what we want in the table first, and then see how you do trying to code the CREATEscript for yourself.

Technically speaking, you can execute a stored procedure by simply calling it (with-out using the EXECkeyword). The problem is that this only works consistently if the sproc being called is the first statement of any kind in the batch. Just having sp_help Customerswould have worked in the place of the code above, but if you tried to run a SELECTstatement before it — it would blow up on you. Not using EXECleads to very unpredictable behavior and should be avoided.

129

Creating and Altering Tables

The Employeestable is another fairly simple table. It should include information on:

❑ The employee’s ID — this should be automatically generated by the system

❑ First name

❑ Optionally, middle initial

❑ Last name

❑ Title

❑ Social Security Number

❑ Salary

❑ The previous salary

❑ The amount of the last raise

❑ Date of hire

❑ Date terminated (if there is one)

❑ The employee’s manager

❑ Department

Start off by trying to figure out a layout for yourself.

Before we start looking at this together, let me tell you not to worry too much if your layout isn’t exactly like mine. There are as many database designs as there are database designers — and that all begins with table design. We all can have different solutions to the same problem. What you want to look for is whether you have all the concepts that needed to be addressed. That being said, let’s take a look at one way to build this table.

We have a special column here. The EmployeeIDis to be generated by the system and therefore is an excellent candidate for either an identity column or a RowGUIDCol. There are several reasons you might want to go one way or the other between these two, but we’ll go with an identity column for a couple of reasons:

❑ It’s going to be used by an average person. (Would you want to have to remember a GUID?)

❑ It incurs lower overhead.

We’re now ready to start constructing our script:

CREATE TABLE Employees (

EmployeeID int IDENTITY NOT NULL,

For this column, the NOT NULLoption has essentially been chosen for us by virtue of our use of an IDENTITYcolumn. You cannot allow NULLvalues in an IDENTITYcolumn. Note that, depending on our server settings, we will, most likely, still need to include our NOT NULLoption (if we leave it to the default we may get an error depending on whether the default allows NULLs).

Next up, we want to add in our name columns. I usually allow approximately 25 characters for names.

Most names are far shorter than that, but I’ve bumped into enough that were rather lengthy (especially since hyphenated names have become so popular) that I allow for the extra room. In addition, I make use of a variable-length datatype for two reasons:

❑ To recapture the space of a column that is defined somewhat longer than the actual data usually is (retrieve blank space)

❑ To simplify searches in the WHEREclause — fixed-length columns are padded with spaces, which requires extra planning when performing comparisons against fields of this type

The exception in this case is the middle initial. Since we really only need to allow for one character here, recapture of space is not an issue. Indeed, a variable-length datatype would actually use more space in this case, since a varcharneeds not only the space to store the data, but also a small amount of over-head space to keep track of how long the data is. In addition, ease of search is also not an issue since, if we have any value in the field at all, there isn’t enough room left for padded spaces.

Since a name for an employee is a critical item, we will not allow any NULLvalues in the first and last name columns. Middle initial is not nearly so critical (indeed, some people in the U.S. don’t have a mid-dle name at all, while my editor tells me that it’s not uncommon for Brits to have several), so we will allow a NULLfor that field only:

FirstName varchar(25) NOT NULL, MiddleInitial char(1) NULL, LastName varchar(25) NOT NULL,

Next up is the employee’s title. We must know what they are doing if we’re going to be cutting them a paycheck, so we will also make this a required field:

Title varchar(25) NOT NULL,

In that same paycheck vein, we must know their Social Security Number (or similar identification num-ber outside the U.S.) in order to report for taxes. In this case, we’ll use a varcharand allow up to 11 characters, as these identification numbers are different lengths in different countries. If you know your application is only going to require SSNs from the U.S., then you’ll probably want to make it char(11) instead:

SSN varchar(11) NOT NULL,

We must know how much to pay the employees — that seems simple enough — but what comes next is a little different. When we add in the prior salary and the amount of the last raise, we get into a situation

For the code that you write directly in T-SQL, SQL Server will automatically adjust to the padded spaces issue — that is, an ‘xx’ placed in a char(5) will be treated as being equal (if compared) to an ‘xx’ placed in a varchar(5) — this is not, however, true in your client APIs such as ADO and ADO.NET. If you connect to a char(5) in ADO, then an

‘xx’ will evaluate to xx with three spaces after it — if you compare it to ‘xx’, it will eval-uate to False. An ‘xx’ placed in a varchar(5), however, will automatically have any trail-ing spaces trimmed, and compartrail-ing it to ‘xx’ in ADO will evaluate to True.

131

Creating and Altering Tables

where we could use a computed column. The new salary is the sum of the previous salary and the amount of the last raise. The Salaryamount is something that we might use quite regularly — indeed we might want an index on it to help with ranged queries., but for various reasons I don’t want to do that here (we’ll talk about the ramifications of indexes on computed columns in Chapter 9), so I’m going to use LastRaiseas my computed column:

Salary money NOT NULL, PriorSalary money NOT NULL, LastRaise AS Salary - PriorSalary,

If we hired them, then we must know the date of hire — so that will also be required:

HireDate smalldatetime NOT NULL,

Note that I’ve chosen to use a smalldatetimedatatype rather than the standard datetimeto save space. The datetimedatatype will store information down to additional fractions of seconds, plus it will save a wider range of dates. Since we’re primarily interested in the date of hire, not the time, and since we are dealing with a limited range of calendar dates (say, back 50 years and ahead a century or so), the smalldatetimewill meet our needs and take up half the space.

The date of termination is something we may not know (we’d like to think that some employees are still working for us), so we’ll need to leave it nullable:

TerminationDate smalldatetime NULL,

We absolutely want to know who the employee is reporting to (somebody must have hired them!) and what department they are working in:

ManagerEmpID int NOT NULL, Department varchar(25) NOT NULL )

So, just for clarity, let’s look at the entire script to create this table:

USE Accounting

CREATE TABLE Employees (

EmployeeID int IDENTITY NOT NULL, FirstName varchar(25) NOT NULL,

Date and time fields are somewhat of a double-edged sword. On one hand, it’s very nice to save storage space and network bandwidth by using the smaller datatype.

On the other hand, you’ll find that smalldatetimeis incompatible with some other language datatypes (including Visual Basic). Even going with the normal datetime is no guarantee of safety from this last problem though — some data access models pretty much require you to pass a date in as a varcharand allow for implicit con-version to a datetimefield.

MiddleInitial char(1) NULL, LastName varchar(25) NOT NULL, Title varchar(25) NOT NULL, SSN varchar(11) NOT NULL, Salary money NOT NULL, PriorSalary money NOT NULL, LastRaise AS Salary - PriorSalary,

HireDate smalldatetime NOT NULL, TerminationDate smalldatetime NULL, ManagerEmpID int NOT NULL, Department varchar(25) NOT NULL )

Again, I would recommend executing sp_helpon this table to verify that the table was created as you expected.

Dans le document SQL Server (Page 159-164)