Home > Education > Chapter 9 – SQL CREATE, DROP, and ALTER

Chapter 9 – SQL CREATE, DROP, and ALTER

Section I – Usage

When to Use

So far we’ve spent our time discovering how SQL can be used to aggregate, sort, and manipulate data for analysis and presentation purposes.  But everything we’ve done is under the assumption the data was already available.  In this lesson we’ll learn about the other part of SQL, architecture!

SQL Architecture consists of creating, deleting (dropping), and altering tables, views, and indexes.  While most DBMSs will come with an out-of-the-box SQL administration tool (such as SQL Server Management Studio), SAS does not.  SAS does allow you to create a table manually using the GUI, however it is slow and cumbersome, so we’ll focus on the actual SQL syntax.

Items

Before we get into the syntax of SQL Architecture, let’s discuss the difference between a table, view, and index.  As mentioned in Chapter 2, a table is a SAS dataset that consists of columns and rows.  A table is a permanent collection of organized data. 

A View is very similar to a table, except it does not contain permanent data.  A view is a virtual table and consists of nothing more than a permanent query.  Each time you open a View the View’s query will run and present the results in a table format.  Views are best utilized when dealing with a normalized database.  It’s easier to create output tables for users rather than require them to learn the complex structure of the database.

An index is used to sort data in a more logical manner than how it is initially entered into a table.  This is done to speed up the processing involved in SELECT statements.  The best way to think of how an index works is to envision an index in the back of a book.  Querying a table using a WHERE statement, if the table is indexed on that column, will result in SAS reading the index instead of the table and will find the rows directly.  A good index can increase the speed by dozens of multiples.


Section II – Our Sample Database

In the following samples, we’ll re-create the database our examples were created in.  Since we’re starting from scratch, make sure you create a folder called C:\Temp\Chapt09\.  Before you begin, assign your librefs and set your options.

Option Source Notes Source2 MPRINT XWait;

Libname Chapt09  “C:\Temp\Chapt09\”;

CREATE Tables

Let’s start out with a basic CREATE table statement.  We’ll create the WeatherStations table and include a handful of basic constraints.

Proc SQL;

Create Table Chapt09.Obj_WeatherStations

(

      ID    char(3)     format=$3.        ,

      City  varchar(50) format=$50.       ,

      State char(2)     format=$3.        ,

Constraint pk_ID        Primary Key(ID)   ,

Constraint nn_City      Not Null(City)    ,

Constraint nn_State     Not Null(State)

);

Quit;

When you look at the above statement, we’ve created a table with three (3) columns (ID, City, and State) and three (3) constraints.  The first constraint is called a Primary Key.  A Primary Key is a unique version of an index.  It is unique in a sense that every value in the ID column must be….unique!  The Primary Key also works as an index, so every value in the ID column will be sorted.

The second constraint is called a Not Null constraint.  What this basically means is, for a row to be entered and saved in the table the values in Columns City and State cannot have a null (blank) value.  In future examples, we’ll see other types of constraints, but for now, the basics!

Now, let’s create an index for this table.

Proc SQL;

Create Index City On Chapt09.Obj_Weatherstations(City);

Quit;

In the previous statement, we created an index called City on the table Obj_Weatherstations on the column City.  When building an index on a table that only utilizes a single column, the index name MUST be the same as the column name. 

Now, if you wanted to delete both the table and the index, you would need to use a DROP statement.  A DROP statement will work the same for indexes, views, and tables, but not constraints (we’ll see this later).

Proc SQL;

Drop Index Name On Chapt09.Obj_Weatherstations;

Drop Table Chapt09.OBJ_WeatherStations;

Quit;

Now, let’s get a little more advanced!  In this example, we’re going to add two new types of constraints, including one that will throw you for a loop come DROP Table time!

Proc SQL;

Create Table Chapt09.Obj_Recorders

