Professional Documents
Culture Documents
Practical SQL- Microsoft SQL Server T-SQL for Beginners -- Mark O’Donovan -- Paperback, 2013 -- Createspace Independent Publishing Platform -- 9781492753407 -- 94ab93a4989975c317048ac6f0cba8d5 -- Anna’s Archive
Practical SQL- Microsoft SQL Server T-SQL for Beginners -- Mark O’Donovan -- Paperback, 2013 -- Createspace Independent Publishing Platform -- 9781492753407 -- 94ab93a4989975c317048ac6f0cba8d5 -- Anna’s Archive
Disclaimer
Although the author and publisher have made every effort to ensure that the
information in this book was correct at press time, the author and publisher do
not assume and hereby disclaim any liability to any party for any loss, damage,
or disruption caused by errors or omissions, whether such errors or omissions
result from negligence, accident, or any other cause.
Title: Practical Sql - Microsoft Sql Server T-SQL for Beginners – Second
Edition
Version: 2.0
Software and Sample Data
The examples in this book used Sql Server 2017 Express which is as of
writing this book a free version of sql server available for download from
Microsoft.
You can download all the sample data and examples for this book from
https://github.com/techstuffy/Practical-Sq
Most examples will run on previous versions of Microsoft Sql Server but
some functions might differ or not exist on previous versions such as the format
function.
If you have problems accessing the sample data please contact me using
techstuffy.com.
Overview
A brief overview of the different sections contained within this book :
Chapter 1
This chapter introduces the book , how to use the book and where to get
downloads.
Chapter 2
Here we cover how to get a free copy of sql server express and the
installation of the software.
Chapter 3
Once sql server has been installed this chapter will take you on a brief tour of
the software and how to login to the sql server for the first time.
Chapter 1
This chapter will show you how to create your first sql server database and
the various properties of sql server databases.
Chapter 2
Once you have created your database this chapter will explain and give
examples of creating sql server tables to store your data.
Chapter 3
In the final chapter of this section with introduce the basic sql statements to
insert, query, update and delete data from a sql table.
Section 3. Advanced Queries
Section 3 goes into sql development in more detail cover ways of grouping
data, creating conditional statements and joining tables of data together.
Chapter 1
Chapter 2
Chapter 3
Chapter 4
When developing sql databases more often than not the data you need to
return will be in more than one table. This chapter covers the various ways you
can combine the data in 2 or more tables.
Section 4. Sql Beyond the Basics
Now that the basics of sql development have been covered Section 4 carries
on by introducing more development techniques such as using Stored
Procedures, Functions and Views, Triggers, database design rules and much
more.
Chapter 1
The sql developer can add rules to the check that the data being added to the
table is valid, this chapter will show you ways to create various constraints.
Chapter 2
Templates are a useful sql server feature. We will show you how to use
Templates to speed up your sql development to save you time and create
consistency and also how to create your own sql server templates.
Chapter 3
When you start to develop more complex queries you can add them to stored
procedures so that they can be saved in the database and executed with a single 1
line statement at a later date.
We will cover to create stored procedures and pass parameters to the stored
procedures.
Chapter 4
Views allow you to hide complex SELECT statements so you only need to
run a simple select statements. Using View can save you copying and pasting
large chunks of code and make it easier to read the sql that you have developed.
Chapter 5
Next we will cover different types of functions that can be created and how
they compare to stored procedures.
Chapter 6
Synonyms are aliases for tables and are especially useful when you start to
develop code that uses references to multiple databases.
We will show you how to create and manage synonyms within your
database.
Chapter 7
Triggers allow you to execute some tsql when an action is taken on the
database or table. We will cover how to create various triggers and use them for
various purposes such as auditing and preventing users from creating tables.
Chapter 8
When you start to develop sql for large amounts of data the design of the
database will be increasingly more important. We will cover the fundamental
rules of database design called normal forms.
Chapter 9
Chapter 10
Finally we cover Transactions. Transactions are the 'all or nothing' in the sql
world. You might have a number of changes to tables within your stored
procedure but want all the changes to be saved as long as there has been no
errors executing any of the statements, transactions will allow to do this.
Section 1. Sql Server Install and Tour
1. Introduction
The purpose of this book is to teach the user sql database development.
More precisely you will learn sql development on Microsoft Sql Server using
the version of Sql from Microsoft called T-SQL (T-SQL stands for Transact
SQL).
With the Practical Series of books and 'Practical Sql' in this case you will be
guided from the basics to more advanced techniques.
The instructions are kept concise with the focus being on useful examples.
The aim here is that you will be more likely to remember what is said about a
topic and can always refer back to the examples at a later date if required.
Practical Sql
'Practical Sql' will cover the tsql development language used on the
Microsoft Sql Server Database system.
Sql Server Development is a topic that many IT Professionals avoid but there
really is no need as the basics and even more advanced techniques can be
acquired easily.
In other words Sql development is not a skill that will be of use to just DBA's
and developers.
There are many applications that rely on sql server databases so some
knowledge of databases it becoming a common requirement.
2. Sql Server Installation
You can download the current version of Sql Server Express from the
following location:
https://www.microsoft.com/en-gb/sql-server/sql-server-editions-express
Processor
RAM
Minimum 512MB
2. Click Install and wait for the installation files to be downloaded and
installed.
3. Once the installation has completed you will be presented with details
about your sql server. In particular make a note of your instance name
as this might be different from the screenshot below if you already
have a version of sql express on your machine:
4. To test your installation you can click the connect now button to
connect to the server as shown below:
5. Click Install SSMS and download the current version of the SSMS.
6. Once the download has completed, click the install and then click
install.
7. Click restart to complete the setup. Once your computer has restarted
you should be able to find the installed Sql Server Management Studio
by searching from the Start Menu:
3. Sql Server Tour
Before we get started learning sql server development we will give a brief
tour of the sql server environment itself.
This chapter will not turn you into a sql server database administrator but the
aim (especially if you are completely new to sql server) is to familiarise yourself
with some of the features, services and basic configuration of sql server.
The main sql server tool that your will be using for the configuration and
development tasks is called the 'Sql Server Management Studio' from now on
this will be referred to as SSMS.
The sql server runs using services, you can view these services in several
ways for example if you go to the Start Menu and search for Sql Server 2017
Configuration Manager.
Click on the Sql Server Services option and you will see the services that are
running
The main service for sql server. You will not be able to access sql server if
this service is not running.
This service allows you to perform various tasks including the scheduling of
jobs for example to backup your sql server databases or execute tsql at a
particular time.
From the sql server configuration manager you can configure each of these
services, for example if the start automatically and the account that is used to
run the service.
The account that is used to run services is important when the sql server
needs to access the filesystem for example when doing backup and restore tasks.
SQL Server Network Configuration
Within the Sql Server Network Configuration you can configure which
protocols can access your sql server.
The protocols are just different ways in which in which messages are sent to
and from your sql server installation.
The 3 protocols which we will cover next are Shared Memory, Named Pipes
and TCP/IP.
This protocol allows users running on the same computer to connect to the
sql server.
Named pipes are often used to allow applications and systems that do not use
TCP/IP to connect to the sql server
\\.\pipe\mytest
3. Go to Sql Server Services , right click on the SQL Server and select
restart.
4. Open SSMS and select Connect - Database Engine.
\\.\pipe\mytest
The reason for using named pipes is so that systems that do not use TCP/IP
can connect to your database.
This is the protocol that you will need to configure to allow your sql server
to be accessed from other machines on your network.
Protocol tab
IP Addresses tab
For example if you need your sql server to be accessed by another machine,
you would need to add the ip address and make sure it was set to active and
enabled, for example:
The default port for sql server is 1433, sql server express uses dynamic ports
by default
When using dynamic ports the port that the sql server uses changes when sql
server restarts.
TCP Port - if you wish to set a port that doesn't change you can enter the
port in the TCP Port field. No change is required here to follow the examples in
this book.
Sql Server Properties
There are various properties of the sql server that can be set using the SSMS.
To view the properties for your sql server installation right click on the Sql
server icon in the object explorer as shown and select Properties:
On the left hand side of the 'Server Properties' dialog that is displayed you
will see that the properties are divided into the following pages:
General
The general settings display various read-only properties such as the version
of the sql server and the version of the windows operating system.
You can also display the properties such tsql commands such as the
following:
SELECT
CONVERT(sysname, SERVERPROPERTY('servername')),
SERVERPROPERTY('ProductVersion') AS ProductVersion,
SERVERPROPERTY('ProductLevel') AS ProductLevel,
SERVERPROPERTY('Edition') AS Edition,
SERVERPROPERTY('EngineEdition') AS EngineEdition,
SERVERPROPERTY('Collation') AS Collation;
The result from this query should look similar to the following screenshot:
Memory
This page shows the sql server memory options, such as the minimum and
maximum amount of memory allowed to be used by the sql server.
Security
This page allows you to set whether Sql Authentication is allowed to be used
to login to the sql server. Windows authentication mode is the default setting.
Connections
The 'Allow remote connections to this server' is the most important option on
this page, especially if you have an application running on another server that
need to access your sql server database.
Database Settings
Here is where you set the default locations for the data (the sql server
database files), Log (sql server logs) and backups:
Data
Log
C:\Program Files\Microsoft SQL
Server\MSSQL14.SQLEXPRESS\MSSQL\DATA\
Backup
Advanced
There are many options on this page. The most important to note at the
moment are:
Default language - make sure this correct for your country and be aware of
the differences between English (US) and British English. The default language
setting is used when creating new logins.
Permissions
The permissions page shows the commands various logins can execute on
the server.
For now if you select the login that you used to connect to the sql server,
then select the 'Effective' tab at the bottom of the page you will see a list of
permissions which are basically a list of things that this login can do while
connected to the sql server, for example:
If you select the login 'NT AUTHORITY\SYSTEM' you will see that the list
of effective permissions is more restricted that your login.
System databases
When you first install sql server there are 4 databases already created.
To view these 4 system databases expand the Databases folder in the Object
explorer, and then expand the 'System Databases' folder.
master
Various pieces of information such as logins and configuration settings.
msdb
Backup, restore history and all details of schedules, operators and jobs.
model
Used as a template for creating new databases.
tempdb
Storage while process queries ie: sorts.
Temporary tables
Temporary tables can be used when you only require a table for a short
period of time when executing some tsql.
You can prove that the tempdb database is used to store temporary fields by
creating a table executing the following tsql:
A local temporary table can only be accessed by the session in which it was
created
If you prefix table name with '##', it is called a global temporary table which
means the table will be able to be accessed by all sessions not just the one where
the table was created.
Expand the tempdb database, then the 'Temporary tables' folder and you will
see the temporary table you have just created.
You may need to refresh the view by right clicking on the 'Temporary Tables'
folder or the tempdb database and selecting the refresh option.
If you close the query window and refresh the view again you will see the
temporary table has now disappeared.
Because the tempdb table is recreated each time the server is started you can
check the last time the sql server was restarted by right clicking on the tempdb
database, selecting properties and checking the 'Date Created' field.
First Login to Sql Server
1. Open the sql server management studio by going to the start menu and
searching for SSMS.
2. Enter the following details into the dialog box:
The most recent log file which has the prefix of 'Current' if the problem you
are investigating happened recently.
As with all systems that keep log files it is important to manage them so that
you do not run out of disk space.
If you expand the Management folder and right click on the 'SQL Server
Logs' folder and select Configure you will see the option to limit the number of
log files that are kept before they are recycled as shown. In the example below I
have set the limit of 6 log files.
2. Within this folder you will find the default folder for the Backup files
(Backup) and Database files (DATA).
Quiz
Question 1
Question 2
Question 3
create databases
tables and fields
fundamental statements that perform the basic operations on your data.
Once you are comfortable creating a database, tables and performing the
basic insert, select, update and delete statements on a table of data the following
sections should not cause any problems.
1. Create a database
1. Right click on the 'Databases' folder in the Object explorer and select
the 'New Database...' :
2. Enter a name for your database in the 'Database name' field, in this
case 'first_db'.
3. Notice as you enter the database name the logical name in the
'Database files' table is automatically generated.
4. The 2 files that will be created are called:
first_db.mdf
first_db_log.ldf
Collation - the collation settings effects the sort order , case and accent
sensitivity of the information in your tables.
Recovery Model - This option determines the type of backups that can
be performed on the database.
For this book all files will be added to the default PRIMARY filegroup.
6. Click on the OK button to create the database, then you will see the
database listed under the databases folder.
2. Create Sql Tables
1. The table we are going to create will consist of the following 3 fields
and data types.
CREATED_DATEdate
CATEGORY varchar(20)
AMOUNTnumeric(5,2)
There are 2 ways that you can create this table. You can either create the
table in the gui or type in the tsql.
3. In the Management Studio expand the database you created and right
click on the Tables folder and select the Table… option.
4. Enter the Column Name , Data Type and check the tickbox if NULL
values are allowed for this field. A NULL value is an empty field.
5. A null value means that you do not have to fill in the field.
6. Once you have entered all the fields press Ctrl+S to save the table and
enter a table name of spending_initial.
Create the table using tsql
1. To create the table using tsql click on the 'New Query' button in the
toolbar or press Ctrl+N to open a new query window.
2. Enter the text below and press Alt+X or the Execute button in the
toolbar to execute the statement.
use first_db
3. In the tsql about the USE statement changes the database to first_db.
If you have called your database a different name you will need to
change it here.
4. The CREATE TABLE statement consists of the table name in the
format:
schema.tablename
Schemas are used to group objects such as tables and views. In this book we
will always be using the dbo schema.
(The 'NOT NULL' option means that when creating a row you need to enter
a value in each field, otherwise you would just enter the text 'NULL')
Create field called amount which is the numeric , the value will have 5 digits
in total with 2 after the decimal point, for example 123.45 :
9. If you need to remove a table from your database you can either right
click on the table and select the Delete option, then click OK to
confirm the deletion or run the follow DROP command:
1. Next we will cover how you can use the CONVERT function to
change expressions such as a datetime returned from a GETDATE()
function into a varchar data type.
2. The format for the CONVERT function is:
US
1 = mm/dd/yy
101 = mm/dd/yyyy
10 = mm-dd-yy
110 = mm-dd-yyyy
British/French
3 = dd/mm/yy
103 = dd/mm/yyyy
German
4 = dd.mm.yy
104 = dd.mm.yyyy
If you cannot find the style you require for your country or the format for the
date you require listed here you can find the full list of codes here:
http://technet.microsoft.com/en-us/library/ms187928.aspx
If you omit the code parameter the field will be returned using the
default date format. Note we have increased the length of the data type we
are using so that the full datetime field is displayed:
The format command returns a formatted result based on the format string
and optional culture parameter that is passed to it.
The format command is only available on sql server from version 2012, if
you try to run this command on previous versions of sql server you will get the
following error:
Msg 195, Level 15, State 10, Line 1
'format' is not a recognized built-in function name.
It is important to remember this just in case there is the possibility that the
code you are developing will at some point run on a previous version of sql
server such as sql server 2008 R2.
Obviously you will not have this problem while learning using 1 sql server
but might encounter it when you start using sql server in a company.
N - Numeric
G - General
C - Currency
Or a format that the users passes for example to format a date string ‘dd-
MM-yy’.
'en-US'= US English
'en-gb'= British English
'de-de' = German
This option defaults to the current language of the session. Next we will
cover an example of how to use the format function.
select format(getdate(),'dd-MM-yy','en-gb')
You should get a result returned in this format (obviously the date will
be different)
14-04-19
Some other fields that you can use for format string when using dates
are:
Code Format
MM Month Number 01-12
MMM Short Month ie: Jan,Feb etc…
ss\s Second
t AM\PM
yy\yyyy Year
Mm Minute
hh 12 hour
HH 24 hour
dd Day
ddd Short day ie: Mon,Tue,Wed etc…
dddd Full name of day
When working with dates the first thing you need to check is that you are
using the correct date format for your country.
You can see a list of the possible languages available on your system using
the following statement: select * from syslanguages
Get the current DATEFORMAT
The DATEFORMAT setting will determine the default format for dates.
DBCC USEROPTIONS
2. A number of rows will be returned, if you look at the row where the
‘Set Option’ field is ‘dateformat’ you will see the current dateformat
setting,for example it might be:
mdy
This defines the order as month day then year. You can change the
dateformat setting using the ‘set dateformat’ command.
For example if you wanted to change the order of the day and month so
that the day is first you would use the following command:
set dateformat dmy
3. Open a 'New Query' window and check the dateformat using the
DBCC USEROPTIONS command.
4. You will see it is mdy and the dateformat does not change for all
sessions.
5. If you change the default language of the login that date format will
change for all sessions.
6. Open the security folder, logins , right click on your login and select
properties.
7. Select the General option on the left side of the dialog and change the
Default Language to British English or English if it is already set to
‘British English’.
8. Open a new query window and execute the DBCC USEROPTIONS
command. You will see the following settings have changed:
languageBritish
dateformatdmy
languageus_english
dateformatmdy
Date functions
In some way or another most tables you will be developing will probably
have a date field, for example the date\time field is often used to show when the
row was created.
Next we will cover the more useful date functions that are available on sql
server.
GETDATE
YYYY-MM-DD hh:mm:ss[.nnn]
For example:
select GETDATE()
2019-04-14 12:00:12.510
CAST
Format: CAST(<expression> as <data type>)
Here are 2 examples of using the CAST function to either return just the date
or time from the GETDATE function.
The default format of the date data type is YYYY-MM-DD, execute the
following statement:
select cast(GETDATE() as date)
2019-04-14
The default format of the time data type is hh:mm:ss[.nnnnnnn] , execute the
following statement:
DATEPART
With the DATEPART function you can obtain certain parts of the datetime
field returned from the GETDATE function .
DATEPART(<part_of_date>,date_expression)
< part_of_date > = a keyword representing the part of the date you require
for example using DAY , MONTH, or YEAR returns the different parts of the
date as you would expect.
The following statement returns the number of the current month ie: 4 for
April:
select DATEPART(month,GETDATE())
Instead of month we could have returned other parts of the date such as:
DAYMONTHWEEKDAY
YEARHOUR
MINUTESECOND
Using the weekday for the first parameter returns the number for the day of
the week, eg:
select DATEPART(weekday,GETDATE())
DATENAME
Format: DATENAME(<part_of_date>,date_expression)
The DATENAME function returns the string values of the part of the date
you require.
For example the following statement will return the word ‘August’ for the
current month instead of 8 (that would be returned by the DATEPART function).
select DATENAME(month,GETDATE())
The weekday option for the first parameter returns the name of the day such
as Monday, Tuesday etc…
select DATENAME(weekday,GETDATE())
Create Fields
A table in a database consists of rows and columns much like a spreadsheet.
To setup a table you need to set the data type of each field. The data type is
used to tell sql server what kind of information to expect such as a string of 10
characters in length, numeric value or a date.
Next we will create a simple table to store the amount of money spent on
different categories and the Month the money was spent. The 3 fields used will
be:
The 3 different data types we will use are char, varchar and money.
char\varchar
For example a data type of char(3) will always use 3 characters even if
the string is less than 3 characters.
varchar data type stands for variable character and means it will only
use the amount of space it requires depending on the length of the string.
Most of the time using char\varchar will be fine unless you are
developing for international users.
3. Sql Queries
Most of the queries in sql development are based around the following 4
types of queries.
Insert - putting data into the table
Select - reading data from the table
Update - updating the rows in the table
Delete - deleting some or all the rows from the table
I would not continue with the other examples until the commands
presented in this chapter are clear and you are happy to execute simple
insert, select, update and delete commands without referring to the book.
INSERT Statement
This needs to be the first statement we cover as we need to put data into the
table before we can read, update or delete that data.
Using SSMS
1. Right click on the table dbo. spending_initial and select the option
'Edit Top 200 Rows'.
2. Press the tab buttons to move between fields. When you press the tab
button from the last field another row will be added. Enter the
following rows:
USE [first_db]
GO
VALUES ('1/9/13','OTHER','15.20')
GO
(1 row(s) affected)
3. If you are entering all the fields into the table you do not need to list
the fields after the table name, for example:
VALUES
('10/8/13','OTHER','10.20')
GO
Next we will cover how you can perform queries on the data in your table.
SELECT Statement
4. To get data out of the table you need to use a SELECT statement
Using SSMS
1. Right click on the statement and select the option Select Top 1000
Rows.
,[category]
,[amount]
FROM [first_db].[dbo].[spending_initial]
4. This will display the same results as the command generated by the
gui.
5. The '*' represents all the fields in the table or you can list the fields you
wish to return for example:
SELECT [created_date],[category],[amount]
FROM [first_db].[dbo].[spending_initial]
6. If you only wanted to display each of the unique categories in the table
you can put the DISTINCT keyword before the fieldname as shown:
FROM [first_db].[dbo].[spending_initial]
7. If you have a table with a large number of fields you can restrict the
number of rows returned using the TOP keyword, for example to
return only 3 rows you would use the following SELECT statement:
SELECT TOP 3 * from spending_initial
8. To specify the ORDER in which the rows are returned you use the
ORDER BY clause which passes a list of 1+ fields so set the order, for
example to return the fields ordered by category and then amount you
would use the following statement:
SELECT TOP 3 * from spending_initial
ORDER BY category,amount
9. By default the ORDER BY clause orders the fields as ascending, if
you would like to reverse the order so that the rows are descending
(sometimes useful for dates so the newest rows are at the top) you
would use the following statement to see the top 3 rows ordered by the
created_date field in descending sequence:
SELECT TOP 3 * from spending_initial
ORDER BY created_date DESC
10. If you wanted to list all the rows where the category had a certain
string of characters in the category you would use the LIKE keyword
in the WHERE clause.
You can use the % symbol to represent ! or more characters.
For example the following statement will return all rows where the
category contains 'COF' , which will probably only be the rows for
COFFEE.
12. You can backup your table of data before experimenting with changes
using the SELECT INTO statement:
The format is :
If you have a small table you can easily edit the data using the SSMS
gui in the same way you used to insert the data. If you have a very large
table or need to update many rows you will need to use the tsql UPDATE
statement.
Using SSMS
1. Right click on the spending_initial table and select 'Edit Top 200
Rows'.
2. Here you can change the data in the field and it will be saved once you
select a field in another row by using the mouse or pressing the tab key
until the cursor moves to another row.
3. Next we will cover how to update rows in the table using the tsql
UPDATE statement.
4. For basic format of the UPDATE statement is:
WHERE <fieldname>=<value>
5. Click the 'New Query' button and choose the first_db database from
the dropdownlist.
6. Enter and execute the following tsql statement to change all the fields
that have a CATEGORY of LUNCH to FOOD :
UPDATE [spending_initial]
SET category='FOOD'
WHERE category='LUNCH'
11. Execute the following tsql SELECT statement to check the results of
the UPDATE statement:
Using SSMS
1. Right click on the table dbo.spending_initial and select the option 'Edit
Top 200 Rows'.
2. Select the row using the column to the left of the first column as
indicated in the next screenshot:
3. Press the delete key and the following warning will appear
[WHERE field=value]
If a WHERE clause is not included all the rows will be deleted from the
table.
1. Click the 'New Query' button and choose the first_db database from
the dropdown list.
2. Enter and execute the following tsql statement to DELETE the rows
where the category is set to OTHER.
WHERE category='OTHER'
3. After the command has executed successfully you can run a simple
tsql select statement to confirm that the rows have been deleted :
Section topics include - Creating Database, Tables and Fields and first sql
queries.
Question 1
Question 2
Question 3
1. Group Data
2. Manipulate strings
3. Total numeric fields in a table
4. Creating various sql database objects
For example still using the previous spending data you might want to total
the amount you have spent in each of the different categories.
To group data you use the GROUP BY clause and aggregation functions.
Aggregation functions
If you use an aggregation function without any GROUP BY clause you will
get the total for the whole table, for example:
SELECT sum(amount)
FROM [first_db].[dbo].[spending_initial]
SUM
The sum function is one of the most common aggregation functions used and
simply totals the values in the field specified within the function.
In the example below we have added a header to the result by adding the
alias 'as' <alias name> :
Using the 'as' keyword in this way can also be used to change field names.
SELECT sum(amount) as spending_total
FROM [first_db].[dbo].[spending_initial]
COUNT
The COUNT function simply returns the number of rows in the data.
The parameter in the count function can either be a fieldname or '*' which
will count all the rows in the table.
For example:
select count(*) as count
from [first_db].[dbo].[spending_initial]
and
select count(category) as count
from [first_db].[dbo].[spending_initial]
COUNT DISTINCT
The COUNT( DISTINCT <fieldname>) function will count all the unique
values that are not null.
select count( distinct category) as count
from [first_db].[dbo].[spending_initial]
Will return a result of 2, because there are only 2 unique categories in the
sample data we are using( COFFEE and FOOD).
MIN\MAX
from [first_db].[dbo].[spending_initial]
from [first_db].[dbo].[spending_initial]
AVG
The AVG function will return the average of the values in the fields.
For example:
select avg(amount)
from [first_db].[dbo].[spending_initial]
2.25
3.29
2.25
3.00
Use can use the DISTINCT keyword with the avg function, for example:
select avg(distinct amount)
from [first_db].[dbo].[spending_initial]
3.29
2.25
3.00
GROUP BY
Using the GROUP BY clause you can summarize your data which can help
you gain a better understanding of your data, this is useful for reports and
especially when you have a large amount of data you are working with.
Fields in the SELECT field list that are not aggregate functions need to be in
the GROUP BY field list.
For example:
SELECT sum(amount) as spending_total
FROM [first_db].[dbo].[spending_initial]
GROUP BY category
will return:
You can add the fields in the GROUP BY list to the fields in the SELECT
statement to make it obvious which value applies to which CATEGORY.
SELECT sum(amount) as spending_total,category
FROM [first_db].[dbo].[spending_initial]
GROUP BY category
will return:
The fields listed in the select statement need to be either in the GROUP BY
clause or an aggregation function.
The HAVING clause is used with GROUP BY much like the WHERE clause
but instead of being applied to single rows in a table is applies to the result of the
aggregation functions.
FROM [first_db].[dbo].[spending_initial]
GROUP BY category
HAVING sum(amount)>5
If you do not use an aggregation function in the HAVING clause such as:
SELECT sum(amount) as spending_total,category
FROM [first_db].[dbo].[spending_initial]
GROUP BY category
HAVING amount>5
2. Strings
There are several functions in sql development that deal with the
manipulation of strings.
Next we will cover the main examples of string functions that allow us to
perform various functions such as:
LEN
CHARINDEX
LEFT \ RIGHT
SUBSTRING
LTRIM\RTRIM
UPPER\LOWER
CONCAT
REPLACE
The examples we will cover show examples of the functions as used in the
SELECT statement but you can also use the functions anywhere a string value
would be required, for example in a WHERE clause, UPDATE or DELETE
statement.
LEN
FORMAT: LEN(<expression>)
from [first_db].[dbo].[spending_initial]
GROUP BY category
CHARINDEX
FORMAT: CHARINDEX(stringtofind,stringtosearch,[startlocation]))
This example searches for the letter 'o' in the category fields:
from [first_db].[dbo].[spending_initial]
GROUP BY category
The result is the index of the first occurrence of the letter 'o' in each of the
category fields.
The next example adds the third optional parameter of the starting location.
from [first_db].[dbo].[spending_initial]
GROUP BY category
The result from this statement is that the COFFEE category returns a result
of 0 because there is no letter 'o' from the 3rd character, whereas the category
FOOD returns a charindex of 3 because the 3rd character is the letter 'o'.
LEFT \ RIGHT
FORMAT: LEFT(Expression,num_of_chars)\
RIGHT(Expression,num_of_chars)
The LEFT \ RIGHT functions are similar and return a number of characters
starting on the left or right side of the string.
For example:
select left(category,3) as read_left, category
from [first_db].[dbo].[spending_initial]
GROUP BY category
Would return:
whereas using the right function instead such as the following statement:
select right(category,3) as read_right, category
from [first_db].[dbo].[spending_initial]
GROUP BY category
You can use the left and right functions on numeric values as well as strings.
SUBSTRING
The start location - The number of characters - starting from the left side of
the string.
from [first_db].[dbo].[spending_initial]
GROUP BY category
Combining functions
For example:
If you wanted to read all the characters in each category from the left until
the first 'o' you could use the following statement:
from [first_db].[dbo].[spending_initial]
GROUP BY category
This statement combines the left and charindex. We have subtracted 1 from
the result returned by the charindex function so that the string returned by the
left function does not include the letter 'o':
charindex('o',category)-1
LTRIM\RTRIM
FORMAT: LTRIM\RTRIM(expression)
Sometimes when you read a string from a database there might be spaces
after the string that can cause problems in certain scenarios such as comparing 2
strings or inserting data into smaller fields.
For example 'my teststring ' would not be equal to 'my teststring'.
Also, you would not be able to insert the field 'my teststring ' into a field of
char(13) because the string is actually 14 characters long (13 characters + 1
space) so this would cause an error.
To get around this problem you can remove the spaces before and after the
string.
Instead of using the LEN function we will use the DATALENGTH function
which return the length of the string in bytes, the reason for this is that the LEN
function ignores trailing whitespace whereas the DATELENGTH function does
not.
This is because it removes the space from the left side of the string.
Using both LTRIM and RTRIM
This is because the spaces on each side of the string have been removed.
The problem with whitespaces is that you cannot see them in the results
returned in the SSMS so you might not initially realize you have a problem with
whitespaces.
UPPER\LOWER
The upper and lower functions convert the string into upper or lower case.
Whereas, the LOWER function below will return a value of: mark.
select LOWER('MaRk')
These functions are often used when comparing fields so that you can make
a comparison regardless of differences in the case of the strings.
CONCAT
The CONCAT function combines the strings in the parameter list into 1
string.
FORMAT:
CONCAT(string1..n)
Use can use the '+' character to concatenate strings and get the same result as
the previous example: select 'My '+'name '+ 'is '+ 'mark'
REPLACE
The REPLACE function allows you to perform a simple search and replace
on strings.
FORMAT:
REPLACE(expression to use, string to find, string to replace with)
For example:
In this simple example we will replace the 'O' characters in each of the
category fields with 'o':
select REPLACE(category,'O','o') as replace_string, category
from [first_db].[dbo].[spending_initial]
GROUP BY category
You can see that the replace function has replaced all the occurrences of 'O'
to 'o' so the FOOD category has been changed to FooD.
3. Conditional statements
In sql development conditional statements allow you to make changes based
on the values of other expressions.
For example: You might want to return 'Good Morning' if the time is before
12AM or 'Good Afternoon' if is after 12AM.
The case statement is used within field lists such as SELECT statements
whereas the IF statement can be used on its own as we will see in the next
example or within stored procedures.
IF Statement
FORMAT:
BEGIN
END
NOTE: The BEGIN and END statements are only required if there are more
than 1 statements to be executed, but it is good practice to include them anyway
in case you need to add more statements later on.
This example will get the current hour and if the value is greater than 12 it
will display the message 'Good Afternoon'.
BEGIN
PRINT 'Good Afternoon'
END
IF...THEN...ELSE
FORMAT
BEGIN
END
ELSE
BEGIN
END
If the first IF statement does not evaluate to TRUE then the statements in the
ELSE part of the statement will be executed.
For example:
IF (SELECT DATEPART(hour,GETDATE()))>12
BEGIN
END
ELSE
BEGIN
Case Statement
FORMAT:
SELECT
(CASE
END) as <fieldname>
An example of a CASE:
SELECT
(CASE
THEN
'Good Afternoon'
END) as current_message
(CASE
THEN
'Good Afternoon'
THEN
'Good Morning'
ELSE
END) as current_message
The message 'You should be asleep' is displayed when none of the conditions in
the WHEN clauses are satisfied. In this case the ELSE clause will be used when
the current hour is not greater than 6 or 12.
4. Joining Tables
Next we will cover 2 different ways to combine the data in 2 tables.
1. JOINS - joins are used to add the fields in 2 different tables together in
different ways.
For example in one type of join you might have the following 2 tables:
TABLE A fields:
a1
a2
TABLE B fields:
b3
b4
In this case you might want to perform a select statement that returns
the fields:
The rows that are returned in this dataset depend on the type of join
used.
The rows in the 2 datasets will be combined and returned to the user.
UNION,EXCEPT,INTERSECT
Sample data for joins
For these examples to join and combine data from 2 tables we will need to
create another table with some sample data.
([user_id],[firstname],[lastname],[department],[budget])
VALUES
(1,'Joe','Blogs','Sales',100)
GO
5. Change the values in the tsql to insert more rows of data. The
spending_users sample data should look like the following table:
6.
7. Finally edit the [spending_initial] table and update the user_id field to
correspond to one of the user_id fields in the spending_users table, in
this example that will be 1,2 or 3.
8. The user_id fields will be used to join the 2 tables in different ways in
the following examples. The spending_initial table should look like
the following screenshot:
Join Types
Table joins allow you to combine columns of data from different tables.
In the following examples we will cover the different types of joins that can
be performed.
INNER JOINS
FORMAT:
INNER JOIN will only display records where there is a matching record in
each table, all other rows will be excluded from the final table.
For example:
2. Make sure there are no rows in the table [spending_initial] with a user_id
of 4.
3. In this example we use '*' for the field list in the select statement to
return all the fields from both tables.
SELECT *
FROM [first_db].[dbo].[spending_initial]
ON [spending_initial].user_id = [spending_users].user_id
4. As you can see from this example all the fields from the
spending_inital and spending_users tables are listed where there is a
match between the user_id fields.
After the SELECT statement there is the INNER JOIN keyword then
the table which you wish to join to the table in the SELECT statement for
example:
INNER JOIN [dbo].[spending_users]
5. The ON keyword is then used to specify the 2 fields that should match
in order for the row to be included in the final table.
6. In this example we are using the user_id field to match rows in the 2
tables although the fields do not have to have the same name.
7. INNER JOIN keyword is the same as using the JOIN keyword.
TABLE ALIASES
To save on typing you can add tables aliases to this query that allow you to
refer to the table by a different name (normally a shorter name if you have any
sense), for example:
SELECT *
ON spent.user_id = users.user_id
You can see that no keyword is required after the table name to give the table
an alias (unlike the field field alias used in the SELECT statement which uses
the 'as' keyword).
OUTER JOINS
An outer join allows rows that do not match to still be included in the final
table of the select statement.
The ‘outer join’ will combine all rows from both tables whether they are
matching or not.
Using our previous example we can change the query to an OUTER JOIN
When joining tables together the first table that is part of the SELECT
statement is also known as the left table, whereas the second table used is known
as the right table. In this example:
This distinction between the left and right tables is not that important with
INNER JOINS but becomes more important when using LEFT and RIGHT
OUTER JOINS.
Using the example from the inner join example simply change the keyword
'INNER JOIN' to 'LEFT OUTER JOIN' as showing the example :
SELECT *
FROM [first_db].[dbo].[spending_initial] spent
LEFT OUTER JOIN [dbo].[spending_users] users
ON spent.user_id = users.user_id
If you change the order in which the tables are used in the statement so that
the spending_users table becomes the first table (LEFT TABLE) that is used in
the SELECT statement and the spending_inital table is used after the 'LEFT
OUTER JOIN' keyword.
In this example all the rows are included from the list of users
(spending_users) whether or not there are matching rows in the spending_initial
(RIGHT TABLE).
SELECT *
FROM [dbo].[spending_users] users
LEFT OUTER JOIN [first_db].[dbo].[spending_initial] spent
ON spent.user_id = users.user_id
You can see that the 5th row of this table includes the user details for the
user_id of 4 , but NULL values for all the fields from the spending_initial table.
The reason for the NULL values is that there are no rows in the spending_initial
(RIGHT TABLE) that have a user_id of 4.
Also note, there are 2 rows with a user_id of 1. The reason for this is that
there are 2 rows in the spending_initial table that have a user_id of 1.
You can replace the keyword 'LEFT OUTER JOIN' with 'LEFT JOIN' and
you will get the same result.
SELECT *
FROM [dbo].[spending_users] users
LEFT JOIN [first_db].[dbo].[spending_initial] spent
ON spent.user_id = users.user_id
RIGHT JOIN
A right outer join is simply the opposite of a left outer join, where all the
rows of the right table are listed in the final table.
In the LEFT OUTER JOIN examples, when we swapped LEFT and RIGHT
tables around we could have just changed the 'LEFT OUTER JOIN' to a 'RIGHT
OUTER JOIN' and we would have achieved the same result. The only
difference would have been the ordering of the fields returned.
For example:
SELECT *
ON spent.user_id = users.user_id
You will notice that the order of the fields returned changes when you
change this query from a 'LEFT OUTER JOIN' to a 'RIGHT OUTER JOIN'.
You can replace the keyword 'RIGHT OUTER JOIN' with 'RIGHT JOIN'
and you will get the same result:
SELECT *
ON spent.user_id = users.user_id
FULL JOIN
The FULL OUTER JOIN returns a combination of all rows from both fields.
1. Edit the spending_initial table and change one of the rows that has a
user_id of 1 to 6.
2. The reason for this is that the user_id of 6 doesn't exist in the
spending_users table so it will demonstrate that all the rows from both
fields are included in a FULL OUTER JOIN.
3. When you edit the spending_initial table the table should look
something like from the following screenshot:
4. Now when you change the join in our statement to 'FULL OUTER
JOIN' as the following text:
SELECT *
ON spent.user_id = users.user_id
6.
7. You can see that the first row of this table is for user_id 6, this row has
null values for the fields that are from the spending_users table.
8. Other the hand the last row in this table which is for user_id 4, has null
values for the fields from the spending_initial table because no rows
exist in the spending_initial table for user_id 4.
Cross join - Cartesian product
The cross join is very inefficient and should really be avoided as it can cause
performance problems on your sql server when using large tables.
The cross join combines every row in the first table with every row in the
second table.
We have 4 rows in each of the tables used in the following statement the
result has 16 rows.
You can join multiple join statements together but for performance reasons it
is best to limit these for 4\5 joins especially for larger tables.
You create a statement with multiple joins by just appending one join clause
after another.
SELECT * FROM [first_db].[dbo].[spending_initial] spent
ON spent.user_id = users.user_id
ON another.user_id = users.user_id
Combining Rows
The 3 keywords used for combining rows we will be covering next are
UNION,EXCEPT,INTERSECT.
Sample data
3. Notice that the second row added is the same as one of the rows in the
spending_initial table, the reason for this is so that we can demonstrate
when duplicate rows are allowed or not.
UNION
Before you can combine the data in 2 tables check that the fields are in the
same order, and the field data types are either the same (best practise) or are
similar enough so they are automatically converted, this is called implicit
conversion.
The UNION keyword is simply placed between the 2 select statements, for
example:
SELECT * FROM [first_db].[dbo].[spending_initial]
UNION
Notice that the following row that is in both tables is not duplicated in the
dataset that is returned to the user:
created_datecategoryamount user_id
2020-07-15COFFEE2.252
Next, change the UNION keyword to UNION ALL and execute the query:
SELECT *
FROM [first_db].[dbo].[spending_initial]
UNION ALL
SELECT *
FROM [first_db].[dbo].[spending_more]
This time you will see that the row that is in both tables is duplicated:
To make the duplicates easier to spot you can add the ORDER BY clause to
the end of the statement as shown:
UNION ALL
ORDER BY created_date
The EXCEPT keyword is placed between the 2 select statements just like the
UNION keyword.
The EXCEPT keyword will return all the rows from the first SELECT
statement that do not exist in the second SELECT statement.
For example:
SELECT * FROM [first_db].[dbo].[spending_initial]
EXCEPT
3 rows are returned as the result for this statement, the one row that is
omitted from the spending_initial table is the one that is duplicated in the
spending_more table.
INTERSECT
The INTERSECT keyword returns rows that are the same in both the first
and second SELECT statements. This can be useful to check for duplicate rows
between tables.
For example the following queries with the INTERSECT keyword between
will return the 1 row that exists in both tables:
SELECT * FROM [dbo].[spending_initial]
INTERSECT
Question 1
GROUP BY category
Question 2
How would to remove whitespace from the left and right side of a string?
Question 3
1. Database Constraints
Next we will cover database constraints.
Database constraints allow you to make extra checks on the data in your
tables before the data is saved.
You have already encountered one form of database constraint when creating
the tables that checks if a NULL value is allowed in the field or not. This
database constraint is used to force applications to enter some value even if it is
a default value in fields that do not allow NULL values.
Using data types correctly provides another type of check constraints. For
example if the data type was set to numeric(5,2) the larger number you could
enter would be 999.99 (5 digits in total with 2 after the decimal point).
1. Check constraints
1. Adding using SSMS
2. Adding when you create a table
The expressions used to define the check constraint can use tsql keywords
such as 'LIKE'. In the next example we will add a check constraint to the
spending_users table to check that all budgets are less than 1000.
2.
3. Right click on the Constraints folder and select the 'New Constraint'
option...
4. Click on the Expression field and enter the following expression:
budget<1000
5. This expression simply checks that the value of the budget field is less
than 1000.
6. Optionally you can add a description such as 'Check Budget Limit is
less than 1000'.
7. Click the Close button to close the CHECK CONSTRAINT dialog box
and then press Ctrl+S to save the table.
8. Right click on the Constraints folder and select the Refresh button,
now when you expand the Constraints folder the constraint you created
called CK_spending_users should now be displayed.
9. The default name for the check constraint is 'CK_spending_users'.
10. To test the check constraint you will need to make a couple of
changes. First select the Tools -> Options menu option, then select the
Designers - Table and Database Designers option on the left side
menu.
11. Remove the tick from the 'Prevent Saving changes that require table
re-creation' option and click the OK button.
12. Right click on the 'spending_users' table and click on the Design
option. Change the data type for the budget field to be numeric(6,2).
You need to make this change if you want to be able to enter a number
in the budget field that is greater than 999.99.
13. Press Ctrl+S to save the table and select 'Yes' to any warnings.
14. To test the check constraint simply edit the table by right clicking on
the table name and selecting 'Edit Top 200 rows'. Try to change the
budget field to be 1000 or greater. You should get an error message
similar to the one below letting you know that the check constraint has
prevented entering a number that is too large.
15. You can get a list of check constraints in a database by querying the
table sys.check_constriants.
Primary Key
The purpose of a primary key is to uniquely identify each row in the table.
You can set the primary key of a table before\after you create the table as
long as the data you wish to use as the primary key only contains unique values
and no NULL values.
6. Once you have saved the table without any errors, close the design
window.
7. Right click on the spending_users table and select 'Edit Top 200
Rows'.
8. Try to add a user_id that already exists in the table and you should get
the following error:
9. Open a new query window and run the following command the list the
key constraints in the table:
10. The primary key constraint you have just created is returned.
FOREIGN KEY CONSTRAINTS
A foreign key (FK) is a field in one table that refers to the primary key (PK)
in another table, this creates a link between the 2 tables.
Therefore the primary key must exist before it can be used in the foreign key.
6. The 'Tables and Columns' dialog box will be displayed where you can
set the primary key table as 'spending_users' and the foreign key table
as 'spending_initial. Both tables will be using the field 'user_id' as
shown:
'spending_initial' table
15. If you expand the spending_inital table, Keys folder you will now see
the foreign key you have just created:
16.
17. You can also see the list of foreign keys by running the following
query:
select * from sys.foreign_keys
1. Right click on the spending_initial table and select 'Edit Top 200
Rows'.
2. Enter a new row\update a row and use a user_id that does not exist and
you should get the following error:
3.
4. Add a row for a user_id that does exist.
Delete Rule
The Delete Rule will delete all the rows in the table that has the foreign key
when the associated row is deleted from the table with the primary key. In
this example if you deleted the row from the spending_users table all the
rows with that user_id in the spending_initial table would also be deleted.
In this example we are going to delete the user_id 1 from the spending_users
table and because with have the 'Cascade' option setup on the foreign key
relationship all the rows with a user_id of 1 in the spending_initial table should
also be deleted.
1. For this example to work first check that you have rows with a user_id
of 1 in both the spending_initial and spending_users tables.
2. Select the spending_users table, right click and select 'Edit Top 200
Rows'.
3. Highlight the row with user_id 1
4. Press the delete key and press the Yes button when you get the
following warning:
FROM [first_db].[dbo].[spending_initial]
6. You should see that the rows with a user_id of 1 no longer exist in the
spending_initial table.
Updating Foreign Key Values
SELECT [created_date],[category],[amount],[user_id]
FROM [first_db].[dbo].[spending_initial]
13. You will see that the user_id that was previously 3 is now set to 13.
Other settings for the Delete\Update action
5.
6. Try not to let it confuse you that when you select the 'Template
Explorer' option a view that has 'Template Browser' is displayed, it
should say 'Template Explorer'. Expand the Stored Procedure folder.
C:\Users\<USERNAME>\AppData\Roaming\Microsoft\SQL
Server Management Studio\14.0\Templates\Sql
1. Within the Template Explorer, right click on the 'SQL Server Template'
icon and select New->Folder:
2.
3. Rename the folder 'my templates'.
4. Right click on the folder and select New->Template
C:\Users\<USERNAME>\AppData\Roaming\Microsoft\SQL
Server Management Studio\14.0\Templates\Sql\my templates
5. Rename the new template 'my_first_template'.
6. Double click on the new template and a query window will be opened.
7. Within the new query window add the following statement:
SELECT * from [dbo].[spending_initial]
8. The format for adding parameters to a template is:
<category,varchar(20),COFFEE>
10. So the query should now be, we have set the default value for this
parameter to 'COFFEE':
11. To edit this template simply right click on the template name and
select edit.
12. To access the Template parameters quickly select Alt+Q, then S.
Along with templates code snippets work well to really boost your
productivity when developing in sql.
7. To add your own snippet you can add a .snippet file to the following
folder:
8. C:\Users\<your own username>\Documents\SQL Server
Management Studio\Code Snippets\SQL\My Code Snippets.
9. Within the SSMS go to the Tools->Code Snippets Manager. Then
click Add and select your My Code Snippets folder.
10. The snippet will then be available within the My Code Snippets
folder.
11. Next is an example code snippet file called my test
snip.snippet2.snippet. To use this just change the information in the
Title, Description, Author and Code tags:
<CodeSnippets
xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<_locDefinition xmlns="urn:locstudio">
<_locTag _loc="locData">Title</_locTag>
<_locTag _loc="locData">Description</_locTag>
<_locTag _loc="locData">Author</_locTag>
<_locTag _loc="locData">ToolTip</_locTag>
</_locDefinition>
<CodeSnippet Format="1.0.0">
<Header>
<Shortcut></Shortcut>
<Author>Mark ODonovan</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Code Language="SQL">
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>
3. Stored Procedures
You have probably used a stored procedure without knowing it as there are
many stored procedures such as sp_who2 which lists current users\processes and
sessions running on the system, you can run the command as:
exec sp_who2
or
sp_who2
The system stored procedures start with 'sp' for example sp_server_info.
When I am creating stored procedures I tend to prefix the name with 'usp'
(for user stored procedure), this is just a naming convention and not a
requirement.
--
-- values below.
--
-- ================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:<Author,,Name>
-- Description:<Description,,>
-- =============================================
AS
BEGIN
END
GO
5. You can delete some of the comments and add a name for you stored
procedure of 'usp_myfirstsp'.
6. Next we will enter the select statement that will be returned when we
run the stored procedure. The select statement we are going to use is as
follows:
SELECT *
FROM [first_db].[dbo].[spending_initial]
UNION
SELECT *
FROM [first_db].[dbo].[spending_more]
7. The press Ctrl+S to save the stored procedure, which should look like
the following code:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- =============================================
AS
BEGIN
UNION
END
GO
8. Press the Execute button in the toolbar or Alt+X to execute the
statement.
This will not run the stored procedure but instead it creates the stored
procedure object in the database.
9. If you expand the 'Stored Procedures' folder you should now see the
stored procedure you have just created.
2. As there are no parameters for this stored procedure you can just click
the ok button.
3. A new query window will open with the following statement and the
statement will be executed:
USE [first_db]
GO
DECLARE@return_value int
EXEC@return_value = [dbo].[usp_myfirstsp]
SELECT'Return Value' = @return_value
GO
1. To change the stored procedure, right click on the stored procedure and
select 'Modify'.
USE [first_db]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:Mark O'Donovan
-- =============================================
AS
BEGIN
UNION
END
3. Notice that the statement for the stored procedure started with
'CREATE PROCEDURE' when you were adding the procedure for the
first time has now changed to 'ALTER PROCEDURE'.
4. We altered and stored procedure to change the SELECT statement to
only return rows when the amount was greater than 10.
WHERE amount>10
UNION
WHERE amount>10
7. Modify the stored procedure again to remove the WHERE clause and
execute the statement to update the object in the database.
Stored Procedure Parameters
@filter_category varchar(20)
10. Next add the parameter @filter_category to our example stored procedure
as shown in the above example.
11. Add the following WHERE clause to each SELECT statement in the
stored procedure to use the parameter :
WHERE category=@filter_category
12. You stored procedure should now be the same as the following
statement(the comments have been removed to save space):
ALTER PROCEDURE [dbo].[usp_myfirstsp]
@filter_category varchar(20)
AS
BEGIN
WHERE category=@filter_category
UNION
WHERE category=@filter_category
END
15. Know when you right click on the stored procedure and select 'Execute
Stored Procedure…' you will see that there is a parameter in the list:
16. Click OK to run the stored procedure without entering any value and
the default value of the parameter will be used which will return only
the rows that have a category of 'COFFEE'.
USE [first_db]
GO
DECLARE@return_value int
EXEC@return_value = [dbo].[usp_myfirstsp]
GO
17. You can see that the command that is run does not pass any parameter
to the stored procedure. The commands generate by 'Execute Stored
Procedure' option include a '@return_value' variable that indicates if
the procedure ran successfully (if zero is returned) or not.
18. Open a new query window by clicking the new query button.
19. Run the stored procedure as:
exec [dbo].[usp_myfirstsp]
20. You can add parameters to the end of the stored procedure name using
the format @param=value, for example:
21. This command will return just the rows with a category of 'FOOD', as
shown:
22.
23. When you pass a parameter to the stored procedure using the ‘Execute
Stored Procedure' option , for example:
24.
25. The following text is generated:
USE [first_db]
GO
DECLARE@return_value int
EXEC@return_value = [dbo].[usp_myfirstsp]
@filter_category = N'CAR'
GO
4. Views
Views are simply SELECT statements.
Views allow you to reduce complex select statements into a simple select
query.
Views are similar to inline table valued functions but you cannot pass
parameters to VIews.
View Requirements
Create a view
1. Expand the first_db database, Views folder.
2. Right click on the view folder and select the 'New View...' option
3. The 'Add Table' dialog will appear to assist with the creation of your
view.
4. There are 4 tabs in the 'Add table' dialog which are:
Tables
Views
Functions
Synonyms
5. Click the Close button on the 'Add Table' dialog and we are going to
create the SELECT statement using tsql.
6. In this example we will add a SELECT statement to combine the rows
from the spending_initial and spending_more tables.
FROM [first_db].[dbo].[spending_initial]
UNION
7. Press Ctrl+S to save the view, set the name of the view to
'spending_all' and press the OK button.
8. The following warning will appear, just click the ignore button.
9. Close the query window, right click on the Views folder and select
Refresh to see the newly created view.
1. Now you can test the view by running the following select statement:
use first_db
2. All the rows from the spending_initial and spending_more tables will
be returned to the user.
Updating a view
FROM dbo.spending_initial
update [dbo].[spending_all]
set category='TEA'
where category='COFFEE'
6. There are some restrictions on when you can use a view to update
underlying tables such as you cannot use the view with an update if
aggregate functions are used in the view.
7. You cannot update a view if the select uses any of the following
keywords UNION, UNION ALL, CROSSJOIN, EXCEPT, and
INTERSECT.
8. The columns to be modified are not changed by GROUP BY,
HAVING, or DISTINCT.
Schemabinding
SCHEMABINDING option prevents any changes being made to the design
of the tables used in the view.
AS
FROM dbo.spending_initial
2. You can create the view with the SCHEMABINDING option using the
following tsql:
AS
FROM dbo.spending_initial
List Views
10. You can list the views in your database using the following statement:
Scalar Functions
Scalar functions return 1 value and can be used anywhere a value is required.
Table-valued functions
Table valued functions return a table of data and can be used as an alternative
to views.
Views can only use 1 select statement whereas tabled-valued functions can
perform more complex queries if required.
Inline
Inline table-valued functions are like views that can accept parameters.
Multi-statement
You have already used various functions such as GETDATE() that returns
the current datetime to the query, for example:
SELECT GETDATE()
Example
1. Next we will show you how to create and update a scalar function.
2. In this example we are going to use the spending example to return the
total sum of the budget field in the spending_users table.
3. The query that we will use in the function is:
5. Right click on the 'Scalar-valued Functions' option and select the 'New
Scalar-valued Function...' option:
8.
9. Enter the values as in the following screenshot and click the OK
button:
10.
11. Delete the comments at the top of the template and press Ctrl+S to
save the script.
12. Your script should look like the following code:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:Your Name
-- =============================================
RETURNS
AS
BEGIN
DECLARE
SELECT =
RETURN
END
GO
13. Now you can fill out the RETURNS,DECLARE, SELECT and
RETURN parts of the function.
Returns
14. The RETURNS part of the function specifies by data type that will be
returned to the query. In this example we will return a numeric value
so set RETURNS to:
RETURNS numeric(5,2)
Declare
15. This is to specify the variable that will be returned to the user, this
should match the data type in the RETURNS statement.
Select
16. The SELECT statement will be used to set the value you have just
defined (@budgettotal). Set the variable using the format <variable>=
<field> in the field list of the SELECT statement.
17. If you are not using an aggregation function such as SUM() and there
is the possibility that multiple rows are returned from the query you
will need to add TOP 1 so that only 1 row is ever going to be returned,
for example:
WHERE user='Mark'
Return
18. This is the statement to return the variable to the user, in this example
we simply specify the variable that we declared and set using the select
statement:
RETURN @budgettotal
19. As an alternative we could have just returned the value of the SELECT
statement, for example.
20. In this example you will get an error message if you do not place the
SELECT statement within brackets.
21. In the same way as the stored procedures when you need to modify
functions you need to change the statement from a 'CREATE
FUNCTION' to an 'ALTER FUNCTION'.
22. To execute this function within a select statement, open a new query
window.
23. Type the following statement:
select dbo.fn_budget_total()
24. Press Alt+X to the execute statement and you should get the total
returned.
25. One difference between the function and the stored procedure is that
you can execute the function when select data from other tables as well
, for example :
select dbo.fn_budget_total() as budget_total,*
from [dbo].[spending_users]
Function Parameters
@dept varchar(50)
RETURNS numeric(5,2)
AS
BEGIN
where department=@dept
RETURN @budgettotal
END
GO
4. As we do not have a default value for this function if you try to run the
following SELECT statement:
5. You will get the following error:
6. To add a default for the parameter (just like a stored procedure) change
the parameter as follows:
@dept varchar(50) = 'SALES'
7. Unlike a stored procedure you cannot run the function without a value
even if there is a default value. You need to enter the keyword
DEFAULT as shown:
select dbo.fn_budget_total(DEFAULT)
8. You can run the function with another value just by entering the value
within single quotes. The next example will return the budget total for
all users within the IT department.
,dbo.fn_budget_total(department) as budget_total
from [dbo].[spending_users]
Inline
Inline table-valued functions are like views that can accept parameters.
3.
4. The template for the inline table-valued function will be displayed in a
new query window.
5. Select the menu option Query->Specify Values for Template
Parameters.. or press Alt+Q,S.
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:Your Name
-- =============================================
(
-- Add the parameters for the function here
@dept varchar(50)
RETURNS TABLE
AS
RETURN
SELECT 0
GO
select
[user_id]
,[firstname]
,[lastname]
,[department]
,[budget]
FROM [first_db].[dbo].[spending_users]
WHERE department=@dept
11. Execute the statement and you should get a the following result if all is
correct:
Command(s) completed successfully.
12. The full script should be:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:Your Name
-- =============================================
@dept varchar(50)
RETURNS TABLE
AS
RETURN
select
[user_id]
,[firstname]
,[lastname]
,[department]
,[budget]
FROM [first_db].[dbo].[spending_users]
WHERE department=@dept
GO
15. In the same way as scalar function you need to change the function
from 'CREATE FUNCTION' to 'ALTER FUNCTION' to modify the
function in the database.
Multi-statement Function
Multi-statement table-valued functions are more like stored procedures.
Rather than a single select statement you can create a table using complex
queries and multiple statements.
As you have probably just started sql development you will not probably not
require them just yet but it is good to know they exist.
The example we will cover here will be straight forward one that selects
values from 2 tables and returns them to the user.
--This will return data about the user and their spending
@user_id int
RETURNS
@spending TABLE
)
AS
BEGIN
WHERE user_id=@user_id
SELECT
@category = category
,@amount = amount
FROM [dbo].[spending_initial]
WHERE user_id=@user_id
INSERT @spending
SELECT @username,@category,@amount
RETURN
END
GO
2. In this statement first we have setup a single parameter for the user_id.
3. Then we define the table that will be returned to the user as follows:
RETURNS
@spending TABLE
4. Next we define the variables that will be used to store the results of the
SELECT statements.
5. DECLARE @username varchar(40), @category varchar(20),
@amount numeric(5,2)
6. The first SELECT statement queries the spending_users table,
concatenates the firstname and lastname field and stores it in the
@username variable.
WHERE user_id=@user_id
7. The second SELECT statment reads the category and amount fields
from the spending_initial table and stores the result in the @category
and @amount variables.
,@amount = amount
FROM [dbo].[spending_initial]
WHERE user_id=@user_id
8. Finally the results stored in the variables are inserted into the
@spending table to be returned to the user.
INSERT @spending
SELECT @username,@category,@amount
9. We can execute this function just like the inline table-valued function
using the following statement:
11.
12. In the same way as scalar function you need to change the function
from 'CREATE FUNCTION' to 'ALTER FUNCTION' to modify the
function in the database.
6. Synonyms
Synonyms are useful for creating aliases for tables. So you can easily
change the table\database that your tsql code is referring without changing your
tsql code. For example you might want to change the database your code is
referring to when moving your tsql from testing to a live environment when
working within a company.
For example:
Now you will be able to run the following select command that will return
the rows from the spending_users table.
select * from userlist
NOTE: that the alias from the synonym does not exist in the Tables folder
but the Synonyms folder as shown:
You can list all the synonyms used in your database using the following
statement:
select * from sys.all_objects where type='SN'
or
1. Click the 'New Query' button to open a new query window and add the
following statement
use first_db
2. In this statement the first line 'use first_db' just changes the context of
the SSMS to the first_db database so that any commands executed are
applied to the first_db database.
3. Next is the CREATE TABLE statement that creates the audit table.
The the fields should be familiar to you except the [id] field which is
using the IDENTITY function:
[id] [int] IDENTITY(1,1) NOT NULL
4. The IDENTITY function allows you to create an integer field that
automatically increments when each row is added to the table.
5. The first parameter is the starting number and the second parameter
specifies how much to increment the field by every time a row is
added. In this example IDENTITY(1,1) means it will start and 1 and
increment by 1 each time.
6. Because the [id] fields uses an IDENTITY function we do not have to
include this field when using the INSERT statement to add data to this
table.
Trigger On a Table
The type of triggers that we are going to cover next are those that manipulate
the data in tables for example Insert, Update and Delete statement which are also
known as DML (Data Manipulation Language) events.
4. The template for the trigger will appear in a new query window.
5. Remove the green comments at the top of the template and press
Alt+Q,S to fill in the template parameters as shown in the screenshot
below:
6. You should now have the following statement in your query window.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:Your name
-- =============================================
ON dbo.spending_initial
AFTER INSERT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
END
GO
7. Now you are ready to add the code to insert the audit record into the
spending_audit table.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:Your name
ON dbo.spending_initial
AFTER INSERT
AS
BEGIN
END
GO
9. Press Alt+X or the Execute button to create the trigger object in the
database.
10. Expand the triggers folder to check that the trigger now exists.
11. As usual if you need to alter the trigger you will need to change the
'CREATE TRIGGER' to 'ALTER TRIGGER'.
Test Trigger
1. To test the trigger right click on the spending_initial table and select
'Edit Top 200 Rows' to insert a new row into the table.
2. You can then check the spending_audit table to check that a row has
been inserted with the correct message,audit_category and
created_dttm fields.
For example:
Trigger on a Database
Triggers on databases are run when certain DDL events occurs such as
CREATE\ALTER\DROP various database objects such as tables and views.
One practical use of these types of triggers is to prevent users from creating
tables in a database or to log security issues such as someone trying to DROP
(remove) a table or view from the database.
BEGIN
...Statments to execute...
END
1. Create a new query window and enter the following create trigger
statement:
CREATE TRIGGER trig_create_table ON DATABASE
FOR CREATE_TABLE
AS
BEGIN
END
2. When this trigger is fired the PRINT statement will display a messages
to the user, the ROLLBACK statement prevents the CREATE TABLE
statement that fired this trigger from being executed.
3. Finally we log a simple message to your spending_audit table so that
we know someone was trying to create a table in our database.
4. Execute the above statement by pressing Alt+X to create the trigger.
You can see the new trigger listed in the Programmability folder, then
Database Triggers ( you will probably have to right click on this folder
and select Refresh for the trigger to appear).
(
testfield int NULL
)
(1 row(s) affected)
Msg 3609, Level 16, State 2, Line 1
The transaction ended in the trigger. The batch has been aborted.
1. To view all the triggers in the database run the following statement:
2. This statement will show you the triggers in your database and the
parent_class_desc will identify the trigger as a database trigger if the
field is set to 'DATABASE' as shown:
Disable\Enable triggers
Sometimes you may wish to disable triggers, for example if you have a
trigger that prevents creating tables and you wish to do some sql development.
3. If you now run the select statement on the sys.triggers table you will
now see that the is_disabled field has been set to 1 if the trigger is
disabled and 0 if it is enabled.
4. When a dml trigger is disabled you will see a red cross on the icon
within the triggers folder of the table:
5. For a DDL event trigger there is no change to the icon when it has
been disabled.
'Instead of' Triggers
1. There are 2 modes that determine when a trigger is run, these are:
INSTEAD OF
ON dbo.spending_initial
AFTER INSERT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
INSTEAD OF INSERT
END
2 SPECIAL TABLES
INSERTED
DELETED
These tables contain the values for the row that has been inserted\deleted by
the user.
If the data is being updated there would be one field for the new value of the
field in the inserted table and another field for the old value in the deleted table.
For example:
ON dbo.spending_initial
AFTER UPDATE
AS
BEGIN
END
2. In the statements of this trigger first we declare the variables that will
stored the old\new values of the amount field and the category field.
SELECT @new_amount=inserted.amount,@category=inserted.category
from INSERTED
4. Note that in the INSERT statement we need to convert the data type of
the @old_amount and @new_amount variables from numeric data
types to varchar data types so that they can be concatenated into the
string used for the message field. If we did not use the CAST function
to change the data type of these variables we would get an error when
the trigger was fired.
5. To test this trigger right click on the spending_initial table and select
'Edit Top 200 Rows' then change the amount in one of the rows and
press the tab key until the cursor goes to the next row to save the data.
6. Next right click on the spending_audit table and click on the 'Select
Top 1000 Rows' option, you should see a message such as :
7. This shows that the old and new values of the amount field have been
obtained from the DELETED and INSERTED tables within the
trigger.
8. Database Design
Next we are going to cover the basics of database design.
The aim hear (as ever) is not to bore you rule after rule about how the perfect
database would be designed so that you read it once and instantly forget it, but
instead focus on the core rules that will make the most difference to your
development.
The design rules we will cover will become more important when you are
dealing with large tables of data or other sql developers who are using the same
rules.
The rules that we are going to cover next are called 'Normal Forms' and
when you apply this rules to your database design you say you have 'Normalized'
the database or refer to the process as 'Normalization'.
We will cover the first 3 normal forms here which are the most important to
remember and apply on a regular basis. The are 5 normal forms but for most
purposes the first 3 normal forms are more than enough to reduce the
redundancy in the database.
As usual we will demonstrate the ideas here using our spending tables.
First Normal Form (1NF)
Primary Key
A primary key is a field that uniquely identifies each row of the table
and cannot be null.
First we will add a field called id and set the value of the 'id' field for
the rows that exist already, then we will set the field as a primary key.
1. Right click on the spending_initial table and select the Design option.
2. Right click on the far left column and select 'Insert Column'
3.
4. Add a column name of 'id' , data type of int and tick the checkbox to
allow nulls as shown:
5.
6. Press Ctrl+S to save the table. If you get an error check it is not being
caused by a previous database trigger.
7. Right click on the spending_initial table and select 'Edit Top 200
Rows'.
8. Update each row with a unique id field.
9. Go back to the Design of the table and right click on id column and
select 'Set Primary Key'.
10. Press Ctrl+S to save the table. Notice that when you set the id field as
a primary key the tick from the 'Allow Nulls' checkbox is removed.
11. Select the id field and then in the Column properties set the 'Identitfy
Specification' settings as shown:
1. Repeated Groups means that if a field has more than one value, each
value should be placed into another table.
2. The new table should contain a primary key and this primary key
should be in the original table.
3. In the case of our spending_initial table if we had the following setup:
4.
5. You can see the row that has an id of 3, the category field has 2 values
of COFFEE and TEA. In this scenario the user might have bought
COFFEE and TEA on that day.
6. For this table to be in First Normal Form you would need to split the
category of "COFFEE TEA" into 2 rows, one with a category of
COFFEE and another with a category of TEA.
7. The result would be :
Second Normal Form
For your tables to be in second normal form they must already be in First
Normal Form before starting to remove the repeating groups of data from the
category field.
For example in our spending example we should not have more than 1 row
that has the same category such as 'COFFEE'. Instead where it is likely more
than one row with the same value you must:
2.
3. We have setup the id field using the identify specification settings so
that the id automatically increments when another category is added to
the table.
4.
5. Add a Primary key to all the rows in the new table.
Use the following statement to add the category to the new table:
UPDATE spending_initial
set fk_category=
2. If you are following the examples throughout this book you should see
results similar to the following screenshot:
3. Now you could remove the category field from the spending_initial
table as it is not required.
Third Normal Form
1. The database must be in the second normal form and you must remove
columns that are not dependent upon the primary key.
It is better to focus on the first 3 normal forms and start using them
consistently.
9. Sql Exceptions
When you start to develop more complex sql statements using more tables
and sometimes multiple databases you possible errors that might occur will
increase.
Because you cannot always predict and write code to prevent errors
occurring when statements such as SELECT or INSERT statements are run you
can define what should happen if any error occurs within a set of statements.
You will use Exception handling to define how to handle any unexpected
errors.
The TRY statements will surround the code that will run and should start
with a 'BEGIN TRY' and finish with an 'END TRY' statement.
The code between the 'BEGIN CATCH' and 'END CATCH' statement will
only run when an error has occurred within the TRY block.
BEGIN CATCH
PRINT 'ERROR'
END CATCH
RAISING AN ERROR
When you create TRY\CATCH blocks and an error occurs you will need to
alert someone to the error that occurred.
One way is to use an INSERT statement to insert a record into an audit table
as we have used in previous examples such as triggers.
Raiserror
The format of the raiserror function is:
The first parameter can either be a message_id from the sys.messages table
that we will cover later in the 'predefined messages' section or alternatively you
can define your own message string.
Predefined messages
To list the predefined messages you can run the following command:
You can use this query to find predefined messages to reuse. For example if
you wanted to use the following error message ' SQL Server Audit could not
write to the security log.' you can see that the error message by running the
following query:
where message_id=33204
Using the message_id of the error message with can run the following
raiserror function and the error message will be returned as expected:
raiserror(33204, 10,1)
returns the message: SQL Server Audit could not write to the security log.
raiserror(33204, -1 ,1)
Severity
Severity levels 0-18 can be used by any user whereas level 19-25 can only
be used by a sysadmin.
As you are running this logged in as the 'sa' user which has sysadmin rights
you will be able to use any severity level.
State
If you use a state of -1, the state associated with the error will be used.
If the state is greater than 255 you will get an error, for example this is the
result of using a state of 300:
If use a state of 300 you will get the following error message:
Arguments
For example if you wish to add an error number you might have the string:
Within the message string use %d for a signed integer and %s for a string.
Would return:
Hello Mark
Msg 50000, Level 1, State 1
10. Transactions
Next we will cover how you can encapsulate a number of statements into a
single transaction.
The purpose of using transactions is so that if there is any problem with any
of the statements in the transaction, the whole transaction will fail and any
changes that have already occurred before the statement that failed will be
reversed.
You can see how using transactions would be useful in scenarios such as
doing transfers between bank accounts where if either the debit or credit between
the two accounts involved in a transfer failed then the other transaction would
also have to be reversed.
New Keywords
1. BEGIN TRANSACTION
The 'BEGIN TRANSACTION' statement indicates that the following
statements will be part of a single transaction.
2. ROLLBACK TRANSACTION
Reverse any transactions since the last 'BEGIN TRANSACTION'
statement.
3. COMMIT TRANSACTION
Save the changes since the last 'BEGIN TRANSACTION' statement.
4. @@TRANCOUNT
The number of transactions running. Running a 'BEGIN
TRANSACTION' statement will increment this value.
BEGIN TRY
END TRY
--Catch block
BEGIN CATCH
PRINT 'ERROR'
END CATCH
6. If we had not used the try\catch blocks but instead had executed the
following 3 statements:
STATEMENT 1
STATEMENT 2
8. Going back to the example using the try catch block we will now
cover a more practical example using INSERT statements so that the
benefit of using transactions can be demonstrated.
9. As in the previous example when you execute the following statements
you will see that the INSERT into the spending_initial table has
worked but the second INSERT statement was not executed because of
the error.
BEGIN TRY
([created_date],[category],[amount],[user_id],[fk_category])
VALUES ('4/4/13','CLOTHES',100,2,0)
([audit_category],[message],[created_dttm])
END TRY
BEGIN CATCH
PRINT 'ERROR'
END CATCH
10. To get this example working with transactions we need to surround the
statements in the TRY block with a BEGIN TRANSACTION (to start
a new transaction) statement and a COMMIT TRANSACTION
statement to save the changes that occurred within the transaction.
BEGIN TRY
BEGIN TRANSACTION
([created_date],[category],[amount],[user_id],[fk_category])
VALUES ('4/4/13','CLOTHES',100,2,0)
--Statement that causes an error
([audit_category],[message],[created_dttm])
COMMIT TRANSACTION
END TRY
BEGIN CATCH
PRINT 'ERROR'
ROLLBACK TRANSACTION
END CATCH
11. The messages printed when you run this code are:
STATEMENT 1
(1 row(s) affected)
(0 row(s) affected)
ERROR
The message '(1 row(s) affected)' is due to the first INSERT statement.
The message '(0 row(s) affected)' is due to the divide by 0 SELECT that caused the error and finally
the
'(20 row(s) affected)' message is cause by the SELECT statement in the CATCH block.
12. Even though the INSERT into the spending_initial table was executed
you will not see an extra row added because changes made by the
INSERT has been reversed by the 'ROLLBACK TRANSACTION'
statement in the CATCH block.
Quiz
Sql Development Objects
Section topics include - Database constraints such a primary and foreign key,
stored procedures, functions and views, triggers, synonyms, database design,
exceptions, transactions and templates.
Question 1
Question 2
What is the purpose for following the rules of database design called Normal
Forms?
Question 3
Hopefully by following the examples in this book you know have a better
understanding of developing Microsoft Sql (tsql). You should now be in a
position to start creating your own examples at home and in work.
There is plenty more to learn about sql development the websites at the end
of the book will give you more information on sql server development.
Mark
Quiz Answers
Section 1. Sql Server Install and Tour
Question 1
Answer
1433
The reason why this is important to know is when you have a firewall
running on your computer that blocks certain ports from being access you might
need to open this port so that applications from outside the server can access sql
server.
Question 2
Answer
Question 3
Answer
Section topics include - Creating Database, Tables and Fields and first sql
queries.
Question 1
Answer
If you just wanted to delete the data within the table you could use:
Or if you no longer required the table you could use the DROP command:
Question 2
Answer
The difference is that nvarchar data types can be used for unicode data that
can stored data in any language whereas varchar data types cannot store data in
all languages. So if you need your application to be truly international it is best
to use nvarchar data types.
Question 3
Answer
DBCC USEROPTIONS will return the current dateformat.
Section 3. Advanced Queries
Question 1
GROUP BY category
Answer
The following statement would correctly group the amount field totals by
category:
GROUP BY category
Question 2
How would to remove whitespace from the left and right side of a string?
Answer
There is no single function that removes whitespace from the left and right
side of a string at the same time. Therefore you need to use the functions
LTRIM and RTRIM together, for example:
select '*' + LTRIM(RTRIM(' please trim this string '))+'*'
I added the '*' so it is easier to see the whitespace has been removed and the
result should be:
Answer
Within a SELECT statement you can use a CASE statement, for example:
SELECT (CASE
WHEN DATEPART(month,GETDATE())>6 THEN
'Second half of year'
ELSE
'First half of year'
END) as half_of_year
Section 4. Sql Development Objects
Section topics include - Database constraints such a primary and foreign key,
stored procedures, functions and views, triggers, synonyms, database design,
exceptions, transactions and templates.
Question 1
Answer
You would setup a foreign key constraint to maintain the integrity of the data
between 2 tables. So in the example used in this book that would mean that only
user_id's that existed in the spending_users table could have entries in the
spending_initial table.
Question 2
What is the purpose for following the rules of database design called Normal
Forms?
Answer
The main purpose of following the normal forms is to reduce the duplication of
data within your tables and make the data easier to maintain.
Question 3
Answer
The most common use for triggers is maintain an audit of actions on
tables\databases.
Useful Websites
http://techstuffy.com
This is the website will all updates and related information for this
book such as sample data.
http://Microsoft.com/sqlserver
http://sqlservercentral.com