(

      ID                varchar(14) format=$14.       ,

      Premise           char(9)     format=$9.        ,

      Name              varchar(50) format=$50.       ,

      OpCo              char(3)     format=$3.        ,

      State             char(2)     format=$2.        ,

      MV90              char(3)     format=$3.        ,

      Active            char(1)     format=$1.        ,

      Interval          smallint    format=2.         ,

      StartDate         date        format=mmddyy10.  ,

      LastUploadDate    date        format=mmddyy10.  ,

      LastFinaledDate   date        format=mmddyy10.  ,

      WeatherStationID char(3)     format=$3.        ,

Constraint pk_ID                    Primary Key(ID)   ,

Constraint fk_WeatherStationID      Foreign Key(WeatherStationID) References Chapt09.Obj_WeatherStations On Update Cascade On Delete Set Null,

Constraint ck_Active                Check((Active = “T”) or (Active = “F”)),

Constraint nn_Opco                  Not Null(OpCo)          ,

Constraint nn_State                 Not Null(State)         ,

Constraint nn_Name                  Not Null(Name)          ,

Constraint nn_MV90                  Not Null(MV90)          ,

Constraint nn_Interval              Not Null(Interval)

);

Quit;

In the above example, the two new constraints were called Check and Foreign Key.  The Check constraint uses boolean logic to prevent rows from being added to the table that would violate said constraint.  In the above example, we are only allowing a ‘T’ or ‘F’ to enter into the Active column.  The Foreign Key constraint, known as a referential integrity constraint, occurs when we limit the available entries into the column based on values in a different table.  In the above example, we are forcing all entries of the WeatherStationID column to exist in the ID column in the Obj_Weatherstations table.  Whenever you declare a foreign key constraint, the columns you include in the parentheses (in this case, WeatherStationID) must relate directly to the Primary Key column in the referenced table.  The statements following the table name (On Update Cascade On Delete Set Null) tell SQL that if we change a value in the parent table (Obj_Weatherstations), it will change the corresponding value in the child table (Obj_Recorders).  If we delete a value in the parent table, we set the corresponding value in the child table to null.

Proc SQL;

Create Index idx_query On Chapt09.Obj_Recorders(MV90, Active, LastUploadDate);

Quit;

In this example, we’re creating a compound index.  It is called a compound index because the index occurs on more than one column.  Also, because we’re using more than one column, we can call the index whatever we wish.  Now try and drop the index and table.

Proc SQL;

Drop Index idx_query On Chapt09.Obj_Recorders;

Drop Table Chapt09.OBJ_Recorders;

Quit;

Get any error messages?


ALTER Table

No doubt you got the following error:

ERROR: A rename/delete/replace attempt is not allowed for a data set involved in a referential integrity constraint.

WARNING: Table CHAPT09.OBJ_RECORDERS has not been dropped.

To drop the table entirely, we need to first drop the foreign key constraint.  To do this, we need to ALTER the table.  An ALTER table statement allows us to add, edit, and remove columns, and drop constraints.  Knowing this, let’s try to drop the constraint THEN drop the table and see if we have any better luck.

Proc SQL;

Alter Table Chapt09.Obj_Recorders Drop Constraint fk_WeatherStationID;

Drop Table Chapt09.OBJ_Recorders;

Quit;

Success!

Views

We’re not going to spend too much time on Views because there not all that valuable in SAS.  However, if you ever get involved in a larger RDBMS you will find them VERY helpful. 

In the below example, we’re going to create a view that joins the Recorder table and WeatherStation table.  Usually when creating views, try to preface the view name with “vw”.

Proc SQL;

Create View Chapt09.vw_Recorders as

Select      A.ID as RecorderID,

            A.Name,

            A.OpCo,

            A.Active,

            B.ID,

            B.City,

            B.State

From Chapt09.Obj_Recorders as A

Inner Join Chapt09.Obj_Weatherstations as B

On A.WeatherstationID = B.ID;

Quit;

Also, dropping a View is just like dropping a table.  However, there can’t be any constraints or indexes on a view.

Proc SQL;

Drop View Chapt09.vw_Recorders;

Quit;


Section III – Examples

Now that we’ve seen how to CREATE, DROP, and ALTER let’s go ahead and construct the rest of the database.  Please take note of a certain type of index we create.  I’ll let you find it yourself and we’ll discuss in class.

Create Tables

 

Proc SQL;

Create Table Chapt09.Obj_WeatherStations

(

      ID          char(3)                 format=$3.              ,

      City  varchar(50)       format=$50.             ,

      State char(2)                 format=$3.              ,

Constraint pk_ID        Primary Key(ID)               ,

Constraint nn_City            Not Null(City)                ,

Constraint nn_State           Not Null(State)

);

Quit;

Proc SQL;

Create Table Chapt09.LKP_LoadPeriods

(

      IDStart           date        format=datetime19.,    

      ID                date        format=datetime19.,

      IDDate            date        format=mmddyy10.,

      IDTime            date        format=hhmm5.,

      IDSeason          char(6)     format=$6.,

      IDYear            smallint    ,

      IDMonth           smallint    ,

      IDDay             smallint    ,

      IDHourEnding      smallint    ,

      IDWeekday         smallint    ,

      IDDayType         smallint    ,

      IDWeekOfYear      smallint    ,

      IDTradePeriod     char(26)    format=$26.,

      DSTStart          date        format=datetime19.,

      DST               date        format=datetime19.,

      DSTDate           date        format=mmddyy10.,

      DSTTime           date        format=hhmm5.,

      DSTSeason         char(6)     format=$6.,

      DSTYear           smallint    ,

      DSTMonth          smallint    ,

      DSTDay            smallint    ,

      DSTHourEnding     smallint    ,

      DSTWeekday        smallint    ,

      DSTDayType        smallint    ,

      DSTWeekOfYear     smallint    ,

      DSTTradePeriod    char(26)    format=$26.,

      DSTFlag           char(1)     format=$1.,

Constraint pk_ID              Primary Key(ID)         ,

Constraint nn_IDStart         Not Null(IDStart)       ,    

Constraint nn_IDDate          Not Null(IDDate)        ,

Constraint nn_IDTime          Not Null(IDTime)        ,    

Constraint nn_IDSeason        Not Null(IDSeason)      ,

Constraint nn_IDYear          Not Null(IDYear)        ,    

Constraint nn_IDMonth         Not Null(IDMonth)       ,    

Constraint nn_IDDay           Not Null(IDDay)         ,    

Constraint nn_IDHourEnding    Not Null(IDHourEnding)  ,

Constraint nn_IDWeekday       Not Null(IDWeekday)     ,    

Constraint nn_IDDayType       Not Null(IDDayType)     ,    

Constraint nn_IDWeekOfYear    Not Null(IDWeekOfYear)  ,

Constraint nn_IDTradePeriod   Not Null(IDTradePeriod) ,

Constraint nn_DSTStart        Not Null(DSTStart)      ,

Constraint nn_DST             Not Null(DST)           ,    

Constraint nn_DSTDate         Not Null(DSTDate)       ,    

Constraint nn_DSTTime         Not Null(DSTTime)       ,    

Constraint nn_DSTSeason       Not Null(DSTSeason)     ,

Constraint nn_DSTYear         Not Null(DSTYear)       ,

Constraint nn_DSTMonth        Not Null(DSTMonth)      ,

Constraint nn_DSTDay          Not Null(DSTDay)        ,    

Constraint nn_DSTHourEnding   Not Null(DSTHourEnding) ,    

Constraint nn_DSTWeekday      Not Null(DSTWeekday)    ,    

Constraint nn_DSTDayType      Not Null(DSTDayType)    ,    

Constraint nn_DSTWeekOfYear   Not Null(DSTWeekOfYear) ,    

Constraint nn_DSTTradePeriod  Not Null(DSTTradePeriod),    

Constraint ck_DSTFlag         Check((DSTFlag = “T”) or (DSTFlag = “F”))

);

Quit;

Proc SQL;

Create Table Chapt09.LKP_StatusCodes

(

      ID                int                           ,

      Code              char(2)     format=$2.        ,

      Description       varchar(50) format=$50.       ,

Constraint pk_ID             Primary Key(ID)         ,

Constraint  nn_Code           Not Null(Code)          ,

Constraint nn_Description    Not Null(Description)  

);

Quit;

Proc SQL;

Create Table Chapt09.Obj_Recorders

(

      ID                varchar(14) format=$14.       ,

      Premise           char(9)     format=$9.        ,

      Name              varchar(50) format=$50.       ,

      OpCo              char(3)     format=$3.        ,

      State             char(2)     format=$2.        ,

      MV90              char(3)     format=$3.        ,

      Active            char(1)     format=$1.        ,

      Interval          smallint    format=2.         ,

      StartDate         date        format=mmddyy10.,

      LastUploadDate    date        format=mmddyy10.,

      LastFinaledDate   date        format=mmddyy10.,

      WeatherStationID char(3)     format=$3.        ,

Constraint pk_ID                    Primary Key(ID)         ,

Constraint fk_WeatherStationID      Foreign Key(WeatherStationID) References Chapt09.Obj_WeatherStations On Update Cascade On Delete Set Null,

Constraint ck_Active                Check((Active = “T”) or (Active = “F”)),

Constraint nn_Opco                  Not Null(OpCo)          ,

Constraint nn_State                 Not Null(State)         ,

Constraint nn_Name                  Not Null(Name)          ,

Constraint nn_MV90                  Not Null(MV90)          ,

Constraint nn_Interval              Not Null(Interval)

);

Quit;

Proc SQL;

Create Table Chapt09.Data_Load

(

      RecorderID              varchar(14) format=$14.             ,

      LoadPeriodID            date        format=datetime19.      ,

      Channel                 smallint                                  ,

      Value                   real                                      ,

      StatusCodeID            int                                             ,

Constraint fk_RecorderID      Foreign Key(RecorderID) references Chapt09.Obj_Recorders on update cascade on delete set null,

Constraint fk_LoadPeriodID    Foreign Key(LoadPeriodID) references Chapt09.LKP_LoadPeriods on update cascade on delete set null,

Constraint fk_StatusCodeID    Foreign Key(StatusCodeID) references Chapt09.LKP_StatusCodes on update cascade on delete set null,

Constraint nn_Channel         Not Null(Channel) ,

Constraint nn_Value           Not Null(Value)  

);   

Quit;


Create Indexes

Proc SQL;

Create Unique Index idx_query On Chapt09.Data_Load(RecorderID, LoadPeriodID, Channel, StatusCodeID);

Create Index idx_query On Chapt09.Obj_Recorders(MV90, Active, LastUploadDate);

Create Index IDHourEnding On Chapt09.LKP_LoadPeriods(IDHourEnding);

Create Index City On Chapt09.Obj_Weatherstations(City);

Quit;

Create Views

 

Proc SQL;

Create View Chapt09.vw_Recorders as

Select      A.ID as RecorderID,

            A.Name,

            A.OpCo,

            A.Active,

            B.ID,

            B.City,

            B.State

From Chapt09.Obj_Recorders as A

Inner Join Chapt09.Obj_Weatherstations as B

On A.WeatherstationID = B.ID;

Quit;

Drop Indexes

Proc SQL;

Drop Index idx_query On Chapt09.Obj_Recorders;

Drop Index idx_query On Chapt09.Data_Load;

Drop Index IDHourEnding On Chapt09.LKP_LoadPeriods;

Drop Index City on Chapt09.Obj_Weatherstations;

Quit;

Drop Constraints

Proc SQL;

Alter Table Chapt09.Obj_Recorders Drop Constraint fk_WeatherStationID;

Alter Table Chapt09.Data_Load Drop Constraint fk_LoadPeriodID;

Alter Table Chapt09.Data_Load Drop Constraint fk_RecorderID;

Alter Table Chapt09.Data_Load Drop Constraint fk_StatusCodeID;

Quit;

 

Drop Tables

Proc SQL;

Drop Table Chapt09.Data_Load;

Drop Table Chapt09.OBJ_Recorders;

Drop Table Chapt09.OBJ_WeatherStations;

Drop Table Chapt09.LKP_StatusCodes;

Drop Table Chapt09.LKP_LoadPeriods;

Drop View Chapt09.vw_Recorders;

Quit;

Advertisement
Categories: Education Tags:
  1. No comments yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.