IntroductionWelcome| 00:04 | Hi! I am Simon Allardice and welcome to
SQL Server 2008 Essential Training.
| | 00:09 | In the next few hours, we'll cover the
core features found in SQL Server 2008 R2,
| | 00:14 | the latest version of Microsoft's
flagship database management system.
| | 00:20 | In this course we'll begin by choosing
the right edition of SQL Server from the
| | 00:24 | many available options.
| | 00:26 | We'll see how to install it properly
and explore the different tools and
| | 00:30 | applications for working with SQL Server.
| | 00:33 | We'll move on to designing and
creating databases and tables and see how to
| | 00:38 | use Transact-SQL, the language of SQL
Server, to retrieve, insert, and manipulate data.
| | 00:45 | We'll perform core database
administration tasks, like working with indexing
| | 00:50 | to improve performance, see how to
secure your data, and how to work with
| | 00:54 | Backup and Restore.
| | 00:56 | We'll even have an introduction to
some of the more advanced features of this
| | 00:59 | product, things like SQL Server
reporting services and integration services.
| | 01:04 | If you've been working with SQL Server
already, you may soon find that you've
| | 01:08 | only scratched the surface of what
it can really do, and if you're just
| | 01:11 | beginning to use SQL Server,
this is the perfect place to start.
| | 01:15 | So welcome to SQL Server
2008 Essential Training.
| | Collapse this transcript |
| Using the exercise files| 00:01 | If you are a premium member of
lynda.com, you can download some exercise
| | 00:05 | files for this course.
| | 00:06 | Now I've got these saved to my Desktop
here and if I open this up, you'll see
| | 00:10 | that a few of the chapters in
this course have their own folder.
| | 00:13 | I could drill down into that folder,
find the number of a movie, and find any
| | 00:18 | file that's associated with it.
| | 00:19 | Now, not all movies have files and in
fact most of what I've provided here in the
| | 00:24 | download is simply a copy of what you
will end up writing if you just follow
| | 00:29 | along with the course.
| | 00:30 | But in a few movies in this course,
you'll see an overlay appear that might
| | 00:34 | point you to a chapter, say Chapter 8,
and a movie, say number 05, with a starter file.
| | 00:40 | That's just designed
to save you a little time.
| | 00:43 | If you don't have access to the
exercise files at that moment, you will be able
| | 00:46 | to follow along just fine.
| | 00:48 | You just may have to type
a couple of lines of code.
| | 00:50 | Now we're also going to be using some
sample Microsoft databases, which aren't
| | 00:55 | part of this download.
| | 00:57 | But I'll show you how to get to those
and install them just a little later.
| | Collapse this transcript |
|
|
1. Getting StartedSQL Server core concepts| 00:00 | You'll often hear SQL Server 2008
referred to as a database, but it isn't.
| | 00:06 | SQL Server 2008 is not a database.
| | 00:08 | It's a database management
system and there is a big difference.
| | 00:12 | More specifically it's a relational
database management system or RDBMS.
| | 00:19 | Okay, you might be concerned that
we're 15 seconds into this course and I'm
| | 00:22 | already starting to hit you with abbreviations.
| | 00:25 | But as you almost certainly know,
SQL Server is not your only choice for
| | 00:28 | managing databases. You have Oracle, DB2,
MySQL, Access. There are dozens of RDBMS products.
| | 00:37 | So if we're going to understand what
SQL Server is, we have two questions.
| | 00:42 | One, why do we need an RDBMS in the first place?
| | 00:45 | And two, if we're going to have one,
since there are many available, why would
| | 00:51 | we want this one, SQL Server,
and what's special about this one?
| | 00:55 | So why have one at all?
| | 00:57 | Well the easy answer, you have some data.
| | 00:59 | You, the company that you work for,
the clients that you have, or even the
| | 01:03 | business that you're wanting to build.
| | 01:05 | This information could be about
customers, products, employees, orders.
| | 01:10 | It could be information
about hits on your website.
| | 01:13 | So it could be text, but
it could also be documents.
| | 01:17 | It could be images, audio, or video.
| | 01:19 | Now if you just had a small
amount of data, you might not need a
| | 01:23 | database management system.
| | 01:25 | There is nothing really wrong with
just using a bunch of text files, or
| | 01:29 | spreadsheets, and storing your stuff in there.
| | 01:33 | But this is not a very robust way to do
it, because once starts off as a small
| | 01:39 | amount of data has a tendency to turn into a
large amount of data and there is your problem.
| | 01:44 | What happens when two people try
to edit this file at the same time?
| | 01:49 | How about 200 people at the same time?
| | 01:52 | What stops people from going into
this and adding invalid or missing data?
| | 01:58 | If this spreadsheet solution is nice
and speedy when there are 20 or 250 lines in it,
| | 02:03 | what happens when
there are two million lines in it?
| | 02:07 | So often the first
pinpoint is having a lot of data.
| | 02:12 | Now what a lot of data means
could differ from place-to-place.
| | 02:14 | It could be 500 piece of information,
20,000, a million, 100 million pieces of
| | 02:20 | information that you've got to manage,
and to ask questions of this, to query it
| | 02:26 | in a variety of ways.
| | 02:27 | So we take it and we put this in a database.
| | 02:32 | The RDBMS, your management
system, manages this database.
| | 02:36 | It controls what gets accessed to that data.
| | 02:39 | If you want to get to the data, you go
through the database management system.
| | 02:45 | But of course, it's not just necessary to have
a database because you've got a lot of data.
| | 02:49 | The other key is that whatever
is in this database is important.
| | 02:53 | You can't lose that.
| | 02:54 | This is critical to your business.
| | 02:56 | But many companies, particularl, in
the web world your, data is your business.
| | 03:01 | Think of Amazon.com, it's a database.
| | 03:04 | eBay, Craigslist, Google, even lynda.
com, the business is the information.
| | 03:09 | Sure, on these sites there are some
great programming and a nice front-end
| | 03:13 | that could be a website or an iPhone
application but it's all about getting to this data.
| | 03:19 | But it would be wrong to think
about a database management system
| | 03:24 | just giving you a place to dump your data.
| | 03:27 | That's the easy part.
| | 03:29 | The true power of a database
management system lies in the other stuff that
| | 03:33 | it gives you, the invisible stuff, the
things you can't see. The security on
| | 03:38 | this data, the enforced integrity of
it, the ability to get to it really fast,
| | 03:43 | and get to it reliably.
| | 03:45 | This has to be robust.
| | 03:47 | It needs to withstand lots of people
at the same time, and even to correctly
| | 03:52 | survive hardware issues
without corrupting your data.
| | 03:54 | Now of course, most database management
systems promise this, so why SQL Server?
| | 04:00 | Well there are a lot of
good reasons to use SQL Server.
| | 04:03 | It's been around for 20 years.
| | 04:04 | It's a very mature product with
an immense amount of features.
| | 04:08 | Now of course the choice
may have been made already.
| | 04:12 | This may be the chosen database system
of the business that you worked for or
| | 04:16 | the clients you have.
| | 04:17 | Not surprisingly, it's very common in
a Microsoft-oriented shop because the
| | 04:22 | integration is great with other
Microsoft products, things like SharePoint,
| | 04:26 | ASP.NET for web development,
Silverlight, all the Office products
| | 04:31 | particularly like Excel.
| | 04:32 | Those are great with SQL Server.
| | 04:34 | Now if you are a web developer,
another very common reason is that many web
| | 04:39 | hosting companies will allow you to
rent and create a SQL Server database and
| | 04:45 | often inexpensively, when it's still
quite rare to find other enterprise-level
| | 04:50 | databases like Oracle or DB2 on offer.
| | 04:53 | Now SQL Server also comes with
many add-ons for advanced features.
| | 04:59 | There are parts of SQL Server that
deal with reporting, with business
| | 05:03 | intelligence and data analysis,
integration for making SQL Server work with
| | 05:07 | other database management
systems and other systems.
| | 05:11 | It's not just a place to dump some data.
| | 05:14 | Now in many larger
organizations, it's not even an either/or.
| | 05:18 | You may have many databases
managed by different RDBMSs.
| | 05:23 | You've got SQL Server and Oracle,
SQL Server and MySQL, DB2, PostgreSQL.
| | 05:27 | Now as I mentioned earlier, you often
hear the term "database" being used to
| | 05:33 | describe the software product you're
using such as Oracle or SQL Server.
| | 05:37 | My database is Oracle.
| | 05:38 | My database is SQL Server.
| | 05:39 | Well that can be a little
confusing when you're first learning this.
| | 05:42 | Again, SQL Server is a
database management system.
| | 05:46 | We use it to create and
manage different databases.
| | 05:50 | One SQL Server can manage many
different databases inside it.
| | 05:55 | In the diagram, you actually often see
these databases represented as cylinders.
| | 05:59 | But a great thing about it is these
cylinders are significantly transferable.
| | 06:05 | Once you know one, it's easy to
work with the others because all these
| | 06:08 | SQL-oriented databases, and there
are dozens, kind of work the same way.
| | 06:13 | They have the same core idea at heart.
| | 06:15 | Your data is stored in
these different databases.
| | 06:19 | The databases themselves are
built of one or more tables.
| | 06:22 | Tables consist of columns and rows.
| | 06:25 | Now we're going to go into the
construction of databases a little later.
| | 06:29 | I'm expecting you probably have
some exposure to these concepts.
| | 06:33 | If you've got some database experience
with a desktop database application like
| | 06:38 | Microsoft Access or
FileMaker, that's great knowledge.
| | 06:41 | But one key difference is that those
are single self-contained applications.
| | 06:47 | When you open up Access, it's what you
use to create the database, to enter data
| | 06:51 | into it, to manage it, to create
reports on it, even to install it on the
| | 06:55 | desktop of your end user.
| | 06:57 | SQL Server is not like that.
| | 07:01 | It's better to think of
SQL Server as an ecosystem.
| | 07:05 | It's not one program, but it's a
collection of different components to choose from.
| | 07:09 | The core database engine is first
installed, typically on a dedicated server or
| | 07:14 | even a dedicated group of servers.
| | 07:17 | And then there are a variety of
different services and tools that you can
| | 07:22 | choose or you can
ignore if you don't need them.
| | 07:25 | Major optional components of SQL
Server include reporting services.
| | 07:29 | This is for creating and
distributing reports based on your data.
| | 07:33 | Analysis services for really deep
data analysis and business intelligence.
| | 07:37 | There is integration services talking
between SQL Server and external sources
| | 07:43 | of data, other applications, other databases.
| | 07:46 | Now on top of that, you have a
collection of different applications that you can
| | 07:50 | install, or not, for working with this stuff.
| | 07:54 | Those include SQL Server Management Studio.
| | 07:56 | This is the big one for
creating and managing your databases.
| | 08:00 | There is Configuration Manager to say
what parts of your DBMS are turned on and
| | 08:05 | who can talk to them.
| | 08:06 | There is Business Intelligence
Development Studio for creating complex analysis
| | 08:11 | and integration projects.
| | 08:13 | Even have things like Visual
Studio if you're a developer.
| | 08:15 | Now if you wanted to be a SQL Server DBA,
a database administrator, you would be
| | 08:21 | expected to know all of these and more besides.
| | 08:24 | Now one thing that often surprises
people coming from desktop database
| | 08:29 | applications is that SQL Server does
not provide any kind of application
| | 08:34 | targeted at the end user.
| | 08:36 | There is no SQL Server data entry program.
| | 08:39 | The idea is that you will build that yourself.
| | 08:42 | You will provide a website, or a
desktop application, or a mobile application
| | 08:46 | that's going to be specific
to the database you create.
| | 08:50 | Now we're not going to focus on
application building in this course.
| | 08:53 | We are going to talk about these components.
| | 08:56 | The core of the database itself and
the things that you use to create and
| | 09:02 | manage your databases.
| | Collapse this transcript |
| SQL Server editions| 00:00 | In this course, we're going to work
with Microsoft SQL Server 2008 R2.
| | 00:06 | This is the latest version of
SQL Server, released in April 2010.
| | 00:11 | R2 added several features on top of the
first release of SQL Server 2008, although
| | 00:17 | the purposes of an
Essential Training course like this,
| | 00:20 | the R2 part really doesn't matter.
| | 00:23 | In fact, most of the core things we're
going to talk about are very similar to
| | 00:27 | even earlier versions like SQL Server 2005.
| | 00:31 | But SQL Server 2008 R2 is the latest version.
| | 00:35 | It's what we're going to use.
| | 00:37 | Now although, SQL Server 2008 R2
is the version that we're using,
| | 00:42 | the capabilities of it will differ
depending on the edition of SQL Server 2008 R2
| | 00:48 | that you have, because this
product has been around for 20 years.
| | 00:53 | The same way that Microsoft Office is
now available in different editions,
| | 00:56 | SQL Server has fragmented into about ten
editions with different feature sets for
| | 01:02 | different audiences.
| | 01:03 | So there is a Compact
edition for mobile devices.
| | 01:06 | There is a Web edition
specific for making web sites.
| | 01:10 | There is an Express Edition, which is free.
| | 01:12 | There is the Azure edition for hosting
your databases in the cloud, all the way
| | 01:16 | up to super high-end versions for
data centers and data warehouses that can
| | 01:20 | handle hundreds of terabytes of data.
| | 01:24 | Now rather than go through some kind
of matrix of the different editions
| | 01:27 | feature-by-feature, which I can
assure you is not that helpful right now,
| | 01:32 | I suggest that you just forget about all
the different editions, because we're
| | 01:35 | interested in one of them.
| | 01:37 | SQL Server 2008 R2 Standard edition.
| | 01:42 | This is the classic edition of SQL Server.
| | 01:46 | So in this course, I'm not going
to talk about the super-advanced,
| | 01:49 | super-expensive edition for data
centers, nor am I going to talk explicitly
| | 01:53 | about the cut-down version of SQL Server
intended for being embedded on a mobile device.
| | 01:58 | We're working with the Standard edition.
| | 02:01 | The core features of SQL
Server found in the core product.
| | 02:04 | If you have a different edition,
that's okay, because everything you'd
| | 02:08 | learn from the Standard edition can be taken
to the other editions later on if you need.
| | 02:13 | Now while that is the focus of this course,
there is one more edition worth mentioning.
| | 02:17 | SQL Server 2008 R2 Express edition.
| | 02:21 | This Express edition is free to download
and free to use, so you can install and
| | 02:26 | run it on your own desktop or your laptop.
| | 02:29 | It's great for developing small
applications and websites, for experimenting, and
| | 02:33 | just for learning how to work with
SQL Server and database development.
| | 02:37 | so we'll see that one too.
| | 02:38 | Of course, there are going to be
differences between the Standard and Express editions.
| | 02:43 | As you might expect, the free version
does not have as many features as the full version,
| | 02:47 | but Express is surprisingly
full-featured and it's not going to be
| | 02:51 | until later in the course that
we'll see where Express leaves off.
| | 02:54 | I'll be very clear where that
happens and where the differences are.
| | 02:58 | So SQL Server 2008 R2 Standard edition
is the one we'll concentrate on in this course,
| | 03:05 | and it's the one we need to understand.
| | Collapse this transcript |
| Applications included with SQL Server| 00:00 | When you're new to SQL Server you'd be
forgiven for thinking that there is one
| | 00:04 | program, one application that manages all of it.
| | 00:08 | But if you could look at the desktop
or the laptop of a typical SQL Server
| | 00:11 | database administrator, you'd see a
bunch of installed Microsoft programs that
| | 00:16 | they would consider to be just
part of their SQL Server 2008 toolkit.
| | 00:21 | In fact, these that I'm looking at
right now are the programs that you'd see
| | 00:25 | on your Start menu after a typical SQL
Server 2008 R2 Standard edition installation.
| | 00:33 | Although the SQL Server database engine
itself might be installed on a separate
| | 00:38 | machine in your back office or data
center or even in the cloud, these programs
| | 00:43 | are what you'd want to have
on your desktop or laptop.
| | 00:46 | They are what you're going to use
to connect to the SQL Server machine.
| | 00:49 | Now you could ask which one is the
most important and of course I'd say that
| | 00:53 | they're all important.
| | 00:55 | But for this course we're initially
interested in three of the available tools
| | 01:00 | and really in one of them more than anything.
| | 01:03 | Here is the main one,
SQL Server Management Studio.
| | 01:07 | This is the program we'll
spend most of our time in.
| | 01:10 | We'll use it to connect to SQL Server,
even to different SQL Server machines.
| | 01:15 | We'll use it to explore what's on the server.
| | 01:18 | We'll create databases with it.
| | 01:20 | We'll work with security with it.
| | 01:21 | We can edit the data in those databases.
| | 01:24 | We can write SQL to administer our database.
| | 01:27 | We'll spend a lot of time in
SQL Server Management Studio.
| | 01:31 | Now at some point, you're also
going to need to use SQL Server Configuration Manager.
| | 01:36 | Now this is actually a small program.
| | 01:39 | It's small but it's essential.
| | 01:41 | This manages which parts
of SQL Server are running.
| | 01:44 | What other machines can talk to SQL
Server and what network protocols are allowed.
| | 01:49 | It lets you start and stop the
different pieces of your SQL Server machine.
| | 01:54 | Now after SQL Server has actually been
installed and configured for the first time,
| | 01:58 | you probably won't need to use
this all that often, but you will run
| | 02:02 | into it now and again.
| | 02:04 | You should also have access
to SQL Server Books Online.
| | 02:09 | This is the help system.
| | 02:11 | Now wait, wait before you dismiss this.
| | 02:13 | Yes, we've all encountered help systems
that aren't worth the name, where you
| | 02:17 | just end up going out to the web to find
the assistance that you're looking for.
| | 02:21 | But SQL Server Books Online is one of
the best technical help systems you'll
| | 02:27 | ever come across and it's
often underestimated by beginners.
| | 02:30 | It's well thought out. It's huge.
| | 02:33 | It covers everything from installation and
setup to using and creating your databases.
| | 02:39 | It's both a complete reference of every
little piece of SQL Server and it's full
| | 02:45 | of tutorials as well.
| | 02:46 | You'll find that when you need to
look things up, you'll often go to Books Online first,
| | 02:50 | instead of out to the web.
| | 02:52 | Now you can find a web-based version
of SQL Server Books Online but I'm a big
| | 02:58 | fan of having it installed on my desktop
as it's easier and faster to use it,
| | 03:03 | to navigate and search through it, and as
you get more advanced you'll use even more
| | 03:08 | of these available tools.
| | 03:09 | Now there are several tools that a
database administrator might use that we
| | 03:13 | won't be using in this course.
| | 03:15 | Things like the Database Engine
Tuning Advisor or the Analysis Services
| | 03:20 | Deployment Wizard, as they are beyond the
scope of this course and we don't need
| | 03:24 | to know them to get moving with SQL Server.
| | 03:26 | But the ones we do need to worry
about right now are SQL Server Management Studio,
| | 03:31 | SQL Server Configuration
Manager, and SQL Server Books Online.
| | 03:35 | So how do we get these if
we don't have them already?
| | 03:38 | If you're going to be installing SQL
Server yourself, you can just choose
| | 03:42 | to install all of these tools during the
full install and we'll see that a little later on.
| | 03:48 | If you already have a database engine
installed somewhere else and you just need
| | 03:53 | the tools to talk to that and work
with it, you can run through a regular SQL
| | 03:58 | Server install but you have an
option to just install the tools.
| | 04:03 | Now to get to this you will still need
the regular SQL Server Install Media,
| | 04:08 | the DVD or the ISO file.
| | 04:11 | If you have an MSDN or TechNet
subscription, you can download it from there.
| | 04:15 | If you're working with the free SQL
Server Express editions you'll find your
| | 04:20 | download options at www.microsoft.
com/express/database and the default
| | 04:28 | downloader that you can get here
installs the database and the management tools.
| | 04:33 | It's a cut down version of SQL
Server Management Studio called SQL Server
| | 04:38 | Management Studio Express.
| | 04:39 | You want to take care with this because
you will find that SQL Server Express is
| | 04:44 | available in a variety of editions ,some
which are just the database only, some
| | 04:49 | are just the management tools, some
are both of them together and some with
| | 04:53 | advanced services, which
includes reporting services.
| | 04:56 | We'll see this when we get to the install.
| | 04:58 | SQL Server Express edition
doesn't include Books Online but you can
| | 05:03 | download that separately and
in this case you would go to
| | 05:06 | microsoft.com/downloads and just search for it.
| | 05:11 | I'd be careful here that I would
search for "books online 2008 r2," because
| | 05:19 | whenever you're downloading anything
from Microsoft do pay close attention to
| | 05:23 | the version numbers. Because there are
so many versions of SQL Server that still
| | 05:27 | need to be supported,
| | 05:29 | it's very easy to end up
downloading a SQL Server 2005 program.
| | 05:33 | So again everything I'm being careful
to look up is not just 2008 but 2008 r2.
| | 05:41 | But with all that in mind we can go
ahead and get ready for the install.
| | Collapse this transcript |
|
|
2. Installing SQL Server 2008 R2Preparing for installation| 00:00 | If we're going to learn SQL Server then
we need to have both SQL Server and all
| | 00:05 | the necessary tools to
talk to it and administer it.
| | 00:08 | Now I'm going to imagine that you fall
into one of the three categories here.
| | 00:13 | First is the idea that you're
going completely from scratch.
| | 00:16 | You have nothing installed at all.
| | 00:18 | You have no existing SQL Server, anything.
| | 00:21 | Now way at the other end is the
idea that you have everything already
| | 00:25 | installed successfully.
| | 00:27 | You not only have a SQL Server 2008 R2
database server to talk to, you also have
| | 00:32 | all the client tools installed and
ready to go. SQL Server Management Studio,
| | 00:37 | SQL Server Configuration Manager,
Books Online, all of that stuff.
| | 00:41 | If so, you can actually just go
skip ahead to the next section.
| | 00:45 | If you're someone in-between, say you
know that you have a SQL Server database
| | 00:50 | you can get to but you have no
management application yet, well, I'm going
| | 00:54 | to talk about going completely from
scratch and you can just pick and choose
| | 00:58 | the bits that you need.
| | 00:59 | Now to be very specific about this,
what we're going to do here is go through the
| | 01:03 | process of getting a local SQL Server
installed, up and running for development,
| | 01:08 | for testing, and for just learning SQL Server.
| | 01:11 | I'm not going to tell you how
to set up your production server.
| | 01:14 | That would be a very different
discussion involving lots of white boarding about
| | 01:19 | budgets and service level
agreements and expected usage numbers.
| | 01:24 | So what do you need to go ahead and
install it? While the Standard and the
| | 01:27 | Express versions of SQL Server 2008
R2 will install on most reasonably
| | 01:33 | up-to-date Windows operating systems,
| | 01:34 | it could be Windows 7, Windows Vista
with Service Pack 2, even Windows XP with
| | 01:41 | the most recent service packs.
| | 01:43 | In a production environment of course,
it's typically installed on a server
| | 01:47 | operating system like Server 2003 or 2008.
| | 01:51 | During this course I'm going to install
it on a 64-bit machine running Windows 7,
| | 01:56 | but again for this course
whatever you can install it on will work.
| | 02:00 | So, how to install this thing?
| | 02:01 | Well, if you don't already have a DVD
or some other install media you'll need
| | 02:06 | to find the installer.
| | 02:08 | If you have a valid MSDN or TechNet
subscription you can log on and download it,
| | 02:13 | though it is a 4 GB download.
| | 02:15 | So it might take a while.
| | 02:16 | You'll find that there are 32 and 64-bit
installers for both of the Standard and
| | 02:21 | the Express editions.
| | 02:23 | For this course you won't see a
difference choosing between those, but if
| | 02:27 | you're installing on a 64-bit operating
system you might as well get the 64-bit installer.
| | 02:32 | If you're not, get the 32-bit installer.
| | 02:35 | Now if you are planning to install the
free Express edition rather than the
| | 02:39 | Standard edition, you don't
even MSDN or TechNet account.
| | 02:43 | As mentioned before the most
direct way to get to this is to go to
| | 02:47 | www.microsoft.com/express/
downloads, as the choices are clearest here.
| | 02:55 | You will find on this page you will be
suggested to grab the 32-bit or 64-bit
| | 03:01 | version of this free edition of SQL Server 2008.
| | 03:06 | You do have some other installation
options and you'll find there is actually
| | 03:09 | four versions you can download,
one that is the Database Engine only.
| | 03:14 | One that is being
Management Studio Express only.
| | 03:17 | One is both the database with the
management tools and the biggest download is
| | 03:22 | the SQL Server 2008 R2 Express
edition database with Advanced Services.
| | 03:29 | This is the one that I suggest that
you get, because it is the biggest.
| | 03:33 | It includes the most features.
| | 03:35 | So grab whichever installation media you
need and once you have that we're ready
| | 03:40 | for the next step, which will
be creating our service accounts.
| | Collapse this transcript |
| Creating service accounts| 00:01 | Next up is an optional step, but it's
one I want to spend a couple of minutes on.
| | 00:05 | You see once SQL Server is installed,
it won't just be running as one piece.
| | 00:10 | As I mentioned before, it will really
be running in the background as several
| | 00:14 | different components and the
recommended best practice is that each of these
| | 00:18 | components has its own unique identity
that it runs under an account that was
| | 00:23 | created just for that piece.
| | 00:26 | Now it's certainly arguable that you
don't need to go to all this trouble
| | 00:29 | when setting up a simple development
SQL Server, that you can just give them
| | 00:33 | all the same account.
| | 00:34 | But I want to show this process.
| | 00:36 | So I'm going to go ahead
and set up five accounts.
| | 00:40 | One for the core database engine, one
for the part of SQL Server called the SQL
| | 00:45 | Server Agent, and that handles a lot
of background jobs and processes to keep
| | 00:50 | everything running, and three for
the big junk pieces, Reporting Services,
| | 00:55 | Analysis Services and Integration Services.
| | 00:59 | While there are a couple of other
components of SQL Server that could have
| | 01:03 | their own accounts, like full text
search and the SQL browser, I'm going to use
| | 01:08 | one of the built-in low-privileged accounts
on this machine when it comes to the installed.
| | 01:13 | So I am on Windows 7.
| | 01:15 | I'm going to go to the entry for My
Computer, right-click it, and select Manage.
| | 01:22 | This might be a little different if
you're on another operating system. I'm going
| | 01:26 | to expand my Local Users and Groups.
| | 01:28 | Now this machine that I'm on
is not connected to a domain.
| | 01:32 | So I'm just creating local users.
| | 01:34 | I need to create five accounts here.
| | 01:37 | I'll right-click, saying New
User, and make the first one.
| | 01:40 | I will call this one SQLEngine.
| | 01:43 | We give it a password, whatever you want there.
| | 01:46 | This is not a real user, so they can't
change the password of the next logon.
| | 01:51 | So I'm going to uncheck that and
select that for our purposes Password never
| | 01:55 | expires is OK, and click Create.
| | 02:00 | I'm just going to repeat the
process for the other four accounts.
| | 02:04 | Now it doesn't matter what the names are.
| | 02:07 | It's just useful if when you're later
looking at these you can recognize why a
| | 02:12 | particular account was
set up in the first place.
| | 02:15 | So I now have my five accounts ready to go.
| | 02:17 | You'll see that during the install I will have
a chance to plug these into the right places.
| | 02:23 | I don't need to make any security
changes to these accounts as the SQL Server
| | 02:27 | install will grant any necessary
privileges during that install procedure.
| | Collapse this transcript |
| Installing SQL Server| 00:00 | So I am going to go ahead and get started
installing SQL Server 2008 R2 Standard edition.
| | 00:07 | I have the installation media for a
regular standard install here. I'm going to
| | 00:12 | launch the setup application.
| | 00:15 | Now I would often tell you to go and
grab a cup of coffee while doing this but
| | 00:19 | there'll be plenty of time for that.
| | 00:21 | Installing SQL Server is a long install
procedure and there are many steps to it.
| | 00:26 | It's not something to try and do in a hurry.
| | 00:29 | So let me tell you a little
bit about what to expect here.
| | 00:32 | If you have a setup that is magically
identical to mine in every single way,
| | 00:38 | then you will have a similar experience to me.
| | 00:41 | But if your machine or your environment
differs in the slightest, you will have
| | 00:46 | a different experience installing SQL Server.
| | 00:47 | So if you have a different operating
system or a different set of applications
| | 00:52 | installed, you might expect to see a
different message now and that's okay.
| | 00:56 | It's just part of the deal
when installing SQL Server.
| | 00:59 | In fact, the first thing that
opens here is not some kind of
| | 01:03 | Next, Next, Next install.
| | 01:04 | It's called the Installation Center
and it's on the first page, which is
| | 01:08 | Planning, and there are
whole bunch of different things.
| | 01:12 | Documentation for requirements and
Setup Documentation and Upgrade Advisors.
| | 01:17 | If you've got old versions,
Upgrade Documentation.
| | 01:20 | What I'm going to do here because I'm
on a fairly fresh machine is just run the
| | 01:24 | System Configuration Checker and it's
going to go through a whole bunch of rules
| | 01:29 | just to give me some idea whether
I can go ahead and install this.
| | 01:33 | So just take your time, run this, pay
extra attention to any messages you get
| | 01:37 | during that installation.
| | 01:39 | You may have to install some prerequisite
software if it's not on your machine already.
| | 01:48 | So this runs through a whole bunch of rules.
| | 01:50 | It says it's Passed: 15 and Failed: 0.
| | 01:52 | I can click for the details and I can
see the type of things it's checking.
| | 01:56 | Things like whether the computer has
been restarted recently, does the operating
| | 02:00 | system work, are there any problems
with incompatible SQL Server versions?
| | 02:05 | Everything looks good, so I'll click OK.
| | 02:07 | That didn't do anything except run a few checks.
| | 02:10 | We'll still have a few more
checks to go on as we go forward.
| | 02:13 | I am going to select the Installation
section here on the left-hand side and
| | 02:18 | over there I'll say I want
to do a new installation.
| | 02:22 | There obviously are different ideas and
different options if I'm installing on
| | 02:26 | top of say SQL 2000 or SQL 2005.
| | 02:28 | But it's a new one for me and before
it does its thing it's going to make me
| | 02:35 | go through a whole bunch of different
questions about how this is going to be installed.
| | 02:41 | It first runs its own set of rules.
| | 02:43 | I can click Show details.
| | 02:45 | Everything looks good. Click OK.
| | 02:47 | Then it gives me the
opportunity to enter in my product key.
| | 02:54 | Also here you could actually
choose to install an evaluation or trial
| | 02:58 | edition without a product key or even
select the Express edition or Express
| | 03:03 | with Advanced Services.
| | 03:04 | I am just going to go ahead and do a
regular install, so I'll click Next.
| | 03:07 | I will accept the license terms and
usually that would be about it, but we still
| | 03:12 | have a long way to go.
| | 03:14 | What SQL Server it will do
now is install support files.
| | 03:18 | This is not at doing the proper install.
| | 03:20 | It takes longer than most installs you
would do but this is just some supporting
| | 03:25 | stuff in the background.
| | 03:26 | So I am going to click the Install
button to go ahead with that and that will
| | 03:29 | take a couple of minutes.
| | 03:35 | When it's done it will appear to
disappear for a second but it should come back
| | 03:38 | in just a moment with the
results of those support files.
| | 03:45 | What I can see here is most things
have been passed. I do have a warning here
| | 03:49 | besides Windows Firewall and if I click
that it will tell me that it's detected
| | 03:54 | that the Windows Firewall is enabled.
| | 03:56 | And that will be a problem if I was
expecting someone else to be able to connect
| | 04:00 | to the SQL Server on this machine, if I
am shutting them down with my firewall.
| | 04:04 | It's okay because this is a development
machine so I am going to say that's not
| | 04:07 | a problem and go ahead and click Next.
| | 04:10 | Next up, we have a choice . Are we
installing SQL Server by selecting the
| | 04:15 | different features, the different
component pieces of it, or do we want to
| | 04:19 | install all features with defaults?
| | 04:21 | The second option here would be the
easy button but I'm not going to do that.
| | 04:25 | I am going to step through the
feature level installation. Even though I am
| | 04:29 | going to install everything I
want to show that part to you.
| | 04:33 | So click Next into the different
features and this is where we see that yes
| | 04:37 | indeed, SQL Server is installed as
our whole bunch of different pieces.
| | 04:42 | The database engine itself and
the different parts of that such as
| | 04:45 | Replication and Search.
| | 04:47 | Analysis Services, Reporting Services,
then a lot of different tools like Books Online
| | 04:52 | the Business Intelligence
Development Studio, the Management Tools.
| | 04:56 | In fact I am just going to go ahead
and click the button to say Select All.
| | 05:00 | I am not going to touch any of the
paths that this will be installed on.
| | 05:05 | Just accept the defaults there and click Next.
| | 05:12 | It runs one more in a whole bunch of
checks that it's running through and
| | 05:16 | everything looks okay. I'll click Next.
| | 05:19 | What it's asking me now is what's the
name of the Instance. And what does this mean?
| | 05:24 | Well, you can actually install
multiple instances of SQL Server and each
| | 05:29 | instance can contain its own set of databases.
| | 05:34 | It's not something you have to do but
you can have up to 50 instances of SQL
| | 05:38 | Server on one machine.
| | 05:40 | If you do, you have to give each of
those 50 or 5 or 10 a different name.
| | 05:46 | But if we're installing it from
scratch we can say I don't need to name this
| | 05:50 | instance because I'm not
intending to put any others on.
| | 05:53 | So I'm just going to call
it the default instance.
| | 05:55 | That means later on if I want to
access this instance I don't really have to
| | 05:59 | care about what it's called because
it's the default instance on this machine.
| | 06:03 | I can see there are no existing instances here.
| | 06:07 | So I will go ahead and click Next.
| | 06:11 | It gives me a summary of the amount
of space it's going to take up,
| | 06:14 | not something I really care about if I've
got plenty of disk space available and I'm
| | 06:19 | not expecting this database to
grow very large. I'll click Next.
| | 06:24 | What we have now is the place that I
can plug in those service accounts that I
| | 06:29 | created a little earlier, giving
different identities to each part of SQL Server
| | 06:35 | that will be running.
| | 06:36 | So I'm going to go ahead and type in
the account names that I had set up
| | 06:39 | earlier, the first one being for SQL
Server Agent and give it the password
| | 06:44 | that it knows about.
| | 06:47 | Then the database engine, which for me
was SQLEngine, and go ahead and enter the
| | 06:52 | remaining service accounts.
| | 06:54 | I am going to leave the last two just setup
as using the built-in local service account.
| | 06:59 | This is a fairly low privilege
account, which is fine for those.
| | 07:02 | The tab behind it is something called Collation.
| | 07:05 | I am not going to touch that.
| | 07:06 | Collation is the idea of how does SQL
Server do things like case sensitivity and
| | 07:12 | accent sensitivity behind the scenes.
| | 07:14 | If you are ordering a bunch of last
names of people, does it care whether it's
| | 07:19 | an uppercase A or a lowercase a?
| | 07:21 | Does it care if it's an a or an a
with an accent over the top of it?
| | 07:26 | I'm going to accept the default,
which is just for this case a SQL
| | 07:30 | Latin1-General case-insensitive,
accent-sensitive, and just not touch it.
| | 07:35 | But if you have to handle
multiple languages, you may have to do
| | 07:38 | something slightly different.
| | 07:40 | So I'll go ahead and click Next and it
asks me how the security is going to be
| | 07:46 | set up on this instance of the database,
and it's saying the authentication mode
| | 07:51 | is Windows authentication or Mixed Mode.
| | 07:55 | Windows is the default and it means
that everybody who's going to get access to
| | 07:59 | these databases has to have a Windows
account and it's by that that we will specify
| | 08:04 | what they're allowed to do.
| | 08:06 | Mixed Mode means there could be either
a Windows account or you could actually
| | 08:10 | set them up their own username
and password within SQL Server.
| | 08:14 | It wouldn't be a Windows account.
| | 08:16 | Now the default and the recommendation
for Microsoft these days is stick with
| | 08:20 | Windows authentication mode
because it's a bit more secure.
| | 08:23 | But in some cases, say when you're
building web applications you may be working
| | 08:27 | with Mixed Mode and you get to
set up different kinds of accounts.
| | 08:30 | I'll leave it at the default, and the
only thing I'm going to do on this screen
| | 08:34 | is down here where it asks me to
specify the SQL Server administrators.
| | 08:38 | I am going to say Add Current User.
| | 08:40 | Yes, I want to be added as
an administrator on this box.
| | 08:44 | I am going to leave the other two tabs
of Data Directories and FILESTREAM, which
| | 08:48 | name both where these files are
going to be installed on the machine.
| | 08:52 | FILESTREAM is a new feature in SQL
2008 that allows you to store large files,
| | 08:58 | even bigger than two gigabytes, on the file
system and still manage them through the database.
| | 09:03 | I'm not going to touch this right now.
It's little bit beyond the scope of this class.
| | 09:07 | So with Windows authentication mode set
and me listed as the user I can go ahead.
| | 09:13 | Just to let you know, you can actually
change the authentication mode later.
| | 09:16 | So it's not a disaster
if you have the wrong one.
| | 09:19 | Next up, it's asking me to specify the
administrators for Analysis Services.
| | 09:25 | This isn't something we've talked about
a lot yet, but what I'm going to do is
| | 09:28 | just go ahead and click that Add
Current User button again and name myself as
| | 09:33 | having unrestricted access there
and just go ahead and click Next.
| | 09:37 | In this screen, we're being asked to set
up Reporting Services, this part of SQL
| | 09:42 | Server that can handle reporting.
| | 09:46 | There are three options here.
| | 09:48 | Installing the native mode default
configuration, getting it set up from scratch
| | 09:52 | to install with SharePoint, and then
installing it but not configuring it.
| | 09:56 | I am again going to accept the default one,
which is the first option, and click Next.
| | 10:02 | I am going to choose not to send any
error reports to my corporate report
| | 10:08 | server and click Next.
| | 10:10 | It runs through a few more checks.
| | 10:12 | I am going to say Show details.
| | 10:14 | Everything looks okay.
| | 10:17 | Click Next and it gives me a
summary. It's going to install all these
| | 10:22 | different features.
| | 10:23 | These are the names it's going to use.
| | 10:25 | These are the accounts that
it's going to use. As you can see,
| | 10:27 | there is a whole lot of stuff
going on here. We're ready to go.
| | 10:32 | I'm going to go ahead and click
Install and this will take several minutes.
| | 10:37 | So I'm just going to go
ahead and let it do its thing.
| | 10:44 | So later on, perhaps much later
depending on the speed of your machine, but
| | 10:49 | certainly after many minutes you should
hopefully get to this screen, that your
| | 10:53 | SQL Server 2008 R2
installation completed successfully.
| | 10:58 | It will give you a log file if you
feel like you need to take a look at it.
| | 11:01 | Obviously if there are any alternate
messages, you get anything else, you need to
| | 11:05 | go and take a look at that too.
| | 11:07 | But hopefully that should do it.
| | 11:10 | Going back to the Installation Center we
can also run a search for product updates.
| | 11:14 | I am not going to do that right now
but it's certainly something that in the
| | 11:17 | long process we should do.
| | 11:19 | So we now have SQL Server
2008 pretty much up and running.
| | 11:22 | If I look at my All Programs I should
find a whole section under SQL Server 2008 R2
| | 11:28 | with the Analysis Services Tools,
Configuration Tools, Documentation,
| | 11:34 | Integration Services and Performance,
and we're going to go through quite a few
| | 11:38 | of these as we go through the course.
| | 11:40 | But we're ready to go.
| | Collapse this transcript |
| Post-installation checks| 00:01 | So it'll be useful to prove to ourselves that
we're actually have a database to deal with.
| | 00:05 | So, how do we do that?
| | 00:06 | Well, opening up our SQL Server programs
there is a couple of things we can look at.
| | 00:10 | If I'm really just interested in the
different parts of SQL Server and how they're
| | 00:14 | running, I could go to my
Configuration Tools section and open up SQL Server
| | 00:19 | Configuration Manager.
| | 00:21 | Now what this will do is allow me to
see those different components, which ones
| | 00:26 | are running, which ones are not.
| | 00:28 | In these SQL Server Services I'll see
that I have the actual SQL Server engine
| | 00:33 | running under the identity of SQLEngine.
| | 00:36 | We've got an Analysis Services as running.
| | 00:38 | The SQL Server Browser is not
and that is by default it doesn't
| | 00:42 | automatically start.
| | 00:43 | Integration Services is running.
| | 00:45 | The Agent is not running.
| | 00:47 | It is stopped, because it's a manual start.
| | 00:50 | The Full-text Filter Daemon is
running and so is Reporting Services.
| | 00:54 | This would be the screen where you
could do things like configure whether they
| | 00:59 | start up automatically or manually,
start them or stop them, change the identity
| | 01:05 | that they're running under.
| | 01:06 | For us, we don't really need
to touch any of that right now.
| | 01:09 | The one other thing that you're
likely to do is in the SQL Server Network
| | 01:13 | Configuration, and you could have two entries
for that depending on if you're 64 or 32 bit,
| | 01:17 | it will tell you the
protocols that were running.
| | 01:20 | How can the other machines talk to us right now?
| | 01:23 | By default we're going
to have TCP/IP as Enabled.
| | 01:27 | That's the default way people
will connect to this machine.
| | 01:30 | If I double-click it, it will tell me a
few entries like is it enabled yes or no
| | 01:34 | and what IP address is this on.
| | 01:37 | By default the TCP port for SQL Server is 1433.
| | 01:42 | That can be changed, but that's
just what I've expect to see right now.
| | 01:46 | But of course we're not looking at anything.
| | 01:48 | It seems to say to us that we've got a
lot of background services running, but
| | 01:51 | what do we actually have.
| | 01:52 | Well, to see that I'm going to go to
the SQL Server management tool, which will
| | 01:58 | be in Management Studio.
| | 02:00 | So, opening up SQL Server Management Studio.
| | 02:02 | What it's going to ask me to do is say,
well, which database engine do you
| | 02:06 | want to connect to?
| | 02:07 | Because we could use this one program
to connect to a database installed on
| | 02:12 | our local machine, to one in our back
office, even one that's out there over the
| | 02:17 | web and in the cloud.
| | 02:18 | Well, I just want to
connect to the local machine.
| | 02:20 | So I can accept the default server name,
type in the name of the actual machine
| | 02:24 | that it says, or even just put a
single dot here and say Connect.
| | 02:30 | What that means is yes, we're actually
connected to this machine right now and
| | 02:34 | I can expand over here my Databases section.
| | 02:38 | That seems to say that I've got some
System Databases and if I expand that I've
| | 02:42 | got master and model and msdb and tempdb.
| | 02:46 | We'll talk about those in a minute.
| | 02:47 | Couple of other databases that are
being used by the Reporting Services part,
| | 02:52 | but that's about it.
| | 02:52 | If you're expecting to find some sample
data, well, you're not really going to,
| | 02:58 | because SQL Server doesn't install any
template databases or any samples for you to look at.
| | 03:03 | But you can get that and we'll see
how to get some data to look at in just a minute.
| | Collapse this transcript |
| Installing sample databases| 00:00 | Although SQL Server installs a lot of
pieces during that whole long-winded
| | 00:05 | install procedure, sample databases
are not one of them, but we can get them.
| | 00:10 | I'm going to open up a
browser and go to the address
| | 00:13 | sqlserversamples.codeplex.com.
| | 00:18 | Codeplex.com is a web site where a
Microsoft put a whole bunch of extensions and
| | 00:23 | downloadable options you can find
for SQL Server and other things.
| | 00:28 | And on this page, you will find
product code samples for SQL Server 2008,
| | 00:31 | but the things that I'm looking for are the
AdventureWorks 2008R2 sample databases.
| | 00:38 | If you've been working with Microsoft
technologies for a few years, you might be
| | 00:42 | familiar with the classic sample
databases that Microsoft have had like
| | 00:47 | Northwind and Pubs.
| | 00:49 | AdventureWorks is the company that
they came up with a few years ago and I'm
| | 00:53 | going to go and click the link that
says they can be downloaded from here.
| | 00:58 | They're a lot bigger than the old
Northwind and Pubs sample databases ever were.
| | 01:05 | And if I agree to this, I'm going to
download these AdventureWorks sample databases.
| | 01:12 | And once it's downloaded, I'm
going to go ahead and run this.
| | 01:15 | Of course, we don't have to install
these databases, but it will give us
| | 01:18 | something to play around with when
we are writing bits of SQL later on.
| | 01:29 | It will unzip a bunch of files and
then run just a little installer that will
| | 01:33 | allow you to go ahead
and basically import those.
| | 01:37 | It's not quite the right word, but it'll
do for the time being, import them into
| | 01:42 | our default installation of SQL Server.
| | 01:45 | You'll notice that there is a few
markers here, that there are certain things
| | 01:49 | that say manually deploy via BIDS after install.
| | 01:53 | These are for the more advanced OLAP
databases for analytical processing being
| | 01:58 | use by Analysis Services.
| | 02:00 | I'm not really going to
attach these in this course.
| | 02:03 | What I'm really just interested in are
the AdventureWorks OLTP and perhaps the
| | 02:08 | data warehouse ones.
| | 02:10 | I'm going to go ahead and install.
| | 02:14 | And after several minutes you
should get to the finish screen.
| | 02:18 | I'm just going to hit
Finish and we should be done.
| | 02:20 | Of course I want to prove this, so I'm
going to close down my browser and go
| | 02:24 | back and open up SQL Server Management
Studio, connect to the local machine, and
| | 02:33 | expand Databases and see what
we can find, and there we go.
| | 02:36 | We've got AdventureWorks, AdventureWorks
data warehouse, and the light versions of it.
| | 02:41 | And I could even start to expand these
and now I'll see inside AdventureWorks.
| | 02:45 | I have tables, which I can expand,
which will have data about employees and
| | 02:50 | people and productions and bill of materials.
| | 02:52 | This is all sample information of course.
| | 02:57 | I could select the
HumanResources.Employee table.
| | 03:00 | We'll talk much more about
what this is in the moment.
| | 03:03 | I'm going to right-click it and save
Select Top 1000 Rows and I'll finally
| | 03:08 | see that we have indeed some data
that's being stored in our SQL Server
| | 03:13 | database that certainly seems like we could
start to manipulate it and play around with it.
| | 03:18 | So even though we're going to get on to
creating our own databases, having the
| | 03:23 | AdventureWorks databases in here in
SQL Server will certainly make it useful
| | 03:27 | when it comes to talking about examples
of retrieving and updating information.
| | 03:33 | Now you'll notice that this
particular SQL Server, what we call the instance
| | 03:38 | of SQL Server and this is the default
instance, itself is containing multiple databases.
| | 03:45 | In this case we have AdventureWorks is a
database that itself contains dozens of tables.
| | 03:52 | AdventureWorksDW is another one.
| | 03:54 | AdventureWoksDW2008R2, AdventureWorksLT,
ReportServer, ReportServerTempDB, and
| | 04:01 | we have the system databases.
| | 04:03 | And it's an important distinction to
make, because it's very common that people
| | 04:06 | talk about SQL Server as if it's a database.
| | 04:10 | They say that very generic term.
| | 04:12 | And of course SQL Server is not a database.
| | 04:15 | SQL Server is your database server that
itself can contain dozens of databases.
| | 04:21 | You might only be interested in making one
database for yourself, but you could have many.
| | 04:26 | So there is very much a distinction
between the databases you have and the
| | 04:31 | instance of SQL Server
that holds those databases.
| | 04:34 | And because these databases are
independent of each other, if you wanted to,
| | 04:40 | you could go through and delete them or do
what's called detaching them, meaning we
| | 04:45 | just don't care about them anymore.
| | 04:47 | I'm not going to do that right now,
because I do want to work with them later
| | 04:50 | but you certainly could do that later on.
| | Collapse this transcript |
|
|
3. Tools and System DatabasesIntroduction to SQL Server Management Studio| 00:01 | Let's take a look at SQL
Server Management Studio.
| | 00:03 | This will be our main toolbox for
working with a SQL Server, and since I'm going
| | 00:08 | to find it under my SQL Server 2008 R2
programs, I'm going to right-click and
| | 00:14 | just pin this to my Start menu.
| | 00:16 | It makes it easier to get to.
| | 00:17 | Now this tool is not intended for the end user.
| | 00:22 | It is an administration tool.
| | 00:24 | It will help us create and change
databases, diagram them, report on them.
| | 00:29 | There is a lot of stuff it can do.
| | 00:30 | Now there is no real point in opening
SQL Server Management Studio without
| | 00:35 | connecting to a SQL Server instance.
| | 00:38 | So that's the first thing you'll be asked to do.
| | 00:41 | And again, you can connect this to
different SQL Servers as long as you know
| | 00:45 | where they are and what
credentials to use to get access to them.
| | 00:48 | I am connecting to the local machine
here so I am just going to use a dot
| | 00:52 | for the server name.
| | 00:53 | I had installed it using Windows
Authentication and I had named myself as the
| | 00:58 | administrator of this instance.
| | 01:00 | So once I connect, I'm in and I can do anything.
| | 01:04 | Now the most obvious section and
the most useful initially is this area
| | 01:09 | over here on the left.
| | 01:10 | It's called the Object Explorer,
but the name is not really important.
| | 01:14 | This is the section that lets you
drill down into different parts of the SQL
| | 01:19 | Server instance you're connected to.
Not just the databases and the data inside
| | 01:24 | them but administrative stuff too.
| | 01:26 | What are the users and the user
identities that SQL Server knows about?
| | 01:31 | What roles does the database understand?
| | 01:34 | How for example would you say that a
user called Bob should be allowed to edit
| | 01:40 | the Orders database but not
allowed to edit the HR database?
| | 01:43 | That stuff is all defined in here.
| | 01:45 | Now when you're clicking around here,
what you can actually do is see a little
| | 01:50 | more information by selecting the
Object Explorer Details pane from the View
| | 01:55 | window and when I have say my databases
selected, I don't just see the names of them
| | 01:59 | but I can see their owner and
their collation if I find that useful.
| | 02:04 | But more than anything you will find
that right-clicking is your friend in SQL
| | 02:09 | Server Management Studio.
| | 02:11 | You can select pretty much any of these levels.
| | 02:14 | Right-click an object in them
and you'll see a collection of
| | 02:18 | context-sensitive options.
| | 02:20 | If you, for example, select a database
like the AdventureWorks database, you can
| | 02:23 | drill down into Tasks and see that you
can take it offline or copy the database
| | 02:30 | or import data or back it up or restore it.
| | 02:34 | One of the common things you are likely
to do with databases, you'll be curious
| | 02:38 | of how much space they take up.
| | 02:40 | So you'll find that right-clicking on
the database allows you to go to Reports
| | 02:44 | where you have a whole bunch of
standard reports that says Disk Usage, how much
| | 02:49 | disk usage is this database taking up.
| | 02:51 | Drill back down into Reports and I'll
find things like Disk Usage by Top Tables,
| | 02:57 | generating lots of really
useful information for that.
| | 03:01 | On the other hand, if you start to
drill down inside the databases themselves
| | 03:05 | and actually start to drill down into
the tables, the things that hold your
| | 03:09 | information, the right-click
choices here will be different.
| | 03:13 | You'll have things like select the top
1000 rows or even edit the top 200 rows.
| | 03:20 | You can even right-click the Tables and
say Design, allowing you to change the
| | 03:25 | table and change what it actually
means to be this data and we'll see all of
| | 03:29 | this a little later on.
| | 03:30 | I do encourage you to explore around
the Object Explorer for a few minutes if
| | 03:35 | you haven't already.
| | 03:36 | Now of course as with any advanced development
environment, take care when you're doing this.
| | 03:43 | You are working directly with the
database instance and if you decide to tell
| | 03:49 | SQL Server Management Studio to delete a
database for example or change a table,
| | 03:54 | it will say "Well, you're
the boss" and it will do it.
| | 03:58 | One example of the place to take care
might be, for example, Database Diagrams.
| | 04:03 | If you start working with some of these
sample databases you'll see a Database
| | 04:07 | Diagrams section and this is
very tempting to play around with.
| | 04:13 | Typically the first time you would
click them you may be prompted that the
| | 04:16 | database doesn't have
everything in place to use this.
| | 04:19 | Do you want to create that?
| | 04:20 | I'm going to say yes I do.
| | 04:22 | Let me close the couple
of reports I have opened.
| | 04:24 | What that then allows me to do is
make a new database diagram based on the
| | 04:30 | actual defined pieces of that database.
| | 04:32 | In this case, I'm doing it on the
database called AdventureWorksLT and I see
| | 04:37 | that I have a whole bunch of tables
here and I can just start clicking Add to
| | 04:43 | add them to my diagram.
| | 04:44 | Maybe I'll err on the side of
just adding everything right now.
| | 04:49 | If I close that, I see that I've got
this rather large diagram going on here.
| | 04:55 | In fact, up at the top of the
screen I can shrink that down.
| | 04:58 | Let's say it's 50%.
| | 04:59 | It's still a little big so I can
drag a few things around if I so desire.
| | 05:05 | But what I'm trying to show is the
point that this is really-really good stuff
| | 05:11 | and the ability to diagram your database
reading from the actual structure of it
| | 05:15 | is a great feature but again, be careful.
| | 05:17 | It's very easy to say look at a
diagram like this and realize that you don't
| | 05:22 | need to show everything, you'll right-
click one of these options and you'll
| | 05:26 | see that there is the option Remove from
Diagram, right next to Delete Tables from Database.
| | 05:32 | And the end result of selecting
these things would be very different.
| | 05:37 | So again, take care.
| | 05:39 | Some great features, but be careful with them.
| | 05:41 | Of course, everything that we are
actually doing with this SQL Server Management
| | 05:47 | Studio interface is generating commands
that talk to the SQL Server instance and
| | 05:54 | if you are someone who lives and
breathes command line operations, you can
| | 05:58 | actually open up something called
SQLCMD, just typing in SQL command, and that
| | 06:04 | will open a command prompt to
allowing to talk to the SQL Server instance.
| | 06:08 | I could do a couple simple things here.
| | 06:10 | I am going to say use AdventureWorks...
And all I'm doing is typing a couple of
| | 06:29 | simple commands to shift the SQL Server
Instance to look at the AdventureWorks
| | 06:34 | database and then show me the top 10
first names from one of the tables.
| | 06:40 | Now I'm not intending to spend any
significant time in the command line prompt
| | 06:45 | here in this course.
| | 06:46 | We're going to use the graphical
interface you can always take what you get
| | 06:50 | there and put it in the command line later.
| | 06:53 | However, we still are going to write a
fair amount of code ourselves. We are
| | 06:57 | just going to do it in SQL Server
Management Studio, which is a much more
| | 07:00 | pleasant way to do that.
| | 07:02 | It does also have some helpers for us.
| | 07:04 | If I go to the View menu and select
something called the Template Explorer, I am
| | 07:09 | going to see this section
appear over here on the right.
| | 07:12 | This is hundreds of pieces of
boilerplate code we can use for the most common
| | 07:17 | tasks in SQL Server.
| | 07:19 | Everything from creating a database for
example, which starts to script it out there,
| | 07:25 | we just go and fill in the blanks,
all the way to advanced database needs
| | 07:30 | such as creating partition schemes,
which can be a bit more complex.
| | 07:36 | Now if the idea of writing a lot of
this code fills you with dread, we will see
| | 07:41 | that quite a bit of our creation can
also be done using the graphical user
| | 07:45 | interface, but you will always be
required to kind of come back and write a few
| | 07:51 | commands that will be executed
by SQL Server Management Studio.
| | 07:55 | We will of course be using a lot more
pieces of this application as and when we
| | 07:59 | need them, but with these core ideas
to get started we can move on and start
| | 08:04 | exploring one more tool.
| | Collapse this transcript |
| Introduction to SQL Server Books Online| 00:00 | When you are new with the SQL Server,
I can assure you that it's a really good
| | 00:05 | idea to have an easy way to
get to SQL Server Books Online.
| | 00:10 | In a default installation you'll find
under the Documentation and Tutorials
| | 00:15 | section of SQL Server 2008 R2.
| | 00:16 | I am actually going to right-click this
and pin this to the Start menu as well
| | 00:22 | just so I have access to both
Management Studio and Books Online very easily.
| | 00:27 | Opening it up, you'll find that it's
really split, at least initially, into a
| | 00:32 | couple of different sections.
| | 00:34 | It starts off with this core section
talking about the categories of SQL Server
| | 00:39 | but really, it split over here on the
left into the Contents section, allowing
| | 00:43 | you to drill down into the
different pieces, and a very useful index.
| | 00:48 | You'll probably spend a lot of time
looking things up in the index because it is
| | 00:52 | huge and links you to a
whole bunch of different stuff.
| | 00:55 | Again, you will find that this
does not just have a reference to it.
| | 00:59 | The index is a great reference but
inside Books Online, you'll find whole areas
| | 01:05 | like SQL Server Tutorials, tutorials on
using Management Studio, or the SQLCMD
| | 01:10 | utility, or the Database Tuning Advisor.
| | 01:13 | So as you start to look through those,
you will be likely to find tutorials
| | 01:18 | in just about everything and you can
see then at the bottom of most of the
| | 01:23 | pages, you even have the ability
to send feedback to Microsoft if you
| | 01:26 | disagree with something.
| | 01:30 | As you start to drill down into the
different parts of it, so for example,
| | 01:35 | selecting the Database Engine section
within Contents, you'll see that you can
| | 01:40 | browse a lot of this material by life cycle.
| | 01:42 | Are you really more interested in
getting started, are you interested in
| | 01:46 | security, are you interested
in deployment or development?
| | 01:51 | Not only that but you can drill down
into a lot of this content by browsing
| | 01:55 | it by the particular role. If you're
a developer or an information worker,
| | 02:00 | you're interested in a different kind
of information than your typical SQL
| | 02:04 | Server administrator.
| | 02:06 | Books Online is huge.
| | 02:08 | Initially, you'll find it rather
overwhelming till your comfortable with making
| | 02:12 | a way around it but it's a very,
very useful application to have.
| | 02:15 | It will be your go-to source of
information most of the time within SQL Server.
| | 02:21 | When you find parts of it that you
think are really, really useful, say for
| | 02:27 | example, you have drill down into the
Information Worker and you found the
| | 02:31 | section about Accessing and Changing
Database Data, you can decide to make this
| | 02:36 | page a favorite up here in the toolbar.
| | 02:39 | You have an Add to Help Favorites link.
| | 02:42 | You click that, and what
you'll find is that the third tab along the
| | 02:47 | bottom on the left-hand side now allows
you to switch from the general contents
| | 02:52 | to the index to your particular
bookmarks, your little Help favorites.
| | 02:56 | That's all I really want to explain
to get a started with Books Online.
| | 02:59 | just get used to keeping this open
in the background and referencing it
| | 03:04 | whenever you can.
| | Collapse this transcript |
| SQL Server system databases| 00:00 | Now although when you install SQL
Server, you don't get any of the sample
| | 00:04 | databases like AdventureWorks,
| | 00:06 | what you will see, if you're looking
through SQL Server Management Studio, is
| | 00:10 | you will see at least four system databases.
| | 00:12 | Four is pretty typical for a right-
out-of-the-box standard installation.
| | 00:17 | You have got master, model, msdb, and
tempdb and I'm often ask how important
| | 00:23 | are these and are you supposed to do
anything with them, are you supposed to change them?
| | 00:28 | Well in this particular course, we're
unlikely to touch any of them at all.
| | 00:32 | You are just going to leave them alone but to
give you the quick runthrough of what they mean,
| | 00:37 | yes, they are important, they are vital.
| | 00:39 | The master database, which even sounds
important straight off the bat, is the
| | 00:44 | one database that says what
exists in this instance of SQL Server.
| | 00:49 | If the master database wasn't available,
the instance doesn't even start. It won't run.
| | 00:55 | This says what else is available.
| | 00:58 | The model database can be changed but
you're unlikely to at this level of content.
| | 01:04 | What model does is it describes
the template for a new database.
| | 01:09 | So later on in this course, when we make a
new database, it will actually be based on model.
| | 01:16 | So say at some point in the future,
you had a very specific database
| | 01:20 | creation process. You might change
model so that every new database was
| | 01:25 | based on your changed design.
| | 01:26 | msdb is used internally and it's used
for queuing and to put some jobs to have
| | 01:33 | things run in the background such as
database mail and a little part of SQL
| | 01:38 | Server called Service Broker.
| | 01:40 | We won't really be touching
either of these in this course.
| | 01:43 | The only other one we have here is tempdb.
| | 01:46 | Again, you might look at the name
and think it looks like it's something
| | 01:49 | temporary and it is.
| | 01:51 | This is really a scratchpad for SQL Server.
| | 01:53 | tempdb is used when SQL Server is doing
large amounts of calculation and sorting
| | 01:59 | and it's reordering things.
| | 02:01 | It uses that as kind of
scrap paper to write things on.
| | 02:05 | If you were to shut down and restart
SQL Server, you'd find a tempdb would be
| | 02:09 | deleted and re-created.
| | 02:12 | So that's the basic idea of
what these four databases are for.
| | 02:15 | In this course, we won't be
touching them, but if you're curious about them,
| | 02:18 | they are vital.
| | 02:19 | just leave them alone.
| | Collapse this transcript |
|
|
4. Creating DatabasesPlanning your database| 00:00 | It's very useful to have these sample
databases to play around and experiment with
| | 00:05 | but let's face it.
| | 00:06 | The main reason we want to have a database
server is so that we can have our own database.
| | 00:12 | But it would be a bad idea to start by
just jumping into SQL Server Management
| | 00:16 | Studio and going crazy with
the right-click mouse button.
| | 00:19 | That is how bad databases get started.
| | 00:21 | So in the next few minutes what I am
going to do is talk about the basics of how
| | 00:26 | to plan or model your
database before we start to build it.
| | 00:30 | You see while in other areas of
development, things like programming and web
| | 00:35 | development, I'm a really big fan of
the iterative incremental design idea
| | 00:40 | that you build apps quickly, you get
them out, you revise them, you add new
| | 00:44 | features repeatedly over weeks or even days, but
that's not what I want to do with the database.
| | 00:51 | You see building a
database is like getting tattooed.
| | 00:54 | You'll really want it to be correct
the first time you do it. Changes are
| | 00:58 | possible but they are painful.
| | 01:01 | The great thing is though while
version of SQL Server 2008 R2 might be new,
| | 01:06 | relational databases aren't.
| | 01:09 | They've been around since the '70s and
that's a good thing, as the methods from
| | 01:13 | modeling a database have been battle-
tested over four decades, and to make a
| | 01:18 | good one, you just follow
pretty much a 40-year old process.
| | 01:22 | It doesn't really even matter what
database management system you're using.
| | 01:25 | Now while you can use a diagramming
piece of software like Visio, all you really
| | 01:31 | need to model a database, at least
initially, is pencil and paper and be prepared
| | 01:36 | to think deeply about a few questions.
| | 01:39 | A database modeling is not a place to
express your inner creativity and find
| | 01:45 | wild and crazy new ways of doing things.
| | 01:47 | If you want to get wild and crazy,
do it in your user interface, in your
| | 01:50 | application, but in your database,
I am afraid you want to be patient,
| | 01:55 | methodical, step-by-step.
| | 01:58 | The first thing we need to do
is ask ourselves a few questions.
| | 02:02 | Number 1, what's it for?
| | 02:05 | What is the point of this database?
| | 02:07 | Be careful of the first
answer that comes to mind.
| | 02:10 | Sure, in most cases, you're building
a database to support an application,
| | 02:14 | whether that's Desktop, or mobile, or
a web application, but say you're building
| | 02:19 | an online bookstore.
| | 02:21 | Well that's way too easy to say that,
the database stores necessary product
| | 02:25 | and order information.
| | 02:27 | Yes, that might be true but you
should be asking what are the goals of the
| | 02:33 | store, or the website, or the application.
Because wherever you wanted to go over
| | 02:38 | the next year or five should
affect what you build right now.
| | 02:42 | Even having an elevator picture or a
mission statement in mind will help you
| | 02:46 | build a better database.
| | 02:48 | If the idea behind your online store
was "We help customers find books, discover
| | 02:53 | what others thought about them,
purchase and track their orders, contribute
| | 02:57 | their own reviews and opinions, learn
about other products they might like based
| | 03:00 | on people with similar reading habits,"
you'll build a very different database
| | 03:05 | from that description than
you would from the first one.
| | 03:09 | The second question.
| | 03:10 | What do you have already?
| | 03:12 | Do you have an existing database, even
in something like Access or FileMaker?
| | 03:16 | If so, well what's wrong with it?
Because you don't want to just make the
| | 03:21 | assumption that you're going to import all
your existing data straight into this new system.
| | 03:26 | There is almost certainly
problems with everything you have.
| | 03:29 | Take the opportunity to fix any
problems before you just re-create those same
| | 03:34 | problems in SQL Server.
| | 03:36 | Do you have an existing process that this
database will replace or help, even a manual process?
| | 03:41 | If so, get all your physical assets
together, printouts, order sheets, filing
| | 03:45 | cabinets, and people, of course,
because understanding the data that you
| | 03:50 | already have is essential before you
can answer the next question, which is
| | 03:55 | what tables do you need?
| | 03:57 | Each database you make will consist of
one or more tables and these tables are
| | 04:01 | the basic building blocks of a database.
| | 04:03 | When you create a separate tables for
each entity, that is each object or each
| | 04:09 | thing that needs to be represented in
your system, some of your tables might
| | 04:14 | represent things that exist in the real
world like a customer, or product, or an
| | 04:18 | employee but others can be more
abstract. A blog entry, a comment, an
| | 04:24 | appointment, or event.
| | 04:26 | Each of these tables will contain
multiple rows of information, whether that's
| | 04:32 | one employee, or a dozen, or a million.
| | 04:35 | This is one of those places where you
could take a look for inspiration at some
| | 04:40 | of the databases that are provided as samples.
| | 04:44 | We can actually expand say
AdventureWorks LT, the light version, and look
| | 04:48 | at their tables here.
| | 04:49 | They've got SalesLT.Customer, Product,
ProductCategory, ProductDescription,
| | 04:54 | SalesOrderDetail, SalesOrderHeader.
| | 04:55 | Now if you notice these are the table
names and they are prefixed here with SalesLT.
| | 05:01 | That is something specific to SQL Server here.
| | 05:04 | It's what's called a schema and it's a
way of grouping your tables together into
| | 05:09 | larger containers if you will.
| | 05:11 | We are not going to do an awful lot
with schemas but to give you some idea
| | 05:15 | of where that goes,
| | 05:16 | if we look at one of the larger sample
databases, the tables in here are grouped
| | 05:22 | into several tables under the
Person schema, such as Person.Address,
| | 05:26 | Person.Contact, Person.ContactType.
| | 05:29 | We have got Production
schemas and HumanResources.
| | 05:33 | So the easy perspective to take is
| | 05:35 | it's just a way of grouping some of
your stuff together. But we're defining
| | 05:39 | fairly simple tables to begin with and
after figuring out what tables need to exist,
| | 05:45 | you then zoom into each
individual table to specify exactly what data
| | 05:52 | should be stored for each entity.
| | 05:55 | So in this case for an employee and here
you need to be as specific as possible,
| | 06:01 | defining separate columns for
each individual piece of information.
| | 06:06 | As a rule, you're going to go as
granular as possible, not just a name but first
| | 06:11 | name and last name or even
title and suffix if needed.
| | 06:15 | As you are defining your columns,
you're going to define what is the data
| | 06:19 | type for each column. What is it?
| | 06:21 | Is it text data? Or is it numeric?
| | 06:23 | Is it a date or time?
| | 06:25 | Or even binary data or XML?
| | 06:27 | You are going to define how big they should be.
| | 06:30 | If it's a text column for example, will
it represent a few characters of a name?
| | 06:35 | Or will represent the contents
of a thousand-page manuscript?
| | 06:38 | Your database management system wants to
know so it can be efficient about storing it.
| | 06:43 | Is this column required or is it optional?
| | 06:46 | Are there maximum and minimum values for it?
| | 06:49 | Should it match a pattern like an
email address, or phone number, or a credit card number?
| | 06:53 | You see flexibility is usually our
friend but it's not what you're looking
| | 06:58 | for in your database.
| | 06:59 | If you want to store an e-ail address,
you want to know it will always be an
| | 07:04 | email address, not sometimes an e
mail address, and sometimes a date, and
| | 07:08 | sometimes an inspiring quots,
and sometimes an MP3 file.
| | 07:12 | Defining your columns as exactly as
possible means that SQL Server will enforce
| | 07:17 | rules on those columns, your data will
stay valid, and you won't end up with a
| | 07:22 | database full of garbage.
| | 07:24 | Next up, you need to define what keys
you have and that really is how do you get
| | 07:29 | to a particular row.
| | 07:31 | Each row in each table should have
something called a primary key and it's
| | 07:37 | something that uniquely
identifies that individual row.
| | 07:41 | If we have an employee ID,
it should take us to only one employee.
| | 07:46 | If we have a customer ID,
it takes us to only one customer.
| | 07:50 | So we define which column it is
that contains our primary key.
| | 07:55 | Now sometimes the key is already
naturally in the data but often you'll need to
| | 07:59 | generate a unique key and the
database can help you with that.
| | 08:03 | Then you'll define what relationships you need.
| | 08:07 | You are splitting your database up
into tables but many of these tables will
| | 08:11 | need to know about each other.
| | 08:13 | If you're creating an order, for
example, that order would be typically
| | 08:17 | connected to a particular customer and it will
represent the purchase of one or more products.
| | 08:24 | We never want to duplicate data in our database.
| | 08:26 | So we don't want to copy customer
information into order or copy product
| | 08:30 | information into order.
| | 08:32 | We instead describe relationships
between our order table, our customer,
| | 08:36 | and product tables.
| | 08:37 | We shortly see how to define
what those relationships are.
| | 08:40 | They can be one to many, many to
many, one to one, or none at all.
| | 08:45 | You can then use these
relationships to answer all sorts of questions.
| | 08:49 | How many orders has a customer had,
how many products were in a particular order,
| | 08:53 | or going the whole other way,
find a particular product and find all the
| | 08:57 | customers you ever ordered it
by going through the order table.
| | 09:01 | After you've planned out of these
tables, these columns, these keys, and
| | 09:06 | relationships, you can technically go
ahead and build them in SQL Server,
| | 09:10 | start adding some data, and see if it
exposes any issues with your first design,
| | 09:15 | and it typically will.
| | 09:16 | You'll realize something needs to be stored
differently or split out into its own tables.
| | 09:21 | There is something
called database normalization,
| | 09:24 | a set of guidelines and rules you can
go through that will expose issues with
| | 09:29 | your database, and they are super
important but I'm going to talk about those
| | 09:33 | after we've seen how to
apply some of this in SQL Server.
| | Collapse this transcript |
| Creating a SQL Server database| 00:00 | To create a database, we are
really defining two different things.
| | 00:04 | The idea of what our database is,
our tables, our columns, our keys, and our
| | 00:10 | relationships, but to do that, we
first need to create the other piece.
| | 00:14 | the more boring mundane piece.
| | 00:16 | See the real deal is that all of our
tables and all of the data in those tables
| | 00:21 | that we want to store will end up
being stored on files on the hard drive.
| | 00:27 | So we need to say what those files are.
| | 00:29 | We need to say where is this
database going to be created.
| | 00:32 | So I have opened up SQL
Server Management Studio.
| | 00:35 | I'm going to right-click my Databases
folder and say New Database, and a new
| | 00:40 | window will appear that's going to ask
me first off to give this thing a name.
| | 00:45 | I just have to name this database.
| | 00:46 | So I'm going call it TwoTreesTest.
| | 00:50 | I am pretending this is a test
database for the Two Trees organization.
| | 00:54 | I am expecting to end up deleting this.
| | 00:57 | So I'm not really too
bothered about how it's created.
| | 01:00 | I can see that down below it,
| | 01:02 | it says this will have two database
files, something called TwoTreesTest
| | 01:07 | and TwoTreesTest_log.
| | 01:09 | This is the default that you will find
that everything you end up putting in the
| | 01:13 | database will be stored in a primary
data file and a transaction log file.
| | 01:18 | I am going to widen this window
just a little wider so we can read it.
| | 01:23 | It will even show you over here
what the path to these files will be.
| | 01:29 | The interesting stuff, however, is
this part, the Initial Size and the
| | 01:34 | Autogrowth, and probably between the
two the Autogrowth is the big deal.
| | 01:39 | Because if we are storing potentially
thousands or even millions of rows of data
| | 01:44 | in our tables and dozens of tables in
our database, well, they are all going in
| | 01:49 | this one file and it could grow pretty large.
| | 01:51 | We have this Autogrowth section here
and if I click the ellipsis button, it
| | 01:55 | will tell me what the behavior will be.
| | 01:58 | We have Autogrowth enabled.
| | 02:00 | What's going to happen is the file
will start off at 2 MB and if it gets more
| | 02:05 | data than that, it's going to
start growing by 1 MB at a time.
| | 02:09 | Now, if you knew you were inserting a
lot of information, you might say, well
| | 02:14 | I want it to grow by 16 MB or 32 MB at a time.
| | 02:18 | We've also got this idea here
of Unrestricted File Growth.
| | 02:22 | Autogrowth can be changed.
| | 02:23 | You can see the second one here says
this is allowed Autogrowth but it will
| | 02:27 | grow, instead of MB,
| | 02:29 | it will by 10% at a time.
| | 02:31 | So, I am just going to click OK.
| | 02:33 | I am not going to change either of that
except the defaults unless you know differently.
| | 02:38 | You can change your Autogrowth factors later on.
| | 02:41 | If I go over to the left-hand side of this
new database window, we do have a few options.
| | 02:46 | I am not going to change anything here
but here's where you could change to a
| | 02:50 | different collation.
| | 02:51 | Again, the collation is the idea of case
sensitivity and accent sensitivity that
| | 02:56 | the database management system will
use when it's sorting, or ordering, or
| | 03:01 | grouping stuff together.
| | 03:02 | And the third part here is
what's called Filegroups.
| | 03:06 | In this particular course, I'm not
really going to get into Filegroups.
| | 03:10 | You can just ignore them.
| | 03:11 | As you are creating more complex
databases, you will find that these are ways of
| | 03:16 | abstracting the physical files that
make up your database so you don't have to
| | 03:20 | deal with the actual
individual files on the hard drive.
| | 03:23 | We are just using one.
| | 03:25 | That's all I'm going to do
with this particular course.
| | 03:28 | I am going to click OK.
| | 03:31 | And we now should have a database.
| | 03:34 | There we go, TwoTreesTest.
| | 03:36 | I could right-click that and say
Properties and you'll find a whole bunch of
| | 03:41 | other information that you can now
start to manipulate and play with.
| | 03:45 | Again if you're new to SQL Server,
I wouldn't suggest that you do, but you
| | 03:49 | can see there are lot of the options
that we had to answer can be changed in
| | 03:53 | the future as we go on.
| | 03:55 | I am going to just click OK there,
because after all, although we have a
| | 03:59 | database, a database that is devoid
of tables isn't much use to anyone.
| | 04:04 | So we'll go ahead and do that next.
| | Collapse this transcript |
| Creating tables| 00:00 | To create new tables, we
need to drill into the database.
| | 00:04 | We want to add those tables too,
then expand the Tables folder and just
| | 00:09 | right-click it and select New Table.
| | 00:13 | Now you would expect to first say
what the table is called but in fact your
| | 00:17 | cursor is blinking away now at a column name.
| | 00:20 | That's because it's giving you this
temporary title for the table here, Table_1.
| | 00:24 | We will get the chance to change that in
just a minute but I'm going to describe
| | 00:30 | a few columns because
apparently that's what I have to do here.
| | 00:33 | Let's say what I wanted to do was
create a table to hold employee information.
| | 00:38 | So I have got things like employee
first name, employee last name, date joined,
| | 00:43 | birth date, phone, that kind of thing.
| | 00:46 | So I'm going to just create
a few simple columns here.
| | 00:48 | The first would be FirstName.
| | 00:50 | Again I'm splitting this up into
first name and last name rather than just
| | 00:53 | having a whole name.
| | 00:54 | Then when I hit Tab, it gives
me a drop-down of Data Type.
| | 00:59 | This is, again, the type of
data that this is going to hold.
| | 01:03 | If I click the drop-down box,
we have a whole bunch here.
| | 01:06 | We have got geography and geometry, is
it decimal, is it date time, is it a bit?
| | 01:11 | We will talk about quite a lot of
these different data types but what I am
| | 01:14 | going to change it to is nvarchar(50),
and what this means is a variable length
| | 01:22 | text field, variable length character field that
can store up to 50 characters, all Unicode data.
| | 01:28 | I am going to talk more about those
data types in a later movie but this
| | 01:33 | will get us started.
| | 01:35 | The next column is do we allow nulls or not.
| | 01:38 | Can this field be blank?
| | 01:39 | A lot of this is going to be done to
your particular business process but let's
| | 01:43 | say that I imagine everybody
in my company has a first name.
| | 01:47 | I am going to say no, I don't allow nulls.
| | 01:50 | Same with LastName and I
will also make that nvarchar(50).
| | 01:57 | Now I will just go through and
do a couple of different things.
| | 02:00 | Title can be nvarchar(50).
| | 02:02 | HireDate will be a date.
| | 02:08 | In fact, what you will is there are
multiple date types. There's datetime, datetime2,
| | 02:14 | but date is fine for me.
| | 02:16 | BirthDate, that I will also have be a date.
| | 02:20 | Phone, that's going to be an
interesting one because we'll see how that
| | 02:24 | one could be stored.
| | 02:26 | We might want to allow people to
put in dashes, for example, or even
| | 02:31 | letters, who knows.
| | 02:33 | So I am going to change that to nvarchar.
| | 02:36 | It certainly won't be 50 characters long
but I'll give it say 20 or 25. 20 will do.
| | 02:43 | And let's perhaps say we
have an employment status field.
| | 02:46 | I am going to call it Status and
this might just mean they're employed or
| | 02:50 | they're not employed.
| | 02:51 | It's just a yes or no.
| | 02:52 | Sure, you could store that as the
text word Yes or the text word No in a
| | 02:58 | character field but what I am going to
do instead is have a field that is a bit
| | 03:03 | and this basically is a little
flag, the equivalent of a checkbox.
| | 03:07 | It's either true or false.
| | 03:08 | And I would say that that has to be required.
| | 03:12 | So let me imagine for right
now that this might be it.
| | 03:16 | So this is all I'm going to
have for my employee table.
| | 03:20 | I can assure you it's really not
complete yet but let's pretend that it is.
| | 03:24 | What I am going to do is
hit Ctrl+S to save this.
| | 03:27 | That's going to now tell me finally,
enter a name for the table and I'm going
| | 03:32 | to call this Employee.
| | 03:34 | Now there is a bit of a tedious debate
over whether to use plural or singular
| | 03:39 | names for your table.
| | 03:40 | Should this be an employees table that
contains multiple rows each representing
| | 03:45 | an employee or is it employee singular?
| | 03:49 | I've worked in places where there's
been a standard one way or the other.
| | 03:53 | I really don't care.
| | 03:54 | I just think you need to be consistent.
| | 03:56 | If, for example, I'll save this as a
singular table name and if you look at
| | 04:01 | say what Microsoft is doing with AdventureWorks,
you can see that this appears to be singular.
| | 04:07 | It's Product, Location, Culture,
Address, Contact, rather than contacts,
| | 04:12 | products and so on.
| | 04:14 | So I'll just take my lead from
them at this particular moment.
| | 04:18 | And the question is so what, what can we do?
| | 04:21 | Well, now that we've got at least one
table created and I can see that in my Two
| | 04:26 | Trees Test database.
| | 04:27 | It's showing up as dbo.Employee and
this again is using the dbo as the default
| | 04:33 | schema, the default container,
if you will, for our tables.
| | 04:37 | I'm just going to leave most of
our tables as that, which is perfectly
| | 04:40 | acceptable for our case.
| | 04:42 | If you get into more complex database
development, such as something on the size
| | 04:47 | of the AdventureWorks one, you may want
to start grouping your tables together
| | 04:51 | into different schemas.
| | 04:52 | Schema don't really mean anything
other than a way to group and understand
| | 04:57 | objects in your database and
potentially to give them different owners.
| | 05:02 | We are not really going
to use them in this course.
| | 05:05 | So you'll see a lot of dbo for our tables.
| | 05:08 | One thing I could do at this point
is open on my Database Diagrams panel.
| | 05:12 | It's going to prompt me that the
database does not have one or more of the
| | 05:16 | support objects required to use database
diagramming and do you want to create them.
| | 05:20 | Well, yes, I do.
| | 05:21 | And the question is what does that mean?
| | 05:23 | Well, right now nothing.
| | 05:24 | I have got the support files to create them.
| | 05:26 | I haven't made one yet.
| | 05:28 | If I click this, and then right-click,
say New Database Diagram, it's going to
| | 05:33 | throw open the diagram and then pop up
this prompt that says "Well, I'm going to
| | 05:36 | give you the option to add your
existing tables to the diagram."
| | 05:40 | Of course, I only have one table so I might
as well add that. I am going to click Close.
| | 05:46 | Then we can see that we are actually
looking at a diagram of our employee table
| | 05:49 | with all our different columns listed in it.
| | 05:52 | Now one thing you can do if you are so
inclined is you can actually use this
| | 05:56 | database diagram technique to create new tables.
| | 05:59 | I could right-click anywhere in the
blank area and actually say that I want
| | 06:03 | to make a new table.
| | 06:05 | It's not going to ask me to
give a name for this table.
| | 06:08 | I will call it Product.
| | 06:10 | And in this, I can directly starts
typing and I will zoom back into 100%, column
| | 06:16 | names such as a ProductID. Let's call
that the nchar data type of 10 is fine.
| | 06:26 | ProductName, nvarhcar(50). Well, let's
say we have long products. Maybe this
| | 06:32 | will be 200 and so on.
| | 06:34 | Now do bear in mind, you are not
just creating a pretty diagram here.
| | 06:41 | I can see that I have got this little
asterisk after the name of product and
| | 06:44 | what that really means is its
detecting there is a change made to this table
| | 06:49 | definition that has not been saved.
| | 06:52 | But if I were to save it, I am just
hitting Ctrl+S, I am saving the diagram here
| | 06:59 | and that's kind of a little deceptive
sometimes because as I'm saving that,
| | 07:03 | it's actually telling me, "Well the following
tables will be saved to your database,
| | 07:06 | "
do you want to continue? Yes I do.
| | 07:09 | That has created not only a diagram but
whatever I did on the diagram really did
| | 07:15 | affect the database.
| | 07:16 | So I now have dbo.Product.
| | 07:19 | I could continue to edit it over here
in the diagram or I could right-click
| | 07:24 | over here and say Design, which would allow
me to jump into the standard view of editing.
| | 07:31 | As you'll see below, anytime I have one
of these columns selected, I do have a
| | 07:35 | whole host of more
properties that I can change about it.
| | 07:39 | And we will visit some of
these a little later on.
| | 07:41 | But that's the general process of how we
start to add tables to our database and
| | 07:47 | how we start to
manipulate columns in those tables.
| | Collapse this transcript |
| Data types in SQL Server| 00:00 | When you're defining your columns in SQL
Server Management Studio, you will find
| | 00:05 | that the data type for each column
presents you with a rather large set of
| | 00:09 | choices of things that you could
possibly use here and it can be a little
| | 00:13 | intimidating if you are new to SQL
Server or you're not quite sure exactly
| | 00:17 | which one you should be picking.
| | 00:19 | So let's explore what some of those
options are, at least what the most common
| | 00:23 | ones that you want to know about.
| | 00:26 | The data types are split
really in two categories.
| | 00:29 | Is it character or text data? Is it a number?
| | 00:32 | Is it a date?
| | 00:33 | What actually is this?
| | 00:35 | And then we can get a little bit more
specific about each of those pieces.
| | 00:39 | Let's start off with character or text data.
| | 00:42 | Well, even when you are looking at this,
you might be a little annoyed by the
| | 00:46 | fact that you have six character
data types: text, ntext, char, nchar,
| | 00:51 | varchar, and nvarchar.
| | 00:53 | And you might think, what, I am supposed
to make six decisions for every single
| | 00:57 | bit of text that I have?
| | 00:58 | Well, actually it's a little simpler
than that because straight off the bat we
| | 01:02 | can lose two of these.
| | 01:04 | Even though text and ntext will show
up in that drop-down data type box,
| | 01:09 | you should not use them.
| | 01:10 | These are old school and they're
officially deprecated in this version of SQL Server,
| | 01:16 | meaning they'll actually be
removed from a future version.
| | 01:19 | They are only there for backwards compatibility.
| | 01:21 | So we're left with four and we can
choose between these four simply by
| | 01:26 | asking two questions.
| | 01:28 | One, is the data we are going
to store Unicode or non-Unicode?
| | 01:33 | And two, is it a fixed
length or a variable length?
| | 01:37 | If we need Unicode data, that's if you
support or ever expect that you might
| | 01:43 | possibly support international language
character sets, you need to pick Unicode.
| | 01:49 | And those are the two character data
types with the letter n at the front of
| | 01:54 | them, nchar and nvarchar.
| | 01:56 | If you know that your text is only
ever going to be plain old Western
| | 02:00 | European character set, pick non-
Unicode which is char and varchar without
| | 02:05 | the n at the front.
| | 02:06 | The impact is that if you pick Unicode,
because Unicode can hold a much bigger
| | 02:12 | character set, many, many different
international languages, that takes up 2
| | 02:17 | bytes per character in SQL Server.
| | 02:19 | If it's not Unicode, it's a char or varchar,
| | 02:21 | it's 1 byte per character.
| | 02:24 | Now officially, SQL Server 2008 R2 has
something called Unicode compressions.
| | 02:28 | So if you are really worried about
the space, you can look into that.
| | 02:31 | Now, I'm just a fan of using
Unicode by default all the time.
| | 02:35 | So I'll pretty much always
pick the one with the n in front.
| | 02:39 | But the next question that I have
to ask is, is this fixed length or is
| | 02:43 | it variable length?
| | 02:45 | And that's simply allows you to choose.
| | 02:46 | If it's fixed length, it's nchar or char.
| | 02:49 | If it's variable length, it's
the one with the var inside it.
| | 02:53 | And of course, that's going to be up to you.
| | 02:55 | What is it that you're storing?
| | 02:57 | If it's product ID, for example, you
might know that it's always going to be
| | 03:01 | 10 characters long.
| | 03:03 | If it's the contents of a blog entry, well,
that's going to be a bit more variable.
| | 03:08 | So you just answer these two questions,
Unicode or non-Unicode, fixed length or
| | 03:12 | variable length, and that will take you to
the character data type that you need to pick.
| | 03:17 | Once you've chosen that, you need
to ask a couple of other questions.
| | 03:21 | See if it's a fixed length character
data like nchar or char, well, you need to
| | 03:26 | then predict the amount of
space that's going to take.
| | 03:29 | If it's nchar(10), meaning it's a
length of 10, that will take up to 20 bytes
| | 03:35 | and even if you only fill 3
characters of it, it will pad it with spaces.
| | 03:40 | If it's just char of 10, it will be 10 bytes.
| | 03:43 | SQL Server likes to know the size of
it so it can make its own optimization
| | 03:48 | about how much space this is
going to take up in the system.
| | 03:52 | But even if you're picking variable
length character data, you need to know the
| | 03:55 | impact this is going to have.
| | 03:56 | If you specify an nvarchar with a length of 10
characters, well, the length of it is flexible.
| | 04:03 | It depends.
| | 04:04 | The maximum of this will be 20 bytes
but if you're only storing one or two
| | 04:08 | characters, it should only take up
the space for one or two characters.
| | 04:12 | Well, one of the questions
might be how long can this get?
| | 04:15 | Well, if you're working with Unicode,
the maximum length you can have of either
| | 04:20 | an nchar and nvarchar is 4000
and that's 4000 characters.
| | 04:26 | Again, because it will take, by default, 2
bytes per character. That's up to 8000 bytes here.
| | 04:32 | Now because 8000 is allowed, if you
are just working with the non-Unicode
| | 04:36 | version, your maximum is 8000.
| | 04:38 | 8000 for a varchar or a char
is the maximum specified length.
| | 04:44 | Well, you might ask what
happens if it's bigger than that?
| | 04:47 | Or if it ever could be more than 8000 bytes
| | 04:51 | out of 4000 Unicode characters
or 8000 regular ASCII characters?
| | 04:56 | Then you have one other choice.
| | 04:58 | You just use the word max or varcharmax.
| | 05:02 | That allows you up to 2 GB per row per column.
| | 05:08 | So you can store some
pretty large stuff in here.
| | 05:11 | You just can't specify a length any larger
than 4000 for Unicode and 8000 for non-Unicode.
| | 05:16 | Once you get beyond that, it's max.
| | 05:19 | Next up, we have numeric data types.
| | 05:22 | Let's start with the exact numbers.
| | 05:24 | We have the classic int or integers,
storing whole numbers from roughly -2
| | 05:30 | billion to +2 billion.
| | 05:32 | Nothing after the decimal point;
they are always whole numbers.
| | 05:35 | If you don't need that much space, you
can have what's called a smallint, which
| | 05:39 | is roughly -32 thousand to +32 thousand.
| | 05:43 | You've got a tinyint, which is 0 to 255.
| | 05:47 | If you know that you have a very small range.
| | 05:49 | But what if you want more than 2 billion?
| | 05:51 | Well, you do have bigint as well,
which be +/-2^63 so that should hold pretty
| | 05:57 | much whatever you can come up with.
| | 05:59 | We also have money and smallmoney.
| | 06:02 | These are exact numbers even though they
have got numbers after the decimal point.
| | 06:07 | It's a fixed length.
| | 06:09 | Both the money and the smallmoney data
types have four digits after the decimal point.
| | 06:15 | Money can hold up to, as you can see
here, that's a fairly large amount, whereas
| | 06:19 | small money is +/-214,748 and then
four digits after the decimal point.
| | 06:27 | Formerly with your exact numbers,
you also have decimal which is a fixed
| | 06:32 | precision and scale.
| | 06:33 | I will explain what that means in a second.
| | 06:35 | Now you'll also see something called numeric.
| | 06:37 | Decimal and numeric are exactly the same.
| | 06:40 | Again, the two terms are here for
kind of backwards compatibility.
| | 06:44 | I pick decimal all the time.
| | 06:46 | It doesn't really matter.
| | 06:47 | Just pick one and stick with it.
| | 06:48 | What precision and scale means is as you
define two numbers. The p represents the precision,
| | 06:54 | the total amount of digits
being stored in this column.
| | 06:59 | And ,s for the scale is the amount
of digits after the decimal point.
| | 07:04 | So for example, creating decimal with
9,2 means there is nine digits in total
| | 07:11 | and two after the decimal point.
| | 07:13 | So the maximum value would be seven 9s
before the point and two 9s afterwards.
| | 07:18 | So that's decimal and numeric.
| | 07:21 | You do have approximate
or floating point numbers.
| | 07:24 | You have got float where you say
exactly what the floating point should be and
| | 07:29 | then you have something called real.
| | 07:31 | I would suggest that if you're getting
into the floating point numbers and you
| | 07:34 | need to be aware of those, we will
look them up on Books Online for more
| | 07:38 | specific information.
| | 07:39 | I will show that in just a second.
| | 07:41 | You do have several date and time data types.
| | 07:44 | We have one that just holds a date.
| | 07:47 | We have one that just holds a time.
| | 07:49 | There is one that's called datetime.
| | 07:52 | That's been around for quite a while.
It holds not only the date but the time as well.
| | 07:56 | Although SQL Server has something
called datetime2, and that is the one
| | 08:01 | that's recommended.
| | 08:02 | Even if it looks kind of an ugly data
type, that's the one you should use if you
| | 08:06 | need to store both dates and times
because it to be more accurate, down to about
| | 08:10 | 100 nanoseconds, and it doesn't
take as much space as datetime does.
| | 08:15 | If you're working, however, with
international time zones and you need to store
| | 08:19 | your time offset from Universal Time
Code, there is also the datetimeoffset,
| | 08:25 | which takes that into account.
| | 08:27 | So you could look at that one and if
you need on the other side a bit less
| | 08:30 | precision, you can also look at smalldatetime.
| | 08:34 | But I'd say the main ones here should
be reasonably obvious, which is you just
| | 08:38 | need a date, use date.
| | 08:39 | You just need a time, use time.
| | 08:41 | You need both, use datetime2.
| | 08:44 | As you start to work with your data
types, you will realize that they are not
| | 08:47 | trying to give you several
possible options for the same need.
| | 08:51 | They really all do have
pretty specific needs to them.
| | 08:53 | There are several other data types.
| | 08:56 | We have binary and varbinary.
| | 08:59 | As you might guess from looking the
char and varchar, this really means a
| | 09:03 | fixed length and a variable length binary
field for storing things like file attachments.
| | 09:08 | That can grow as big as 2 GB, which you
will find is the fairly magic number for
| | 09:13 | large column sizes in SQL Server.
| | 09:15 | There is bit which is basically a
field that can be true or false.
| | 09:20 | You have got XML. You can store raw
XML data, even though it is text, and you
| | 09:25 | can think surely I could just put it
in a text field. You could, but the XML
| | 09:29 | column has the ability for SQL Server to
understand the XML and even parse the XML if needed.
| | 09:35 | There is a unique identifier, which
would create a 16 digit unique ID, what's
| | 09:40 | often referred to as a GUID, a
Globally Unique Identifier, and you can even
| | 09:45 | define your own data types, though we
are not going to do this in this course.
| | 09:50 | There is a couple of other
rare ones that rounded up.
| | 09:53 | If you start looking through the
drop-down box, you will see things
| | 09:55 | like geometry and geography for
ellipses and paths and even for
| | 10:00 | latitude and longitude.
| | 10:02 | And there is a few other deprecated ones
like timestamp and image not to be used.
| | 10:07 | Here is the real deal. Until this all
becomes second nature, what you want to be
| | 10:12 | doing is making sure that you're using
SQL Server Books Online and use that as
| | 10:18 | your little quick reference for these.
| | 10:20 | Let me show you the easiest
way to start working with that.
| | 10:23 | If I open up my SQL Server Books Online,
what I'm going to do is I want to find
| | 10:29 | my data type definitions.
| | 10:30 | Well, I can just type in
the word in my index here.
| | 10:33 | So I'm looking in my index, the
second tab, and I am saying data types.
| | 10:37 | Now I select data types and
I have all sorts of things.
| | 10:40 | It says data types here and blanks
and currency and all sorts of stuff but
| | 10:45 | unfortunately I am picking the wrong
ones, because SQL Server Books Online is
| | 10:49 | showing me a bit too much information
because I got data types in PowerPivot for
| | 10:53 | Excel and data types in CLR
integration and data types ODBC.
| | 10:58 | What I'm going to do is filter this
down a little bit. Tather than have the
| | 11:03 | unfiltered showing me every possibility,
| | 11:06 | I'm going to say to say give me the SQL
Server 2008 Database Engine and let me
| | 11:10 | try that data types again.
| | 11:13 | Well we have a few still here.
| | 11:14 | Data types CLR, data
types ODBC, data types OLE DB.
| | 11:19 | Data types SQL Server is what I'm
looking for and if you are thinking, well,
| | 11:23 | how do I know for sure?
| | 11:24 | Well, unless, you know that you're
going for OLE DB or SMO or SQL Server
| | 11:28 | application, this one is a pretty good bet.
| | 11:31 | And if I highlight that, I can see that it
starts talking about the related data types.
| | 11:36 | So I will come down in this page.
| | 11:37 | Let me delete that a little bit.
| | 11:40 | We've got the data type categories,
we have got the bigints, and bits,
| | 11:43 | and decimals, and ints.
| | 11:44 | I could jump into any of these pieces
such as say smallmoney and it will tell me
| | 11:50 | exactly what that range is for smallmoney.
| | 11:54 | So this looks like a pretty useful
page to have for my data types as I am
| | 11:58 | getting used to them.
| | 11:59 | And in fact what I'm going to do is go
up here onto my menu bar and just click
| | 12:04 | Add to Help Favorites, hit that button,
and what that means is that from now on
| | 12:10 | if I want to just go ahead and remind
myself of the data types, I jump to my
| | 12:13 | Help Favorites tab in Books Online.
| | 12:16 | I hit that and it will allow me to
drop through all the different data types.
| | 12:20 | The other ones, the binaries, the
Unicode, character, date and time, all of it.
| | Collapse this transcript |
| Defining keys| 00:00 | One thing you should do on all of
your tables, at least as a general rule, is
| | 00:04 | defined what's called a primary key.
This is a way that's going to identify
| | 00:09 | how do we get to an individual role.
One value that would always take us to
| | 00:14 | just one row in that table.
| | 00:16 | And your primary key can be any of the
columns that you actually have defined if
| | 00:22 | that makes sense. Sometimes
it does, sometimes it doesn't.
| | 00:26 | If I look at my Product Table, for
example I have ProductID, ProductName,
| | 00:31 | UnitPrice and UnitsInStock, and let's
say that my business process was such
| | 00:36 | that ProductIDs were decided around a
conference table and manually entered into the database.
| | 00:42 | Well I could say then
ProductID should be my primary key.
| | 00:47 | One ProductID should always identify
a row in this table in this database.
| | 00:52 | Well I have it open in Design. I can right-
click the column and just say Set primary key.
| | 00:58 | Notice what happens to the
Allow Nulls column when I do this.
| | 01:02 | It's going to turn it off because when
you think about it, it doesn't make sense.
| | 01:05 | You can't really have a unique
primary key if you're allowing that value to
| | 01:10 | not be entered at all.
| | 01:12 | So I'm going to hit that and say cool, I'm done.
| | 01:14 | A ProductID will be unique and it will
be manually entered in for each product.
| | 01:20 | I'm going to now try and save my changes
and the problem that I run into, it will
| | 01:25 | say "Saving changes is not permitted."
| | 01:27 | The changes that I've made require the
following table to be dropped and re-created.
| | 01:32 | Now this is one of the problems here,
one of the issues. It's why I say that you want
| | 01:37 | to figure your database tables out
before you build them, because you don't want
| | 01:42 | to have to go back in and
edit them multiple times.
| | 01:45 | Many of the changes that you might
think are just a small change, according to
| | 01:49 | the database are fairly big ones, and in
fact SQL Server Management Studio is not
| | 01:54 | letting me save that change. The
change it cares about was not actually the
| | 01:58 | primary key. It was me saying that
Nulls were allowed and now they're not.
| | 02:03 | Even though I have no data stored in
this table yet, it's still considering that
| | 02:09 | a really significant change so
it's stopping me from doing it.
| | 02:12 | Well I can tell SQL Server Management
Studio to lighten up a little bit. I am
| | 02:17 | going to go to my Tools > Options and
find my Designers section where I have an
| | 02:25 | option here that says Prevent saving
changes that require table re-creation.
| | 02:29 | I am going to uncheck that, so I am
saying yes, I can save a substantial change
| | 02:34 | that requires the table to be re-created.
| | 02:36 | You want to be careful with that one
because obviously un-checking that allows
| | 02:41 | you to make some fairly significant
changes that you might not want to.
| | 02:45 | So I'm going to now try that, save again,
and we are good. W now have a primary
| | 02:50 | key defined on that column.
| | 02:52 | Well what about the other table?
| | 02:55 | We have dbo.Employee here.
| | 02:56 | I am going to right-click and select Design.
| | 02:59 | I can scan the columns here and see
that there is no primary key because you do
| | 03:03 | get it just showing up there if you
need to. And I can look at that and think,
| | 03:07 | well, is the one that is
obvious? And there isn't.
| | 03:12 | You could make a case that says well,
perhaps first name and last name together
| | 03:16 | could be a primary key, and in
fact you can do something like that.
| | 03:20 | It's what's called a compound key,
but still in a big company there is no
| | 03:24 | guarantee that you wouldn't get two
people with the same first and last name.
| | 03:28 | So here would be a good idea for just
creating one. I am going to add an EmployeeID,
| | 03:33 | and this one I'm going to say
is just going to be an integer.
| | 03:39 | It's just going to be a number.
| | 03:41 | If we say that every employee has to
have one, I'm going to uncheck this and say
| | 03:45 | no, don't allow Nulls. Don't
allow that missing value there.
| | 03:50 | And I could just right-click and name
this as the primary key and that would work.
| | 03:54 | However, it does mean that right now I
would have to manually type this in or
| | 03:59 | have an application that creates it.
| | 04:01 | What a nice thing would be is can we
get SQL Server to help us generate that
| | 04:07 | EmployeeID every time a new employee is added.
| | 04:10 | And not surprisingly, and I know where
you think I'm going with this, you can.
| | 04:14 | If I keep this column highlighted so
EmployeeID is highlighted and then down in
| | 04:19 | the Properties for the column we have a
section called Identity Specification.
| | 04:24 | This is a little switch that we can flip
and it says Is Identity from No to Yes.
| | 04:30 | And then what it changes and it says
you've got an Identity Seed and Identity
| | 04:34 | Increment, which is basically what number do we
start with and how much do we go up each time.
| | 04:40 | So the default is we start at number 1
and add 1 to it every time around, but
| | 04:44 | I can decide to start it any number. Let's
start at 500 and go up by 3 each time around.
| | 04:52 | I'm going to now just save these changes
and we now have a primary key defined there.
| | 04:56 | Well it'd be nice to prove it.
I'll go ahead and do that. I'm going to
| | 05:01 | right-click the Employee table and say
Edit the Top 200 Rows. That switches me
| | 05:06 | into this editing view.
| | 05:07 | I don't have any data yet, so
let's put in our first piece.
| | 05:11 | So the FirstName I'll say that
will be Joe, LastName as West.
| | 05:15 | You'll notice that every time I am
entering something in I get the exclamation mark
| | 05:19 | and it's telling me that the cell
has changed but the change has not been
| | 05:22 | committed to the database.
The original data was NULL.
| | 05:25 | I'll just continue on. That sounds all right.
| | 05:27 | I'll see the Title is a Manager, and the
HireDate was the first of February in 2005.
| | 05:34 | BirthDate was the first of January of 1970.
| | 05:38 | Phone number was just a text value.
I could put pretty much anything in here.
| | 05:44 | The Status was the bit data type and
that really means just expecting a Boolean
| | 05:50 | value, either true or false.
| | 05:52 | A lot of developers wonder should they
put a 1 or a 0. Well you can just write
| | 05:56 | the word true in there.
| | 05:58 | You might think well what happens if I
didn't, if I just typed in the number 99?
| | 06:03 | Well as soon as I try and tab off it,
it's going to say, "I'm sorry this change
| | 06:07 | value is not recognized as valid."
You'd get this on any of these fields.
| | 06:11 | The string was not
recognized as a valid Boolean.
| | 06:14 | Okay, that makes sense.
| | 06:15 | I'll click OK and I'll type true, which
should be a valid Boolean, and it allow me to tab off.
| | 06:23 | Now you notice here I'm now on EmployeeID.
| | 06:27 | This is the one that should be our
identity and should be automatically created.
| | 06:32 | So I am not going to type anything in here.
| | 06:34 | I am just going to tab, which
would make me go to the next row.
| | 06:37 | And when I do that we take off that
first row, and by leaving the row all these
| | 06:42 | changes should now be committed to the
database, and if I move to the right a
| | 06:45 | little bit I can see that I am
actually Employee 500, that it's been entered
| | 06:50 | correctly, and if I would to enter in
more information, it will be 503, 506, 509,
| | 06:53 | 512 because we said that the Identity
Increment was a factor of 3 for that.
| | 07:04 | And the last thing I'm going to actually
do here is change this EmployeeID and I
| | 07:09 | want to show it first and I can
just do that by rearranging my column.
| | 07:13 | I am going to grab it and just drag
it up to the top and save my changes.
| | 07:17 | Just going to close these existing
windows down right now and reopen the
| | 07:22 | Employee table and I'll just
say select the Top 1000 Rows.
| | 07:26 | And what'll happen is it's bringing
back that information where EmployeeID 500,
| | 07:31 | all the data that I just entered in,
and it does actually show me the command
| | 07:35 | that is really being executed right
now, which is just a Select statement.
| | 07:39 | We'll get into those a lot later.
| | 07:42 | And you'll notice that I do have a
Keys folder and I can expand it and it
| | 07:46 | can show me PK_Employee, which means that
the primary key for employee has been defined.
| | 07:53 | Now there are different kinds of keys
that you can create. You can also create
| | 07:56 | what are called secondary keys,
anytime you know you're going to be using a
| | 07:59 | particular field to try and access
a part of the database, but we'll talk
| | 08:04 | about those a little later on. Primary
keys are what we need to start dealing with first.
| | Collapse this transcript |
| Creating default values| 00:00 | When you're designing databases, it's
a good idea to apply as many rules or
| | 00:05 | constraints to your data as possible.
| | 00:08 | And one of the classic ways to do this is by
setting up default values for your columns.
| | 00:12 | The idea of this of course is simple.
| | 00:14 | We have a table such as an OrderItem table
made of product IDs and quantities and unit prices.
| | 00:21 | Whereas a lot of this information is
very different from row to row, Quantity
| | 00:26 | for example might typically be the
number 1. Occasionally it might be 2, but
| | 00:31 | nine times out of ten or nineteen
times out of twenty or ninety-nine out of a
| | 00:35 | hundred it will be the number 1.
| | 00:36 | So we will make this the default value
for that column, so it doesn't always
| | 00:41 | have to be entered, either by
the application or by the user.
| | 00:45 | I'm going to go into my OrderItem table in
SQL Server Management Studio and select Design.
| | 00:51 | Applying a default value is very simple.
| | 00:54 | Find the column that you're looking
for, in this case Quantity, and then
| | 00:57 | down here in the Column Property section,
you'll find a section that says Default Value.
| | 01:02 | We hit the number 1.
| | 01:04 | That's counted as a change
to the database definition.
| | 01:08 | So you'll see that we have the asterisk up here.
| | 01:10 | I am going to hit Save to
save those changes to the table.
| | 01:14 | Close that down and now let's test it.
| | 01:16 | I am going to right-click and say Edit Top 200
Rows and I am going to enter in a new order item.
| | 01:22 | I am, of course, just going to do this manually.
| | 01:23 | Now, right now I have OrderItemID added
as an identity column for a primary key,
| | 01:31 | which means it will generate that too.
| | 01:32 | Hopefully, the number 19 or the number 20.
| | 01:34 | I am going to put in ProductID-123.
| | 01:38 | I'm going to Tab to skip over the
Quantity and I am going to say the
| | 01:42 | UnitPrice is 54.98.
| | 01:43 | Then I am going to tab off on to next row.
| | 01:47 | Now you will quite often see this
message where the row itself kind of shows up
| | 01:52 | in a pale color and the exclamation
mark, if I tooltip over it, it will say,
| | 01:57 | "This row was successfully
committed to the database.
| | 02:00 | However, there was an issue with
retrieving the data back after the commit,
| | 02:04 | because the displayed data is read-only."
| | 02:07 | But it almost certainly worked.
| | 02:09 | So I'm going to just come out of this
and go back in and just select the Top
| | 02:15 | 1000 Rows again, just to double check that.
| | 02:18 | I can see that yes, at position 19
we have ProductID 123 with a default
| | 02:23 | value of 1 at 54.98.
| | 02:25 | Now bear in mind though that the only
real point of working with the default value
| | 02:31 | is it will have an effect
when a row is being added to the table.
| | 02:36 | If I was editing rows and I just decided,
for example, to leave a blank value,
| | 02:42 | it's not going to dump in a new
default value for a row that already exists.
| | 02:46 | So I will hit Escape there.
| | 02:48 | The only place where default values
can have an effect after the fact is when
| | 02:53 | we're adding a new column.
| | 02:55 | Let's say going back into OrderItem.
I am going top hit Design and I am going to
| | 03:00 | add a new column here
that I will call DateCreated.
| | 03:04 | I want this to always have a
date or indeed a datetime.
| | 03:07 | I will use datetime2 and uncheck Allow Nulls.
| | 03:11 | I always want a value in this
column of when that row was created.
| | 03:16 | When I make that change, if I'm trying
to save my changes back, I'm going to get
| | 03:20 | this Post-Save Notification pop-up.
| | 03:23 | It was unable to modify the table.
| | 03:25 | It gives me a long-winded
explanation that really comes down to
| | 03:30 | you can't create a column and say it's
not allowed to have null values and then
| | 03:35 | add it to lots of
existing rows with null values.
| | 03:37 | Well, one of the ways we can use the
default value here is I'm going to say the
| | 03:43 | default value is getdate.
| | 03:46 | This is the default value of DateCreated.
| | 03:49 | If I now save this, what will happen is
it's going to use that rule for any new row.
| | 03:56 | Because we've also used it for pushing a
change to this table, it's going to use
| | 04:01 | that value for the old rows as well.
| | 04:03 | Just to close down my existing information,
I will then right-click and reopen it up.
| | 04:09 | And I can actually see that the DateCreated
has been filled out for all those old rows.
| | 04:15 | From this point forward if I add a
new row, ProductID 456, I will skip over
| | 04:20 | Quantity because that
should give me a default value.
| | 04:22 | I will do a UnitPrice of 98 and
I will skip over the DateCreated.
| | 04:28 | If we then close that down and just
reopen it, I'm going to see that I have
| | 04:34 | both the default value of 1 and
the DateCreated of just a moment ago.
| | Collapse this transcript |
| Creating check constraints| 00:00 | Another way that we can increase the
reliability, the integrity of our data, is
| | 00:05 | to apply what are called check constraints.
| | 00:07 | A check constraint is a simple idea.
| | 00:09 | If we have some data such as Quantity
where we can look at that and understand
| | 00:14 | this really unacceptable
range for this to be in,
| | 00:17 | even though this column is actually
being defined as an int, we don't need all
| | 00:21 | that an int can give us.
| | 00:22 | Because an integer can support from
roughly -2 billion to plus 2 billion,
| | 00:27 | it is quite unlikely that someone will
order -2 billion quantities of a unit.
| | 00:33 | So let's say I want to enforce some
rules on this column that says Quantity must
| | 00:37 | be greater than 0 and less than 51 say.
| | 00:40 | Well, I do this by applying a
check constraint to the table.
| | 00:45 | I am going to right-click
anywhere in the Designer area.
| | 00:47 | It really doesn't matter. And I have
a section called Check Constraints.
| | 00:51 | Right now it's saying there are
no check constraints on this table.
| | 00:54 | I am going to add one.
| | 00:55 | It's typically called CK_ the name of the table.
| | 00:59 | What we need to type in is an expression.
| | 01:02 | In this case, it's quite simple.
Quantity > 0 AND Quantity < 51. Close.
| | 01:17 | We now have a check
constraint defined on the table.
| | 01:19 | It is considered a table change.
| | 01:20 | So I see the asterisk.
| | 01:22 | I have got to save that. Close this down.
| | 01:26 | Now, when I go into that table and I
say change one of the existing rows, 50 is
| | 01:33 | accepted as a change and
I can click off that row.
| | 01:36 | 51 will actually throw an error here.
| | 01:40 | The update statement
conflicted with the check constraint.
| | 01:44 | I also can't put a 0 Quantity and
I can't put a negative Quantity.
| | 01:52 | Check constraints can easily be removed.
| | 01:54 | I need to escape out of here
before it tries to apply those changes.
| | 01:58 | I could go back into the Design view,
again right-clicking anywhere in the
| | 02:02 | Designer, because the check
constraints are defined for the table.
| | 02:05 | They're not defined specifically on a column.
| | 02:08 | It's just this expression.
| | 02:09 | You could have one check
constraint that has multiple columns in it.
| | 02:13 | Quantity above a certain amount
if ProductID in a particular range.
| | 02:17 | But if we wanted to, we could just
come in here and hit the Delete button to
| | 02:21 | remove the check constraint from
the table, but I'm going to keep it.
| | Collapse this transcript |
| Creating unique constraints| 00:00 | Another kind of constraint you can work
with is what's called a unique constraint.
| | 00:04 | Now in fact, we already have one
of these on most of our tables.
| | 00:08 | If you have a primary key, you have
a unique constraint. That primary key
| | 00:12 | cannot be duplicated.
| | 00:14 | In this case, there can only be
one ProductID with 1008 in it.
| | 00:20 | But occasionally, you will want to
define another column as being a unique
| | 00:25 | constraint, that the value cannot occur
more than once in the entirety of the
| | 00:31 | column in that table.
| | 00:32 | Now right now none of these
columns should be made unique.
| | 00:36 | Certainly not UnitsInStock and
certainly not Color. That repeats quite a lot.
| | 00:41 | We might have ProductName made unique,
but not the way that we work with it.
| | 00:44 | For example, I have a Road-650 58 in
Black and I have a Road-650 58 product in
| | 00:52 | Red and a Road-650 58 product in Green.
| | 00:55 | I can't make ProductName unique.
| | 00:57 | What would be interesting, however,
is if I could force uniqueness on a
| | 01:01 | combination of the two.
| | 01:02 | What that allows me to do is make sure
that they aren't accidentally two rows
| | 01:07 | that represent the same product color
combination, that the database would not
| | 01:11 | allow me to enter that.
| | 01:13 | Everything we do in our database design
should all be about enforcing valid data.
| | 01:18 | So how do we do this?
| | 01:19 | Well, not surprisingly, it's going to
be in the Design view of the product.
| | 01:23 | I'm going to right-click
that table and jump into Design.
| | 01:26 | Now you won't find any on the
unique options in your Column Properties.
| | 01:31 | What you have to do is right-click in
the blank designer area and while we had
| | 01:36 | things like Check Constraints there,
you don't see a unique constraint.
| | 01:39 | The area that we are
interested in is this one, Indexes/Keys.
| | 01:44 | If I select that, we should
find we already have one.
| | 01:47 | Here's my index for the primary key.
| | 01:49 | It's saying this is the ProductID.
| | 01:52 | It is unique, yes, and it is the primary key.
| | 01:55 | We don't want to mess with that.
| | 01:56 | What I want to do is add another one.
| | 01:59 | It's not a primary key.
| | 02:00 | It's what's called a unique key.
| | 02:02 | I am going to click Add and we get this
IX_Product, because this dialog box that
| | 02:08 | I'm looking at is how we
add new indexes to our table.
| | 02:11 | How we add new ways of looking things up
quicker when we have large amounts of data.
| | 02:15 | Now, we are going to be talking
about indexes a little later on.
| | 02:18 | So don't worry too much about all the
options here like Create As Clustered
| | 02:22 | and all that stuff.
| | 02:23 | I actually want to change this.
| | 02:25 | I click the Add button and I want
to say no, this is not an index.
| | 02:28 | This is a unique key.
| | 02:30 | It changes the Is Unique to Yes.
| | 02:32 | We do have to pick the
columns that we are interested in.
| | 02:35 | It's defaulted to ProductID,
but ProductID is already unique.
| | 02:39 | I am going to click the little ellipsis button.
| | 02:41 | I am going to say what I actually
want is for my column to be ProductName.
| | 02:46 | And because it's going to create its
own little set of product names to make
| | 02:52 | sure that there won't be a
duplicate one, we can choose whether that
| | 02:55 | Ascending or Descending.
| | 02:56 | It doesn't matter here.
| | 02:57 | However, I don't want it to be just ProductName.
| | 02:59 | That wouldn't work.
| | 03:00 | In fact, I couldn't enforce
that rule on my existing table.
| | 03:03 | It's going to be ProductName and I am going to
click beneath it and say Color. That's fine.
| | 03:08 | Color Ascending,
ProductName Ascending. I click OK.
| | 03:11 | It's now telling me that the combination
is both of them, ProductName and Color.
| | 03:16 | I can ignore the rest of the
stuff and just click Close.
| | 03:20 | This still is considered an
unsafe change to my table.
| | 03:23 | So I'm going to save the change now.
| | 03:24 | I am going to go back into editing
that and I'm going to add a new product.
| | 03:32 | Let's say in this case it's going to
be Road-660 60 in Black and there's 3
| | 03:40 | UnitsInStock and that works just fine.
| | 03:43 | Now let's say we add Road-650 58 in Green.
| | 03:50 | Now this one already exists.
| | 03:52 | So when I tab off, I should get a problem.
| | 03:54 | "I'm sorry, there was a Violation of UNIQUE
KEY constraint, can't insert duplicate key.
| | 03:58 | The statement has been terminated."
| | 04:01 | Again, if you are a developer, a lot
of the times developers think, "Well,
| | 04:04 | surely, I could just take
care of that in my application.
| | 04:07 | I'll make a check beforehand."
| | 04:09 | But the great thing about doing it here
is we are saving those rules as business
| | 04:13 | rules in the database.
| | 04:14 | We are making sure that we'll never
get that duplicate data entered in rather
| | 04:19 | than just trusting an application
or a user to make that check for us.
| | 04:23 | I won't be able to save that.
| | 04:25 | So I can either add it as a new color,
Blue, which would allow me to save that row,
| | 04:31 | or I could have deleted that row.
| | Collapse this transcript |
| Introduction to relationships and foreign keys| 00:00 | A vital part of designing any database
is the ability to create relationships
| | 00:05 | between your tables.
Let's go through an example.
| | 00:08 | We have a simple product table, dbo.Product, here.
| | 00:12 | It has its own primary key, the
ProductID, which is automatically generating a
| | 00:18 | unique number for each product
as it's entered into the database.
| | 00:21 | And one of the benefits of having that
primary key is we can use it elsewhere.
| | 00:26 | So we have a different table, this
time called OrderItem, helping us
| | 00:30 | construct our orders.
| | 00:32 | Itself it has its own primary key with
its own automatically incremented value,
| | 00:37 | but what's a bit more interesting is
it has another column here of ProductID.
| | 00:43 | Now ProductID in OrderItem should
reference the ProductID in the Product table,
| | 00:49 | but whereas in the Product table it has
to be unique, in OrderItem it doesn't.
| | 00:53 | We could have for example the ProductID
1001 three times in OrderItems, or four
| | 01:00 | times, or a dozen, all
referencing the same product.
| | 01:03 | We could have 1010 pointing to our
1010 product. We could have 1002.
| | 01:10 | This is the relationship that
we're talking about between our tables.
| | 01:15 | In the Product table, ProductID is
referred to as the primary key. It is unique.
| | 01:20 | In the OrderItem table, ProductID
is referred to as a foreign key.
| | 01:25 | It's a key to some other table,
allowing us to join our information together.
| | 01:30 | The benefit of having this relationship
described is we can go either way we can
| | 01:34 | go from the OrderItem and go and get
product details, or we can go from the
| | 01:39 | product and find how many order
items have been created for that product.
| | 01:43 | And when you have a relationship
like this it's what's defined as a
| | 01:47 | one-to-many relationship.
| | 01:50 | For every one product we
can have many order items.
| | 01:53 | Now you'll end up creating dozens or
potentially hundreds of relationships when
| | 01:59 | you design your databases.
| | 02:00 | If you're using SQL Server Management
Studio to show a database diagram you'll
| | 02:05 | actually see that
relationship defined between the tables.
| | 02:09 | And as you create more-and-more complex
databases, you'll find that you're going
| | 02:12 | to have relationships between most of them.
| | 02:15 | What I'm looking at here is just a
zoomed out diagram of the AdventureWorks
| | 02:18 | database and that's not even
a particularly large database.
| | 02:21 | It's very, very common to have
relationships between your tables.
| | 02:26 | And there really are two main kinds
of relationships that we care about.
| | 02:29 | The first one, the most common,
what we just explored, the idea of a
| | 02:33 | one-to-many relationship.
| | 02:35 | So one customer many orders, one
category has many products in it, one
| | 02:41 | department has many employees.
| | 02:43 | Now bare in mind when you describe a one-
to-many relationship you don't actually
| | 02:48 | have to have many. Any one
customer might only place one order.
| | 02:53 | Might even place zero orders, but
one customer can have many orders,
| | 02:58 | one category can have many products,
one department can have many employees.
| | 03:03 | But the important point is here that
at least according to your own business
| | 03:07 | rules the opposite of these
statements is not true, that in your business an
| | 03:12 | order has one customer.
| | 03:14 | You don't say an order can
have many customers. It can't.
| | 03:17 | An employee has one department.
| | 03:19 | A product has one category.
| | 03:21 | So you can view this either from the top-
down or the bottom-up, whatever makes sense.
| | 03:25 | Now as this is the most common thing
that you're going to see when you're
| | 03:29 | looking at a diagram in SQL Server
Management Studio, you'll see the relationship
| | 03:33 | defined like this with this icon.
The key represents the one and the infinity
| | 03:38 | sign represents the many.
| | 03:40 | So when you're looking at this diagram
it doesn't matter whether the tables are
| | 03:43 | shown on top or underneath.
What's important is where the key is.
| | 03:48 | The next kind of relationship we can
have is called a many-to-many relationship.
| | 03:53 | It's not as common as one-to-
many, but it's still quite common.
| | 03:56 | Now you often have to think about this
one, because these business situations
| | 04:01 | can often feel like one-to-many.
| | 04:02 | At first, let's say we have an author
table with a list of a few authors inside it
| | 04:10 | and their names, and some kind of
key and identity for them, and we also
| | 04:14 | have a title table with the list of book titles.
| | 04:18 | Well at first glance what we might
say is okay, this is a one-to-many
| | 04:22 | relationship. We could take the author
number 74, Jordan Winters, and say that we
| | 04:27 | want to represent that author has written
both book one, DB Design, and book 3, SQL Server.
| | 04:34 | And we can say that Fred Summers,
author number 75, wrote book 2 on SharePoint.
| | 04:39 | And if this was a classic one-to-many
relationship, one author, one or more
| | 04:43 | titles, we could add a new column to the
title table. This would be an author ID column.
| | 04:49 | It would be a foreign key to the author table.
| | 04:52 | But here is the issue. What happens if
in a day, or a week, or a month we say
| | 04:58 | we'll actually the SQL Server
book was written by two authors?
| | 05:03 | Well the way that we have it right now,
we have that author column can only store one,
| | 05:07 | storing a foreign key to author ID 74.
| | 05:10 | And this is what we mean by a many-to-
many relationship. One author can have
| | 05:15 | many titles, one title can have many authors.
| | 05:18 | Now the way some people try and model
this is they'll add a new column to the
| | 05:23 | title table. They'll put in author
ID 2 and they'll have that be 76 and
| | 05:28 | pointed to John Marr.
| | 05:29 | However, adding new columns to your
tables, and particularly these kind. what are
| | 05:35 | called repeating groups or repeating
columns. is a really, really bad idea and
| | 05:40 | it's a definite no-no in database design.
| | 05:42 | So we'll get rid of that idea. Well
some other people think, "Well I'm going to
| | 05:46 | cheat a little bit and I'll just do
something quick and dirty and I'll just
| | 05:50 | slide in little set of
comma separated values there."
| | 05:53 | So that the author column can point to
both 74 and 76, but that's just a cheat
| | 05:59 | and like adding a new column
this is not suggested either.
| | 06:04 | In fact we're going to solve this problem
by getting rid of the author column entirely.
| | 06:10 | So we go back to two completely
detached tables and what we do to fix this is
| | 06:15 | we add another table.
| | 06:18 | We add what's often referred to
as a junction or a linking table.
| | 06:21 | Now the only reason for this table to
exist is to join author and title together.
| | 06:27 | So in fact the name of this title
by convention would be authortitle.
| | 06:30 | It could also be titleauthor.
| | 06:32 | It doesn't really matter which way round
it goes, because what we're going to do
| | 06:36 | is setup two one-to-many relationships.
| | 06:39 | In fact, you cannot, in SQL Server
or in any other relational database,
| | 06:44 | you cannot express a many-to-many
relationship directly. You can only do two
| | 06:50 | one-to-many relationships.
| | 06:51 | So what we'll do is we'll define a one-to-
many relationship from the author to authortitle.
| | 06:57 | So one author with ID 74 can exist
in the AuthorID foreign key column in
| | 07:03 | authortitle twice, or three
times, or five times, or a dozen.
| | 07:07 | Using that we can go from author to
authortitle, find a TitleID ,and map it up
| | 07:13 | to the title table.
| | 07:14 | And we can also go the other way.
| | 07:17 | We can take the identity of a title
like number 3, take it back to the
| | 07:21 | authortitle table to two rows there so
one-to-many relationship back the way,
| | 07:25 | grab the AuthorID, and follow
that back up to the author table.
| | 07:30 | So we are expressing now a
many-to-many relationship.
| | 07:34 | And if you go looking in say some of
the sampled database, whether it's the
| | 07:38 | larger ones like AdventureWorks or
even the small ones like AdventureWorksLT,
| | 07:43 | anytime you see a table name that
seems to join the name of two other tables--
| | 07:48 | So we have ProductModel,
ProductDescription, and then
| | 07:52 | ProductModelProductDescription.
| | 07:53 | You can make the assumption that the
one with a long name is simply there to
| | 07:57 | join ProductModel and
ProductDescription together.
| | 08:00 | In fact, if you want to confirm that what
we could do is make a new database diagram.
| | 08:06 | I'm going to add just those three
tables that I suspect that from,
| | 08:10 | ProductDescription, I'll hold
down Ctrl and select ProductModel and
| | 08:13 | ProductModelProductDescription,
click Add, close this,
| | 08:18 | and what I can actually see here is
my many-to-many being rendered out.
| | 08:23 | We go from ProductModel is the one, to
the many, a ProductModelProductDescription.
| | 08:27 | ProductDescription is the one to the many.
| | 08:30 | The only reason for the existence of this
table is to join the other two together.
| | 08:35 | In a large database you're going
to end up with a lot of one-to-many
| | 08:39 | relationships between your tables and
a few of those will really be used to
| | 08:44 | create a many-to-many relationship.
| | 08:46 | Officially, there is also a one-to-
one relationship that is possible, but
| | 08:50 | it's not common at all.
| | 08:52 | If you think about it, if one row in
one table is pointing to one row and only
| | 08:57 | one row in another table, well you
might as well just combine them so it's just
| | 09:01 | one row in both places.
| | 09:03 | Although also bear in mind that if
those are the official three kinds of
| | 09:06 | relationships, one-to-many very
common, many-to-many quite common, and
| | 09:11 | one-to-one not common at all, you also
have what some people consider a fourth
| | 09:16 | kind of relationship.
| | 09:17 | Zoom into any large database diagram
and you'll find things like this, a table
| | 09:22 | just existing without any.
| | 09:24 | Some people consider "none" to be a relationship.
| | 09:27 | If you get obsessive about what these
relationships are, and again the geek
| | 09:31 | trivia term is the cardinality is
what we call something that describes the
| | 09:35 | relationship between tables.
| | 09:37 | Some people say none is
an official relationship.
| | 09:39 | I don't think so, but
you'll certainly see that a lot.
| | 09:42 | You don't have to connect your
tables to other parts of your database.
| | 09:46 | So the key question is
going to be, how do we do this?
| | 09:49 | And we'll see that next.
| | Collapse this transcript |
| Creating relationships in SQL Server Management Studio| 00:00 | I am going to go ahead and describe a one-to-
many relationship between two of my own tables.
| | 00:06 | So I have two very-very simple tables here.
| | 00:08 | I have a product table, which
has a few products in it right now.
| | 00:12 | It's got a ProductID as the unique
key, the primary key for this.
| | 00:17 | That's automatically incrementing, ranging
from roughly 1000 through 1013 right now, and
| | 00:23 | I also have an OrderItem table.
| | 00:25 | This itself has its own primary key,
OrderItemID, that I don't really care
| | 00:29 | about, but it's got a place for a ProductID
and this is going to become the foreign key.
| | 00:35 | I'd like to be able to create
multiple order items for each product so that
| | 00:40 | ProductID 1001 can be used
several times if I deem it necessary.
| | 00:46 | That means our many-to-one
relationship is one product, many order items.
| | 00:52 | So how do I make it?
| | 00:53 | Well I am going to close down these tables.
| | 00:55 | There are a couple of
different ways I can do this.
| | 00:58 | One way would be to go to the
Database Diagrams area, add a new satabase
| | 01:02 | diagram, grab the two tables that I'm
interested in, OrderItem and Product, and I
| | 01:08 | could actually drag and drop between them.
| | 01:13 | Grabbing hold of the little column
to the left, grabbing ProductID and
| | 01:16 | dropping it on here.
| | 01:17 | However, I am not going to step through
that way, because we haven't really been
| | 01:21 | doing too much with relationships and
I'd rather show you a slightly more manual
| | 01:25 | way to do it, just editing the tables directly.
| | 01:28 | I'm going to go into the
OrderItem table into Design view.
| | 01:32 | So I am in the many table here.
| | 01:35 | I am going to right-click on the blank
area and come down where I have an option
| | 01:39 | for Relationships and it's going
to tell me there are no foreign key
| | 01:44 | relationships right now.
| | 01:45 | So I'll click Add to make one.
| | 01:48 | Now it doesn't actually
know what this relationship is.
| | 01:51 | So it's actually telling me here that
the Tables And Columns Specification property
| | 01:55 | needs to be filled in before the
new relationship will be accepted.
| | 01:58 | That's this expandable drop down here,
where right now it's saying "Well I don't
| | 02:03 | know who the foreign key and the
primary key tables are so please tell me" and
| | 02:08 | there is a little ellipses button
that you need to click. We open that up.
| | 02:11 | What it's going to say is here's the
drop-down for the primary key table.
| | 02:15 | Who is really in charge, where is the one, and
the one is going to be in the Product table.
| | 02:22 | I select that and then click in the
column below and I'll select ProductID.
| | 02:27 | Foreign key table here, it says it's
OrderItem. That's correct but it's not
| | 02:30 | OrderItemID that I want to link up.
| | 02:33 | Very commonly we are going to be
linking up two columns with the same name.
| | 02:37 | They don't have to have the same name, but
they do have to have the same kind of data.
| | 02:41 | You couldn't for example link an integer
on one table to a date on another table.
| | 02:48 | You'll notice that by tweaking this,
| | 02:50 | it's actually saying up
here as far as it's concerned
| | 02:52 | it's foreign key _OrderItem_Product,
just giving us a hint that there is two
| | 02:57 | tables involved, and it's the
OrderItem table and the Product table.
| | 03:00 | So I am going to click OK
and I'm going to click Close.
| | 03:03 | Now this is still considered an unsaved change.
| | 03:06 | So I am going to try and save it.
| | 03:08 | I'll hit the Save OrderItem and it will
say, "The following tables will be saved.
| | 03:12 | Do you want to continue?"
| | 03:13 | Kind of prompting me that there are
really two changes here. Yes, I do.
| | 03:17 | Unfortunately, it's giving me an error.
| | 03:20 | Error was encountered during the save process.
| | 03:22 | The ALTER TABLE statement
conflicted with the foreign key constraint.
| | 03:26 | So what's going on here?
| | 03:28 | Well if I open back up this Product
table and the OrderItem table, what's going
| | 03:35 | to happen if I spent my time as I could
scan through this Product ID and figure
| | 03:40 | out that perhaps a couple
of them just aren't right.
| | 03:42 | I have a ProductID down here for 500.
| | 03:45 | Well there is no product with ProductID
of 500, and if we are trying to enforce
| | 03:50 | that foreign key, that relationship,
the database is saying no, we can't do it.
| | 03:55 | We can't enforce it for product that doesn't exist.
| | 03:58 | So let me say that perhaps this was
intended to be 1005 and I've got another
| | 04:03 | one here for 1012, because we don't have a
1012 product so that wouldn't work either.
| | 04:09 | So you might have to do a little bit of
tidying up of your data before you can
| | 04:14 | enforce any new relationships.
| | 04:16 | I am going to go back to the table design
where it should still have our change saved.
| | 04:21 | We've got the little asterisk
marking that there is a dirty change here.
| | 04:24 | So I am going to try and save it again. Save.
| | 04:25 | Do I want to do this?
| | 04:28 | Yes I do and well that seemed to work.
| | 04:32 | So let's go ahead and see
what impact this would have.
| | 04:36 | If I go into my OrderItem now and
actually start to change one of these, perhaps
| | 04:42 | I'll change the one that was 500
and I'll change it back to 500.
| | 04:46 | Well, it's not going to let me do that.
| | 04:48 | This is the benefit of having that
relationship, that foreign key, described.
| | 04:52 | We now have the idea of
integrity, which often referred to as
| | 04:56 | referential integrity here.
| | 04:57 | When you describe that
relationship it means something.
| | 05:01 | If you describe the ProductID in this
table as the foreign key to another table,
| | 05:05 | then you better have a legitimate value here.
| | 05:08 | Now the impact of this does mean that
in a lot of cases your applications have
| | 05:12 | to be very careful in what order they do things.
| | 05:15 | If for example, you wanted to add a
new product and add a new order item,
| | 05:19 | you better do them in that order,
because the product needs to exist first.
| | 05:24 | Once we add a new product, this one
being added automatically with 1014,
| | 05:33 | we could then change the value
immediately to 1014 in another row
| | 05:38 | that references that.
| | 05:39 | We just can't at this point change it to 1050.
| | 05:44 | And bearing in mind, if you want to create
a many-to-many relationship, that's not
| | 05:48 | created directly. You do two
one to many, you do two of these.
| | 05:53 | Follow that process twice
with the in-between table.
| | 05:56 | What if I wanted to take a look at this
relationship, perhaps just confirm that
| | 06:01 | it worked. And let me hit the Escape key
to get out of my changes here, because
| | 06:05 | it won't allow me to save that.
| | 06:06 | I am going to make a new database diagram.
| | 06:08 | I am going to add those two tables
and what should happen is that closing that,
| | 06:14 | it should show us the relationship.
The key to the infinity symbol, the Product
| | 06:19 | to OrderItem as the one to the many.
| | 06:22 | We can have the option here to
even use the diagram to delete the
| | 06:25 | relationship from the database.
Not something that I really want to do but
| | 06:28 | something that I could do.
| | 06:30 | I do get the option to tweak this.
| | 06:31 | I am going to right-click one of the tables.
| | 06:33 | I'll right-click OrderItem and jump
into Relationships because the one thing
| | 06:37 | that I did want to show you, bringing up
this relationship is this little dropdown here.
| | 06:43 | The INSERT and UPDATE Specification.
| | 06:45 | You've got something called a Delete
Rule and an Update Rule and what that means
| | 06:49 | is if I delete something from the
Product table and there are references to it
| | 06:56 | in OrderItem table, will it let me do that?
| | 06:58 | Now by default there should be No Action.
| | 07:01 | No, that's a problem.
| | 07:02 | But you can set it to do
what's called cascading deletes.
| | 07:06 | That means if I went into the Product
table and I deleted the product with the
| | 07:10 | ID 1005 that it would cascade down
into the OrderItems and delete every order
| | 07:16 | item with that foreign key of 1005.
| | 07:20 | Cascading is not something that is
typically recommended. You can have it turned on
| | 07:25 | but I'm not going to.
| | 07:26 | Just to go back and prove that I can
see that in OrderItem, not only can't I
| | 07:32 | change ProductID to something that
doesn't exist -- so I'll hit Escape and change back --
| | 07:37 | if I pick one of the ProductIDs that I
am using, 1001 for example and go over
| | 07:42 | there and try and delete the product row,
| | 07:46 | it's going to say, "Are you sure?
You are about to delete one rows."
| | 07:48 | Yes I am going to try that.
| | 07:49 | "Oh! I'm sorry you can't do it."
Again, keeping the referential integrity of
| | 07:54 | the database together.
| | 07:56 | So we won't be allowed to do that.
| | 07:58 | If I wanted to delete that product,
I would first have to go and find every
| | 08:03 | order item that referred to it, either
change this ID or delete that row, and then
| | 08:08 | and only then would it allow me to go
back and delete the row of the product.
| | Collapse this transcript |
| Database normalization| 00:00 | Database normalization is the process
of taking your database design through a
| | 00:04 | set of rules called normal forms.
| | 00:07 | So that it conforms to relational
database standards and you really want to
| | 00:11 | do this, so that your database will
contain a minimum of duplicate data or
| | 00:16 | redundant data.
| | 00:17 | It'll contain data that's easy to get
to define to edit and maintain, and that
| | 00:23 | you can perform operations even
difficult ones on your database without creating
| | 00:28 | garbage inside, without
invalidating the state of it.
| | 00:31 | It should be carried out for every
database you design, and it's really not that hard,
| | 00:36 | even though yes, when you
first start reading about database
| | 00:39 | normalization, you're likely to run
into phrases like "your database won't be
| | 00:44 | in third normal form until every non-
prime attribute of R is non-transitively
| | 00:48 | dependent (i.e. directly dependent) on
every candidate key of R," but you don't
| | 00:52 | have to get into all this language.
| | 00:54 | You just have to understand these were
a set of rules developed about 40 years
| | 00:59 | ago by E. F. Codd, the father of
databases, and we step through them basically
| | 01:05 | one, two, three, first normal form,
second normal form, third normal form.
| | 01:10 | So what's first normal form?
| | 01:13 | Well, it starts off with
stuff we've been doing already.
| | 01:16 | Your data needs to have a unique key.
| | 01:18 | It should always have a unique key.
| | 01:20 | There are a few very rare situations
in which you don't have a unique and
| | 01:24 | primary key, but we're going to
have one for all our databases.
| | 01:28 | Really, the key for first normal form
is that each of your columns, each of
| | 01:32 | your fields, should contain one value
and just one value and there should be no
| | 01:38 | repeating groups.
| | 01:40 | Okay, what does this mean
with actually our tables?
| | 01:43 | Well, let's say, for example, I
begin developing a customer table.
| | 01:47 | I've got a customer ID, so that's good.
We've started off for first normal form.
| | 01:51 | I've got the name of the
customer and the city they're based in.
| | 01:54 | Then what I decide to do is say that
all our customers have a representative,
| | 01:58 | the person we talk to.
| | 02:00 | So add another column to the table.
| | 02:02 | This would be the customer contact.
| | 02:04 | Who do we speak to at ACME Corp?
| | 02:06 | Who do we speak to at Two Trees or Acacia?
| | 02:08 | The issue is what happens when one of
these companies starts to grow a little bit,
| | 02:13 | and we find out that
we've got more than one contact.
| | 02:15 | Well, there is a couple of
ways you could deal with it.
| | 02:19 | You could just start stuffing
extra data into that one column.
| | 02:24 | So we could just start putting
commas or any other delimiter and putting
| | 02:28 | multiple values in the one Contact column.
| | 02:31 | Well this is a no-no.
| | 02:33 | This is not in first normal form if
you do this because first normal form
| | 02:38 | demands that every column,
| | 02:40 | every field, contains one and only one value.
| | 02:43 | If you decide to show multiple values
in like this, you'll find it harder to
| | 02:47 | search, you'll find it harder to sort,
you'll find it harder to maintain.
| | 02:51 | Well, what some people do is they rip
it out that way, go back to the original one,
| | 02:55 | and then they start adding more
columns, Contact, Contact 2, Contact 3.
| | 03:01 | This is what's called a repeating group
and there should be no repeating groups.
| | 03:05 | The classic sign of a repeating
group is fields with the same name and
| | 03:09 | different numbers.
| | 03:11 | We don't want either of these things.
| | 03:13 | So what do we do?
| | 03:14 | What we do is what we do for a
lot of the normalization steps.
| | 03:18 | We rip the Contact data out and
create our own customerContact table.
| | 03:23 | This then has relationships.
| | 03:25 | We go to many-to-one relationship
between customer and customerContact, where
| | 03:29 | we can go from customer 1, find the
contact, go from customer 2, find the
| | 03:32 | contact, go from customer 3 and find
the three contacts, and this would get it
| | 03:37 | in first normal form. That's step one,
because to go onto second normal form,
| | 03:43 | well, first you have to be in first normal form.
| | 03:45 | You don't pick and choose.
| | 03:46 | You go through this one, two, three.
| | 03:49 | Second normal form has the rather
puzzling phrase that "any non-key field should
| | 03:54 | be dependent on the entire primary key, "
and that's about as simple as it can
| | 03:58 | get phrased.
| | 03:59 | Now what does this actually mean?
| | 04:01 | Well, for most of what we've done in
this course, this isn't an issue for us.
| | 04:06 | We're already in second normal form.
| | 04:08 | Let me show you a table that
currently is in first normal form, but not
| | 04:13 | in second normal form.
| | 04:14 | I have an events table here that
has an ID of a course and a Date and
| | 04:18 | a CourseTitle.
| | 04:19 | Now what's actually happening is this
table has been defined so that it's using
| | 04:25 | two columns as the key to it.
| | 04:28 | This is what's referred to
as a compound primary key.
| | 04:31 | Instead of just one ID column, which I
can't use the ID here, because as you see
| | 04:35 | SQL101 appears multiple times, but I
can combine the ID with the Date and in a
| | 04:42 | lot of cases this makes sense.
| | 04:44 | The issue is if you do this and use a
compound key, you need to look at the
| | 04:50 | other columns in this table.
| | 04:52 | So I have got CourseTitle as Intro to SQL.
| | 04:55 | Seats, five seats available.
| | 04:57 | It's in room 14 and a lot of this
information is unique to this one entry
| | 05:02 | and that's fine.
| | 05:03 | But second normal form demands that
all my non-key columns, things aren't keys,
| | 05:09 | CourseTitle, Seats and Room,
they have to be dependent on the entire
| | 05:13 | primary key.
| | 05:14 | Now that is the case for Seats and Room.
| | 05:17 | Those are unique values based on the
fact that we're running this course on a
| | 05:21 | particular date in a particular room
with a certain number of seats available.
| | 05:24 | But CourseTitle I could get from
just the course ID part of the key.
| | 05:31 | This might sound a bit ivory
tower, but here's the impact.
| | 05:34 | What happens if somebody reaches into
this table and they change that course ID,
| | 05:40 | because accidentally it was SQL101?
| | 05:43 | It's now changed to ASP101.
| | 05:43 | Well, now I've got the
wrong title for a piece of data.
| | 05:48 | That's because my data is not in second
normal form, and if I now look at this row,
| | 05:52 | ASP101, Intro to SQL,
well, which one is right?
| | 05:55 | Is it the wrong ID or the wrong title?
| | 05:57 | I don't know.
| | 05:58 | So how do we fix this?
| | 06:00 | Well, once again we're going
to rip out the CourseTitle.
| | 06:04 | We're going to create a separate
courses table where we can map the ID from the
| | 06:10 | events table to the ID in the courses
table and always have one specific value
| | 06:16 | for one specific ID, and everything
in the events table is all based on the
| | 06:21 | whole key, in this case both ID and Date.
| | 06:24 | Again, if you're not using
compound keys, it's not really a concern.
| | 06:27 | You can just step ahead, go right
through second normal form and into third
| | 06:32 | normal form. About as plain English as I
can describe this one is that no non-key fields,
| | 06:38 | and things that are not part
of the primary key, none of them are
| | 06:42 | dependent on another non-key field.
| | 06:45 | This is in a way
similar to second normal form.
| | 06:47 | It's still saying, can I figure out
any of the fields I have from other
| | 06:52 | fields that I have?
| | 06:53 | So for example, I'm looking at an
updated version of the events table.
| | 06:57 | This is in both first normal form
and second normal form, but it's not in
| | 07:02 | third normal form.
| | 07:03 | It's not in first normal form.
| | 07:05 | I have got my key.
| | 07:07 | I don't have any repeating groups and I
don't have any repeating values within a column.
| | 07:12 | It's actually in second normal form
because I have decided to change it to
| | 07:16 | have one column primary key, which is
EventID, but it's not in third normal form. Why?
| | 07:22 | Well, what I can do is scan through
my non-key fields, which for me is
| | 07:26 | everything other than EventID.
| | 07:27 | SQL101 is occurring on the 2nd of April.
| | 07:33 | There are apparently five seats
available. That's being held in room 14.
| | 07:36 | There is a capacity of 18.
| | 07:38 | These values, the date, the availability,
the room, could be different from row
| | 07:44 | to row so they're fine.
| | 07:45 | The issue is with the Capacity column.
| | 07:49 | If we are looking at the room, so Room
14 has 18 seats and Room 11 has 24 seats
| | 07:54 | and Room 8 has 12 seats, well that
means one non-key field that we have,
| | 07:59 | Capacity, is dependent on
another non-key field, Room.
| | 08:03 | If we can figure out Capacity from
Room, we don't need to store in the same table.
| | 08:09 | We need to, you've guessed it,
split this out into its own table.
| | 08:12 | So we need to pull out Capacity
from this table and just keep Room.
| | 08:17 | That's as long as Room can always tell us
the capacity if we have, say, a Room table.
| | 08:22 | Another example of third normal form
would be this, which is quite common.
| | 08:26 | You'll often see it's an orderItems table,
which has an ID and a ProductID and a
| | 08:31 | UnitPrice and a Quantity and a Total,
but if I look here the Total is based on
| | 08:36 | Quantity times UnitPrice.
| | 08:38 | Quantity and UnitPrice are both non-key fields.
| | 08:41 | We can figure out what total is
from the other fields that we have.
| | 08:45 | So we rip it out.
| | 08:47 | Don't store information that's easily
ascertained from other non-key fields.
| | 08:51 | Now, you can actually in SQL Server
create what's called a computed,
| | 08:55 | a calculated field that's not
really stored in the database.
| | 08:58 | So if you wanted this actual behavior
to make an easy way to scan the Total
| | 09:03 | particularly when you've got complex
quantities, you can do that and I'll show
| | 09:06 | you that a little later. But don't
store it because there is nothing that would
| | 09:10 | stop me from storing UnitPrice for
100, Quantity of 3, Total 75,000.
| | 09:16 | It doesn't have to make sense
and we want our data to make sense.
| | 09:19 | Now in fact third normal form is quite
an odd one, because you will actually
| | 09:23 | find that a lot of tables out
there are not in third normal form.
| | 09:28 | A classic example is any table
that's full of address information.
| | 09:33 | If I look at a table like this and I
see that I've got PostalCode being stored
| | 09:38 | as the last column here, well, I can
figure out what the City, the State and the
| | 09:43 | name of the state are from the PostalCode.
| | 09:45 | That means I have non-key fields that
are dependent on another non-key field.
| | 09:50 | You've probably had situations
yourself where if you're talking to someone on
| | 09:54 | the phone and filling in an address,
they don't actually ask for the city and state.
| | 09:57 | They just say, "Can I get the
postal code?" because that's all they really
| | 10:00 | need is the postal code.
| | 10:02 | If I get the postal code,
I can figure out the rest of it.
| | 10:05 | Now AddressLine1 is not
dependent on the PostalCode.
| | 10:10 | So AddressLine1 isn't a problem.
| | 10:12 | It's City, State and the name of the state.
| | 10:15 | We could rip out that
information and put it in a separate table.
| | 10:19 | Now, a lot of the time we don't do
that just because it makes it easier and
| | 10:22 | quicker to scan through, say, address
tables, and in fact the process of taking
| | 10:27 | all the way to third normal form,
ripping the stuff out and then deciding to put
| | 10:31 | it back in, is what's called denormalization.
| | 10:34 | But make no mistake.
| | 10:36 | If you decide to store the City and
the State and the name of the state
| | 10:40 | information in your address table,
you are storing redundant data.
| | 10:44 | There is no real reason why you should
store the ZIP code 91502 and the city
| | 10:49 | Burbank and the state of CA, and
the full name of California a thousand times,
| | 10:53 | when you could get it all from
having a zip code database with a city
| | 10:58 | and a state in it.
| | 10:59 | So you might denormalize to make
things a bit more efficient, but do it knowingly.
| | 11:04 | And those really are the three
steps that we would go through.
| | 11:08 | You can take normalization even
further into what are called voice card and
| | 11:13 | fourth and fifth normal forms, but
that's really not very typical and I've very,
| | 11:17 | very rarely run across that.
| | 11:19 | We want to take our database designs
through the first normal form, about our
| | 11:25 | primary key and on non-repeating fields.
| | 11:27 | Our second normal form, making sure our
data is based on the whole key, and third
| | 11:33 | normal form, that all of our data is
based on the whole key, or if you prefer,
| | 11:37 | the quicken mnemonic is that your data
should always be based on the key, the
| | 11:42 | whole key and nothing, but the key. So help me God.
| | Collapse this transcript |
| Creating computed columns| 00:00 | There is a column that you can add to
your tables that comes in handy from
| | 00:05 | time-to-time and really it's not a
real column at all. What it is, is a
| | 00:09 | calculated or computed column.
| | 00:11 | So let's say for example we're working
with this OrderItem table, and I've got
| | 00:16 | multiple entries here.
| | 00:17 | I've only got 20 or so but we could
have 50,000 of them that deal with
| | 00:21 | ProductIDs, Quantities and UnitPrice.
| | 00:24 | Or you might find it useful to have
kind of a rolling total of each order item going,
| | 00:30 | particularly if you've
got a lot of separate quantities.
| | 00:33 | So instead of having to load this data
into an application to then perform a
| | 00:37 | calculation, it just might be nice if each
order item entry had its own little subtotal.
| | 00:43 | So we can do that of course. We could
just add a regular column. I'll go into
| | 00:48 | that table into Design view and I'll
add a new column called Total. I'll make
| | 00:53 | it a money column, save my changes,
I've allowed Null so won't complain about
| | 00:59 | that right now, and then I go back in and try
and edit directly in SQL Server Management Studio.
| | 01:05 | One order item, which is 1 of 12.32 would
be 12.32, 1 of 234 would be 234, and so on.
| | 01:14 | The issue is there is nothing that's
actually stopping me here from typing in
| | 01:19 | 50,000, and now there is no
relationship between the total and the unit price
| | 01:24 | and quantity, and there really should be.
| | 01:27 | And it's for this reason that in
general database design, not just in SQL Server
| | 01:32 | but in overall database design,
you should never be creating a column that
| | 01:37 | stores a separate value that can be
calculated based on other columns.
| | 01:42 | So we don't want to do it this way.
| | 01:43 | However, we can still get
the result that we want.
| | 01:45 | I am going to go back into Design, come
down into the Total of money, and what
| | 01:50 | I'm going to do is come down into the
Column Properties and this is the part
| | 01:55 | that I'm interested in,
Computed Column Specification.
| | 01:59 | But I am telling it,
don't store this data separately.
| | 02:02 | Just figure it out every time I ask for
one of these rows. And it gives a place
| | 02:06 | to type in a formula,
which for us is very simple.
| | 02:09 | It's simply Quantity * UnitPrice.
| | 02:17 | Is Persisted mean is saved No. Just
leave that at the default and what that
| | 02:20 | actually means is I'll save this,
and there I was talking about making
| | 02:24 | changes to two tables simply because
I have a relationship between this one
| | 02:28 | and the Product table.
| | 02:30 | But when I now go into OrderItem and
click Edit the Top 200 Rows I can see that
| | 02:35 | total is automatically doing this
totaling of the Quantity * UnitPrice.
| | 02:40 | So I've got 3 of 74.12, 222.36.
| | 02:46 | It shows up in this kind of a lighter
brown color as does the primary key, giving
| | 02:51 | us the hint that we're not supposed to
directly enter in anything. In fact if we do
| | 02:56 | it will be ignored.
| | 02:57 | So a computed column result is actually
recalculated when we retrieve, when we
| | 03:02 | ask for that data back, but it can be
very useful or at least very convenient
| | 03:07 | for the data in your tables.
| | Collapse this transcript |
|
|
5. Importing Existing DataUsing the SQL Server Import and Export Wizard| 00:00 | It's a very common need that when
creating a database we need to import some
| | 00:04 | data that exists somewhere else.
| | 00:07 | That could be in an Excel file, a CSV
file, an Access database, even another
| | 00:12 | instance of SQL Server or a previous
version of it, or we can do all of these
| | 00:16 | things using the SQL
Server Import/Export Wizard.
| | 00:20 | Under my installed programs for SQL
Server 2008 R2, I actually have this link,
| | 00:25 | Import and Export Data 32-bit
and 64-bit, I have two versions.
| | 00:30 | Now the reason for that is that while
my SQL Server instance is installed as
| | 00:35 | 64-bit, some of the data sources that I
might want to import from or export to aren't
| | 00:42 | 64-bit so I need to talk to them using
the 32-bit version, and basically if one
| | 00:46 | of them doesn't work try the other.
| | 00:48 | So I've opened the wizard here.
| | 00:50 | It just gives me a greeting message
that it will copy between databases,
| | 00:54 | spreadsheets, text files, and so on.
| | 00:56 | I'm going to click Next because I need
to give it two pieces of information:
| | 01:00 | where am I copying from
and where I'm copying to.
| | 01:03 | Now when I click this top level drop-
down box I can see I have a bunch of
| | 01:08 | selections here. I've got the ability
to talk to Oracle, to talk to Microsoft
| | 01:12 | Excel, to talk to Access SQL Server,
and depending which one I pick, I may have
| | 01:18 | to provide other really simple
information such as selecting from Excel, give it
| | 01:22 | the file path, and say which version it is.
| | 01:25 | If how many other hand I'd selected to
import from Oracle, we have all the .NET
| | 01:30 | Framework Data Provider source and I
have to provide things like the password
| | 01:34 | and the user ID and the data source information.
| | 01:37 | Essentially once this is declared then
we just double it up about and say where
| | 01:41 | it's actually going to.
| | 01:42 | It will then step us through the process.
| | 01:45 | I'm going to show a couple of
examples of that in just a minute.
| | 01:48 | Now one thing to show is though even
that we could copy from SQL Server itself
| | 01:53 | using this method, it's not the
suggested way to do it. In fact if I click the
| | 01:57 | Back button to that first greeting page,
it does tell you or remind you to move
| | 02:02 | or copy databases and their objects
from one SQL Server instance to another,
| | 02:06 | cancel this wizard and use the Copy
Database Wizard instead, I'll show you where
| | 02:10 | that is in just a minute.
| | 02:12 | And this is the last thing before I get
started. I would say that this same thing
| | 02:17 | is available through SQL
Server Management Studio.
| | 02:20 | So if you are in the middle of designing
your databases, say my TwoTreesTest, and
| | 02:25 | I know that I want to import some
information here, if I right-click my database,
| | 02:30 | come down to Tasks, which shows me
a whole bunch of different things.
| | 02:34 | Take it offline, shrink it, back it up,
restore it. But down here I have Import
| | 02:39 | Data and Export Data.
| | 02:40 | Well, not surprisingly clicking those
is just going to open up exactly the same
| | 02:46 | wizard that will allow us
to step through that process.
| | 02:50 | Again we're getting that same message
that to use the Copy Database Wizard if
| | 02:54 | we want to copy SQL Server databases and you
won't find that under any of the tools options.
| | 02:59 | It is again under one of the tasks.
| | 03:02 | Instead of selecting the task to
import and export, I'd clicked Copy Database.
| | 03:08 | That would open up the Copy Database Wizard.
| | 03:10 | I'm not going to use that one right now.
In fact, I'm basically going to shut
| | 03:14 | that down and show you one more thing here.
| | 03:18 | And this is just the phrase that it
uses on the welcome page of the wizard.
| | 03:23 | This wizard helps you to create
simple packages. Now what does this mean?
| | 03:28 | Well we're really using a part of SQL
Server called SQL Server Integration
| | 03:33 | Services, which can get much more
involved than just a simple import, and if
| | 03:38 | you're looking at setting I'm not
just a one-off import but a scheduled,
| | 03:41 | repeatable, automated import that
happens twice-a-week or even twice-a-day,
| | 03:46 | you're going to be looking at
using SQL Server Integration Services.
| | 03:50 | And I'll be covering that
towards the end of this course.
| | 03:52 | But before we get to that let me walk through
a few examples of just using this Import/Export Wizard.
| | Collapse this transcript |
| Importing Excel files into SQL Server| 00:00 | So I'm going to go ahead and take a
straightforward Excel spreadsheet and
| | 00:05 | import that into SQL Server.
| | 00:07 | This is the spreadsheet
that I have at the moment.
| | 00:09 | It's a list of names,
addresses, and zips and email, just some
| | 00:13 | contact information.
| | 00:15 | I can see that the first row does seem
to contain the column names for this, so
| | 00:19 | that might be useful in just a moment.
| | 00:21 | But that's what I want. I just want it
in my database, because it's way too easy
| | 00:25 | to mess it up when it's an Excel.
| | 00:27 | So I'm going to open up the SQL
Server 2008 R2, Import and Export Data.
| | 00:34 | I'll open up the 32-bit one, so
it should be all I would need here.
| | 00:37 | I'm going to click Next.
| | 00:39 | Select that my data source is Microsoft Excel.
| | 00:43 | It's going to ask me for the file path,
which is just out here on my desktop.
| | 00:48 | And it's going to ask me for the
Excel version and I think it's 97-2003.
| | 00:51 | If there is a problem with that it
will probably tell me in just a moment.
| | 00:55 | And I'll leave this checked.
| | 00:57 | Yes the first row has
column names. I'll click next.
| | 00:59 | It's asking me now where is it going to.
| | 01:02 | Well, this really means the current SQL
Server, SQL Server Native Client 10.0.
| | 01:06 | But I could be copying to anywhere.
| | 01:09 | Again, all these management tools don't
have to be running on the local machine
| | 01:14 | of a SQL Server instance, so it's
just asking for the server name.
| | 01:17 | Well, I'm just going to put in the
period here. I could type in the name of my
| | 01:22 | machine as well. That would work.
| | 01:24 | If I click the drop-down box it will
try and see if there's any more that it
| | 01:27 | knows about and there won't be right
now. So that's just my local machine.
| | 01:32 | It doesn't matter which one I use.
| | 01:33 | I'm going to say yes, I'm talking
to it Using Windows Authentication.
| | 01:37 | And because I've named that if I click
the drop-down box now I should see a list
| | 01:41 | all of the databases there, and yes I do.
| | 01:44 | I'm going to select my
TwoTreesTest custom database that I have.
| | 01:49 | I would even have the option to
make a new database at this time.
| | 01:52 | Now I'm going to do that. I'm
going to click Next and it's going to ask
| | 01:56 | what we are copying.
| | 01:57 | Now this is a little bit over-complex
for what I'm doing right now, because it's
| | 02:00 | saying are we copying data
from one or more tables or views?
| | 02:05 | And this is a bit more useful when say
you're coping from an Access database and
| | 02:09 | you only want to copy certain pieces of it.
| | 02:12 | I'm going to leave the default selected
and click Next and it's going to tell
| | 02:15 | me this is the stuff that it knows about.
| | 02:18 | Apparently, it's got a
source of data called exceldata$.
| | 02:22 | And it will create
something called dbo.exceldata$.
| | 02:26 | Not quite what I'm after, but
I can always change that later.
| | 02:29 | The interesting button here is going to be
this one down at the bottom, Edit Mappings.
| | 02:34 | That's going to tell me what it's
going to try and do with the columns in the
| | 02:39 | Excel data source and what it's going to map it to.
| | 02:42 | Now right now, they're named quite well.
| | 02:44 | We've got the FirstName, LastName,
Address, City, State, and so on.
| | 02:47 | I'll keep those names and it will even
tell me here what it's going to do with them,
| | 02:52 | what data types it's going
to use when it creates this table.
| | 02:56 | And mostly they're listed as nvarchar,
so variable-length Unicode fields that
| | 03:00 | are nullable and is this generic size of 255.
| | 03:05 | That's not quite what I was looking for
and this one definitely looks wrong.
| | 03:09 | Yes my Zip is numeric,
but it's certainly not a float.
| | 03:13 | That's an estimate based on the
data that existed in that spreadsheet.
| | 03:18 | So I could change that.
| | 03:19 | And again, depending on what I'm
doing, whether the postal codes I know
| | 03:23 | might have letters in them or they might
have dashes, even if I'm using US postal codes.
| | 03:28 | So I could change that to an nvarchar as well.
| | 03:32 | But I see that what it did there was
actually change it to max, which is
| | 03:36 | not what I really want.
| | 03:37 | It doesn't need 2 gigabytes of space to go
and in fact, 20 would probably do it just fine.
| | 03:42 | You will occasionally
find that it does this, where
| | 03:44 | it doesn't accept
something that you're typing into.
| | 03:47 | And there is a couple of
different ways as you could do it.
| | 03:49 | So for example, I've changed the data
type and suddenly seemed to take my 20.
| | 03:52 | So I'm going to now change it back.
It just seems to be a little of strange
| | 03:56 | behavior I've seen a couple of times.
| | 03:58 | And it's up to you whether you want
to change them to be Nullable or not.
| | 04:03 | I'm going to leave this as is. Click OK.
| | 04:06 | Then I'm going to click Preview, which
just shows me, yes this is the data that
| | 04:11 | it's going to try and fetch from Excel.
| | 04:14 | It all seems to be mapped
correctly. I'll click OK.
| | 04:17 | Click Next.
| | 04:18 | It's giving me a little prompt here
that it's kind of letting me know that it
| | 04:22 | thinks that zip was a double, and
I'm wanting to store in an nvarchar.
| | 04:26 | So is there a conversion
process going on? And yes there is.
| | 04:30 | Well, what if there's an
error, what do I want to do?
| | 04:33 | Do I want to do something special, do
I want to fail the whole thing or just
| | 04:36 | ignore it and move on? If the
data was going to be truncated,
| | 04:40 | so if say I decided to move it into a
varchar with a maximum length of two digits,
| | 04:46 | we'd have a lot of truncation going on.
| | 04:48 | I'm just going to use the Global
Settings, which are these ones down here.
| | 04:52 | Any error makes it fail and
any truncation makes it fail.
| | 04:56 | I'll click Next, and I'll
tell it yes, Run immediately.
| | 05:00 | The other option would be to save this
as an SSIS Package, which is SQL Server
| | 05:05 | Integration Services.
| | 05:07 | Again, we'll talk about more of that later.
| | 05:09 | But just to let you know, even a
simple import that you're doing is using
| | 05:12 | integration services.
| | 05:13 | I'm going to say Run immediately. Click Next.
| | 05:16 | It gives me a summary and click Finish.
| | 05:19 | It runs through a whole bunch of stuff.
We even get a message here that 101
| | 05:23 | rows were transferred.
| | 05:25 | I'm going to close this, go back into
SQL Server Management Studio, connect to
| | 05:30 | the database, and not surprisingly
we should find now in our tables this
| | 05:36 | rather ugly looking dbo.exceldata$, but
I could open it up and say Select Top 1000 Rows.
| | 05:43 | And we're bringing back all our content.
| | 05:46 | I could right-click the table right now,
and just rename it to something more specific.
| | 05:50 | Let's imagine these were coming from
customers, so I called it the Customer table.
| | 05:55 | And of course, I can even right-click
and hit Design, jump into this, play
| | 06:01 | around with the data types, even add a
primary key, perhaps even generate one.
| | 06:06 | This is the basic procedure of how you
would import from an Excel spreadsheet.
| | Collapse this transcript |
| Importing CSV files into SQL Server| 00:00 | If the data that you want to import is
in comma separated values or indeed in
| | 00:05 | anything that's just a
regular text delimited file--
| | 00:08 | in fact here I've got to some very
straightforward values, very similar to the
| | 00:12 | last time, but they are
separated with the vertical bar.
| | 00:15 | I can also bring this into SQL Server
although the way of doing it does have
| | 00:19 | quite a few different
options than doing it with Excel.
| | 00:23 | So I'm going to go ahead and open
up my Import and Export Data Wizard.
| | 00:28 | I'm going to use the 32-bit one.
| | 00:30 | The source I'm going to
pick here is Flat File Source.
| | 00:34 | And when I select that, not
surprisingly it's going to ask me to browse to that file,
| | 00:39 | which is currently
saved as a CSV on my desktop.
| | 00:42 | And once I do that we have a very
different screen for determining what that data is.
| | 00:48 | If I click on the Columns section on the
left, it will take a look and think yes,
| | 00:52 | this column delimiter seems to be a
vertical bar, and if you select that, this is
| | 00:56 | what the date is going to look
like and it looks pretty good.
| | 00:59 | Although it does seem to say that
the first name, last name, address, and
| | 01:03 | city are values. Now it's not the case.
I actually did one of those to be the column names.
| | 01:08 | If I look back on my general section
I'll see that I do have a checkbox.
| | 01:13 | The column names are in the first data row.
| | 01:15 | So we click back to the Columns, and yes
we seem to have that now sorted correctly.
| | 01:19 | Interestingly, if I go to the
Advanced section, it will tell me the way it's
| | 01:24 | interpreting these values.
| | 01:26 | So it's breaking down all the different
columns and saying FirstName it thinks is
| | 01:30 | a string that's 50, and LastName as a string
that's 50, and Address as a string that's 50.
| | 01:35 | And in fact you'll see this a lot.
| | 01:36 | It's pretty much going to assume that
everything as a string of 50, even a zip,
| | 01:42 | and email, and phone, and that's okay,
but it might lead us into issues.
| | 01:47 | For example, I'm pretty sure I have
some e-mail addresses that are longer
| | 01:50 | than 50 characters.
| | 01:52 | There is a button-down
here called Suggest Types.
| | 01:55 | Now what that will do is look through
some of this semi-mapped data and make
| | 02:01 | a prediction that if something is purely
numeric, well maybe it should be an integer.
| | 02:06 | I'm not a big fan of using Suggest Types,
because I tend to find that it gets a bit too pessimistic.
| | 02:12 | So for example, if I were to click
Suggest Types here, it might go through
| | 02:16 | all the last names
| | 02:17 | and if the largest one that it finds is
12 characters, it's going to assume that
| | 02:21 | the widest this column
needs to be is 12 characters.
| | 02:25 | That may be true, but that may
lead you into issues later on.
| | 02:28 | So I'm going to leave that alone.
| | 02:31 | If I click Next, we then say
where are we copying this data to.
| | 02:34 | And I'll get a chance to map it again
in just a minute, but I'm copying it to
| | 02:38 | my current SQL Server database, which I'm
going to represent with just the dot, the period.
| | 02:43 | I'm using Windows Authentication and
that should give me the drop-down list
| | 02:47 | where I can select my new
custom database. Click Next.
| | 02:52 | It's telling me it's going to import a table.
| | 02:55 | That's importing from the CSV data and
it's going to create a table called csvdata.
| | 03:01 | I could choose to change that if I wanted,
but let me just leave that right now.
| | 03:05 | Once again, I'm going to click Edit Mappings.
| | 03:08 | Now we'll see here that everything
is now being listed as a varchar with
| | 03:11 | a maximum size of 50. That may work.
| | 03:15 | That may not.
| | 03:16 | In fact I'm pretty sure that certain
things like my address should be at least a
| | 03:22 | hundred and that my e-mail
should be at least a hundred as well.
| | 03:27 | I'm going to click OK, click Next,
tell it that yes I want to run immediately.
| | 03:32 | click Finish and go.
| | 03:34 | And we see that we've got an error here,
we've got some messages popping-up
| | 03:37 | hat's saying, unfortunately the
output column Email failed because
| | 03:44 | truncation occurred.
| | 03:45 | And the truncation row disposition
on the output column specifies failure on
| | 03:50 | truncation. What does this mean?
| | 03:53 | Again it's to do with how we're
specifying this copy, this import, to work.
| | 03:58 | I'm going to click Back quite a bit here
and go back to where it thinks these
| | 04:05 | mappings occur, and in fact the problem
is probably on Email. Wll that's were
| | 04:09 | it said the problem was.
| | 04:11 | Right now it does think that it only
needs 50 characters to do its mapping.
| | 04:14 | I'm going to say no, you need a
hundred characters or truncation will occur.
| | 04:19 | I'm going to click Next and
go ahead keeping the same data.
| | 04:24 | What I've got an issue
with now is with Mappings.
| | 04:27 | So we'll take a quick scan of those,
now it did say address was different, but
| | 04:30 | it didn't complain about
address so I'll just leave that.
| | 04:33 | Click Finish and try this again,
and that looks a lot better.
| | 04:36 | We now have a warning here. The
total number of rows processed is 101.
| | 04:41 | There is a partial row at the end of the file.
| | 04:44 | That's quite common message to get.
You can check that later, but we do seem to
| | 04:48 | have a hundred rows transferred.
| | 04:50 | So I'm going to close that, open up
Management Studio, and just double-check that
| | 04:54 | everything looks okay.
| | 04:59 | And it does seem to have brought everything in.
| | 05:01 | We do have the columns named correctly.
| | 05:04 | We do have a hundred rows.
| | 05:06 | It does not seem to have created anything
in that last one, so we're looking good.
| | 05:10 | Once again of course we could
change the definitions of that.
| | 05:13 | But if you know that you are
immediately needing to go in and change this
| | 05:16 | information, you should try and do a
lot of it as you are mapping it before you
| | 05:20 | actually create the table during the import.
| | 05:22 | But that's the process
of bringing in a CSV file.
| | Collapse this transcript |
| Importing Access databases into SQL Server| 00:00 | If the requirement you have is to take
an Access database and get back into SQL Server,
| | 00:05 | either all of it or part of it,
you have a couple of ways of doing that.
| | 00:09 | Not surprisingly one of them is
using the Import and Export Wizard.
| | 00:14 | But it's possibly a little
different from what you're expecting.
| | 00:18 | If I pick the 32-bit one, I am going
to click the Next button and then when I
| | 00:22 | select my data source, I could just
easily carry on and select Microsoft Access.
| | 00:27 | It asks me to browse the file.
| | 00:29 | It's looking for an Access database.
| | 00:31 | But I'm browsing to my
desktop and it doesn't show up.
| | 00:35 | That's because it's going to be
looking for the old school pre-Access 2007
| | 00:39 | Access files, .mdb files
which are not going to show up.
| | 00:44 | If I try and bypass that by just
selecting all files and then I will select this
| | 00:48 | classic Northwind Access database.
| | 00:51 | It's in the .accdb format. I could try that.
| | 00:55 | I'll click Next and it's
not going to work at all.
| | 00:59 | That's because this original data
source is old school Microsoft Access.
| | 01:04 | It's not going to work.
| | 01:06 | Well, what can I do?
| | 01:08 | Well, not a lot immediately, because
what you need to have installed-- and I'm
| | 01:14 | just going to open up an Internet Explorer.
| | 01:16 | If you are importing from Access
2007 or Access 2010, before you do this,
| | 01:23 | you will need to go out to
microsoft.com/downloads and download some
| | 01:29 | connectivity components.
| | 01:31 | In fact, that's what I am going to
search for here is the phrase "data
| | 01:35 | connectivity components."
| | 01:40 | You'll see a couple of different choices here.
| | 01:42 | If you have the 2007 version, you
can get the Office 2007 System Driver:
| | 01:47 | Data Connectivity Components.
You want it to come from Access 2007.
| | 01:50 | If you're coming from Access 2010, get
the Microsoft Access Database Engine 2010
| | 01:57 | Redistributable, which comes in two
versions, either the 32-bit or the 64-bit.
| | 02:03 | Now I've installed the 64-bit.
| | 02:05 | What does that mean?
| | 02:07 | Well, it means right now when I open
up my 64-bit Import/Export Wizard,
| | 02:14 | what I'm going to find on this is a data source of
Microsoft Office 12.0 Access Database Engine.
| | 02:22 | Now this, formally speaking is what's
called an OLE DB Data Provider, which is a
| | 02:27 | little bit of a tedious phrase.
| | 02:29 | In fact, when you try and open it, it's not
going to just say "Well, point to the accede."
| | 02:36 | Really that's what it's after.
It just doesn't make it obvious.
| | 02:39 | So it says "Enter the data
source and/or location of the data."
| | 02:43 | Location is blanked out.
| | 02:45 | But I actually can enter
the data source of this.
| | 02:47 | In fact, if I just right-click
it to find the address of it here,
| | 02:51 | it's right here on my desktop.
| | 02:53 | I am going to copy that path and
paste that in and \Northwind.accdb.
| | 03:02 | I am going to click the Test
Connection button and it says test
| | 03:05 | connection succeeded.
| | 03:07 | Once they do that, it's going to allow
me to click on Next through, to select
| | 03:11 | then where I'm going to put it.
| | 03:13 | In this case, I might decide to
create a new database or I could put it in
| | 03:19 | the old Two Trees Test.
| | 03:21 | I got the same screen I got with an
Excel import that I can select from one or
| | 03:26 | more tables or views.
| | 03:27 | And if I do that, it will give me
the screen here where I can choose just
| | 03:32 | individual pieces of this Access
database or the entire thing, with each one then
| | 03:38 | breaking down into the
mappings that it's going to do.
| | 03:41 | Now, if you're looking in this with
the idea that you are going to check
| | 03:46 | everything and bring in the entire
Access database, you can do it this way.
| | 03:51 | I just wouldn't advise it.
| | 03:53 | I'll show you the way that you do it after that.
| | 03:56 | So if I just said I'm going to bring in
one piece of information, which is the
| | 04:00 | Products table, just unchecking
that, select Products, click Next.
| | 04:06 | It just gives us the same idea
that it's going to create a SQL Server
| | 04:10 | Integration Services package
and it's copied across 45 rows.
| | 04:14 | So that's just one thing.
| | 04:16 | If, on the other hand, what you are
wanting to do is take the entire Access database,
| | 04:20 | this is the way I would advise it.
| | 04:22 | In 2007 or 2010, open up Access and get into
your system however it is you need to do it.
| | 04:30 | You want to close down any object you
have open and simply select from your
| | 04:35 | Database Tools, where you have this
upsizing wizard, a way of migrating some or
| | 04:41 | all of your database into SQL Server.
| | 04:43 | So this way you are doing a push and what it is
going to step you through is the whole process.
| | 04:48 | Would you like to use an
existing database or create a new one?
| | 04:50 | I am going to say create a new one.
| | 04:53 | It's asking the same kind of
information that we have to give when we are
| | 04:56 | connecting to the SQL Server ourselves.
| | 04:58 | What machine is it?
| | 04:59 | Well we are using the phrase "local,"
which is fine. A dot would work as well.
| | 05:03 | It's going to ask, do I have a login
ID and password? Well, no, I don't.
| | 05:06 | I'm logged in right now as the administrator.
| | 05:09 | So I am going to tell it to use the
current connection, the trusted connection.
| | 05:12 | It's going to then say if you want to make
a new database, what you want to call it?
| | 05:16 | We will say NorthwindSQL. I will click Next.
| | 05:18 | Which tables do you want?
| | 05:20 | Let's just say all of them.
Click two arrows, then Next.
| | 05:24 | Then also asking, what do I want to upsize?
| | 05:28 | Do I want to copy across my
indexes or my validation rules?
| | 05:32 | Or my default values and table relationships.
| | 05:35 | In fact, I am going to take all of them.
| | 05:37 | I am going to leave the other
options in the default. Click Next.
| | 05:41 | It's going to give me the option to
kind of separate the data parts from
| | 05:44 | the Access front end.
| | 05:46 | I'm not going to do any of them.
| | 05:47 | I just want to take all the data
and move it up into SQL Server.
| | 05:51 | So I will click Next.
| | 05:52 | It says it has all the
information it needs. Then click Finish.
| | 05:55 | This may take a few minutes
depending on the size of your database.
| | 06:00 | But when it finally comes back, it
will even give you this Upsizing Wizard Report
| | 06:04 | and tell you the details of
what it's actually taken and uploaded.
| | 06:10 | Information about how it's mapped
the different fields across here, so you can
| | 06:14 | actually page through that.
| | 06:16 | Certainly, something that you
will often have to do is a little bit of
| | 06:19 | revisiting the table design
once you get in into SQL Server.
| | 06:22 | So don't imagine that
everything is going to work perfectly.
| | 06:26 | I didn't get any errors on this because
it was a fairly vanilla database of the
| | 06:31 | basic Northwind sample.
| | 06:32 | But what I would like to do is
certainly go and check and see if it's in
| | 06:36 | SQL Server correctly. And I expect so.
| | 06:39 | The database was called NorthwindSQL.
| | 06:42 | That looks like it's there.
| | 06:44 | I can even start using the regular database
diagramming tools once I've provisioned them.
| | 06:49 | I can say, for example,
create a new database diagram.
| | 06:52 | And I'm going to add just
several tables on the top of it.
| | 06:56 | The reason I am doing this is just to
show that you can tell the database design
| | 07:01 | has mapped across correctly and even
as we start to look at them, things like
| | 07:05 | the relationships have started to be
copied across as well into parts of this.
| | 07:10 | Of course, you're going to take some time
and verify that everything seems to work.
| | 07:15 | But it's looking pretty good right now.
| | 07:19 | So your real decision most of the time
is when you're bringing in information
| | 07:22 | from Access, are you just
bringing in a table here or there?
| | 07:26 | In which case, using the
Import/Export Wizard is just fine.
| | 07:29 | If you're trying to migrate the entire
database, I do it more of a push from the
| | 07:33 | Microsoft Access side.
| | Collapse this transcript |
|
|
6. Retrieving Data with SQLIntroduction to Transact-SQL| 00:00 | Structured Query Language or SQL is the
common language that lies at the heart
| | 00:05 | of not only Microsoft SQL Server, but
every RDBMS that you're likely to use.
| | 00:11 | Now, you've probably noticed the
different pronunciation of this.
| | 00:14 | Some people say "Sequel." Others say "S-Q-L."
| | 00:17 | I tend to say S-Q-L when I talk
about the original language itself
| | 00:20 | and "Sequel" when it's combined
as an SQL Server, T-SQL or MySQL.
| | 00:26 | SQL the language has been around since the 70s.
| | 00:29 | It's actually one of the few
languages that I was writing 25 years ago and
| | 00:33 | I'm still writing now.
| | 00:35 | A lot of programming languages have
come and gone, become fashionable and
| | 00:39 | unfashionable, but SQL has stuck around and I
still expect it to stay for a long time to come.
| | 00:44 | Now SQL is a pretty small language and
the key to learning it is to understand
| | 00:50 | that it's a little different from other
programming languages you might have come
| | 00:53 | across, things like C, Java, or Python.
| | 00:57 | SQL is what's called a declarative
language whereas those others are what are
| | 01:01 | referred to as procedural
or imperative languages.
| | 01:04 | Okay, this is jargon, yes.
| | 01:07 | What it means with a declarative
language is that you use SQL to describe
| | 01:12 | what you want and you let the database
management system handle how that's actually done.
| | 01:17 | You don't have to manually layout the
algorithm, the different steps of the
| | 01:21 | procedure, as you would do in
other programming languages.
| | 01:25 | So let's say we have got a thousand
different products and I want to know which
| | 01:29 | of these products have a price
of less than a hundred dollars.
| | 01:32 | Well, in a procedural or imperative
language like C or Java, I would describe
| | 01:37 | the steps to do this.
| | 01:39 | I would write some code that would loop
through all the individual products one
| | 01:43 | by one, and every time I went through
the loop, I will have to ask the question
| | 01:46 | again, is this less than a hundred?
| | 01:48 | If so, do one thing.
| | 01:50 | If not, do another thing.
| | 01:52 | Even in pseudocode it looks complex.
| | 01:54 | I would be writing a loop, I would
be writing conditions, I would be
| | 01:58 | writing return statements.
| | 02:00 | That's a procedural language, but
in SQL you describe what you want.
| | 02:05 | In English, you would say I
want all products less than $100.
| | 02:08 | That written in SQL is this:
SELECT * FROM products WHERE price < hundred.
| | 02:16 | No conditions, no loops, no return
statements. Just the description.
| | 02:21 | The database management
system will look at your data,
| | 02:24 | it will figure it out, and it will
take this and return what's called the
| | 02:29 | result set, whether this is one product
or five hundred products or even none,
| | 02:34 | based on this query.
| | 02:36 | So SQL can be used to retrieve or
read your data and ask questions of it.
| | 02:41 | But it can also be used to create
data, to update it, and to delete it.
| | 02:46 | This Create, Read, Update and
Delete is often referred to with a
| | 02:50 | wonderful acronym of CRUD.
| | 02:52 | But SQL can be used actually to
create the databases themselves as well.
| | 02:57 | Now, this module is
about something called T-SQL.
| | 03:00 | That's because most database management
systems have their own implementation of
| | 03:06 | the core SQL language.
| | 03:08 | If you work with Oracle, you're
using something called PL/SQL.
| | 03:10 | We're working with Microsoft SQL Server
and Microsoft's flavor of SQL they call
| | 03:17 | Transact-SQL or T-SQL for short.
| | 03:20 | It's still SQL at heart, but there are a
few simple things added to it that will
| | 03:24 | come in handy later on.
| | 03:26 | SQL is a language you can learn in a
few hours and be using it for decades.
| | 03:32 | Get rid of all the fancy GUI interfaces,
the query builders and the qizards and
| | 03:36 | you can still do anything you need to
do to a database as long as you have a
| | 03:40 | command line prompt and know a little SQL.
| | Collapse this transcript |
| Using SELECT statements| 00:00 | Let's begin by going through
some simple SQL to read or retrieve
| | 00:04 | information from our database.
| | 00:06 | I am going to open up SQL Server
Management Studio and connect to my instance here.
| | 00:12 | After it's open, the button that I am
going to click is this one, the New Query
| | 00:15 | button on the toolbar.
| | 00:17 | A query, well, that's the Q in SQL.
| | 00:20 | It's Structured Query Language.
| | 00:22 | We write queries and this one will use the
most common piece of SQL, the SELECT statement.
| | 00:29 | We are selecting or choosing information
from one of the tables in one of our databases.
| | 00:35 | So I am going to write this phrase to
begin with SELECT *, using the asterisk, From.
| | 00:40 | I want to get everything from somewhere.
| | 00:43 | Well, there's the question. Which database?
| | 00:46 | Which table?
| | 00:48 | Because in SQL Server Management
Studio I can see that I have got quite a few
| | 00:51 | databases, even the system databases.
| | 00:54 | And I could be writing a select
statement that goes against any of them.
| | 00:57 | So I am first going to have to
say which database I'm coming from.
| | 01:00 | So I'm going to say I
want to use AdventureWorksLT.
| | 01:03 | So I will type A and I immediately get
this IntelliSense, this auto complete
| | 01:08 | that pops up which is great.
| | 01:09 | I am going to come down with my cursor
key to AdventureWorksLT and that's the
| | 01:13 | one that I am going to use, the LT
version, then do a dot, and then instead of
| | 01:17 | getting directly to the tables, I am
getting to the schemas and roles here.
| | 01:21 | I will explain that in just a second.
| | 01:22 | But for the moment, I will select
SalesLT., come down to Customer.
| | 01:29 | This is actually a complete SQL query.
| | 01:32 | I don't need to finish it with a
semicolon or anything like that.
| | 01:36 | I can actually go ahead and run or
execute this either by clicking this button
| | 01:40 | that says Execute or I could
hit the F5 key on my keyboard.
| | 01:44 | It would do the same thing.
| | 01:46 | Down here it says Query executed successfully.
| | 01:48 | It took 847 rows of data out of the
database and it's now showing them to me.
| | 01:54 | It is just a select, so you're
not going to find these are editable.
| | 01:57 | We are just reading this information.
| | 01:59 | By convention, you'll see that the SQL
keywords such as Select and Insert and
| | 02:05 | Update and From, and we will see quite
a few of them, are written in uppercase.
| | 02:10 | It actually doesn't matter.
| | 02:11 | SQL Server Management Studio and
even SQL Server is not going to care.
| | 02:15 | I could just as easily write select in
all lowercase and it would work as well.
| | 02:20 | But by convention of many, many years
you tend to see SQL statements written
| | 02:25 | with the keywords in uppercase.
| | 02:27 | If we were going to write a lot of SQL
statements, it would get a little tedious.
| | 02:31 | You'd have to write the name of the
database again and again and again, because
| | 02:35 | typically you are going against
the same database all the time.
| | 02:38 | But I do have to say which
database I'm interested in.
| | 02:41 | There's a couple of ways to do it.
| | 02:43 | I can put it in the From part to say
explicitly what table and what scheme and what database.
| | 02:49 | Another way that I could do it if I
was going to write many SQL statements is
| | 02:54 | before the first one, I just have
the phrase Use AdventureWorksLT.
| | 03:00 | This would do exactly the same thing.
| | 03:02 | If I hit Execute again, I
will see the same results.
| | 03:05 | Another way that I could do it, if you
notice that this Use AdventureWorksLT,
| | 03:10 | we've also got it popping up here.
| | 03:12 | This is the equivalent.
| | 03:13 | It's actually selecting the database
that we are interested in right now.
| | 03:18 | So, I can also get rid of that and just
make sure that the correct database is
| | 03:22 | showing up in SQL Server Management Studio.
| | 03:26 | Execute and there we go.
| | 03:28 | It's a common problem for beginners
that you're writing a piece of SQL and
| | 03:32 | you think it's correct, but without you
noticing it, the wrong database is highlighted.
| | 03:38 | Say master is the very common default
database and when you execute, it says
| | 03:43 | "I have no idea what
this SalesLT.Customer is."
| | 03:48 | So I will make sure I'm on the right one.
| | 03:49 | Now I am using the SELECT * here.
| | 03:54 | SELECT * just means select everything.
| | 03:57 | Give me every column in this particular table.
| | 04:01 | While that's nice and convenient when
you're in SQL Server Management Studio,
| | 04:04 | you probably don't want to end up doing that.
| | 04:07 | Because when you're writing say an
application, of course the database may change.
| | 04:11 | So you want to be very specific about
the columns you are going to retrieve.
| | 04:14 | All I can see that I have things
like FirstName, MiddleName, LastName,
| | 04:18 | SalesPerson, his EmailAddress is here.
| | 04:21 | So I can instead of using the
asterisks, I can say I would like FirstName.
| | 04:27 | And you notice I have IntelliSense there.
Comma, LastName, comma, EmailAddress From SalesLT Customer.
| | 04:36 | I can break this up onto another line as well.
| | 04:39 | This will work just fine.
| | 04:40 | If I hit Execute now, then I
get a filtered amount of data.
| | 04:44 | This is what you want to do as a
general rule unless you are writing really
| | 04:47 | casual SQL statements.
| | 04:49 | Be specific about the
columns that you're interested in.
| | 04:52 | Now, if we were writing this SQL
because, for example, we were going to be
| | 04:56 | printing this information on a report,
we might even want to combine the
| | 05:01 | FirstName and LastName.
| | 05:02 | Even though they are stored separately
in the database, which is a really good way
| | 05:06 | of filtering and sorting things,
combining them there is a way we are going
| | 05:10 | to write them out in a report or an email.
| | 05:13 | Well, we can combine them on the fly within SQL.
| | 05:16 | I can actually instead of using the
comma here, I could use the plus sign to
| | 05:21 | concatenate or join these two together.
| | 05:23 | Now, if I just use the plus sign,
we are going to have a problem.
| | 05:26 | If I hit Execute, what I am going to
see is we are combining or concatenating
| | 05:32 | these two together into this and it
says, "Well, there's no column name."
| | 05:36 | It is no FirstName or LastName.
| | 05:37 | It's kind of something in-between.
| | 05:39 | Not only that, but we have the FirstName
and LastName squished up against each other.
| | 05:45 | Well, we'll fix that in two ways.
| | 05:47 | One is I am going to say that rather
than combine FirstName and LastName
| | 05:51 | directly together, I'm going to
combine them with a space in the middle.
| | 05:55 | Now, when we are doing a space or a string,
we use the single quotes to separate it.
| | 06:01 | So I am doing single quote, space, single quote.
Add FirstName, then a space, add LastName.
| | 06:06 | We will execute that and that looks a
little better in the values that we are
| | 06:11 | getting back, but it still says No column name.
| | 06:14 | It probably be useful to have a kind of
madeup or constructed column name here.
| | 06:19 | The way we do it is this.
| | 06:21 | We are saying I want to select
FirstName and space and LastName AS FullName.
| | 06:27 | There isn't a FullName column in that table.
| | 06:30 | So not a problem there.
| | 06:31 | But we can make it seem like there is.
| | 06:33 | So I execute that and now it seems
like we are retrieving the FullName column
| | 06:38 | and the EmailAddress.
| | 06:40 | So what we've seen very quickly is
just by using a few little key phrases,
| | 06:44 | we can start to get very flexible about
the information that we're retrieving.
| | 06:48 | Now, right now I'm bringing back
847 rows. That might not be what I want.
| | 06:53 | We are going to go ahead and
start adding on to this simple SELECT
| | 06:57 | statement where we are saying select
the data that we want from the table
| | 07:03 | that we are interested in.
| | 07:04 | But we need to move on and make sure
that we are only retrieving the data in the
| | 07:08 | right circumstance or in the right
order or when certain conditions are true.
| | 07:13 | So we are going to build on that next.
| | Collapse this transcript |
| Changing the default database| 00:00 | When you first begin working with
SQL Server Management Studio, a lot of
| | 00:04 | people do write queries.
| | 00:05 | That's how they're getting to
grips with the database and with SQL.
| | 00:09 | Some folks can get a little
frustrated by the fact that when you reopen
| | 00:12 | Management Studio and click New Query,
you will find this drop-down list of the
| | 00:18 | default database often
shifts back to whatever it was.
| | 00:23 | Meaning that you have to remember
to change it or to write the word USE
| | 00:28 | AdventureWorksLT for example, or to include
the name of the database in your SQL statement.
| | 00:33 | And that can be a little annoying.
| | 00:35 | Now what a lot of people try and do is
they say, okay, if it keeps coming up
| | 00:39 | with master or a different database,
they go and look in say Tools > Options
| | 00:44 | and they try and find some setting in SQL
Server Management Studio where this is controlled.
| | 00:50 | And they won't find one.
| | 00:51 | So sometimes they give up and say, well,
it's always going to be master or it's
| | 00:55 | always going to be a particular database.
| | 00:57 | Well, really, this setting has not a lot
to do with SQL Server Management Studio
| | 01:03 | and more to do with how you are logged
on to this database instance, because
| | 01:08 | every user has their own identity in SQL Server.
| | 01:12 | If I expand the Security folder,
the one right of the top here,
| | 01:15 | I am going to expand Logins
and find myself listed here.
| | 01:19 | This is all the information about
me as a user logged on to SQL Server.
| | 01:23 | I right-click and select Properties.
| | 01:26 | What I will find is that
I have a default database.
| | 01:30 | And what's happening is Management
Studio is just reading my settings.
| | 01:34 | What I need to do is change this to,
for example, AdventureWorksLT, click OK,
| | 01:41 | and now if I close down Management Studio
and a little later or the next day I
| | 01:47 | reopen it, I connect to that instance,
and I say I want to make a new query,
| | 01:51 | it's going to read my data, say what is
your default database, and that's what
| | 01:56 | will show up in this drop-down list.
| | 01:58 | So, you might find that
convenient from time to time.
| | 02:01 | Though do bear in mind that every
different user has a different default
| | 02:05 | database and if somebody else has a
different one from you, you might not
| | 02:09 | necessarily just be able to copy and
paste them SQL in an email and have it work.
| | 02:14 | But this makes it a bit more convenient
than remembering to type the name of the
| | 02:18 | database all the time in your SQL.
| | Collapse this transcript |
| Creating conditions in SQL| 00:01 | So we have this very simple SQL query,
selecting these three columns from the
| | 00:06 | SalesLT.Customer table in
the AdventureWorksLT database.
| | 00:11 | If I execute that, it's going to
bring back the entire contents of that
| | 00:14 | table, which is 847 rows.
| | 00:17 | But I can either see by scanning through it
or down here in the status bar, 847 rows.
| | 00:23 | But of course, if I don't want all
those rows available, if I want to filter
| | 00:27 | that information, it's a very common thing.
| | 00:30 | So, the way that I do it is
by using the WHERE keyword.
| | 00:35 | I only want to bring back that data
where people have a certain last name or
| | 00:41 | have a certain email address or their
customer ID is in a particular range.
| | 00:43 | Now it all depends on what kind
of data that you're filtering on.
| | 00:47 | So, for example, if I wanted to bring
back information where the LastName of the
| | 00:51 | person was equal to Vargas,
| | 00:54 | well, if it's text I need to write it in quotes.
| | 00:58 | Another single quote again here.
| | 01:00 | If I execute that, I get in
this case four rows coming back.
| | 01:04 | It looks like my table may even have
some duplicate data that I will need to
| | 01:08 | look at a little later.
| | 01:09 | You'll find that this
equality is case insensitive.
| | 01:13 | That is based on the collation all the database.
| | 01:15 | So whether it's lowercase v or
uppercase V, it doesn't matter.
| | 01:18 | But I do need the quotes.
| | 01:20 | After all if I was missing the quotes,
the SQL Server database is trying to
| | 01:25 | imagine that this is probably a column.
| | 01:26 | I try and execute it.
| | 01:28 | It says I have no idea what this is meant to be.
| | 01:31 | So if it's text, it's in the single quotes.
| | 01:34 | If however it is a number,
| | 01:36 | so for example this table has
a CustomerID, which is numeric,
| | 01:41 | it's just an integer,
| | 01:42 | I could say CustomerID = 600.
| | 01:45 | I don't want the quotes here and I
am now retrieving that piece of data.
| | 01:49 | Now you notice that I can put a WHERE
clause here based on a column that I'm not
| | 01:56 | retrieving in my SELECT part of the
statement, which is perfectly acceptable.
| | 02:01 | I can either be bringing back
CustomerID or not. it doesn't matter.
| | 02:04 | I can still filter on it.
| | 02:05 | Now just as we have the equal sign, we could
always say WHERE CustomerID > 600 and execute that.
| | 02:14 | 466 rows returned.
| | 02:16 | Well, surprisingly again, we have the less than sign,
less than and equal to, all the usual suspects.
| | 02:25 | We can also describe a range.
| | 02:27 | I could say WHERE CustomerID >600 and
it's >800 and the way that I would
| | 02:33 | write is using the keyword AND actually written
out here. AND CustomerID < 800. Execute that.
| | 02:43 | We get 59 rows returned.
| | 02:46 | We also have a slightly more readable
way of doing it where I could actually say
| | 02:50 | WHERE CustomerID between 600 and 800.
| | 02:57 | However, this one is considered an
inclusive statement, meaning that if I was
| | 03:02 | actually retrieving the CustomerID as
part of my statement, just to take a look
| | 03:07 | it at, we can see that when
it says between 600 and 800.
| | 03:11 | It's like a greater than or equal to.
| | 03:13 | So we are retrieving 600 there rather than
a greater than sign, which would skip the 600.
| | 03:21 | You can also do this with
textual or character fields.
| | 03:33 | Although in this case because we have
no one exactly matching A and C, we are
| | 03:37 | just bringing back all the B LastNames.
| | 03:41 | If you wanted to check for multiple
values where you're interested in several
| | 03:45 | different LastNames,
| | 03:46 | for example, we could of course say
where a LastName = Smith or LastName =
| | 03:51 | Bright or a LastName = Bremer.
| | 03:54 | Just like having the AND
we can have an OR statement.
| | 03:56 | But we can also use the
keyword IN to describe a range.
| | 04:09 | Because I'm checking for a text value,
I do need to surround each independent
| | 04:15 | value with the single quotes
and just separate them by commas.
| | 04:20 | Now getting a little bit more flexible
with this, let's say for example that we
| | 04:24 | have been retrieving some
information including the CompanyName.
| | 04:29 | And when we are scanning things,
we are finding several companies with very
| | 04:33 | similar names, like Metro for example.
| | 04:38 | Well, what I could ask is to bring back
this information where the CompanyName
| | 04:45 | begins with the word Metro.
| | 04:47 | The way that I do this is I
actually use the keyword LIKE.
| | 04:54 | I type in the text that I want to find
and for whatever else it could be,
| | 04:57 | the wildcard is the percent sign.
| | 05:00 | In a lot of languages or other ways of
doing this, this might be represented
| | 05:04 | with an asterisk, but in SQL it's
the percent sign and we use LIKE.
| | 05:08 | So this should bring me back
anything where the company name begins with
| | 05:12 | Metro, anything else.
| | 05:14 | We click execute, and oops!
| | 05:16 | Unfortunately, what I've got to
be careful with this is I had Metro
| | 05:19 | actually highlighted.
| | 05:20 | That means it was just
trying to execute that word.
| | 05:23 | I do need to make sure that I haven't got
any particular piece of text selected there.
| | 05:26 | And there we go. We are bringing back 14 rows
with several different places, Metro Cycle Shop,
| | 05:32 | Metropolitan Bicycle
Supply, Metro Manufacturing.
| | 05:38 | Again, like any text
operation this is case insensitive.
| | 05:41 | So it doesn't matter whether it's an
uppercase M or lowercase m. You can also
| | 05:46 | put the % sign at the beginning of the
word, and in this case this would do
| | 05:51 | a wildcard search for anything in
the company name column that had etro
| | 05:57 | anywhere in that string.
| | 05:59 | I execute that and we are also getting
back Petroleum Products Distributors.
| | 06:05 | If however, you're just looking for a
single letter, you can represent that with
| | 06:10 | the underscore in your LIKE statement,
which in this case brings back the same
| | 06:16 | information, but is a
slightly more specific way to do it.
| | 06:20 | Do you bear in mind that if you're
doing lots of wildcard searches, this can
| | 06:24 | be very inefficient, particularly on
large databases if it has to scan the
| | 06:30 | tables and go through every column
row by row figuring out if these letters
| | 06:35 | occur anywhere there.
| | 06:36 | Now depending on the data that you
are retrieving, sometimes you will get a
| | 06:41 | value and sometimes you won't.
| | 06:43 | If I retrieve the MiddleName, for
example, I can scan the data returned and see
| | 06:47 | that several of them have NULL being returned.
| | 06:51 | This is also slightly
highlighted to indicate it's not word null.
| | 06:55 | It is a NULL value.
| | 06:56 | There's nothing here.
| | 06:57 | Well, what if I wanted to only
retrieve those rows where that value was NULL?
| | 07:03 | Well, I might be tempted to say WHERE
MiddleName = NULL and we try and execute
| | 07:14 | that and nothing comes back.
| | 07:16 | Because that's not the word that we use
when we are checking for the existence of NULL.
| | 07:21 | What we want is the word IS where
MiddleName IS NULL, not = NULL, because
| | 07:27 | a quality is a value.
| | 07:28 | This is the lack of a value.
| | 07:29 | So, now I'm retrieving the 343
rows where MiddleName is NULL.
| | 07:36 | Conversely, if I'm just interested in
the fact where it's not NULL, well,
| | 07:41 | we just say IS NOT NULL and execute that.
| | 07:47 | And now, we only have the rows where
the MiddleName is not NULL and has a value.
| | 07:54 | You can of course get a little deeper
than this on your conditions and we'll
| | 07:58 | see how to connect values to other tables and
what's going on in other parts of the database.
| | 08:03 | But with what we've just seen, that'll
get you writing most of the conditions in
| | 08:08 | at least your basic SQL statements.
| | Collapse this transcript |
| Sorting your output| 00:00 | So let's take the idea of
filtering our data a bit further.
| | 00:04 | In this very simple SQL statement I am
retrieving all the product information
| | 00:10 | from the Product table here, and I
have got a lot of different things in
| | 00:13 | different colors, with names
and Product IDs and list prices.
| | 00:17 | What I would like to do is go buy
the cheapest to the most expensive.
| | 00:22 | Well it's yet another SQL clause and
we'll put it right at the end of the SQL
| | 00:27 | statement, and I'll just put in Order By.
| | 00:30 | Well, order by what?
| | 00:31 | Well, in this case I'd
like to Order By ListPrice.
| | 00:35 | I hit F5 to execute that and we
are going with the ordered ListPrice.
| | 00:41 | By default it will be ascending.
If we want to make it descending we just
| | 00:45 | type-in the word DESC afterwards,
hit Execute and now we have by
| | 00:50 | ListPrice descending.
| | 00:52 | You can if you want to pick multiple
columns to order on, so I could order for
| | 00:57 | example by Color, ListPrice, and what
this would do is order by color ascending
| | 01:04 | and then ListPrice descending within it.
So if I execute that we have first off
| | 01:09 | all the Null colors because that
will come before any values and they are
| | 01:13 | ListPrice descending, and then black and
then blue and multi and red and so on.
| | 01:19 | You can of course combine this with the
WHERE clause to filter these even more.
| | 01:25 | So if I wanted to just ask for Color =
'Red', well I now don't really need to
| | 01:30 | order by color, but just have the red
products ordered by ListPrice descending
| | 01:36 | and we get 38 rows instead of nearly 300.
| | 01:40 | Now a lot of the times when you start
to order your data you might even not be
| | 01:46 | interested in the full amount.
So say in this case when I am ordering by
| | 01:51 | ListPrice descending I might not be
interested in the fact that there is 295 of them.
| | 01:56 | But I might be interested in the most
expensive 10 or the most expensive 20.
| | 02:01 | What we can do if we only want to have
say ten results is I can put right after
| | 02:06 | the SELECT TOP 10. Now I'll
split this up onto a separate line.
| | 02:11 | It doesn't matter if you kept it altogether
but this might be a little easier to read.
| | 02:15 | So select the top 10 ProductID, Name,
Color, and ListPrice from the Product table,
| | 02:20 | order by ListPrice descending. It will do
the ORDER BY first and then just return
| | 02:24 | the top ten values, so in this
case we are getting ten rows back.
| | 02:28 | Quite similarly you can also go, let's
say if we wanted the top quarter products,
| | 02:33 | we could say TOP 25 PERCENT, hit F5,
and in this case we are getting about 74 rows
| | 02:40 | and seeing as the amount
of total rows is nearly 300,
| | 02:44 | that looks about right.
| | 02:46 | And very simply one of the ways we
could actually get the first most expensive
| | 02:51 | list price we could go and use the MAX
function, but in here I am just going to
| | 02:56 | say SELECT TOP 1. We'll find
the most expensive product.
| | 03:00 | Now it is possible here that there
could be multiple ones with that exact same
[00:03:05. Even though we are
ordering by ListPrice descending it's really
| | 03:09 | going to be a bit of the luck of the
draw which one we get if we are limiting
| | 03:12 | it to only one result, and it's more
about how that data will be internally
| | 03:17 | stored in the table.
| | 03:18 | But it can certainly be very useful.
And that's how you start to sort your results.
| | Collapse this transcript |
| Using aggregate functions| 00:01 | Next up, we have a few more keywords
to work with an SQL and these would be
| | 00:05 | grouped under the idea of something
called aggregate functions, which is a
| | 00:08 | fairly unpleasant name for a very useful piece.
| | 00:11 | Now we've seen already how we can do a
simple select statement like this, SELECT
| | 00:16 | * FROM SalesLT.Product,
and this returns everything.
| | 00:20 | All our columns, all our rows and in
fact, I can see it's 295 rows either
| | 00:24 | by scrolling down to the bottom of the
results or just reading it here in the status bar.
| | 00:29 | But what if that was the
piece of information I wanted?
| | 00:32 | What if I just wanted to
know the answer was 295?
| | 00:36 | We have 295 products.
| | 00:38 | I don't care about the rest of the data.
| | 00:40 | Well, I can do that by using
a piece of SQL called COUNT.
| | 00:45 | And what I'm going to do is give it
a little argument here, a little bit
| | 00:50 | of information that says I want the
count of everything. SELECT COUNT(*)
| | 00:53 | FROM SalesLT.Product.
| | 00:54 | Execute and it basically
returns just that value, just 295.
| | 01:00 | I can see that I don't
have a column name for it.
| | 01:02 | If it was important for me to have a
column name, I could perhaps return it as
| | 01:08 | TotalProducts and execute it that way,
but that might be necessary if I was
| | 01:13 | sending this SQL back to a developer.
But this is all I need, SELECT COUNT(*).
| | 01:18 | Now occasionally I'm asked, is it really
important that I have the star, for example?
| | 01:25 | Because if all I was doing
earlier was bringing back ProductID From
| | 01:30 | SalesLT.Product, that's 295 as well.
| | 01:33 | So couldn't I just say SELECT COUNT of
ProductID, instead of COUNT(*), and you can in fact.
| | 01:41 | If I do that I'll get the same result, 295.
| | 01:44 | You just need to be careful here because star
will always give you the count of everything.
| | 01:52 | If you pick another column, so if I was
to pick Color, which is a column in the
| | 01:58 | Product Table, and execute that,
well, in this case I get 245 instead of 295
| | 02:05 | because what it's doing is it's
ignoring any null values that might occur.
| | 02:10 | So as a general rule if you want a
count of everything, it's SELECT COUNT(*).
| | 02:15 | You can of course also use WHERE clause,
as if you want to restrict the results
| | 02:19 | to where products have a color of red.
I could just type that in and execute it.
| | 02:24 | I still got the count and in this case it's 38.
| | 02:26 | Now sometimes however the
count isn't what you want.
| | 02:30 | If you're looking at some of the data
that you have, in this case, I'm going
| | 02:33 | to back to selecting everything, I can
see that I have a lot of products and
| | 02:37 | they're all split up with different list
prices and standard costs and weight and so on.
| | 02:42 | But what if I wanted to find out
what the maximum ListPrice was?
| | 02:48 | Well, I could do an ORDER BY with the top one or
I could do something like this. use the word MAX.
| | 02:54 | Now in this case I wouldn't say MAX(*)
because it's not the max of everything.
| | 02:59 | I want the maximum of the column ListPrice,
hit Execute on that, and it tells me
| | 03:05 | the most expensive thing was 3578.27.
| | 03:10 | Well, if we have MAX, it's a pretty good
guess that we're also going to have MIN
| | 03:14 | and we do, 2.29, and we also have AVG.
Give us the average price and if you want
| | 03:22 | to of course you can start to throw
some of these together, using several of
| | 03:30 | these aggregate functions to in this
case return the maximum and the minimum and
| | 03:35 | the average price of our products.
| | 03:38 | Again, I don't have to use the AS
keyword here. I just think it's a bit more
| | 03:42 | useful if you're doing multiple
functions that return different columns to
| | 03:47 | give them all names.
| | 03:48 | Now depending on the kind of data that
you're working with, these may be what
| | 03:52 | you are looking for.
| | 03:53 | For example, if I open up my
AdventureWorksLT database, I know that I have
| | 03:58 | things like
SalesOrderDetails and SalesOrderHeaders.
| | 04:02 | I am going to just quickly SELECT *
FROM SalesOrderHeader and by scanning
| | 04:13 | some of that information, I can find
things like the TotalDue and SubTotal
| | 04:19 | and Freight amount.
| | 04:20 | Well, let's say what I wanted to do is find
the maximum amount of all our sales orders.
| | 04:26 | Of course, we can use MAX as we've done
a little earlier, but what we can also
| | 04:36 | do here is use the word SUM.
| | 04:39 | SUM, instead of just counting
them, will total them all up.
| | 04:43 | When some people new to SQL kind of get
a little mixed up between SUM and COUNT.
| | 04:48 | Remember that COUNT is just going
to give us the number of rows that
| | 04:53 | had something in them.
| | 04:54 | In this case 32 whereas SUM is going
to take the TotalDue column and add
| | 04:59 | them all together, and that's often very
useful when you're working with financial data.
| | 05:04 | Now going back to the Product Table, I'm
going to start off with something quite simple.
| | 05:14 | Now we've seen how we can use the word
COUNT to get a total number of products
| | 05:20 | or add the WHERE clause to filter that down.
| | 05:25 | Well, what if I wanted to
have the counts grouped by color?
| | 05:31 | It's quite a common thing that what
people will try and do is they will say
| | 05:34 | well, perhaps I can say SELECT COUNT(*),
Color, and execute that, and the problem
| | 05:42 | is you're going to get this message
that it can't give you Color because Color
| | 05:46 | is not part of an aggregate function.
| | 05:48 | You get this wonderful phrase it is
not contained in either an aggregate
| | 05:51 | function or the GROUP BY clause.
| | 05:53 | If you see this message that says the GROUP
BY clause, that's kind of a little heads up.
| | 05:57 | There is another part of SQL that can
probably give you what you're looking for.
| | 06:02 | What I'd like to have here is the
different counts for the products with
| | 06:06 | different colors or grouped together
and I don't want to run that as several
| | 06:10 | different SQL statements.
| | 06:12 | So this is the way you do that.
| | 06:14 | I want both the COUNT and the Color, but
I need to tell SQL Server that you need
| | 06:23 | to group the results by color.
| | 06:25 | Once this GROUP BY clause has been added,
it will allow this first column to be
| | 06:30 | retrieved in that statement.
| | 06:32 | I execute that, and this is what we get
in return: 89 Black, 26 Blue, 1 Gray, 8
| | 06:41 | Multi and 50 other products that
have a NULL value in the Color column.
| | 06:46 | Now if you start to use things like
GROUP BY, you can also use some of the other
| | 06:52 | aggregate functions as well.
| | 06:53 | So I could start to kind of mix them
up here, say for example MAX (ListPrice)
| | 06:58 | and we're still showing the color and
grouping by color, and in which case we're
| | 07:02 | getting the maximum list price for each color.
| | 07:04 | So, very useful ways of getting to the
important parts of your data, simply by
| | 07:09 | using some of these aggregate functions.
| | Collapse this transcript |
| Finding unique values| 00:01 | Okay, next up is a fairly easy one.
| | 00:02 | Let's say I have got a straightforward
SQL statement here, just selecting star
| | 00:07 | from SalesLT.Address, and I scan some
of this information and see that I've
| | 00:12 | got a lot of information such as different
states and different countries and regions.
| | 00:16 | And what I might be interested in this is this.
| | 00:19 | I don't really care about the
individual pieces of data, but I'd like to know,
| | 00:23 | for example, what the different
countries are that we ship to.
| | 00:27 | Well, I could start off by
just filtering this data down.
| | 00:31 | Rather than SELECT *, I'll just
say well, SELECT CountryRegion FROM
| | 00:35 | SalesLT.Address and execute that.
| | 00:39 | It still returns 450 rows that I could
scan through, and it certainly doesn't look
| | 00:43 | like there are too many countries, but
just to be sure how could I start to ask
| | 00:48 | for those individual values.
| | 00:50 | I really just want to know it is Canada,
the US, and whatever counties there are.
| | 00:54 | Well, this is what I do.
| | 00:56 | I use the word DISTINCT in the SELECT
statement just before the actual column
| | 01:02 | that I'm interested in, which really
means only bring me back an individual value,
| | 01:07 | just bring it back once for each
value, even if it's repeated. I execute that.
| | 01:13 | We get now the distinct values for
this column, which is Canada, United
| | 01:17 | Kingdom, and United States.
| | 01:18 | Now, if you find it useful, you can
even go a little deeper than that.
| | 01:22 | If I, for example, wanted to find both
the distinct country regions and within
| | 01:27 | that, we're actually storing StateProvince too.
| | 01:30 | That's one of the columns in this table.
| | 01:33 | I don't need to use the word DISTINCT
again, but if I execute this line, what
| | 01:38 | I'll get is the distinct countries
and the distinct state provinces, whether
| | 01:42 | they're repeated or not.
| | 01:44 | DISTINCT can be a very useful keyword
when you find yourself getting too much
| | 01:48 | data back and you really just want to
filter it down, and in fact you'll find
| | 01:51 | that using this DISTINCT keyword can
actually be very useful even if you feed it
| | 01:55 | into one of the other functions.
| | 01:57 | For example, I could surround that
phrase with the COUNT function, execute that,
| | 02:07 | and I just get the answer. How
many countries do we ship to? Three.
| | 02:11 | I'm counting the distinct
ones and just totaling them up.
| | Collapse this transcript |
| Joining multiple tables together| 00:00 | After awhile you are going to
find that be very straightforward SQL
| | 00:03 | statements, like this one where I'm simply
selecting three pieces of data from the Product table,
| | 00:09 | well they don't get all
that fantastically useful.
| | 00:12 | What I'm retrieving here is the name of
a product, the color of the product, and
| | 00:17 | the ProductCategoryID, which in this case
is 18 or 27 or 23, which is not all that
| | 00:25 | helpful if I'm just reading this data.
| | 00:27 | I want to know what the category is.
| | 00:29 | Well I know that my database has the
category stored in it but it's not in this
| | 00:35 | table and here's why.
I have got a simple diagram
| | 00:38 | that's just showing these parts of
this AdventureWorksLT database.
| | 00:43 | There is a Product table with all
these columns in and then there a
| | 00:47 | ProductCategory table and this
is simply good normalization.
| | 00:53 | We can have multiple products in
category, so it's a good idea to take that
| | 00:57 | category data out and put it in its
own table. And what this really means for
| | 01:02 | MySQL statement is I want one SQL
statement to be retrieving data from two
| | 01:10 | different tables or even more potentially.
| | 01:13 | And we do this typically
through what's called a join.
| | 01:16 | We are joining two tables
together to get at data in both of them.
| | 01:19 | Now how we do that?
| | 01:20 | Well, rather than just say I won't
retrieve information from SalesLT.Product,
| | 01:26 | I'm going to use the word JOIN and say
I'm also going to retrieve information
| | 01:31 | from SalesLT.ProductCategory.
| | 01:35 | Now, as soon as I do this, we are going
to start getting these little squiggly
| | 01:39 | underlines here, that it's looking at
it and saying, "Well, Name is now ambiguous
| | 01:44 | and ProductCategoryID is now ambiguous."
| | 01:48 | Meaning that if I look at those
definitions of the tables, we have the Name in
| | 01:52 | the Product table and the Name
in the ProductCatagory table.
| | 01:55 | We have a ProductCategoryID in one
and ProductCategoryID in the other.
| | 02:01 | So SQL Server Management Studio is
already telling us there's a problem.
| | 02:05 | You need to get a bit more specific here.
| | 02:07 | Now the way we deal with this first
problem is we have to say okay, well
| | 02:12 | SalesLT.Product, I'm going to just
put the letter "a" after it and after my
| | 02:17 | second table I am going to put the letter "b".
| | 02:19 | Now the letters aren't important.
| | 02:21 | You could pick a, b, p, c. It's up to you.
| | 02:24 | "a" and "b" is pretty common and then
because you're naming the tables, you will
| | 02:28 | actually say well, if I have named the
first one "a" I am going to say that I am
| | 02:32 | interested in a.Name.
| | 02:34 | That is now no longer
ambiguous and thus quickly disappear.
| | 02:37 | It says "Okay, you want a.Name so I am
looking for the a table" and in this case I
| | 02:44 | want a.ProductCategoryID, just to
keep everything similar right now.
| | 02:48 | So that gets us pass the
ambiguous column names but then what?
| | 02:52 | Well I could try and execute this, but
the problem is its saying I have got an
| | 02:57 | issue here. I have incorrect syntax and
really what it's complaining about is you
| | 03:01 | are telling him to join these
two tables and it doesn't know how.
| | 03:05 | Now depending on which database
background you come from, you might be looking
| | 03:08 | at these relationships that you know
exist in the database and thinking well,
| | 03:12 | surely SQL Server already knows how to
join these two together. No, it doesn't.
| | 03:17 | It wants you to tell it.
| | 03:18 | So we have to say how are these tables joined
and the way we do that is we use the word ON.
| | 03:25 | And well they are joined is on the
ProductCategoryID. The ProductCategoryID
| | 03:30 | for a particular product should connect to
the ProductCategoryID for the Category table.
| | 03:36 | So what I am going to type is ON
a.ProductCategoryID = b.ProductCategoryID.
| | 03:45 | We have now described how the join happens.
| | 03:50 | I can execute that.
| | 03:51 | What we get right now is exactly the
same date as I got before, because I say
| | 03:57 | that I'm joining this new table of
ProductCategory, but not actually using
| | 04:03 | anything from it, because
what I want is the category name.
| | 04:06 | Now the category name in that table
is just called Name. We already have a
| | 04:11 | Name in our select statement but we
need the second one. Well luckily we've
| | 04:15 | already suffixed the table.
| | 04:16 | So we just say I also want b.Name, and
do notice that when I am using that b
| | 04:23 | or a it knows which table I am talking about.
| | 04:26 | So if I say a., it gives me all
the columns from the Product table.
| | 04:30 | If I say b., it's given me just the fewer
columns from the ProductCategory table.
| | 04:35 | So on b.Name, execute that one and now
we're bringing back this information.
| | 04:40 | We are joining the two together and we're
getting the names of the categories back.
| | 04:45 | In fact because of this I could
pretty much say I don't really care about
| | 04:49 | ProductCategoryID anymore, so I
could pull that off the SQL statement.
| | 04:54 | Now officially what's happening here is
we're doing what's called an inner join
| | 04:59 | and if I was to be very correct about
this, and I usually would be, I am actually
| | 05:04 | going to use the words INNER
JOIN instead of just JOIN here.
| | 05:08 | What INNER JOIN means is we are
only interested in those records where
| | 05:13 | they match on both.
| | 05:15 | So if there was anything in
ProductCategory that didn't have any products
| | 05:19 | attached to it, we don't care.
| | 05:21 | If there were any rows in Product
that did not have a ProductCategoryID,
| | 05:26 | we wouldn't care about those.
| | 05:27 | We are only showing the rows where this
information that matches in both tables.
| | 05:33 | Again if I execute that, changing it to
INNER JOIN, we get exactly the same results.
| | 05:38 | There is also something called in OUTER JOIN.
| | 05:41 | An OUTER JOIN means we are going to
pick one of the tables and say well, we are
| | 05:45 | interested in say all the Product
Categories and all the matching products.
| | 05:51 | That sounds a little weird.
| | 05:52 | So let me just demonstrate
what the difference would be.
| | 05:54 | Right now we are doing an INNER
JOIN, which gives us 295 rows.
| | 05:59 | I'm going to do what's called an OUTER
JOIN, but I can't just write OUTER JOIN
| | 06:03 | because it's going to get a little bit puzzled.
| | 06:06 | With an OUTER JOIN you're always saying one
of these tables takes presence over the other.
| | 06:11 | We are always going to
have everything that's in one.
| | 06:14 | So we have to say am I interested in
the second table, the one on the right, or
| | 06:20 | am I interested in the first table,
the one on the left of the JOIN statements.
| | 06:24 | And what I would actually say is
either left OUTER JOIN or right OUTER JOIN.
| | 06:30 | And what I am actually going to say here
is I want to do a right OUTER JOIN on
| | 06:34 | the ProductCategory table.
| | 06:36 | Here is what the difference is.
| | 06:37 | I execute that, bang!
| | 06:39 | I actually have 299 rows now because
we get four new rows and this is the
| | 06:45 | difference, those first four.
| | 06:47 | What's actually happening here is we're
bringing back the names from the second table,
| | 06:52 | the ProductCategory table, of Bikes,
Components, Clothing, and Accessories,
| | 06:57 | and it's actually telling us there is
nothing in the Product table that is
| | 07:02 | actually pointing directly to those categories.
| | 07:06 | But I want to list the categories anyway.
| | 07:09 | Now the reason for this in this
particular example is that this table has
| | 07:14 | categories that reference each other,
but there are no products that actually
| | 07:19 | have the ProductCatagory Bikes, no
products with Components, no product with
| | 07:22 | Clothing or Accessories. And if we
want them to show up, we do a right OUTER JOIN,
| | 07:27 | giving precedence to
the ProductCategory table.
| | 07:30 | If we are only interested in the match,
we say INNER JOIN and they will go away.
| | 07:35 | Now there are a few other more
unusual join things like CROSS JOIN. I'm not
| | 07:41 | going to go through them in this course.
| | 07:43 | If you're interested again as with
everything, you want to be having a good look
| | 07:48 | at Books Online to see some further
examples of where you can go with this.
| | 07:52 | Do bear in mind that lynda.com also
has a dedicated SQL course that gets into
| | 07:57 | some of these join ideas as well.
| | Collapse this transcript |
| Using subqueries| 00:00 | As you get more comfortable with
writing SQL statements, you'll find yourself
| | 00:04 | wanting to combine information from
multiple tables more often than not and
| | 00:10 | though a join is a classic way of
doing it, it's not the only way.
| | 00:14 | There is another way called a sub-
query and let me explain that by kind of
| | 00:17 | taking you step-by-step through the
roadmap of how you might get there.
| | 00:22 | So we start with something really simple.
| | 00:24 | We've got a SELECT * statement here.
| | 00:26 | It'll give me everything
from SalesOrderHeader.
| | 00:28 | Now if I execute that, I'm getting all
the totaling of my sales orders, including
| | 00:33 | things like the customer IDs and
the subtotal, and the total due.
| | 00:37 | And I of course can scan this
information just fine and look at it, but what
| | 00:41 | if I'm more interested in specific stuff.
| | 00:44 | What about if I want to know information
about the biggest order that ever happened?
| | 00:48 | Well, I could, of course, just do
something very simple like an ORDER BY.
| | 00:57 | TotalDue, which of course will give it to
me ascending which might not be that helpful.
| | 01:02 | So let's do TotalDue descending.
| | 01:05 | We execute that and we know then that
the first row should have the maximum
| | 01:10 | number that was ever ordered, and we
could scan more of that and look and try
| | 01:14 | to find our customer ID and so on.
| | 01:16 | But we're getting way more
information back than we want.
| | 01:19 | Really what I'm interested in is
customer information. Who did this?
| | 01:23 | Who placed this order?
| | 01:25 | Well, I could go to something simple.
| | 01:27 | Instead of saying SELECT *, we could
say SELECT CustomerID, execute, and we're
| | 01:34 | getting them returned in their order.
| | 01:36 | But I don't need the rest of them.
| | 01:37 | I just want this one.
| | 01:38 | Well, we could, knowing what we know
now, even say SELECT TOP 1 and we've
| | 01:44 | got that customer ID.
| | 01:45 | But the issue is, I don't know who this is.
| | 01:49 | What I'm interested in is what company
is this, who was the contact, and that
| | 01:53 | information is stored in a
different table, in the Customer table.
| | 01:57 | Okay, so we could do a join here.
| | 01:59 | I'm going to show you how you do with
the join and then with the sub-query.
| | 02:01 | So if we want to do a join, we know
that we need to add the JOIN word after the
| | 02:08 | first table and this is going to be an
inner join, because I'm not interested in
| | 02:12 | all the other customers.
| | 02:13 | I'm just interested in one.
| | 02:16 | So we're going to say
INNER JOIN SalesLT.Customer.
| | 02:20 | Now, of course, because it's immediately
saying this is now an ambiguous column,
| | 02:25 | because customer ID is in both tables,
we better do the little a and b to say
| | 02:32 | which tables these are.
| | 02:33 | I'm going to say SELECT TOP 1 a.CustomerID.
| | 02:37 | But we're still missing one thing.
| | 02:39 | Even though I've named two tables,
it doesn't know how to join them.
| | 02:42 | So what I'm going to do is the join word,
which is ON, and we have to name the columns.
| | 02:47 | Well, we're joining them based on the
column CustomerID that's in both the tables,
| | 02:51 | so a.CustomerID = b.CustomerID.
| | 02:52 | Now if I execute this, I should get
exactly the same result, because I'm not
| | 03:01 | asking for any new
information to be retrieved yet.
| | 03:03 | So let's just double-check that. Yup, 29736.
| | 03:05 | But what I can do is now
comma b. and I get CompanyName,
| | 03:14 | b.FirstName, b.LastName.
| | 03:22 | If I execute it, we can get
all that information coming back.
| | 03:26 | Now what's the issue? Well, not a lot.
| | 03:28 | I mean if this was commented, which we
could do in the raw SQL with just fetch
| | 03:34 | details for the biggest order,
it might be obvious what it is.
| | 03:40 | But if I was looking at this SQL
six months down the line, I might be a
| | 03:45 | little challenged to figure out exactly what
it was doing because it's not all that clear.
| | 03:49 | But it works, which is fine.
| | 03:51 | So let me show you the other way of
doing this that doesn't involve doing a join.
| | 03:55 | So I'll take it back to what we had
just a minute ago, which was fetch me that
| | 04:01 | TOP 1 CustomerID, no join needed.
| | 04:05 | We're getting that same
CustomerID back. Well, here's the deal.
| | 04:12 | I want the information from the Customer table.
| | 04:15 | So I am going to approach it
from the other end completely.
| | 04:19 | I'm just going to move that
down to the bottom a little bit.
| | 04:21 | I'm going to write a completely
separate SELECT statement that describes the
| | 04:25 | information I want, which is SELECT
FirstName, LastName, CompanyName FROM the
| | 04:36 | Customers table WHERE CustomerID equals.
| | 04:45 | The question is, equals what?
| | 04:47 | Well, I want this information from the
Customers table, whether CustomerID is
| | 04:52 | equal to what I got back from this
query, and that's what a sub-query is.
| | 04:58 | We're going to take the query that
returns the CustomerID and just feed it
| | 05:02 | into the first one.
| | 05:03 | I'm going to just put it
in the parentheses here.
| | 05:06 | So this first query, the inner query
or the sub-query, will be executed first.
| | 05:12 | We'll end up with the result 29736 and
it would be the same as saying give me
| | 05:16 | the FirstName, LastName, and
CompanyName from the Customer table, where
| | 05:19 | CustomerID equals 29736.
| | 05:22 | So we execute that and we get the
FirstName, LastName, and CompanyName, and
| | 05:27 | this is a sub-query, a query within a query.
| | 05:31 | Now it might sound like a sub-query and
a join are just choices, you just make
| | 05:36 | the decision one or the other.
| | 05:38 | Well, sometimes that's true, but you
will find as you get more familiar with them
| | 05:41 | sometimes it's more natural to do
a join, sometimes it's more natural to
| | 05:45 | do a sub-query, because there is
crossover, but they're not always the same.
| | 05:49 | There are instances when a sub-query
is a much better, in fact, sometimes the
| | 05:54 | only possible way to get some data coming back.
| | 05:57 | For example, let me take you through
another example of a sub-query, but this
| | 06:01 | time it will be something that will
be quite challenging to do in a join.
| | 06:04 | What I start to do is perhaps I
start writing a query like this.
| | 06:08 | I want the FirstName, LastName, and
CompanyName from the Customer table where
| | 06:13 | these customers have not placed any orders.
| | 06:18 | The question is well, how
do I find that information?
| | 06:22 | Now particularly when you've got a SQL
statement that needs to find some kind of
| | 06:26 | negative information, give me
information where this doesn't join to something,
| | 06:30 | that can be a little challenging.
| | 06:33 | And oftentimes, a little
trick of this is to turn it on its head.
| | 06:37 | Well, let's say how would I get the
first name, last name, and company name for
| | 06:41 | all the customers who
have ever ordered anything?
| | 06:44 | But what I really want is that
information where the CustomerID is to be found
| | 06:49 | in the SalesOrderHeader table.
| | 06:53 | So I could do that with the sub-query.
| | 06:55 | I'm going to create my sub-query down here
and then copy it up into the top level.
| | 06:59 | I'm going to say SELECT
CustomerID FROM SalesLT.SalesOrderHeader.
| | 07:10 | Now this little SELECT statement will give
me a lot of different CustomerIDs and
| | 07:15 | it could give me the same
ones again and again and again.
| | 07:18 | I only want the same CustomerID once.
If CustomerID 75 is placed seven orders,
| | 07:24 | I don't need seven
CustomerIDs of 75. I just want one.
| | 07:27 | So I'm going to say SELECT DISTINCT.
| | 07:32 | So if this part, which is going to be
my sub-query, returns a whole bunch of
| | 07:37 | different Customer IDs, how do I tie
it into the first one? Well, this is how.
| | 07:48 | We use the keyword IN, which is
going to allow us to provide a range.
| | 07:58 | Again, the sub-query is evaluated first.
| | 08:00 | Give me all the distinct customer IDs
that are found in that SalesOrde Header
| | 08:05 | table and then use that to bring me
the information from the Customer table.
| | 08:11 | So I execute that and we are actually
getting now 32 rows, which sounds about
| | 08:15 | right because there were 32 orders.
| | 08:17 | But what I originally asked for was I
want the information of the customers that
| | 08:24 | have not placed an order, whatever
that means. Maybe it was canceled, maybe
| | 08:27 | didn't make it all the way through.
| | 08:29 | Well, because we can use IN,
we can also use NOT IN.
| | 08:34 | We're taking a positive result of
selecting the distinct customer IDs and
| | 08:39 | getting it to feed us into
really kind of a negative result.
| | 08:43 | I want the customer
information where this is not true.
| | 08:47 | They're not in SalesOrderHeader.
| | 08:49 | So I execute that and this one I get
815 rows, a whole bunch of orders that
| | 08:56 | haven't been completed.
| | 08:57 | So this is a second example of the kind of
things that you could do with a sub-query.
| | 09:03 | Now word of warning.
| | 09:04 | This kind of information, particularly
on a group of large tables, could be quite
| | 09:09 | an inefficient query to run if you're
starting to scan through tables to find a
| | 09:16 | bunch of results and then say well,
where do all these results not match in some
| | 09:20 | other scanned table?
| | 09:21 | So a little word of warning there. Pay
attention to that and as you get a bit more
| | 09:26 | familiar with SQL, we're going to start
running into things like analyzing our
| | 09:29 | queries and taking a look at
how quick things are going to run.
| | Collapse this transcript |
| Viewing execution plans| 00:00 | After you've written a few more
complex SQL statements where you're using
| | 00:04 | joins and sub-queries, you'll
probably end up wondering, well which one is
| | 00:08 | better performance-wise?
| | 00:10 | Is one objectively faster
or slower than the other?
| | 00:13 | And of course it depends on how you are
doing the join and how you are doing the
| | 00:16 | sub-query, but there is a way to find out.
| | 00:18 | So I'm looking right now here at the
example I did in the previous module,
| | 00:23 | which is selecting the company with
the most expensive order, one way doing it
| | 00:29 | using a JOIN, Action Bicycle Specialists, and
one way doing a sub-query. Same data, same result.
| | 00:38 | But what if we want to know which one is faster?
| | 00:42 | Well there are quite a few ways of
doing it to get fairly detailed. You can get
| | 00:46 | into what's called the SQL Server
Profiler, but we don't need to go that heavy.
| | 00:50 | What I'm going to do is select the two
blocks that I want to do. This is now
| | 00:54 | considered our batch, but formally,
the entire file is because there is
| | 00:58 | nothing else in the file.
| | 00:59 | I'm going to come up here to my toolbar
and I'm going to click this button that
| | 01:03 | says Display Estimated
Execution Plan. Hit that, bang.
| | 01:09 | And what we are actually going to get
if I drag this up a little bit is the
| | 01:13 | execution plans for both of these.
| | 01:17 | And the reason that I wanted to do both
is so I can get them compared to each other.
| | 01:20 | So it's actually telling me that the
first one was 54% of the batch and the
| | 01:26 | second one was 46%. Not a huge
difference but not tiny either.
| | 01:31 | There's definitely a difference going on there.
| | 01:33 | Now the details are being shown up
graphically and as they are actually must
| | 01:37 | over and clicked on it will tell you
things like the I/O cost and the CPU cost.
| | 01:42 | Right now of course we're on a small
database and really all of this is going to
| | 01:47 | just be invisible to any user, but even
so, as you get more complex you'll find
| | 01:52 | yourself looking at execution plans a bit more.
| | 01:54 | Now what that will actually point out
to you is there are certain places where
| | 01:58 | it's doing what it calls index seeks.
| | 02:03 | That you'll find them in both of these
queries, and there are certain things
| | 02:08 | that you'll find in the execution
plans that are going to show up as having a
| | 02:13 | significant cost, like here
for example 55% was in the sort.
| | 02:18 | Okay, maybe a good thing, maybe a bad thing.
| | 02:20 | Now you'll find that a lot this
you won't be able to really change or play
| | 02:24 | with until you've started exploring
indexing, because it will expose some issues
| | 02:29 | where you have to traipse through the
entire table because there is no index to
| | 02:34 | allow you to drill down to a particular point.
| | 02:36 | But all we can get from this now, and
it's still valuable, is that right now it
| | 02:40 | seems that the 54%, which was the inner
join, and 46% was the sub-query, so the
| | 02:47 | sub query appears to be a bit of a winner here.
| | 02:51 | Formally though that is the estimated
plan. You can actually check this little
| | 02:55 | button on the toolbar to say Include
Actual Execution Plan, and what that means
| | 03:00 | it is really just the selection.
| | 03:02 | It's now got the little blue line,
blue box around it, and it means when I
| | 03:06 | execute this again I'll get both my
results, any messages that came back, and the
| | 03:12 | actual execution plan, which again looks
identical to the estimated one, which was
| | 03:17 | 54% for the join and 46% for the sub-query.
| | 03:20 | Again it's not always going to be the
case. Sometimes you'll find the join would
| | 03:25 | be the better way of doing it.
| | 03:26 | But starting to look at execution
plans. Even if you are not at this point
| | 03:30 | completely comfortable with what each
particular part of it means, it's a very
| | 03:34 | useful habit to start to get into.
| | Collapse this transcript |
|
|
7. Inserting and Updating DataWriting INSERT statements| 00:01 | Selecting information is all very well,
but after a while we are going to need
| | 00:05 | to start inserting some
information into those databases.
| | 00:08 | Now of course if you have SQL Server
Management Studio you can do the kind of
| | 00:13 | cheap and nasty way of doing it, which
is right-click one of these tables,
| | 00:17 | select the Edit Top 200 Rows, and either
start clicking and selecting in here to
| | 00:22 | change things, or you can scroll right
down to the bottom and where the asterisk
| | 00:27 | row is just start typing.
| | 00:29 | But this is not really a very
scalable way of doing some inserts.
| | 00:32 | It's really just there for emergencies.
| | 00:34 | We need to understand how to
construct SQL statements to do this.
| | 00:38 | Having said that, it is very useful
to often look at this this way to
| | 00:42 | familiarize yourself with
what data you are about to enter.
| | 00:45 | So I'm going to create a new query
and I'll be using AdventureWorksLT, as we
| | 00:51 | have been all along.
| | 00:53 | I'm going to insert into the
ProductCategory table here, simply because
| | 00:57 | it's quite a small one.
| | 00:59 | Again before I start writing the
insert statement let me take a quick look at
| | 01:03 | what I have here, just selecting from it.
| | 01:05 | We have ProductCategoryID, ParentCategoryID,
Name, then a rowguid and a ModifiedDate.
| | 01:14 | Well even just looking at this I might
have the idea that you know some of this
| | 01:18 | is going to be automatically generated.
| | 01:20 | If I want to double check that I
could right-click this table and select
| | 01:23 | Design, because if I wasn't a person who had
created it I'll certainly want to take a look.
| | 01:29 | So ProductCategoryID is
declared as the primary key.
| | 01:32 | It's an integer and if I scan the
properties of it I can see that it is set up
| | 01:37 | to be an identity automatically
incrementing, so I shouldn't be the person
| | 01:42 | inserting this value.
| | 01:44 | I should probably be the person inserting the
ParentCategoryID. Yeah, looks like the case.
| | 01:49 | It's not an identity.
| | 01:51 | I'll be the person inserting name.
| | 01:52 | And then we get to rowguid.
| | 01:53 | Well, this is a globally unique
identifier and it's set up with a default value
| | 01:58 | of the newid function, which means I
shouldn't insert this either and nor should
| | 02:03 | I do the modified date which is getdate.
| | 02:06 | So it looks like I'm only inserting two
things, the ParentProductCategoryID and the Name.
| | 02:11 | All right, well back to our insert
statement. Well I haven't started it yet.
| | 02:15 | In fact it's not the word INSERT. It's
actually the phrase INSERT INTO and now
| | 02:21 | we're going to use the name of the table.
| | 02:22 | We are inserting into SalesLT.
ProductCategory. Well then what?
| | 02:28 | Well I have to have a way of saying I
only want to insert those two particular
| | 02:34 | columns, which was
ParentProductCategoryID and Name.
| | 02:38 | The way I do it is open parenthesis
and I type the names of the columns that
| | 02:42 | I'm wanting to insert.
| | 02:43 | Then I use the word VALUES, then I have
another parenthesis where I enter in,
| | 02:55 | in the order that I declared them,
the values that I want to insert.
| | 02:59 | In my case I'm going to insert the
value of 1 for the ParentProductCategoryID
| | 03:04 | and I'm going to insert the phrase Hybrid Bikes.
| | 03:07 | And if you don't supply the column
names for the columns that you're going to enter,
| | 03:16 | the SQL Server will expect that
you're going to give it the values of
| | 03:21 | everything of every column,
but we don't need every column.
| | 03:24 | So I'm going to go ahead and
execute that and see what happens.
| | 03:28 | We hit it and we see one row affected.
| | 03:31 | It doesn't actually tell us what, but
we can get to that a little later on.
| | 03:36 | This is an INSERT statement.
| | 03:37 | It just says yes it worked.
| | 03:40 | If I want to prove that I could just
very quickly right-click, say Select Top
| | 03:44 | 1000 Rows, and come down right to the
bottom and there I can see Hybrid Bikes.
| | 03:49 | It has a guid that has been generated.
| | 03:51 | It has a modified date that's been generated.
| | 03:54 | I have a product category ID.
| | 03:54 | I've been playing around a little bit
with inserting stuff, so I can see that
| | 03:59 | I'm missing a few
numbers here. But that's okay.
| | 04:01 | It's looking good.
| | 04:03 | Going back to this, you can also, if you
want to insert multiple rows at the same time,
| | 04:08 | all I could do here is put a
comma and then another open parenthesis and
| | 04:14 | say perhaps here I'm putting
in something for Girls Bikes.
| | 04:19 | Now here is a question. What do I do if
I want to put in an spostrophe, because
| | 04:23 | if I just type it what's going to
happen is it's going to close my string here,
| | 04:29 | my little text thing.
| | 04:30 | Well the answer is this.
| | 04:31 | If you want to have the single
apostrophe and you have to use the single quote,
| | 04:35 | you just use 2. So this should
allow me to insert another entry here.
| | 04:41 | Now here interestingly we're going
to have a problem because there is a
| | 04:44 | constraint on this field that means it
should only have one product category
| | 04:50 | name of the same name. We've already
inserted Hybrid Bikes, so let's see what
| | 04:53 | happens if we try and insert this again.
| | 04:55 | I had Execute and unfortunately gives me
a violation of a UNIQUE KEY constraint.
| | 05:01 | Cannot insert a duplicate key in
object ProductCategory. Okay, that's fine.
| | 05:07 | Let's say that was an accident.
| | 05:08 | Anyway what I wanted was in this case
this should have been Boys Bikes. I'm
| | 05:13 | going to use the two single quotes as well.
| | 05:15 | That's not double quotes.
| | 05:17 | It's two single quotes and I'm
going to try and insert that.
| | 05:21 | There we go, two rows affected, and if
I right-click and do another select it
| | 05:28 | looks pretty good. We have
52, 54 and 55 going on here.
| | 05:33 | Although it does look like I
accidentally put some wrong data in the
| | 05:37 | ParentProductCategoryID,
| | 05:39 | all bikes should have a
ParentProductCategory of one.
| | 05:42 | Oh well. So I'll have to see how to
update that in just a few minutes.
| | Collapse this transcript |
| Writing UPDATE statements| 00:00 | Well just about as often as
inserting information you're going to need to
| | 00:04 | update information too.
| | 00:05 | Let say the example that I was
looking at, I know that I've got a problem
| | 00:09 | with one of these rows.
| | 00:11 | This last row here a
ProductCategoryID 55 should have had a
| | 00:15 | ParentProductCategoryID of 1 instead of 2.
| | 00:19 | So let's see how to go ahead
and do a simple example like that.
| | 00:22 | We will use the word UPDATE and we're
going to pick the table name, which is in
| | 00:27 | this case SalesLT.ProductCategory.
| | 00:29 | And just as SELECT has a FROM and
INSERT has INTO, UPDATE has a SET.
| | 00:38 | We're going to SET.
| | 00:39 | We want to say what the
values that we want to change are.
| | 00:43 | In this case it was
actually ParentProductCategoryID.
| | 00:46 | IntelliSense is smart enough to know
that if we're working with the
| | 00:49 | ProductCategory table these are
the only options that we have.
| | 00:52 | And then I can say and in this case I'm
going to do quite a specific change SET
| | 00:56 | ParentProductCategoryID equal to 1.
| | 01:00 | But if I were to run this code right
now it would update every single row in
| | 01:05 | the ProductCategory table and set back
column to one, which is certainly not what we want.
| | 01:10 | So when you're doing an UPDATE,
you tie a WHERE clause to it.
| | 01:14 | Exactly like a SELECT statement.
In fact more important than when you're doing
| | 01:18 | a SELECT statement.
| | 01:19 | So I want to say well, WHERE? Under
what conditions do I want to do this?
| | 01:24 | Again the example that I shown was that
we had an incorrect one right at the end
| | 01:29 | here, which was ProductCategoryID equal to 55.
| | 01:32 | Now I could use any of the same
WHERE clauses that I used in the select
| | 01:36 | statement but that's the easy one. So
I'll say WHERE ProductCategoryID equal to
| | 01:42 | 55 and let's execute that.
| | 01:46 | One row affected. Well right now just
like doing the INSERT the UPDATE doesn't
| | 01:51 | tell you anything about what it did.
| | 01:53 | It can but not this using a plain
old update statement like this, and this
| | 01:58 | would be something that we could
theoretically execute again and again and
| | 02:01 | again because it's just
going to do the same thing.
| | 02:03 | Not that I recommend it, but it should work
and now if I go and take a look at that
| | 02:08 | ProductCategory table we
should find that yes, indeed the
| | 02:11 | ParentProductCategoryID has been set to 1.
| | 02:14 | But do bear in mind that whatever you
put in the WHERE statement, whether it's
| | 02:19 | a range or whether you miss it out
entirely, if you had retrieved multiple
| | 02:25 | values, if you put that WHERE in the
select, you would update multiple values
| | 02:29 | if that's in an UPDATE.
| | 02:30 | Now what about if I wanted to
update multiple columns in that one row?
| | 02:37 | Well that's pretty easy. So I just have
that after the SET. We're setting the
| | 02:41 | first column here ParentProductCategoryID
equal to 1, Name equal to, for
| | 02:48 | example, Commuter Bikes and we
just execute that. One row affected.
| | 02:56 | Now this is the most you're going to
get right now of the information about
| | 03:00 | what actually happened.
| | 03:01 | Obviously you can do a
little bit more than that.
| | 03:03 | Let's say for example I
update a different table.
| | 03:07 | I'm going to update SalesLT.Product
and I'm going to set the list price.
| | 03:13 | Let's say we've had a conversation,
which is we want to increase our prices by
| | 03:18 | two dollars where our prices are less than 50.
| | 03:22 | Well I'm going to say SET ListPrice equal to.
| | 03:25 | Now how do I do this?
| | 03:26 | Well very easy. I just say ListPrice
equal to whatever ListPrice is +2 WHERE
| | 03:34 | ListPrice < 50. Execute and we see on
this 49 rows affected. Your number may be
| | 03:44 | slightly different if you're following along.
| | 03:46 | Now if you're constructing an UPDATE
statement and you again a little nervous about
| | 03:50 | how many rows you might affect,
| | 03:51 | do bear mind that the WHERE clause is
what you want to look at and before you
| | 03:56 | run your UPDATE statement you could, if
you're worried, about it just say SELECT
| | 04:02 | *FROM SalesLT.Product, keeping the same
WHERE clause, and figure out well how many
| | 04:09 | is that going to actually change?
| | 04:12 | In this case it is telling me 49 rows.
| | 04:15 | Now I might have had a slightly
different result because I've already executed
| | 04:18 | my update but this would give
you the verification of the update.
| | 04:22 | It's going to update as
many things as you expect.
| | 04:25 | Like everything else in SQL Server
you can get a little deeper than this.
| | 04:29 | I recommend that you check out some of the
available options that you will see for
| | 04:32 | the UPDATE statement on SQL Server Books
Online but that's the core of how to do
| | 04:36 | an UPDATE statement.
| | Collapse this transcript |
| Writing DELETE statements| 00:01 | A while ago I mentioned that there
is an acronym that you'll occasionally
| | 00:04 | come across with SQL databases which was that
of CRUD for create, read, update and delete.
| | 00:13 | Create obviously being the INSERT INTO
statement, read being our SELECT, update
| | 00:17 | being UPDATE, and we might as
well finish it off with some DELETE.
| | 00:22 | DELETE has an associated word. Like we
have UPDATE, SET and INSERT INTO and
| | 00:28 | SELECT FROM, we have DELETE FROM and
in fact DELETE is probably as close to
| | 00:34 | SELECT as you're going to find.
| | 00:35 | In fact this is about the
simplest statement there is.
| | 00:38 | We say we're going to
DELETE FROM a particular table.
| | 00:41 | In this case I'm going to DELETE FROM
SalesLT.ProductCategory and I want to be
| | 00:47 | very careful here because if I hit F5 right now,
I would go and delete every row in this table.
| | 00:55 | The same way that if I said SELECT *
FROM we bring back everything, this would
| | 01:00 | delete everything, and certainly one
of the dangers with using SQL Server
| | 01:03 | management studio or having just
admin level access to a database.
| | 01:08 | Yes, if you do the wrong thing, you can
blow away a lot of stuff very easily.
| | 01:13 | So all your DELETEs should have a
WHERE. Unless you're wanting to delete the
| | 01:19 | entire table you need some
kind of WHERE clause here.
| | 01:24 | Preferably you're going to be using
something like a primary key, so in this
| | 01:28 | case a ProductCategoryID and I
know that I have one, 55 for example.
| | 01:31 | And what I'm hoping as the when I
execute this code I get little message that
| | 01:38 | says one row affected.
| | 01:41 | Another thing to be very careful of is
it's an easy thing to do something like
| | 01:45 | highlight the DELETE statement and
hit Execute but do bear in mind the SQL
| | 01:48 | Server Management Studio if you
highlight some code, it will actually execute
| | 01:53 | just that code. So be
careful what you have selected.
| | 01:56 | You're going to hit Execute
and we have one row affected.
| | 02:00 | If I were to try that statement again,
Execute, zero rows affected. Why?
| | 02:05 | Well because the row with that ID has
gone. It's just not there anymore.
| | 02:11 | And once again, if you're ever getting
ready to do a DELETE statement and you're
| | 02:16 | not sure how many things it's going to
effect, there are a couple of ways of
| | 02:19 | getting around that.
| | 02:20 | But one of the simplest ways is just
to say SELECT * FROM and copy your WHERE
| | 02:27 | clause that you're just about to use.
| | 02:28 | You could find out then now hopefully
this will affect just this one row so I'll
| | 02:37 | comment my SELECT, uncomment
my DELETE< and give that go.
| | 02:40 | One row affected, execute it again,
zero rows affected. We're looking good.
| | 02:44 | The same options are available in
your WHERE clause for a DELETE statement
| | 02:48 | that are available for an UPDATE
statement or a SELECT statement. It's the same thing.
| | Collapse this transcript |
| Using the OUTPUT clause to return inserted keys and GUIDs| 00:00 | It's very common that as you start
inserting information into your databases,
| | 00:06 | what you're going to need or at least
what your applications are going to need
| | 00:09 | is to find out a bit more
information about what you just inserted.
| | 00:13 | Particularly in the case where you are
inserting information into a table that
| | 00:17 | is going to generate keys for you,
either identity columns like this one,
| | 00:22 | ProductCategoryID just going up one
by one, or guids that are being built as
| | 00:27 | well or perhaps both at the same time.
| | 00:31 | But in the INSERT example we saw
before, all that I'm inserting is a
| | 00:35 | ParentProductCategoryID and a name,
because the guids and the identities are
| | 00:40 | being generated for us.
| | 00:41 | Now, we want to get that
information after this INSERT has happened.
| | 00:46 | This used to be a bit of
a problematic thing to do.
| | 00:48 | In fact often what you used to have
to do is write little pieces of code to
| | 00:53 | generate that guid yourself and then insert
it yourself, so that you knew what it was.
| | 00:58 | Well, it's a lot simpler these days.
| | 01:01 | What we just do is we take our INSERT
statement and we change it just a little bit.
| | 01:06 | See, before the VALUES that we were
inserting, I'm using this new clause called OUTPUT.
| | 01:13 | And we can actually use this on an
INSERT, we can use it on an UPDATE,
| | 01:17 | we can use it on a DELETE.
| | 01:20 | OUTPUT is a special kind of a unique
clause here. What it allows us access to is
| | 01:26 | the inserted columns that are just
about to happen and it knows they haven't
| | 01:30 | happened yet, but it
knows that we will have them.
| | 01:32 | In fact, if I say OUTPUT inserted,
notice that inserted is in IntelliSense, and
| | 01:38 | I hit that, I hit the dot, and that's even
smart enough to tell me here in IntelliSense,
| | 01:42 | "Well, you are inserting into
ProductCategories, so these are your only options.
| | 01:47 | Which one would you like?" Well!
| | 01:48 | Let's say that what I want to do is I
want to find the ProductCategoryID that's
| | 01:53 | going to be generated as an identity field.
| | 01:56 | And now when I hit Execute, what
happens is I don't just get the phrase "one
| | 02:01 | row affected," I get the new
ProductCategoryID that I just created, which was
| | 02:06 | ProductCategoryID number 56.
| | 02:08 | Now you can even output
multiple inserted values.
| | 02:13 | So I can hit comma.
| | 02:14 | I want now the inserted
guid that's happening there.
| | 02:18 | I have got to be careful because I'm
running another INSERT statement and
| | 02:21 | Commuter Bikes already inserted
there and that has to be unique.
| | 02:24 | So I'll just change that to Custom
Bikes, hit Execute, and we get back 57,
| | 02:30 | which was to be expected.
| | 02:32 | And the new generated rowguid.
| | 02:34 | That again is being set because
there's a default constraint on the
| | 02:39 | ProductCategory table that will
generate a new rowguid every time.
| | 02:43 | Now in essence, what's going to happen
here is if you've got an application that
| | 02:48 | is executing this code, it's almost
like having a mini SELECT statement that
| | 02:52 | returns these values afterwards.
| | 02:54 | It's just a lot easier to write.
| | 02:56 | And we can see later how this might be
added to and inserted into say a stored
| | 03:02 | procedure to make it a bit more
friendly and a bit more reusable.
| | 03:05 | But this is the general
idea of using OUTPUT clause.
| | 03:09 | In fact, I will show you another example.
| | 03:11 | If I wanted to do a DELETE, I'm going to
say that I'm going to DELETE FROM, same
| | 03:18 | table not surprisingly. Again usually
I just put the WHERE clause. Always want
| | 03:26 | a WHERE clause when I'm doing this DELETE.
| | 03:29 | So ProductCategoryID = well let's say
the one that we just entered in a couple
| | 03:35 | minutes ago, which was 56.
| | 03:36 | And again, I'm putting in
the OUTPUT clause. Well!
| | 03:41 | It's not going to be inserted this time around.
| | 03:43 | That doesn't make sense but I will have
an OUTPUT deleted. and I can say I'd
| | 03:48 | like to know what the Name was.
| | 03:50 | I'd like to know what the deleted guid was.
| | 03:55 | We hit Execute and it tells us the name
was Commuter Bikes and that was the rowguid.
| | 04:00 | So we can get that information back as well.
| | 04:02 | I try and execute that again, not
surprisingly I get no output because there is
| | 04:08 | no row with ProductCategoryID equal to 56 anymore.
| | 04:12 | Now it can also be used on an UPDATE statement
but it's probably not what you are expecting.
| | 04:18 | Here's the deal. When we construct a
regular UPDATE statement here such as UPDATE
| | 04:23 | SalesLT.ProductCategory, of course
we have to use our SET, what are we
| | 04:28 | actually doing here.
| | 04:30 | I am going to just do a SET
parent ProductCategoryID = 1, WHERE
| | 04:39 | ProductCategoryID = 57.
| | 04:45 | Now, usually you might be ahead of me,
thinking well, we put the OUTPUT in here
| | 04:52 | and we had an inserted. for
insert and a deleted. for deleted.
| | 04:57 | So presumably we have an
updated. And no, we don't.
| | 05:02 | Here's the deal. What that inserted
word and the deleted word represent is
| | 05:08 | essentially a temporary table in memory.
| | 05:11 | If we do an INSERT, the inserted
table represents what happened after the INSERT.
| | 05:16 | If we do a DELETE the deleted
table represents what got deleted and
| | 05:21 | if we do an UPDATE, we don't have an updated
one. Wat we really have is the inserted table.
| | 05:26 | It's the changes that were made.
| | 05:28 | So if I want to say output some
information about the roq that's just getting
| | 05:33 | updated, I could say OUTPUT inserted.Name.
| | 05:38 | So hit that Execute and we find that
we have just updated ProductCategoryID
| | 05:44 | number 57 with a ParentID of 1 where
the name was Custom Bikes and we are able
| | 05:50 | to get that information out
about what we just updated.
| | 05:55 | Nine times out of ten, the real use for the
OUTPUT clause is going to be after an INSERT.
| | 06:00 | That's the most important thing for most
application developers is allow them to
| | 06:06 | insert a new row and find out
immediately what the identity or the guid of that
| | 06:11 | row was, but it can also be used
with your UPDATE and with your DELETE.
| | Collapse this transcript |
|
|
8. SQL FunctionsIntroduction to SQL functions| 00:00 | Earlier we saw a few examples of what
are called aggregate functions in SQL,
| | 00:05 | like using COUNT to return the total
number of rows in a table or using MAX to
| | 00:11 | return in the largest value in a
particular column, or average or SUM or MIN.
| | 00:16 | These functions, like in other languages,
are just a way of packaging up a piece
| | 00:21 | of useful behavior and giving it a name,
so that we can use it again-and-again.
| | 00:26 | When you're writing these in SQL Server
Management Studio they tend to show up in hot pink.
| | 00:31 | We do have a few other aggregate
functions, but these are really just the tip of
| | 00:35 | the iceberg, because SQL
Server has over 200 functions.
| | 00:40 | But don't worry. You don't need to go
and memorize every single one of them,
| | 00:43 | because although some of these 200
things, like COUNT and MAX and MIN, are so
| | 00:48 | common and so useful that you could end
up using them on almost a daily basis,
| | 00:53 | some functions are specialized enough
that you might work with SQL Server for
| | 00:57 | years and never come across them.
| | 00:59 | But they're all packaged
behavior, packaged operations.
| | 01:03 | So a simple and common operation like
return the total number of rows becomes
| | 01:09 | packaged up as the COUNT function
and we can use it again-and-again.
| | 01:13 | But we also have operations like
"Return the angle in radians between the
| | 01:17 | positive x-axis and the ray from the
origin to the (y, x), where x and y are the
| | 01:21 | values of the two specified float expressions."
| | 01:24 | And that is also packaged up inside
SQL as the ATN2 or arctangent function.
| | 01:30 | But just between you and me, I've
been working with SQL Server for over ten
| | 01:34 | years and I've never needed this one.
| | 01:36 | So how do we get familiar with
the good and the useful ones?
| | 01:39 | I'm going to go through some of my
favorite functions and show you how to use them.
| | 01:43 | But like so many other things, treat Books
Online as your friend and companion here.
| | 01:48 | If you open up Books Online and go
to the Index, you'll be able to look
| | 01:53 | for the word Functions.
| | 01:55 | Now when you do this, you're going to
see them show up in many different areas.
| | 01:58 | Functions for ODBC, SQL Server. There
will be quite a few, depending on what
| | 02:03 | you're filtering on.
| | 02:04 | In fact the one that I'm interested in,
is actually functions Transact-SQL, so
| | 02:09 | functions for T-SQL,
| | 02:11 | because it's a bit more specific and
it gets down to the functions quicker.
| | 02:15 | And this page, I quite like this one,
so I'm going to click somewhere in the page
| | 02:20 | so that the Favorite button
becomes active and I'll add that to my list of
| | 02:24 | favorite, so I can come back
to this whenever I need to.
| | 02:27 | The functions are grouped. We have
the Aggregate Functions here and I can
| | 02:30 | drop-down and explore things like the Count
function and see how it's meant to be used.
| | 02:36 | Click back a couple of times, I've also
got configuration functions, things like
| | 02:40 | the server name and the version,
mathematical function, signs and cosigns if I
| | 02:45 | need those, security and string
functions for working with the text.
| | 02:50 | And I can drill down into each of
them and see examples and read about
| | 02:53 | exactly how to use them.
| | 02:55 | Now the thing about functions is they're
actually stored as part of your database.
| | 03:00 | In fact if I connect to my SQL Server
instance and drill down into any of these
| | 03:05 | databases, like AdventuresWorksLT,
I'll find that each database has a
| | 03:09 | Programmability folder and each of
those has a Functions folder and each of
| | 03:14 | those has a Systems Functions folder.
| | 03:16 | And what I'm going to find here is a
list just presented differently of the
| | 03:20 | same available functions.
| | 03:21 | The aggregate functions that we have,
the configuration, the date and time, the
| | 03:26 | mathematical functions.
| | 03:28 | And it can be useful to have these
showing up in SQL Server just to take a quick
| | 03:32 | look at what's available. Remind
yourself what the name is for example.
| | 03:35 | Now you'll see that most functions
have the parentheses after them, and
| | 03:40 | that's how they're called.
| | 03:42 | We've seen examples using COUNT,
passing in the star and parentheses, using
| | 03:47 | average, passing in ListPrice, but
you'll find even when you're not passing
| | 03:52 | something in those
parentheses, you still need them.
| | 03:54 | There is a very popular function called
GETDATE, but when you use it you need
| | 03:58 | the two parentheses even if it's empty.
| | 04:01 | Now there are a few functions that just use
the name of the function with no parentheses.
| | 04:06 | If you're into geek trivia this is
what's known as an Niladic function.
| | 04:10 | Most of the functions without
parentheses are easy to recognize because they
| | 04:14 | have two @ signs in front of them.
| | 04:16 | Although there are three or four little
odd ones that don't like CURRENT_USER.
| | 04:21 | It doesn't have parentheses
and it doesn't have @ signs.
| | 04:24 | The two @ signs aren't magical.
They're just a way of marking a few of these
| | 04:30 | functions. In fact most of the ones
with @ signs, if you see them in SQL Server
| | 04:35 | Management Studio, you'll find them in
the Configuration section and there are
| | 04:39 | things like the version of the server.
| | 04:42 | The server name, the language of the
current server, the option set on it.
| | 04:46 | The thing is you don't want to get
worried about whether the two @ signs are
| | 04:50 | there or whether the parentheses are
there, because there is an easy answer.
| | 04:54 | If you see the function in SQL Server
Management Studio or in Books Online
| | 04:58 | and it has parentheses, then you use
parentheses. If it doesn't then you
| | 05:03 | don't, end of story.
| | 05:04 | But the thing about all of these
functions is that they give you a value back.
| | 05:10 | COUNT gives me back an integer that
represents the number of rows in that table.
| | 05:16 | Average, well that gives me
back whatever I passed into it.
| | 05:19 | If ListPrice was a money column
then I get a money average back.
| | 05:25 | If it was an integer I get an integer back.
| | 05:28 | If I used the GETDATE function I
will get a date-time value back.
| | 05:33 | If I used the @@LANGUAGE function I get a
varchar back with, in this case US_English.
| | 05:39 | If I called the CURRENT_USER function,
well depending on how my database is
| | 05:43 | configured, I may get dbo.
| | 05:44 | That will be a very common response from that.
| | 05:46 | A few functions can return several
results and that would usually be in
| | 05:51 | the form of the table.
| | 05:52 | But most functions are like these.
| | 05:54 | They return what's called a scalar value.
| | 05:57 | This is an old computing
term for a single value.
| | 06:00 | COUNT is a function that returns one integer.
| | 06:03 | GETDATE returns one date time value.
| | 06:06 | They don't return a collection, they don't
return an array. They return one scalar value.
| | 06:12 | So how do you use these functions?
| | 06:13 | Well we've seen functions used in SELECt
statements and that's very, very common
| | 06:17 | but they can be used in WHERE clauses,
in UPDATEs, INSERTs, all over the place.
| | 06:22 | So next I'll take you through a few of them.
| | Collapse this transcript |
| Using SQL configuration functions| 00:00 | Some of the simplest functions
to begin with are just using the
| | 00:03 | configuration functions.
| | 00:04 | These allow us to get information like
the server name and the version and the
| | 00:09 | connections that have occurred
since this server was last booted up.
| | 00:12 | If I am going to write an SQL
statement to read them, I still need to have a
| | 00:16 | good old SELECT statement here because
that's how we fetch information. Well, what
| | 00:20 | I'm interested in is
things like the server name.
| | 00:23 | I'm going to do the two @ signs
because most of the configuration functions
| | 00:29 | are the ones without parentheses that
begin with two @ signs. I use my trusty
| | 00:33 | IntelliSense and I've got quite a few.
There is about 30 something to choose from.
| | 00:38 | Lets take a little look at @ sign.
| | 00:39 | @@SERVERNAME.
| | 00:40 | Now you'll notice that I'm not
saying use AdventureWorks because doesn't
| | 00:45 | really matter where I am.
| | 00:47 | This functions is going to execute and
return the name of my standalone PC here,
| | 00:51 | which is just SIMON-PC.
| | 00:54 | I could do @@VERSION to find the
version of SQL Server that is currently
| | 00:59 | running, which tells me that it's the 2008
R2(RTM) and even the point releases of it.
| | 01:05 | Like any SQL statement that you're
executing without an actual official column name,
| | 01:10 | we're getting the No
column name result over here.
| | 01:13 | If I wanted to give that return value a name
I could use AS. Let's call it ServerVersion.
| | 01:21 | Execute that and we have a named result
here. But using these functions is kind
| | 01:27 | of like specifying any column or
list of columns in a SELECT statement.
| | 01:31 | I can type multiple ones in here.
| | 01:35 | The main difference is I don't need a
FROM statement. So it's telling me now I've
| | 01:39 | got the version, I've got the server
name, and apparently there's been 6847
| | 01:45 | connections that have been either
successful or attempted but unsuccessful
| | 01:50 | against this server
since it was last started up.
| | 01:53 | So experiment with a few of the
available configuration functions. Yu can
| | 01:57 | either look at them and Books
Online or again drilling down into the
| | 02:01 | individual databases.
| | 02:03 | You can find your System Functions,
Configuration section where you'll see a
| | 02:07 | lot of those listed.
| | 02:09 | Some you may not be too bothered
about and others you're going to find
| | 02:12 | essential as you move on.
| | Collapse this transcript |
| Using string functions| 00:00 | Every SQL Server database you are
going to work with is likely to contain
| | 00:04 | immense amounts of text in
varchar and char columns.
| | 00:09 | So it's no surprise that there are many
string functions to deal with that text
| | 00:14 | and let me go through a few of those.
| | 00:15 | So I am going to use AdventureWorksLT
just to have some columns to work with and
| | 00:20 | play around with here.
| | 00:21 | Let's say we just start off with a very
simple SELECT statement, selecting the
| | 00:25 | LastName FROM SalesLT.Customer.
| | 00:29 | Now, this is no surprise.
We are not using a function yet.
| | 00:33 | It's simply going to go against that table
and fetch every row but just that one column.
| | 00:38 | But we can use that information and feed
that into any of those string functions.
| | 00:44 | We could start with the simple ones.
| | 00:45 | There're functions like UPPER. It shows up
in hot pink here and just takes one argument.
| | 00:51 | We feed in LastName into the UPPER
function and it will return the result of
| | 00:57 | that function, which in this case not
surprisingly is just turning all of those
| | 01:01 | LastNames into uppercase.
| | 01:02 | Now do bear in mind this is not
changing the data in the database.
| | 01:07 | It's performing this operation on the
way out as we are reading it and just
| | 01:11 | making it a convenient way to read through this.
| | 01:14 | You might know that there's quite a few
countries that actually quite like the
| | 01:17 | presentation of a name to
have the LastName uppercased.
| | 01:20 | So what we could do is start to combine this.
| | 01:23 | Perhaps say I want FirstName and then a
space and then uppercase the LastName
| | 01:29 | and I will call the result
FullName from SalesLT.Customer.
| | 01:35 | Execute that and we get
this presentation returning.
| | 01:39 | So it's a nice way to add some
flexibility to what your applications might want
| | 01:43 | to do without changing the data
that's actually in your tables.
| | 01:47 | But that's only the beginning
of what we can do with strings.
| | 01:49 | There are other things that we can ask for.
| | 01:51 | Let's say I'm curious about the
maximum length of a FirstName.
| | 01:57 | Well, I can get both the FirstNames and
I can call the function L-E-N or LEN to
| | 02:02 | be the length of that.
| | 02:03 | Again, feeding in a character column to
get that information back. Hit Execute
| | 02:10 | and we are retrieving both the FirstNames
and the length of the FirstNames as an integer.
| | 02:16 | One of the great things about using these
functions is you can nest one inside the other.
| | 02:22 | So if I have executed this and I
found out that we've got a whole bunch of
| | 02:25 | different values but I have got
thousands of rows, well, what's the largest one?
| | 02:29 | Well, we've seen already the
aggregate function called MAX.
| | 02:33 | We can use that here.
| | 02:35 | What I'm going to do is just use the
MAX function, open parenthesis, and pass in
| | 02:39 | the LEN function inside of it.
| | 02:41 | So now we'll execute the LEN part first.
| | 02:44 | We will find the length of everything
and then we will find the MAX of that.
| | 02:47 | Execute and we apparently find out
that someone has a FirstName with 24
| | 02:52 | characters. Well, that's fairly long.
| | 02:54 | Of course, this way of doing it
isn't actually telling me who that is.
| | 02:58 | Well, here's where we can actually take
some of these functions and instead of
| | 03:03 | just using them in the SELECT statement
or the SELECT part, we can actually use
| | 03:08 | them in a WHERE or in this
case in an ORDER BY clause.
| | 03:11 | Plus I want to select FirstName
from SalesLT.Customer ORDER BY, not the
| | 03:21 | FirstName descending, but the
length of FirstName descending.
| | 03:26 | Execute and we find that indeed
we have Janaina Barreiro Gambaro is
| | 03:31 | apparently the longest one.
| | 03:33 | That's quite a mouthful.
| | 03:34 | As ever, you will find the
Books Online is your friend here.
| | 03:37 | You will see that there's a String
Functions section where it talks about things
| | 03:41 | like our UPPER, our LOWER, our LEN.
| | 03:44 | There's ways of finding the LEFT, for
example, which will turn the left-hand
| | 03:48 | side of the character strings, say
the first three characters or the
| | 03:52 | first four characters.
| | 03:54 | We have the ability to reverse
them, to get things on the right.
| | 03:58 | If you're working with fixed length
strings, you might look at LTRIM and
| | 04:02 | RTRIM, which have the ability to trim off
any trailing or leading spaces from that length.
| | 04:07 | And the wonderfully titled STUFF allows
you to insert one string into another string.
| | 04:14 | You'll also find a few odd ones, which you may
not even have thought existed in the database.
| | 04:19 | Let me show you an example of using SOUNDEX.
| | 04:22 | I am going to jump back over here
into my SQL and what I am going to do is
| | 04:26 | select FirstName, LastName and then call
the function called SOUNDEX on LastName.
| | 04:37 | FROM SalesLT.Cutstomer.
| | 04:39 | And what is this going to do?
| | 04:42 | Well, it actually runs through an
algorithm that figures out as much as it can.
| | 04:48 | What the pronunciation, what the sound
alike value is of these particular names.
| | 04:53 | What will happen is you will get
this four-character result for calling
| | 04:57 | SOUNDEX that starts with the leading
letter and then has a series of numbers
| | 05:02 | kind of representing what it
considers to be the overall sound of the
| | 05:07 | remaining vowels and consonants.
| | 05:10 | But what does that mean?
| | 05:11 | Well, let's take it bit by bit.
| | 05:13 | What would be interesting is if we then
decided to ORDER BY the SOUNDEX of the LastName.
| | 05:18 | Now, not surprisingly, where we have got
some duplicate data here, they are matching up.
| | 05:26 | But if I go down a little bit, what I
am going to find is certain parts will
| | 05:30 | actually starts to turn up where we
are getting the same result, the same
| | 05:35 | SOUNDEX, for actual different LastNames.
| | 05:38 | So in this case, it's actually giving
us the estimate here that Barker and
| | 05:42 | Berger have kind of the
same sound alike ability.
| | 05:45 | So if we were trying to do a function
or perhaps searching through customer
| | 05:50 | names because we think that somebody's
had the wrong name entered and we are
| | 05:53 | not quite sure what it might've been
spelled as, but we could do something like
| | 05:58 | search for a particular customer WHERE
the SOUNDEX LastName is equal to, and let's
| | 06:07 | say their LastName is Brown.
| | 06:09 | But we want to actually find that if it was
possibly entered in under some other title.
| | 06:14 | So if I execute that, what I am now
actually getting is it's finding the overall
| | 06:19 | sound of Brown and then matching that
against anything else that sounds the same
| | 06:25 | in the Customer table and returning that.
| | 06:27 | So in this case, we are
getting Brian, Brown, Bruno.
| | 06:31 | We might debate if they actually sound
alike but you could certainly see how
| | 06:34 | this could be useful, particularly
if you are trying to do, say, customer
| | 06:38 | lookup applications.
| | 06:39 | Again as ever, Books Online is going
to be something that you want to have
| | 06:44 | bookmarked and favorited until you
become familiar with the different string
| | 06:49 | functions and pick your little favorites.
| | 06:51 | So take a look in Books Online at
those available string functions.
| | 06:55 | You'll find that some of them you're
likely to use all the time, others not so much.
| | 07:00 | But diving into each of the named
functions is going to give you all the
| | 07:04 | necessary information you
need to know about how to use it.
| | 07:07 | Most of the examples I
showed just took one parameter.
| | 07:10 | You will find a few of these functions
such as SUBSTRING and STUFF will take
| | 07:15 | more than one parameter because
they're working with larger strings and they
| | 07:19 | need to know where to start and where to finish.
| | 07:22 | But other than that, these string
functions kind of work the same way.
| | Collapse this transcript |
| Using date functions| 00:00 | When you're new to SQL Server you can
often find the date and time data types and
| | 00:04 | functions a little bit confusing just
because there appears to be so many of them.
| | 00:08 | We have multiple different
data types for dates. We have multiple
| | 00:12 | functions, DATENAME, DATEPART, DATEDIFF,
DATEADD, but really you'll probably
| | 00:18 | find yourself using the same two or
three over and over again and it starts off
| | 00:22 | with a very common function in SQL Server.
| | 00:26 | The ability to say GETDATE. Even though
it doesn't take any arguments we do need
| | 00:33 | to use the parentheses here, both the
opening and closing ones. I execute that and
| | 00:38 | we get the date and time right now.
| | 00:41 | This is local on the machine, working
with the machine's time zone. If you're more
| | 00:45 | interested in getting the universal
time code, you can say GETUTCDATE and
| | 00:50 | execute that, but for most people
most of the time GETDATE is just fine.
| | 00:56 | Now what's often the case of course
is that we don't want to have the full
| | 01:00 | date and time. We're interested in one
particular piece of this, maybe it's the
| | 01:05 | month, maybe it's the day.
| | 01:06 | Well if it's that straightforward,
we can't actually just jump into that and I
| | 01:10 | could say well what I'm
interested in is the DAY.
| | 01:14 | Now you can just say GETDAY. There is
a function called DAY. As we can see,
| | 01:19 | it's showing up in hot pink, but when I open it
it's expecting a date time to be passed into in.
| | 01:26 | Well we just saw how to get a daytime,
which was GETDATE, so I'll wrap GETDATE
| | 01:33 | in the call to DAY, hit Execute,
| | 01:37 | and we have 14 and it is the 14th of
November right now so that seems to make sense.
| | 01:42 | Now you'll find that there are the
equivalents for MONTH and YEAR, but beyond
| | 01:51 | that you might want to get a little
bit more granular. Well you can do.
| | 01:57 | If you want to get to something very
specific such as the day of the week,
| | 02:01 | we use a different function called
DATEPART but we call it the same way. DATEPART
| | 02:06 | and let me just remove the rest because
again you want to use IntelliSense when
| | 02:11 | you getting used to this. DATEPART
takes two arguments: an interval, really
| | 02:17 | meaning what part of the date you are
interested in, which piece of it, and what
| | 02:23 | date do you want that part of. It
sounds little silly but say we wanted to know
| | 02:28 | the weekday off today's date.
| | 02:30 | Well, I can actually put in the word
WEEKDAY, comma, and then we're getting the
| | 02:35 | date right now, which we'd just call
trusty old GETDATE and execute that and
| | 02:40 | we get one back here. Because the way
that this server is configured right now
| | 02:45 | Sunday, which is the day I'm recording this
on, is considered the first day of the week.
| | 02:49 | Now that can differ depending on what
country you've installed SQL Server on.
| | 02:54 | If you actually want to check you can
look for the configuration variable called
| | 02:58 | DATEFIRST, execute that,
| | 03:01 | and what it's actually telling me is,
it sounds a little counterintuitive, but
| | 03:05 | it's actually telling me is that as far as
this server is concerned the seventh day
| | 03:10 | of the week is the first day of the week.
| | 03:12 | Let me explain what that means. It
basically means Sunday is considered day 1 and
| | 03:18 | that's what DATEPART is
actually returning for me here.
| | 03:21 | Well what if I didn't want this one?
What if I actually wanted a text value here?
| | 03:27 | Yes I've got the DATEPART and it's the
weekday, but I wanted the name of the week.
| | 03:32 | How can I do that?
| | 03:33 | Well there is another useful function
that's called to DATENAME and what I can
| | 03:39 | do with that one is actually just pass
it the same information. I'm interested
| | 03:43 | in the weekday, its that interval,
and I'm saying tell it for today.
| | 03:48 | Of course I am using GETDAY. You'll
typically be using one of the date fields
| | 03:52 | that's in your tables, but this will
the trick here. I execute that and it tells
| | 03:57 | me yup we are Sunday.
| | 03:59 | Now what you're probably seen is as
I've started typing say the word DATE,
| | 04:03 | we get things like DATEADD, DATEDIFF,
DATENAME, DATEPART and we've seen DATEPART
| | 04:09 | and we've seen DATENAME, so let's do
DATEADD. This gives us the ability to add
| | 04:14 | days or weeks or months or
whatever you want to an existing date.
| | 04:19 | So if I want to say what is the date
30 days from today, I'm going to call
| | 04:24 | DATEADD and tell it I'm interested
in adding on days. How many? 30.
| | 04:30 | Onto what? Onto today's date.
| | 04:34 | Close that.
| | 04:35 | It takes those as parameters, it figures
out the result, and it returns the result
| | 04:40 | here that says 30 days from
today is the 14th of December.
| | 04:44 | Well what if we wanted to go backwards?
| | 04:47 | Now depending on how your mind works,
you might be expecting to find a date
| | 04:50 | subtract function, but no there
isn't a date subtract function.
| | 04:54 | But what you can certainly do is pass in
a negative amount, -30 days, or in this
| | 04:59 | case let's say I'll go back to seven months ago.
| | 05:05 | We return that and that apparently was
the 14th of April. No particular surprise there/
| | 05:11 | Of course it is the 14th today here.
| | 05:14 | The great thing is what we could decide
to do is start to combine all of this.
| | 05:19 | If we know that that's the date time
value that we're retrieving I could then
| | 05:24 | start to wrap it and say I want to call
DATENAME, I'm interested in the weekday,
| | 05:31 | and the value that I'm going to pass
is what's return from combining DATEADD
| | 05:37 | with GETDATE, again being very careful
here on making sure that your parentheses
| | 05:43 | are lining up where you have the right
opening and the right closing ones, all
| | 05:47 | needing to match of course. Then execute
this and we find that seven months ago
| | 05:53 | on the 14th of April it was a Wednesday.
| | 05:57 | As I'll continue to suggest, Books
Online is a great help here the date and
| | 06:02 | time data types and functions will
actually break it down, even splitting those
| | 06:07 | up into functions that modified date
and time values, functions that get the
| | 06:11 | difference were it be using the DATEDIFF
function, just passing in two dates instead of one.
| | 06:17 | And then being able to use some of the
things we've already seen like DATEPART
| | 06:21 | and DATENAME to pick certain
pieces out of those date time objects.
| | Collapse this transcript |
| Creating user-defined functions| 00:00 | Not only do you have the over 200
functions defined in SQL Server, you can also
| | 00:06 | define your own, what are referred to
as user-defined functions, sometimes
| | 00:10 | abbreviated to UDFs.
| | 00:12 | So let's say I've got a piece of SQL
here which is doing a sub-query and what
| | 00:17 | this is doing right now is finding the
company name for the customer who has
| | 00:22 | placed the largest order.
| | 00:24 | Okay, it's a simple example
but this should do the trick.
| | 00:27 | Let's imagine that I want to get
this page of information 25 times a day.
| | 00:32 | So I'd like a function that returns it.
Well I can start off with this SQL that
| | 00:37 | I have, but I do need to provide a
few more pieces of information for me to
| | 00:42 | describe what this function is and for a start,
I am going to have to give it some kind of name.
| | 00:48 | Now functions often take parameters.
| | 00:51 | So I do have to tell SQL Server does
this one have any parameters or does
| | 00:55 | it have no parameters. And then I've also
got to say what is returned by the function.
| | 01:03 | So most of what I am going to have to
write is actually wrapping around the
| | 01:08 | contents the actual behavior of
this function that I'm going to do.
| | 01:11 | Well, luckily however SQL Server can
help you a little bit with that and there
| | 01:16 | are two ways of getting that.
| | 01:18 | I have my Template Explorer
open on the right-hand side.
| | 01:21 | If yours is closed, you can get it from
the View menu and just hitting Template
| | 01:25 | Explorer and you'll find that in the
Function folder, you actually have several
| | 01:31 | boilerplate sets of code for creating functions.
| | 01:35 | Inline function, table-valued
function, multi-statement function, scalar
| | 01:39 | function new menu, and scalar-valued function.
| | 01:42 | Well, this one is quite simple.
| | 01:44 | We are going to return a scalar
function, which is the most common.
| | 01:47 | It's the single value.
| | 01:49 | So I have a couple of choices here.
| | 01:51 | Well, which one should I pick?
| | 01:52 | They both do the same thing but
just let me show you the difference.
| | 01:56 | If I pick me Create Scalar-valued
Function and double click that, what it gives
| | 02:01 | me is some boilerplate code here that
sets me through what I've got to do.
| | 02:05 | Now this is all right, but I actually
prefer the other one, which is this guy,
| | 02:09 | Create Scalar Function (New Menu).
| | 02:13 | It's a bit longer but most of it's a comment.
| | 02:15 | Now this is the same one that you
would get if you drilled down into the
| | 02:21 | database that you want, found in
your Programmability folder, opened up
| | 02:26 | Functions, opened up Scalar-valued
Functions and then right click and set New
| | 02:30 | Scalar-valued Function.
| | 02:31 | Now that's what we want.
| | 02:33 | So I might as well do that.
| | 02:34 | Now the boilerplate code that
Microsoft provides has a lot of green
| | 02:38 | comments and I am just going to pull
those out for readability right now.
| | 02:42 | But there's a couple of
places you could work with them.
| | 02:44 | Let me close this to give us
a bit more room to breathe.
| | 02:48 | The first lines up at the top
are just a couple of good settings.
| | 02:52 | SET ANSI_NULLS ON SET QUOTED
IDENTIFIER OFF and these are really about how
| | 02:57 | things like equality comparisons are happening.
| | 02:59 | I could actually remove
these lines from this code.
| | 03:02 | It would work nonetheless but I am just
going to leave them there, because this
| | 03:06 | is the stuff that we're
interested in. Create function.
| | 03:10 | well, I said on my other tab here that I
needed a section for a name, I needed a
| | 03:14 | section for parameters and a return
value, and then what does the function do.
| | 03:20 | And we are going to do all of that here.
| | 03:22 | Here's where we actually say we
are giving the function a name.
| | 03:25 | Unlike any other object in our database
we are really going to name it with an
| | 03:30 | object name that will be inside a schema.
| | 03:32 | I have currently got
AdventureWorksLT selected as my default database.
| | 03:37 | I could otherwise say use
AdventureWorksLT here if I wanted to be doubly assure.
| | 03:40 | Well, what I'm going to do is create
a function and call it SalesLT. and
| | 03:46 | then the function name.
| | 03:47 | Well it's quite common that you'll
see user-defined functions with the
| | 03:51 | prefix such as UDF_ or UDF by itself or
something like UFN I have seen quite a lot lately.
| | 03:59 | I am going to call this ufnBigSpender.
| | 04:03 | The reason for the UFN is it just
makes it obvious if there's an error being
| | 04:07 | generated later on that this is a user function.
| | 04:11 | This next section is when I add any
parameters. Does this take any arguments and
| | 04:16 | in the way that say the MAX
function requires a column name.
| | 04:20 | Well, it actually doesn't.
| | 04:21 | So I am just going to delete that,
no parameters, but I'll leave the that
| | 04:27 | just to make that clear.
| | 04:28 | And I said we've got to tell it what it
returns and you notice here it's saying
| | 04:32 | you have got to say the function data type.
| | 04:35 | Well, this is going to return the name
of the company, in which case it's going
| | 04:38 | to be a NVARCHAR, and I have got to
actually declare it here because it's not
| | 04:43 | returning the column.
| | 04:45 | it's whatever we decide this is.
| | 04:47 | So I am going to say it returns an
NVARCHAR with a length of 50, but I haven't
| | 04:52 | yet said what does this do.
| | 04:55 | Now for the first-time what we are
hitting is a way of defining a block in SQL.
| | 05:00 | We have got this phrase begin and end and
this is really the contents of our function.
| | 05:06 | We've have set it up here with a name
and return type and then what it's asking
| | 05:11 | us to do is declare a return variable,
have the two SQL statements for what the
| | 05:16 | function actually does, and then
return the result of the function.
| | 05:20 | So we haven't worked with variables yet, so
this is a good place to declare our first one.
| | 05:25 | What I have to do is just have a
placeholder, some named bucket to hold that
| | 05:31 | company name, so I can return it later.
| | 05:33 | The way we typically do it in SQL, on
SQL Server certainly, is we will use the @ sign
| | 05:39 | and that's just a little bit of
shorthand. We could call it whatever we
| | 05:42 | wanted, but it becomes obvious this
is our own variable and I will call it
| | 05:47 | company and then I give it the data
type of NVARCHAR(50) because of course
| | 05:53 | that is what I'm going to return.
| | 05:55 | Then it says Add the T-SQL
statements to compute the return value.
| | 06:00 | Well, I'm going to copy
them across from my other file.
| | 06:04 | It isn't perfect, but we can do it here.
| | 06:07 | So I am saying SELECT CompanyName.
| | 06:09 | Now it's highlighted a problem here
where I don't just have a boring old
| | 06:15 | regular SELECT statement.
| | 06:17 | what I need to describe inside this SQL
is where does this new variable that I
| | 06:23 | just get created get filled.
| | 06:25 | What I need to say is this.
| | 06:27 | SELECT @Company = CompanyName FROM
SalesLT.Customer where our CustomerID is the
| | 06:36 | top one based on the SalesOrderHeader table.
| | 06:38 | That looks all right.
| | 06:40 | So we declare the variable, we fill it, and
then finally we return it and we are done.
| | 06:49 | Now, bear in mind what I'm describing here.
| | 06:52 | I am not describing the function.
I'm writing the code to create the function.
| | 06:59 | We have this line up here. That's
what I'm telling as SQL Server to do is
| | 07:03 | create this function.
| | 07:05 | I only want to execute all this code once.
| | 07:09 | So I take a scan of it.
| | 07:11 | It looks all right.
| | 07:12 | I'm going to hit Execute. Bang!
| | 07:15 | What I get is Command(s) completed successfully.
| | 07:17 | Now you may be wondering well, why don't
I see the name of that company? Because
| | 07:23 | I wasn't asking to do it.
| | 07:25 | I just created that
function. Prove it, you say.
| | 07:28 | Well, I can.
| | 07:29 | Let me go over to the section of
the database where I created it.
| | 07:33 | I am looking at the folder
that says Scalar-valued Functions.
| | 07:36 | It's not showing up here
and they should be there.
| | 07:38 | That's because I need to go up to the
top of my Object Explorer and hit Refresh
| | 07:42 | and then I see that I do
have SalesLT.ufnBigSpender.
| | 07:47 | Okay, things are looking good.
| | 07:48 | In fact, I can actually close that
code that I used to create it and then
| | 07:52 | close that one as well.
| | 07:54 | But it wouldn't be much good if
we couldn't prove that this works.
| | 07:57 | So let's open a new query window. I'm
looking at AdventureWorksLT as my default.
| | 08:03 | So I'm just going to say
Select and drag this across.
| | 08:08 | It is a function so it should end in
the parentheses and I will hit F5 and yes
| | 08:13 | indeed, calling the function
ufnBigSpender brings me back Action Bicycle
| | 08:17 | Specialists, which right now is the
customer that's placed the largest order.
| | 08:21 | Now you will notice that I'm
getting the red squiggly here.
| | 08:25 | It can't find this user-defined
function or aggregate or the name is
| | 08:29 | ambiguous, and usually the reason
for that is that the IntelliSense just
| | 08:33 | hasn't updated itself.
| | 08:35 | Now there is a couple of tricks for
getting around that, but the easiest and
| | 08:38 | most simplistic way is just reopen
SQL Server Management Studio. Bang!
| | 08:45 | Open a new query and the next time I
type it, SalesLT.ufnBigSpender is now
| | 08:57 | actually showing up and we
don't get the red squiggly anymore.
| | 08:59 | Now, when you're new to SQL Server,
creating your own functions isn't something
| | 09:05 | that you should be thinking
that you need to do a lot.
| | 09:08 | In fact, it's quite rare compared to
other parts of SQLite stored procedures
| | 09:13 | that we are going to get into a little later.
| | 09:15 | But it is a possibility.
| | 09:17 | These functions can even be used in-
line as part of WHERE clauses or INSERTs or
| | 09:22 | UPDATEs, but they can't be used to
actually do an UPDATE or INSERT themselves.
| | 09:28 | It wouldn't allow me to actually
write an UPDATE or an INSERT statement
| | 09:32 | inside that function.
| | 09:34 | Now the last question is what happens
if I want to change it a little bit?
| | 09:37 | Well, I can go back into that
function which will be in my
| | 09:41 | Programmability > Functions > Scalar-
valued Functions and notice that when I pick
| | 09:47 | my user-defined function here,
I can right-click and say Modified.
| | 09:51 | What I will have here is something
that's very similar to the SQL I had before,
| | 09:57 | but notice the phrase here.
| | 09:59 | When I run this, it's
not saying create function.
| | 10:02 | It's saying alter function.
| | 10:03 | So this is the SQL I would run to make
any changes to it and open it up make a
| | 10:10 | few tweaks, maybe change my sub-query
to adjoin or what have you, and then run
| | 10:15 | this SQL again to update that function.
| | Collapse this transcript |
|
|
9. Stored Procedures and TransactionsIntroduction to stored procedures| 00:00 | All these functions that we have are
great and they're very useful and you'll
| | 00:04 | use them all the time, but you
probably won't end up writing a lot of them.
| | 00:09 | However, spend any time with SQL
Server and you will write stored procedures.
| | 00:14 | A stored procedure is simply a chunk
of SQL wrapped up, given a name, and then
| | 00:21 | stored in the database.
| | 00:24 | It can then be executed multiple times
from SQL Server Management Studio, called
| | 00:28 | from an application.
| | 00:29 | It's available to anyone
who can get to the database.
| | 00:32 | And these will be the
main way that you reuse SQL.
| | 00:36 | Talk to developers and database
administrators and they'll tell you that almost
| | 00:41 | all of the SQL they write is
intended for a stored procedure.
| | 00:45 | Now we've written a lot of SQL in the
past few hours, but if I'd wanted to save
| | 00:50 | and reuse any of this I simply would
have just have the option to go to my File menu
| | 00:56 | and save this as a text file on my desktop.
| | 00:58 | Well, that's fine for some
personal learning and testing.
| | 01:02 | But when you write some more complex SQL
that you're happy with and you want to
| | 01:05 | reuse it, you want to wrap it up in a
stored procedure so you can use it later.
| | 01:10 | Like there are lots of built-in functions,
| | 01:12 | there are hundreds of stored
procedures already in SQL Server.
| | 01:15 | If I expand any of the databases here,
even the AdventureWorksLT, open up
| | 01:21 | Programmability, this is where
we saw our functions earlier.
| | 01:24 | We also have stored procedures,
and if I expand the System Stored
| | 01:29 | Procedures here I see just quite a
ridiculous amount of stored procedures,
| | 01:34 | There is hundreds of them.
| | 01:36 | Having said that, what you'll find
is that many of these are intended for
| | 01:41 | advanced administration tasks.
| | 01:44 | Working with Active Directory policy
management, logging, optimizing your
| | 01:49 | indexes and your partitions, and it's
very common that that'll begin with Sys
| | 01:54 | for sys.sp_, meaning
stored procedure of something.
| | 01:59 | I'll find in some of these test
databases, there are also a couple of
| | 02:04 | user-defined stored procedures, which
you'll often see with USP at the start of them.
| | 02:08 | There is couple of them in AdventureWorks Light.
| | 02:11 | There is a few more if you look at
the larger AdventureWorks examples.
| | 02:16 | Now there are similarities between creating
a stored procedure and creating a function.
| | 02:22 | They both need a name, and they can be
defined with parameters. They can return values.
| | 02:27 | Well, that does sound very similar to a
function, but there are some substantial
| | 02:32 | differences really about
what they're intended for.
| | 02:35 | Functions are typically designed to
return a scalar value and they're SELECT only.
| | 02:41 | they're not allowed to change anything.
| | 02:44 | If you write a function, you cannot put
an INSERT, an UPDATE or DELETE inside it.
| | 02:49 | It's designed to be a
quick way of returning a value.
| | 02:54 | Functions themselves are designed to be
used in-line as part of other SQL statements.
| | 02:59 | So, while a function can be used
inside of an INSERT or an UPDATE, it can't
| | 03:04 | itself do an INSERT or an UPDATE.
| | 03:07 | Stored procedures on the other hand are
much bigger in scale and much bigger in scope.
| | 03:12 | And they are executed directly.
| | 03:14 | There is in E-X-E-C, EXEC statement.
| | 03:17 | You execute the entire stored procedure.
| | 03:20 | Stored procedures can do multiple things
including inserting and updating and deleting.
| | 03:25 | Stored procedures themselves can
use functions, but functions won't be
| | 03:29 | using stored procedures.
| | 03:30 | Stored procedures can do
multiple things at the same time.
| | 03:34 | They can contain batches of SQL.
| | 03:37 | Particularly useful if you want to do
say an insert to several different tables
| | 03:42 | at the same time. They're great for that.
| | 03:45 | And after just taking your SQL and
wrapping up and saving it as a stored
| | 03:49 | procedure we can add parameters,
variables, error handling, even flow control,
| | 03:54 | having basic control in
the case of IF statements.
| | 03:57 | It's very much like
turning it into a mini program.
| | 04:01 | And in fact I've worked in several
places, which did not allow developers to
| | 04:05 | write their own INSERTs, UPDATEs,
DELETEs, even SELECT statements in their programs.
| | 04:10 | They had to execute stored procedures.
| | 04:13 | One of the benefits of that is all
the SQL stays in the database and can be
| | 04:18 | controlled and hopefully
optimized by the database administrator.
| | 04:21 | But let's see how to do one.
| | Collapse this transcript |
| Creating stored procedures| 00:00 | The process of creating a stored
procedure is quite similar to that of doing a
| | 00:04 | function, or indeed of defining any
procedure, function, or method in any other
| | 00:10 | programming language.
| | 00:11 | We're going to name it.
We have to give it a name.
| | 00:13 | We're going to define any
parameters that it takes.
| | 00:16 | We're going to actually describe what
it does, which in our case will be run
| | 00:20 | either a single SQL statement
or even batches of T-SQL.
| | 00:25 | And then return any values,
describe what it is that gets sent back.
| | 00:30 | So how do we do that?
| | 00:31 | Well, luckily, SQL Server
Management Studio has some helpers for us.
| | 00:36 | If I actually drill down into the database
in which I want to create my stored procedure,
| | 00:40 | I'll use AdventureWorksLT,
| | 00:41 | I'll open up the Programmability
section and we see that we have the Stored
| | 00:46 | Procedures folder right
beside the Functions folder.
| | 00:48 | I'll open that guy up.
| | 00:50 | I'll right-click the Stored Procedures
folder and say New Stored Procedure.
| | 00:55 | Again, we get a lot of boilerplate code.
| | 00:58 | Just to make things clearer,
I could get rid of some of the comments.
| | 01:01 | I'm going to just ignore the settings
here for ANSI_NULLS and QUOTED_IDENTIFIER.
| | 01:05 | You just as a general rule leave those
alone and then what we have is this.
| | 01:10 | We have the CREATE PROCEDURE. Give it a name.
| | 01:13 | Define the parameters if it takes any.
| | 01:17 | If it doesn't, you can just scrap that.
| | 01:19 | Then describe what it is the stored
procedure does, which by itself if it's got
| | 01:25 | SELECT statements is also
defining what it returns.
| | 01:29 | So, creating the simplest stored
procedure in the world, let's give it a name.
| | 01:34 | Well, we do have to put a schema for it,
which could be the usual schema of SalesLT.
| | 01:39 | Or quite commonly
you'll also seem under dbo.
| | 01:42 | For our case, it really doesn't matter.
| | 01:44 | We just have to give it a name.
| | 01:46 | I'll call this uspSimple, a user
stored procedure. Very simple one.
| | 01:54 | I'm going to make one that takes no
parameters, so I can just delete those lines.
| | 01:58 | I'm going to leave the usual
message here of NOCOUNT ON.
| | 02:02 | We'll talk about that in a second, and
then I'm going to describe what actually
| | 02:05 | happens in the stored procedure.
| | 02:07 | Well, we could be doing INSERTs, we
could be doing UPDATEs, we could be doing
| | 02:10 | DELETEs, or we could just
be doing standard SELECTs.
| | 02:13 | I could just type in a very straightforward one.
| | 02:16 | SELECT * From SalesLT.Customer.
| | 02:22 | Perhaps that's what I want
the stored procedure to be.
| | 02:25 | It's a little bit of SQL,
wrapped up and given a name.
| | 02:31 | So let me create it.
| | 02:33 | I'll run this SQL right now.
| | 02:36 | Again, this SQL is
creating the stored procedure.
| | 02:40 | So when I say Command(s) completed
successfully, I don't expect to see any results yet.
| | 02:44 | We've now made the stored procedure.
| | 02:46 | We just haven't run it.
| | 02:47 | If I go over to the Object Explorer,
it doesn't show up and that's because
| | 02:50 | I need to refresh it.
| | 02:52 | So I'll come up here to the
Refresh button and then I can see,
| | 02:55 | yes, I've got dbo.uspSimple. Great, looks good.
| | 03:00 | I'll close these two files down.
| | 03:01 | I don't need them anymore, and open up a
new query window so I can actually run this.
| | 03:08 | Well, we don't use the word SELECT.
| | 03:10 | If we're running a stored procedure, we do this.
| | 03:13 | We say EXEC for execute.
| | 03:16 | I could type in dbo.uspSimple.
| | 03:21 | That's not showing up in my
IntelliSense right now, because the IntelliSense
| | 03:25 | just hasn't refreshed itself.
| | 03:27 | But we should be able to get this to work.
| | 03:28 | If I hit F5, yep, it does the same
thing as would have happened if I had
| | 03:34 | manually typed SELECT * FROM SalesLT.Customer.
| | 03:39 | If I get annoyed about the red squiggly lines
that it couldn't find that stored procedure,
| | 03:43 | I can either restart SQL Server
Management Studio, or with my cursor in this
| | 03:49 | SQL box, I can go to the Edit menu, click
IntelliSense, and just say Refresh Local Cache.
| | 03:55 | That takes a second and then
the red squiggly should go away.
| | 03:59 | Yes of course, this is the
simplest stored procedure on the planet.
| | 04:03 | You're not really going to be doing things
like this all the time, although it's possible.
| | 04:07 | If I want to change that, what I do
is go back to the Object Explorer.
| | 04:12 | I'll right-click that stored
procedure and click Modify.
| | 04:16 | It brings up a very similar SQL,
except changing the CREATE PROCEDURE word
| | 04:21 | to ALTER PROCEDURE.
| | 04:23 | I'll just make my changes
and run this file again.
| | 04:27 | You can also execute it by right
clicking the stored procedure directly.
| | 04:32 | Execute Stored Procedure.
| | 04:33 | It throws up a dialog box here that
gives you the opportunity to type in any
| | 04:38 | parameters you might use.
| | 04:39 | In our case, we don't have any.
| | 04:41 | So I'll just click OK and we get the
generated code to run a stored procedure here.
| | 04:46 | There is a little bit more than we
need, because it's setting up for return values,
| | 04:50 | which we don't really care about.
| | 04:53 | But that's the general process.
| | 04:55 | So, what if I want to do
something that's a bit more complex?
| | 04:58 | Well, rather than type it out bit by
bit, I'm going to use one of the few
| | 05:04 | pre-created files that I have here.
| | 05:06 | I have got a similar looking file here
to create a stored procedure, except this
| | 05:12 | has a bit more to it.
| | 05:13 | In this one, what I'm actually
doing is inserting three rows into
| | 05:18 | three different tables.
| | 05:20 | Now, the question is why?
| | 05:22 | Well, here is the deal.
| | 05:23 | If I come over to my
AdventureWorksLT, I have three tables called
| | 05:29 | ProductDescription, ProductModel, and
ProductModelProductDescription. What's this about?
| | 05:34 | Well, the idea is that in this database
if you're inserting a new ProductModel,
| | 05:40 | you basically just insert the name.
| | 05:42 | If I took a look at this, I can see
that there are things like Classic Vest,
| | 05:46 | Cycling Cap, Half-Finger
Gloves, Road Frame, and so on.
| | 05:50 | Well, the idea is that this table is
going to support multiple international
| | 05:55 | languages potentially.
| | 05:56 | So, I'm not just going to put in a
description straight for that ProductModel.
| | 06:02 | I have a separate ProductDescription table.
| | 06:04 | If I look at that one, I can see that I have
certain descriptions that are being stored.
| | 06:10 | But as I come down, I've actually got
some odd text showing up, because we're
| | 06:14 | actually using multiple languages here.
| | 06:16 | We've got French.
We have got some of the big five languages.
| | 06:19 | Now the issue is that we could have
different descriptions for the product
| | 06:25 | models and potentially with
descriptions like Chromoly steel, we can have
| | 06:31 | different product models for the descriptions.
| | 06:33 | So we've got a many to many
relationship going on here.
| | 06:36 | That's what this third table represents.
| | 06:39 | PublicModelProductDescription.
| | 06:41 | Well all this one really does is hook
up a particular ProductModelID from the
| | 06:46 | ProductModel table, to a
ProductDescriptionID from the ProductDescription table,
| | 06:51 | and then adding the Culture.
| | 06:54 | So we could have English, we
could have French, we could have Thai.
| | 06:58 | Okay, even if that seems
a little vague right now,
| | 07:02 | it's a very common situation. When
you're inserting some information, all I want
| | 07:07 | to do is I've just got some new
ProductModel and Description information.
| | 07:11 | I don't really care about how many
tables have to be created and how many rows
| | 07:17 | I need to do and in what
order I need to do the rows.
| | 07:19 | But of course, it is drastically important.
| | 07:22 | If I want to make this work, I have to
insert the model, then the description,
| | 07:27 | and get both of the keys that have been
generated before I can insert the third one.
| | 07:32 | So this is a great thing for a stored procedure.
| | 07:35 | In fact, that's what this
stored procedure example does.
| | 07:39 | It takes three parameters.
| | 07:41 | A productname that will be used to
go into the ProductModel table,
| | 07:46 | a productdescription that will be used
to go into the ProductDescription table,
| | 07:51 | and a culture, which will be used to go
into the one that joins them together.
| | 07:56 | In fact, culture I've
set up here with an equal sign.
| | 07:59 | That means this is a default value.
| | 08:01 | I don't have to pass that
information into the stored procedure.
| | 08:05 | The idea is I can call the stored
procedure once, give it a couple of pieces of
| | 08:09 | information, and end up with three rows.
| | 08:13 | So breaking it down a bit further.
| | 08:15 | Inside the contents of the stored
procedure, I define two variables that are
| | 08:20 | going to hold the keys of the two inserted rows.
| | 08:23 | So in a moment, we'll insert a
new ProductModel and we'll grab
| | 08:27 | the productmodelid.
| | 08:29 | Then we'll insert a new
ProductDescription and we'll grab the generated
| | 08:32 | productdescriptionid.
| | 08:34 | Then we'll take both of those and
insert them into ProductModelDescription.
| | 08:38 | So, step one is we insert the customer
row with the parameter of productname.
| | 08:43 | Then we use of this line, SELECT
@productmodelid, that's our variable that we
| | 08:48 | defined, = @@IDENTITY.
| | 08:51 | This is a useful function that will
actually grab the last inserted identity field.
| | 08:59 | Step two, we do the equivalent for
the ProductDescription table, inserting
| | 09:04 | Description, and then we grab its
IDENTITY into our productdescriptionid.
| | 09:10 | Then finally, step three.
| | 09:11 | We do our third INSERT statement.
| | 09:14 | Inserting into the join table,
| | 09:16 | the ProductModelID, the
ProductDescription, and the Culture.
| | 09:21 | So let me run this SQL to
create this stored procedure.
| | 09:26 | Execute, Command(s) are completed successfully.
| | 09:28 | All right, well, let's find out.
| | 09:31 | I open up a new query.
| | 09:33 | I'm going to refresh my IntelliSense.
| | 09:38 | Make sure I'm using AdventureWorksLT.
| | 09:40 | Then I'll say EXEC uspCreateModelAndDescription.
| | 09:48 | It's telling me here that I should
be giving it a couple of parameters.
| | 09:52 | The one that's highlighted in bold
says "Well, give me the productname."
| | 09:55 | That should be in nvarchar.
| | 09:57 | I'll call it Groovy new product.
| | 10:01 | I hit the comma and it
highlights the next one, productdescription.
| | 10:06 | Groovy new product description.
| | 10:10 | If I wanted to, I could add a different culture.
| | 10:14 | If I did the comma, it would tell me that
I should put in a string for the culture.
| | 10:19 | But you know, I'm not going to.
| | 10:20 | I'm just going to leave that blank, because
there is a default value of en for English.
| | 10:25 | Well, let's give this stored
procedure call a try. I hit Execute.
| | 10:30 | Command completed
successfully. Okay, looks good.
| | 10:33 | Let's prove it.
| | 10:34 | The quickest way is going to be, let's take
a look at the entire table, right-click,
| | 10:40 | Select Top 1000 Rows.
| | 10:42 | Zoom right down to the bottom
| | 10:44 | and we see that we have a Groovy new
product inserted with a ProductModelID of 130.
| | 10:51 | Take a look at the ProductDescription.
| | 10:53 | Select that Top 1000 Rows.
| | 10:55 | All the way down to the bottom and we
have a Groovy new product description of 2012.
| | 11:01 | So what I'm hoping to see now is
that in ProductModelProductDescription.
| | 11:05 | I will see 130 looking up
to 2012 with a culture of en.
| | 11:11 | Right down at the bottom, that's what we have.
| | 11:13 | 130 key looking up to
ProductDescriptionID of 2012 with the Culture of en and
| | 11:19 | all of the default values
generated as they should be.
| | Collapse this transcript |
| Introducing transactions| 00:00 | When we're updating data in our databases
we'll often need to work with transactions.
| | 00:05 | A transaction is an incredibly
important thing in the world of databases.
| | 00:09 | And to understand them the best way
is to think about what we think of as a
| | 00:13 | transaction in the regular world.
| | 00:16 | If you talk about making a transaction,
you often mean something in the world of commerce.
| | 00:21 | Say you hand over $15 to the bookseller;
| | 00:23 | the bookseller gives you the book.
| | 00:25 | That's the transaction.
| | 00:26 | It's important that both of these
things happen. If you hand over the money you
| | 00:31 | expect to get the book.
| | 00:32 | If they hand you the book
they expect to get the money.
| | 00:35 | Either both of these things
happen or neither of them do.
| | 00:39 | In a computing system, a classic
example of a transaction is a banking system.
| | 00:45 | Imagine that you log on to your bank's
web site and you want to transfer $1000
| | 00:50 | from one of your accounts to the other.
| | 00:53 | That's going to require to update
operations. One, to subtract $1000 from
| | 01:00 | account A, and the next
to add $1000 to account B.
| | 01:05 | If the first part of this transaction
happened and then we tried to add a
| | 01:08 | thousand dollars to account B
and there is a problem with it,
| | 01:11 | say it was locked for editing,
| | 01:13 | we need to reverse the first part of
the transaction, because we never want to
| | 01:17 | be in a situation where $1000 had been
debited from the first account but not
| | 01:23 | added to the second.
| | 01:24 | This transaction needs to happen.
| | 01:26 | It's a unit of work. Either both of
these things happen or neither of them do.
| | 01:32 | So there is a common acronym that
you will come across when working with
| | 01:36 | transactions in a database.
| | 01:38 | ACID, A-C-I-D. A transaction must be
Atomic, Consistent, Isolated and Durable.
| | 01:46 | A transaction being atomic refers to
the core idea that the transaction must
| | 01:50 | completely happen or not at tall.
| | 01:52 | Whether there are two steps to the
transaction or 20, they all contained in the
| | 01:58 | transaction, they all complete
successfully, or they all return to the original
| | 02:03 | state, they roll back.
| | 02:05 | There is no such thing as a
transaction that halfway occurs.
| | 02:09 | Now whether the reason for the
transaction failing is that the database had
| | 02:12 | a power failure, or ran out to space to hold
the new data, or there was an application error,
| | 02:18 | it doesn't matter.
| | 02:19 | It's an all or nothing rule.
| | 02:23 | For a transaction to be consistent,
it means that any transaction must take
| | 02:27 | the database from one valid state to another
valid state based on the rules of your database.
| | 02:34 | So even if a transaction is
successfully atomic it cannot result in a situation
| | 02:39 | that violates any of the
integrity rules defined in the database.
| | 02:44 | A transaction being isolated
refers to the idea that the data in that
| | 02:48 | transaction is essentially locked for the
moment in which the transaction is occurring.
| | 02:53 | So while we're trying to change a
balance say on one of our account records,
| | 02:58 | another part of the system must not be
allowed to access that data until the
| | 03:02 | first transaction has finished.
| | 03:05 | And for a transaction to be durable, it
means the transaction must be considered robust.
| | 03:10 | If it happens and the database
management system says this transaction is
| | 03:15 | happened successfully then
that transaction is guaranteed.
| | 03:19 | Say if you go to a travel website and
purchase a fly on an aircraft and you've
| | 03:23 | been guaranteed seat 2A, you should be able
to regard that transaction as being durable.
| | 03:29 | Even if half a second later that
database itself had a power failure and shut down,
| | 03:34 | when it's rebooted the
transaction will have survived that failure.
| | 03:38 | They're not going to go and sell your
seat to someone else, simply because there
| | 03:42 | was a glitch in the system half a
second after you made your purchase.
| | 03:46 | Now the great thing about working with
the database management system like SQL
| | 03:50 | Server is that these
capabilities are built into the system.
| | 03:54 | When you're writing code there has to
be a transaction, you don't have to worry
| | 03:58 | about how to program these.
| | 04:00 | You just need to know when to tell
the database system, "now this is a
| | 04:04 | transaction, that these two things,
these three things, these four things must
| | 04:10 | be done together," and that's
the little code that you add.
| | 04:13 | Bear in mind, not everything you do as
a transaction, you need to decide what
| | 04:18 | your transactions are and then you
will be adding just a little code to control them.
| | Collapse this transcript |
| Creating transactions| 00:00 | So I'm going to take this
stored procedure a little further.
| | 00:03 | The stored procedure I'm working with
right now has three INSERT statements.
| | 00:08 | It inserts an entry into the
ProductModel table, it inserts a
| | 00:13 | ProductDescription, and then it inserts a row
that hopefully joins these two new rows together.
| | 00:18 | Okay, so let's see it work.
| | 00:20 | I'm going to flip over to where I
have a prewritten piece of SQL that
| | 00:26 | will execute that stored procedure,
passing in ABCD123, and ABCD123
| | 00:31 | product description.
| | 00:33 | So I execute that code.
| | 00:35 | We get a result, the
Command(s) completed successfully.
| | 00:38 | To double check that, I have a
little bit of code over here that's simply
| | 00:42 | selecting the most recently added row to
each of those three tables. I'll run that.
| | 00:48 | And I get what I hoped for, that
the first row that was added was for
| | 00:53 | ProductModelID 139, so that
primary key was generated, ABCD123.
| | 01:00 | We have the Description that's under
2016, and ABCD123 product description, and
| | 01:06 | then we have the third row that is joining
139 to the first row and 2016 to the second.
| | 01:14 | So everything looks correctly happened
and in the right order. Here is the issue.
| | 01:19 | What happens if I run that again?
| | 01:22 | Well, it should work just
fine, right? I execute it.
| | 01:25 | Well, we have a problem going on here.
| | 01:28 | The message isn't all that friendly, but
it's telling me there is a Violation of
| | 01:31 | UNIQUE KEY constraint. Cannot
insert duplicate key in object
| | 01:34 | SalesLT.ProductModel.
| | 01:36 | Maybe I'm getting this message and I'm
the developer and I know what that means.
| | 01:39 | It's not the friendliest thing in
the world, and here is the issue.
| | 01:43 | If I go back and run this code again
to see the most recently added records,
| | 01:48 | what I'm going to see is that the row
for ProductModel will nothing got added
| | 01:53 | with that second call there.
| | 01:55 | The issue is that there is a constraint on
the table that says this name must be unique.
| | 02:00 | So we didn't get a new entry.
| | 02:02 | Having said that, the problem is we
did get a new row for the Description.
| | 02:08 | Because the last time around, it was 2016.
| | 02:11 | We now have a new row in there with
this Description, but it won't be connected
| | 02:15 | to anything because we couldn't insert
the first one, and because we didn't get
| | 02:19 | the first one done, we didn't get the
third one done either, because there was
| | 02:22 | no ProductModelID to insert.
| | 02:24 | So they're all now out of step.
| | 02:26 | We've got a bit of a problem.
| | 02:27 | We have this orphaned record hanging around.
| | 02:30 | We'd have to go in and manually hook up.
| | 02:32 | Well, what can we do with that?
| | 02:35 | Well, really the deal is this.
| | 02:37 | I want my stored procedure to work completely.
| | 02:41 | I want either all three of these
inserts to occur correctly or not at all.
| | 02:47 | There are a couple of steps of
doing that. Let's do step one.
| | 02:50 | It's very, very simple.
| | 02:51 | What I'm going to do is surround my
three INSERT statements with BEGIN TRAN.
| | 02:57 | It doesn't have to be in uppercase, but
that's by convention, and COMMIT TRAN.
| | 03:05 | So we're beginning the transaction.
| | 03:06 | We're going to try and do the first INSERT,
then the second INSERT, then the third INSERT.
| | 03:12 | Hopefully, by the time we get past it, we're
going to commit those changes to the database.
| | 03:16 | So this is just the edited SQL
for altering that stored procedures.
| | 03:21 | So I'm going to execute that.
| | 03:23 | Command completed successfully, looks good.
| | 03:25 | Let's go over to this and we're
going to shake up this entry a little bit.
| | 03:31 | Let's say we're now trying to
enter in a couple of other things here.
| | 03:35 | We're entering a model description
for DEF123, just so we can be sure
| | 03:39 | that that's unique. I'll execute that.
| | 03:42 | Command completed successfully.
| | 03:44 | Go back over and check what
the three most recent rows were.
| | 03:47 | We have 141 for DEF123, 2018 for DEF123,
and then 141 and 2018 joined. Looks good.
| | 03:57 | Now, here is the proof.
| | 04:00 | Let's try and run this because we have
the transaction around them. I execute it.
| | 04:05 | Okay, we have the error.
| | 04:08 | That's to be expected.
| | 04:09 | Just having a transaction doesn't mean that
there wasn't a problem. We have a problem.
| | 04:13 | We're trying to insert a
duplicate key into the ProductModel.
| | 04:17 | Here is the question though. What happened?
| | 04:20 | Well, if I go over and run this code again,
we're actually running into this situation.
| | 04:25 | 141.
| | 04:27 | Okay, that was the one from the previous time.
| | 04:29 | We didn't get one inserted there,
but we did get a new one inserted here,
| | 04:33 | because if you look at the last entry
on the joining table, it was 141 to 2018.
| | 04:40 | We've now got 141, but we have a 2019.
| | 04:42 | So, what's going on?
| | 04:45 | Here is the problem.
| | 04:46 | Just because we said that we wanted
to work with the transactions and we
| | 04:54 | surrounded our three statements with
this BEGIN TRAN and COMMIT TRAN, well, that
| | 04:59 | doesn't really mean anything.
| | 05:01 | Because just because there was a problem,
well, we didn't actually tell it that
| | 05:04 | we wanted to roll anything back.
| | 05:07 | So here is what we do instead.
| | 05:08 | Now to make this a little bit more
readable, I'm just going to get rid of a
| | 05:12 | couple of the blank lines here.
| | 05:14 | Before I do my BEGIN TRAN,
I'm going to write this.
| | 05:18 | BEGIN TRY and END TRY.
| | 05:24 | Now these officially don't have to
be nested, but to make it a bit more
| | 05:27 | readable, I'll do that.
| | 05:32 | So we open up what's called a TRY block.
| | 05:34 | Our TRY block means we're trying things from
the opening of the TRY to the end of the TRY.
| | 05:39 | That's where we're trying to do our transaction.
| | 05:41 | The flipside of that is that if there
is a problem, what happens is our TRY
| | 05:47 | block is going to leap out
and go looking for a CATCH block.
| | 05:57 | What I need to do in here is say this.
| | 06:00 | I want to ROLLBACK the transaction,
which will just reverse anything that
| | 06:06 | happened inside the BEGIN
TRAN and COMMIT TRAN keywords.
| | 06:10 | What would also be useful is if I do a
little bit of the tracing information.
| | 06:17 | I'll print out a message
that says there was an error.
| | 06:20 | That won't be all that helpful so I
better output a little bit more and this is
| | 06:25 | the way I would do that.
| | 06:26 | I'm going to use one of the
built-in functions called ERROR_MESSAGE ().
| | 06:33 | This only works if you use
ERROR_MESSAGE inside a CATCH block.
| | 06:37 | It's only actually ever going to
have anything if there was a problem.
| | 06:41 | So this has changed the stored procedure.
| | 06:43 | Now I'm going to of course execute
that to make sure that the database knows
| | 06:48 | that the stored procedure has been changed.
| | 06:50 | So again, we need to go back
and test it and check it.
| | 06:53 | I'm going to jump across here in the
first try and make one that works.
| | 06:57 | Let's verify that
everything is actually working okay.
| | 07:02 | We're going to try and enter in
the GHI123 and GHI123 product description. Execute.
| | 07:10 | Come over and check the recently retrieved
records, and we have 143, GHI123. 2020, GHI123.
[00:07:20.00 ]
143, 2020.
| | 07:23 | So the hope that I would have is if I
go back and run that stored procedure
| | 07:27 | exactly the same as it was, then
when I come back to this page, I see
| | 07:31 | exactly the same thing.
| | 07:33 | I don't suddenly get an extra
ProductDescription row in there.
| | 07:37 | Let's go and find out. We jump across.
| | 07:40 | Again, I am executing this again.
| | 07:42 | Just because we have a transaction
doesn't mean there isn't a problem. There is.
| | 07:45 | Execute. There we go.
| | 07:48 | We can see that we jump to our CATCH block.
| | 07:50 | I've got there was an error.
| | 07:52 | Then the message that pops out says
Violation of UNIQUE KEY constraint,
| | 07:56 | Cannot insert duplicate key in
object SalesLT.ProductModel.
| | 08:00 | Same problem. We want to see if
there is a different behavior now.
| | 08:03 | So hopefully, we'll see 143, 2020,
and 143, 2020 when I execute this.
| | 08:09 | We run it, and yes indeed,
143, 2020, 143 and 2020.
| | 08:15 | Because of having those BEGIN TRAN and
COMMIT TRAN inside the TRY block, and
| | 08:21 | then catching it, rolling it back, and
printing out the message, we've managed
| | 08:25 | to roll back all those changes.
| | 08:27 | So, very easy to start to wrap your
different blocks of SQL with that TRY and
| | 08:33 | TRAN in a very controllable
way of handling that stuff.
| | Collapse this transcript |
|
|
10. Core Administration TasksUnderstanding and creating indexes| 00:00 | Flip to the back of any thick technical
book and you're going to find an index.
| | 00:05 | If you need to look up some content
that's buried somewhere in a thousand pages
| | 00:09 | of text, you're going to turn to the
back of the book, scan through the index to
| | 00:13 | find what you're looking for, say
deviation analysis, realize it's on page 322 and
| | 00:19 | then turn directly to that
section to read that content.
| | 00:23 | Indexes give you a quick
way to look something up.
| | 00:26 | That's what they do in books and
that's what they do in databases.
| | 00:30 | When we're working with SQL Server
2008, we can create two kinds of index.
| | 00:35 | The first is what's called a clustered index.
| | 00:37 | A clustered index is applied to one
of the columns in our table and it will
| | 00:42 | order our table based on that index.
| | 00:46 | In this case I'm looking at it as
the CustomerID in ascending order.
| | 00:50 | If for example I remove the clustered
index from that column and applied it to
| | 00:55 | the LastName column, it would
require that the data itself be reorganized
| | 00:59 | internally based on that clustered index.
| | 01:02 | So this method of indexing will
actually have an effect on the internal
| | 01:06 | structure of your tables.
| | 01:08 | It'll order it internally based on the index.
| | 01:11 | Now because of that, you can only
ever have one clustered index per table.
| | 01:16 | We can't actually order our data by both
last name and customer ID at the same time.
| | 01:22 | Now because of this, it is actually quite
common that it's your primary key and
| | 01:27 | in fact when you apply a primary key to a
new table it will cluster that by default.
| | 01:33 | And it's a pretty good idea to have
your primary key be the clustered index.
| | 01:37 | You'll be using that key to
directly access those rows.
| | 01:41 | It's a very fast way to work with your content.
| | 01:44 | So in this example that I'm looking at,
I almost certainly wouldn't create the
| | 01:48 | clustered index on the last name.
I'd leave it on the CustomerID.
| | 01:52 | And in that situation we might be in a
place where we would use two kinds of indexes.
| | 01:57 | We go back to the idea that our
CustomerID was our clustered index, but we know
| | 02:02 | that we also want to directly look up
people by say last name or company name.
| | 02:07 | It's all really dependent on
what the needs of your business are.
| | 02:10 | So we'll create a non-clustered index,
and we'll do that on the LastName column.
| | 02:16 | What we'll do is scan through the
LastName column and create its own index, a
| | 02:21 | separate index that points to
the different places in our table.
| | 02:26 | So if we now have a non-clustered
index based on LastName, and we're looking
| | 02:30 | for the last name of Beck,
| | 02:32 | I can scan quickly through that index.
| | 02:34 | Find the entry that will
actually point me to the row 16.
| | 02:38 | And if you are writing SELECT
statements that need to select again say in this
| | 02:42 | case last name or company name,
| | 02:44 | you'd want to think long and hard about
do I need a non-clustered index? Because
| | 02:48 | that will improve the performance of
the selects of queries, of joins, with all
| | 02:53 | my retrieval statements.
| | 02:55 | Non-clustered indexes than are a
separate index based on a column.
| | 02:59 | You can actually add multiple, so you can
have several non-clustered indexes per table.
| | 03:05 | Now you might be thinking well, why I
don't just make everything a non-clustered
| | 03:09 | index, why don't I index every single
part of every single table of my database?
| | 03:14 | Well here is the issue.
| | 03:16 | Because you're storing that in separate
indexes, if you insert a new row into that
| | 03:21 | table it's going to cause
an extra right per index.
| | 03:24 | If you have 10 indexes and insert
one row, it's going to have to update
| | 03:29 | those indexes 10 times.
| | 03:31 | So, well it can improve the
performance of your SELECT statements.
| | 03:35 | It can certainly have a detrimental effect to
your INSERTs, to your UPDATEs, to your DELETEs.
| | 03:41 | We want to use non-clustered indexes
when we know that we're going to be
| | 03:46 | searching on that column, using that
column to look something up, using it in a
| | 03:50 | where clause or in ordered by,
because it will help to those queries.
| | 03:55 | So how do we make one?
| | 03:56 | It's actually very simple.
| | 03:58 | We drill down into our database and
find the table that we're looking for.
| | 04:02 | Let's say for example we're
working with the Customer table here.
| | 04:10 | Now I'm working with a very small
database that only has 847 rows.
| | 04:15 | But let's say I was working with one
with 100,000, 200,000, two million rows.
| | 04:21 | I'm going to leave the CustomerID as
the clustered index, because it's a great
| | 04:25 | one to have, we use the CustomerID a lot.
| | 04:27 | But I might want to ask how we can
improve the performance of SELECT statements
| | 04:34 | that go against the LastName.
| | 04:36 | Oh, here is how I do it.
| | 04:37 | I'm going to right-click
Customer and jump into Design.
| | 04:41 | Well it doesn't become immediately
apparent, the best way to look at your
| | 04:44 | indexes is right click in the
blank area here and select the
| | 04:48 | Indexes/Keys section.
| | 04:50 | And one that is actually telling me is
that I have a couple of indexes already there.
| | 04:54 | I've got the PK_Customer_customerID, PK
representing not surprisingly primary key.
| | 05:01 | So our primary key index is on
CustomerID ascending and I can see down here
| | 05:07 | it's created as clustered.
| | 05:09 | And that would have been the case
when this table was first defined.
| | 05:11 | There's also an extra index here on
EmailAddress, so I've got the IX, which
| | 05:17 | tends to represent index.
| | 05:19 | It is non-clustered. Again it can't be.
| | 05:21 | We can't change this to clustered,
because we've already got a clustered index.
| | 05:26 | But somebody has obviously indexed
EmailAddress if they think they're going to
| | 05:29 | use that, which is a pretty good idea.
| | 05:31 | And an EmailAddress is
a very good exact match.
| | 05:35 | Well, I'm going to add one for the LastName.
Click Add and we get IX_Customer something.
| | 05:42 | What we need to do first of is say what
column that we want the index to be on.
| | 05:46 | I'll click the ellipsis.
| | 05:48 | It's not going to be CustomerID.
| | 05:50 | It's going to be a LastName
and Ascending is fine. Click OK.
| | 05:54 | Doesn't have to be unique. That's fine.
| | 05:56 | We would expect that in a larger or even
a small company we would have multiple last
| | 06:02 | names, and the type is an index.
| | 06:04 | We can't just say to unique key.
| | 06:06 | Nope, that's not what we're after. It's just index.
| | 06:08 | So give it a name by standard.
| | 06:11 | It's the table name and the
field name, so I'll just call this
| | 06:13 | IX_Customer_LastName.
| | 06:18 | And that's pretty much it. Close.
| | 06:20 | This is still considered an
unsaved change to this table.
| | 06:24 | So I'm going to save this now, and we
now have a non-clustered index added
| | 06:30 | to our Customer table.
| | Collapse this transcript |
| Monitoring and rebuilding indexes| 00:00 | Because your indexes will get updated
whenever there is a change to your main table,
| | 00:06 | if there is an insert, we have to
change the index, if there is an update, we
| | 00:09 | change the index, if there is a
delete, we change the index.
| | 00:12 | Or your indexes can become what's
called fragmented. They can become
| | 00:16 | inefficient and split across multiple
parts of the files that SQL Server uses
| | 00:21 | to organize itself.
| | 00:23 | Well, we can find out if that's an issue.
| | 00:26 | Though I will tell you in a typical
production database, it will be an issue and
| | 00:29 | you want to defragment, even
rebuild your indexes from time to time.
| | 00:34 | Luckily, in SQL Server Management Studio,
I can right-click any of my databases,
| | 00:39 | come down to Reports and I will about
find that in the Standard Reports section
| | 00:43 | there's both an Index Usage Statistics,
how much of these index is being used,
| | 00:48 | and Index Physical Statistics.
| | 00:49 | Both of these are great.
| | 00:51 | If I click on Index Usage Statistics,
it will tell me and this is going to be
| | 00:55 | fairly recent information,
how my indexes are being used.
| | 00:58 | There's my new one that I created a moment ago.
| | 01:01 | The index for the last name of the
customer has been used a whole one time.
| | 01:06 | Well, of course, we are on a
development server. I wouldn't expect to see huge
| | 01:10 | amounts but it would let us know if a
particular index is or is not being used.
| | 01:14 | Doesn't tell us whether it's fragmented
though. For that we need the other report.
| | 01:18 | And to come down into Reports > Standard
Reports and Index Physical Statistics,
| | 01:24 | which will scan all the indexes of all
the tables, clustered and non-clustered,
| | 01:29 | and you will often see a recommendation
here to Rebuild and an index needs to be
| | 01:34 | rebuilt when it's above a
certain level of fragmentation.
| | 01:37 | Now here's the issue.
| | 01:39 | It's telling us that most of
these indexes have to be rebuilt.
| | 01:42 | The problem is, is this database and all
its indexes are so small, so very, very tiny.
| | 01:49 | There are only a few hundred rows in
them, that these indexes will almost always
| | 01:53 | show up as fragmented.
| | 01:55 | Let's see if we can find
something that's a little bit bigger.
| | 01:57 | I am going to drop into the
AdventureWorks Data Warehouse, AdventureWorksDW.
| | 02:01 | Even though that's still
technically a very small database,
| | 02:04 | it's bigger than AdventureWorksLight.
| | 02:05 | So I am going to go over into
Standard Reports and look at our Index
| | 02:11 | Physical Statistics.
| | 02:14 | And as I scan, I see some recommendations.
| | 02:16 | One says Rebuild here, the fragmentation's at 50%.
| | 02:20 | Another says Reorganize, the fragmentation's at 6.
| | 02:22 | It's still not a very big index.
| | 02:27 | I can tell here that it's says this.
The number of pages this indexes made of is
| | 02:31 | 32 and the pages only an 8K chunk
of how SQL Server organizes itself.
| | 02:37 | So there's still not a lot going on.
| | 02:38 | I am going to come down a little bit further.
| | 02:42 | And let's say here we have got FactResellerSales
as one of the tables in this data warehouse.
| | 02:47 | If I expand that, it says it's
recommending a rebuild on this FactReseller_Sales
| | 02:53 | EmployeeKey- NonClusteredIndex.
| | 02:55 | That's a 43% Fragmentation with 113
pages. We might see a difference here.
| | 03:01 | So how do I do this?
| | 03:02 | Well, I need to find the indexes
for this table, FactResellerSales.
| | 03:08 | So I will expand the Table
section in Management Studio.
| | 03:11 | I will find FactResellerSales.
| | 03:14 | I will expand that and inside the table,
we're mostly been working with Columns
| | 03:18 | and Keys but there is an Indexes
folder which shows me all those indexes.
| | 03:24 | I could find the FactReseller_Sales
EmployeeKey, which is the one I'm looking at here,
| | 03:29 | and I could right-click that and I
have a choice to Rebuild or Reorganize.
| | 03:34 | I can also right-click the Indexes
folder and Rebuild All or Reorganize All.
| | 03:38 | What's the difference?
| | 03:39 | Well, If I say Reorganize, what it's
going to do is take some of those pages,
| | 03:45 | those little 8K chunk that are been
used to store this index and shift them
| | 03:49 | around in a bit of a better order.
| | 03:51 | Reorganizing is quite quick and we
will get you some of the way there.
| | 03:55 | If I say Rebuild, it actually dumps
the index, completely drops it and
| | 04:00 | rebuild it from scratch.
| | 04:01 | A much better way of getting a better
index but it will take a while. In fact
| | 04:05 | if you have a very large database,
it may be hours or even for terabytes of
| | 04:10 | data, days to do this.
| | 04:12 | This one shouldn't take anywhere near as long.
| | 04:14 | I am going to right click
this folder and say Rebuild All.
| | 04:17 | What will happen is its scans all those
Indexes, tells me the fragmentation, that
| | 04:21 | we really don't have
anything apart from this last one.
| | 04:24 | But I am going to click OK anyway.
| | 04:27 | It bangs through all of them
and just rebuilds those indexes.
| | 04:30 | So, let's see if we can get a
better report for FactResellerSales.
| | 04:35 | I will run the report again, come
to the Database, right-click, go to
| | 04:39 | Reports > Standard Reports > Index
Physical Statistics, and then come all the way
| | 04:44 | down to FactResellerSales and I am not
being recommended anymore to rebuild it.
| | 04:51 | If I expand that one,
it looks actually pretty good.
| | 04:53 | We have a 0%
fragmentation across 113 pages, nice.
| | 04:58 | Now typically, what you're going
to look at when you get into index
| | 05:02 | defragmentation and this will be part
of your overall maintenance plan that
| | 05:06 | you and/or your DBA are
going to help build and create.
| | 05:10 | Like a lot of other things when
using Management Studio, if you are
| | 05:15 | rebuilding all your indexes, you do
have the opportunity to script that to a
| | 05:20 | new query window and it will
actually generate the SQL to rebuild those
| | 05:25 | indexes if you want to.
| | 05:26 | And that might be a starting point
for creating say a larger SQL script
| | 05:31 | that will execute a maintenance plan, the
maintenance structure on your entire database.
| | 05:37 | When you're getting into that, you
certainly want to go out to the Internet and
| | 05:41 | start looking at some blog posts
and finding some good routines.
| | 05:44 | Because you'll find that certain
people gather up their suggested scripts and
| | 05:48 | make them available for general
plans for database maintenance.
| | 05:52 | But for us on our development server,
this is how we approach monitoring and
| | 05:57 | defragmenting our indexes.
| | Collapse this transcript |
| Monitoring database size and integrity| 00:00 | Looking at index fragmentation, can
give us a very specific idea of a tiny
| | 00:06 | little piece that we want to keep
an eye on and fix and maintain in our
| | 00:09 | database, but what about the larger
idea of the database itself and the
| | 00:14 | consistency and integrity of the database?
| | 00:16 | Well we can use some of those reports
to get some very useful information.
| | 00:20 | If I right-click any of my databases I can
drop into my reports, my standard reports,
| | 00:26 | and start off with something very simple
and straightforward like the disk usage idea.
| | 00:30 | How much space is this taking up?
| | 00:32 | Getting this little pie chart that
will tell me how much of it is data the
| | 00:36 | purple stuff, how much of it is index,
how much of it is unallocated and just
| | 00:40 | being held back for new
rows and new information.
| | 00:43 | And that's useful, but won't really guide you
in any particular direction to doing anything.
| | 00:48 | However, some of the other reports
can be a bit more useful that way.
| | 00:52 | We can drop into disk usage by top
tables, allowing you to quickly scan which of
| | 00:56 | your tables are taking up,
| | 00:58 | both of them have a space and have the most
rows in them, not necessarily the same thing.
| | 01:03 | We can drop into our reports, and
one of the ones that I like is the Disk
| | 01:07 | Usage by Partition.
| | 01:09 | Now we don't cover partitioning in this course.
| | 01:12 | Partitioning is the ability to take
large tables and actually split them across
| | 01:16 | multiple physical file structures.
| | 01:18 | It's not something we can do
with SQL Server Standard edition.
| | 01:22 | It's only actually available
in the Enterprise editions.
| | 01:25 | But the report nonetheless gives us
some interesting stuff to look at.
| | 01:29 | Because it will show us all our tables
and allow us to scan things like our
| | 01:34 | indexes and how much space those take up.
| | 01:37 | So here at the DimCustomer table
18,000 rows, 9,000 K, and I can scan the
| | 01:44 | indexes as well, but seems
to show some consistency.
| | 01:47 | I've got 18,000 rows in them, but it shows
me how space the indexes are taking up.
| | 01:53 | Dropping back in to the Reports we have
things like view all our transactions.
| | 01:58 | I haven't executed anything against
this database for quite a while so there is
| | 02:02 | nothing that's been run.
| | 02:04 | But we would have that if we wanted.
| | 02:06 | We've got user statistics, schema
changes, the index usage and physical
| | 02:10 | statistics we saw in the previous movie.
| | 02:13 | I also have this one,
Database Consistency History.
| | 02:16 | Now the first time you run it,
you're likely to see no messages at all.
| | 02:20 | Because what it's telling you is this.
| | 02:22 | It's a history of executions of DBCC CHECKDB.
| | 02:26 | Well what the devil does that mean?
| | 02:29 | DBCC CHECKDB is a command that you can
run if you're in the SysAdmin role and
| | 02:34 | it does internal
consistency checks on the database.
| | 02:38 | Let me show you how you do it.
| | 02:39 | Open up a new query window, making
sure that AdventureWorksDW is selected or
| | 02:44 | whatever database that I want to run this on,
and I simply type DBCC CHECKDB. Execute.
| | 02:51 | Depending on the site of your
database it may take a while to do it.
| | 02:55 | But when it comes back, it's going to
run a whole bunch of internal checks on
| | 03:01 | your tables and some of the
background objects that support your tables.
| | 03:05 | And hopefully you will end up with
CHECKDB found 0 allocation errors and 0
| | 03:10 | consistency errors in the database.
| | 03:13 | Even if you're doing backups regularly,
even if you're taking a look at your
| | 03:17 | indexes and defragmenting those, you
should be running this DBCC CHECKDB on a
| | 03:23 | fairly regular basis, at least weekly.
| | 03:25 | Possibly more often if you've
got a very volatile database.
| | 03:28 | Again like with your indexes this
should be part of your enterprise level
| | 03:33 | maintenance plan idea.
| | 03:34 | But the nice thing about it is every
time it's run, it is then stored in the log,
| | 03:39 | and if I run my report again on
the Database Consistency History, I should
| | 03:43 | expect to see 2 instance of
this and how long they took.
| | 03:47 | Now obviously we're starting to
build very complex structures here.
| | 03:51 | And a real deep discussion on what we
should be doing for database monitoring
| | 03:55 | and optimization is beyond the scope of this course,
but there's an immense amount of material, both in
| | 04:00 | Books Online and on the web, that
you'll probably want to take a look at as you
| | 04:04 | get deeper into your databases.
| | Collapse this transcript |
|
|
11. Backing Up and RestoringCreating backups| 00:00 | We have all these great features of SQL
Server to keep our data fast and clean.
| | 00:05 | We've got constraints for integrity,
transactions, indexes, but at the end of
| | 00:10 | the day all these databases are being stored
on files on a hard drive and hard drives break.
| | 00:18 | So even if you've created your database
files on a nice RAID 10 unit, you still
| | 00:23 | need to be it backing up
and backing up regularly.
| | 00:25 | Or we can do this using SQL Server
Management Studio or even just SQL commands.
| | 00:30 | We can get this going.
| | 00:32 | We backup one database at a time.
| | 00:34 | So open up the databases, select the one
you're interested in, not that it really matters,
| | 00:39 | and come down to tasks where you'll
find an entry for backup. I select that.
| | 00:45 | The reason why I say it doesn't matter
which database you right-click on is
| | 00:49 | because the first question you get in
the backup window is which database you're
| | 00:54 | interested in backing up.
| | 00:56 | Most of the time for a
straightforward situation, you're going to keep
| | 01:00 | the default values.
| | 01:02 | Really the only choice you're interested
in here is this backup type. Is it full
| | 01:06 | or is it deferential?
| | 01:08 | And in fact the first time through the only
option you'll be able to do is a full backup.
| | 01:13 | After you've done one full backup,
you can select to do a differential one,
| | 01:18 | which will be smaller in size, because
it's essentially the changes between your
| | 01:22 | last full backup and the
state of the database right now.
| | 01:26 | The reason that SQL Server is able to
do this is because it keeps track of the
| | 01:31 | different backups that you've done.
| | 01:32 | It likes to understand when you did
your full backups, when you did your
| | 01:35 | differentials, and one of the impacts of
that, I mean that if you're selecting a
| | 01:39 | full backup, you also
have this option here to do
| | 01:42 | what's called a Copy Only Backup, which
really detaches from the main chain of
| | 01:48 | backups, creating a self-contained one.
| | 01:50 | You'll notice that you're not able
to do a copy only backup when it's
| | 01:53 | differential, because you haven't
got anything to make a difference on.
| | 01:57 | So we're going to do a full backup.
| | 01:59 | It's not a copy only,
And backing up the database.
| | 02:02 | We can give it a name.
| | 02:03 | I'll accept the default here.
| | 02:04 | There is an expiration option here
that the backup set will expire after
| | 02:09 | certain amount of days.
| | 02:10 | If it's zero that just
means it won't expire at all.
| | 02:14 | Now this section down here, the
destination, this can trick people and trip
| | 02:19 | people up. I've known several
people that have been bitten by this.
| | 02:23 | This is the default location
that your backups will go to.
| | 02:27 | It's actually just the path that SQL
Server is installed at and we've got a
| | 02:30 | Backup\AdventureWorksLT.
bak file. Okay, that's fine.
| | 02:36 | But people see this button. They can
click Add and it gives them the ability to
| | 02:41 | add a new path or add a new destination on disk.
| | 02:45 | That looks all right.
| | 02:46 | Here's the issue. If you do this and
you can add multiple locations in here
| | 02:51 | to back out to, but it does not copy the
backup and duplicate it from place-to-place.
| | 02:56 | What it will do is almost like a basic
RAID pan that will split up the backup
| | 03:02 | across multiple files.
| | 03:03 | Now that means it can be faster, which
is a good thing, but it means if you have
| | 03:07 | multiple locations and you have a
need to do a restore, you have to get the
| | 03:12 | backup files from every location.
| | 03:14 | So this is not a redundancy
option. It's just a speed one.
| | 03:17 | I'm going to click over here
on the left to the Options page.
| | 03:22 | Now I've already done a couple of
backups, both full and differential, and it's
| | 03:26 | asking me here, do I want to
back up to the existing backup set?
| | 03:29 | And yes I do. I'm continuing it but I do
have the options where I could say back
| | 03:33 | up to a new media set or
overwrite all the old ones.
| | 03:37 | I do have some options here to
verify the backup when finished.
| | 03:40 | Yup, I think I'll do that.
| | 03:42 | Click back to the General page and
I'm just going to go for it. Click OK.
| | 03:46 | This is a fairly small database.
| | 03:48 | So it's a pretty quick job, but
obviously if you have lots of rows it's going to
| | 03:52 | take a little while to work.
| | 03:54 | That's how you'd get your first backup started.
| | 03:56 | Now your organization may have and
hopefully does have a more strategic backup
| | 04:02 | strategy that should include SQL Server.
| | 04:04 | You may have third-party tools that
you're dealing with, because backup and
| | 04:09 | restore should really be
an enterprise-wide idea.
| | 04:13 | But if you're going to be involved
even in basic administration of SQL Server
| | 04:17 | you certainly want to be
comfortable with doing a casual backup.
| | Collapse this transcript |
| Creating differential backups and using backup compression| 00:00 | Once we've done at least one full
backup, we can actually continue to do the
| | 00:04 | next ones by doing differential ones, although
every now and then we'll do a full backup again.
| | 00:10 | All we do with this is go in and just
change our backup type to Differential,
| | 00:14 | and I can just click OK.
| | 00:15 | Now that's not very exciting, so let
me show you a couple of other options
| | 00:19 | that you have there.
| | 00:21 | Once again just going back into the
database, Tasks and Backup. To get a bit of
| | 00:26 | information about how many times we
have done a full backup, how many times
| | 00:30 | you've done a differential backup,
| | 00:32 | we can select the destination path and
come down here to the Contents button.
| | 00:35 | And that will allow us to kind of
step through or different backup sets,
| | 00:39 | which ones were full, which ones were
differential, and how long we've been
| | 00:42 | keeping them around for.
| | 00:44 | This whole collection, this whole suite
of full and differential backups, are in
| | 00:48 | order and they are known as a media-set.
| | 00:50 | SQL Server likes to understand the
history of how you've done your full and your
| | 00:56 | differential backups.
| | 00:57 | It makes a lot of use of that.
| | 00:59 | That can be impactful if you
want to change a few other options.
| | 01:03 | So let's say I drop into the second
page here and I can see that my default is
| | 01:07 | I am backing up to the existing media-set.
| | 01:09 | And I start to look at some of the
other information like Verify backup and
| | 01:13 | Perform checksum on media.
| | 01:15 | And then I look at this guy here.
Compression, Set backup compression.
| | 01:19 | This is a reasonably new
feature with SQL Server.
| | 01:22 | If you have large databases it's a
good thing to have, because you can't
| | 01:26 | compress the backup files.
| | 01:27 | With the choice of whether we do or not
is based by default on the server setting.
| | 01:32 | What does the server want to do, and I'll
show you how to change that in a minute.
| | 01:36 | But let's say I've looked at this
and think, oh well I can apparently
| | 01:39 | override this, great.
| | 01:40 | While I'll decide that I'm
going to compress my backup.
| | 01:43 | So I'll click OK and it says "No, you
won't." That's because when you've got a
| | 01:48 | media-set of full and differential
backups they either have to be all
| | 01:53 | uncompressed or all compressed,
you can have a bit of both.
| | 01:57 | So my options here, if I wanted to
compress the backup is that I have to click
| | 02:01 | this guy here to backup to a new
media-set and erase all the old ones.
| | 02:06 | I don't want to do that, so I'm
actually going to leave it at the default and
| | 02:11 | just run through it there.
| | 02:12 | One last thing that I could do, if
I don't want to come into SQL Server
| | 02:16 | Management Studio and perhaps I
just want to script a job to occur,
| | 02:20 | we can, once we've set this up, let's
say I want to get ready to do differential
| | 02:24 | one, I'll check my
options and they look all okay,
| | 02:27 | I can come out to the top of the
window and click the script button, which
| | 02:31 | gives me a few options.
| | 02:32 | Generate a script action to a new
query window, script action default to
| | 02:36 | clipboard, to job, what does this do? Well,
| | 02:39 | it's quite simple.
| | 02:41 | If I hit that, Cancel, I'm going back
now here it's generated the SQL version of
| | 02:47 | what we were just doing with
SQL Server management studio.
| | 02:52 | This is the SQL command for doing a
backup. We are backing up the database to
| | 02:57 | this particular address and
it's a differential backup.
| | 03:02 | So if you want to start writing your
own commands, you could always start off
| | 03:05 | with that window and then just script it
and make any changes that you wanted to do.
| | 03:11 | But finally on that idea of setting
the server default for our backup
| | 03:16 | compression, if you want to, you
can change this at the server level.
| | 03:19 | I'm going to right-click the instance
name itself, come down to properties, and
| | 03:23 | you'll find that particular setting
under the database settings here, where
| | 03:28 | we've got the option here
to compress backup or not.
| | 03:32 | Now I'm going to leave it unchecked as
it was before, but that's where I could
| | 03:35 | change it, if I was very much intending
to do backup compression on everything.
| | Collapse this transcript |
| Restoring databases| 00:00 | One of the reasons I like to get into
the habit of backing up regularly even
| | 00:05 | when I'm just working with sample
databases on a development server is that
| | 00:09 | it's way too easy to run a little
bit a code that maybe does a little bit
| | 00:13 | more than you expected.
| | 00:14 | So I'm pasting in a few delete
statements here. This is not the kind of code you
| | 00:19 | want to execute a lot.
| | 00:20 | Well this is going to do with the no
WHERE statements is it's going to go
| | 00:24 | through and delete
everything in all of those tables.
| | 00:28 | So say this accidentally happened
yesterday, a few hours ago, a few seconds ago.
| | 00:34 | And I'm now in the problem that when I go
and look at my Customer table, for example,
| | 00:41 | I have nothing whatsoever
and this is not what I want.
| | 00:44 | Well luckily I was doing regular
backups so I can restore these.
| | 00:49 | I'm going to do this from SQL Server
Management Studio, though you can do it from
| | 00:54 | the SQL command line.
| | 00:56 | I'll right-click one of the
databases again it doesn't matter.
| | 00:59 | Even if the database wasn't showing
up, you can still pick any of them.
| | 01:03 | Go into Tasks and then Restore.
We're going to restore the database.
| | 01:07 | And again it gives you the drop-down.
Is this the one that you want? Yes it is.
| | 01:11 | So a point in time most
recent possibly? Yeah absolutely.
| | 01:15 | If you had a specific date and times in
a long chain of backups, you can pick it
| | 01:20 | from a particular place. We don't need to here.
| | 01:23 | And because I've been using SQL Server
management studio to do my backups, it's
| | 01:27 | taken a look and says okay I have the available
files. I know the backup set. I'm ready to go.
| | 01:33 | What else would you like to do?
| | 01:34 | I do have a few options.
| | 01:36 | I'm going to leave everything as is.
There are some options you might want
| | 01:39 | to look at if your situation is a
bit more unusual, because there's what's
| | 01:44 | called a recovery state.
| | 01:45 | What state do we want the
database to be in when it brings up?
| | 01:50 | Perhaps you're trying to recover a
state of the database where you're just
| | 01:54 | interested in getting it as accurate as
possible, but as far as you're concerned
| | 01:58 | it could be in read only mode.
| | 02:00 | Well that's not usual. I want to have
this database ready to go and ready to use.
| | 02:04 | I'm going to leave all the options there.
| | 02:06 | I'm going to click OK.
| | 02:11 | It's throwing me up an error that exclusive
access could not be obtained because the
| | 02:15 | database is in use. Well we've got
a couple of things we can try there.
| | 02:18 | It's probably just a little bit more
concerned with the fact that I only just
| | 02:23 | did those DELETEs and it's hanging on
to some locks here, so I'm just going to
| | 02:27 | reconnect to the instance.
| | 02:33 | Go back in and try to select to
restore the database again, leaving all the
| | 02:38 | default options, and then click OK.
| | 02:43 | And this time we're looking good.
| | 02:45 | Of course, the proof is can we go back
into that database and find to say the
| | 02:51 | customer information? And yes, we can.
| | 02:53 | Now similar to working with your
incremental and your full backups, if you are
| | 02:59 | working with a restore, that can be
scripted if you need to. Hopefully you are
| | 03:05 | not having to do a restore of your
database often enough that you actually need
| | 03:08 | to have a permanent script file for doing it.
| | 03:11 | And certainly if your database is in a
more complex situation, if you're doing
| | 03:17 | not just the regular full and
differential backups, but you have split your
| | 03:21 | backups into the more granular pieces
of file groups and transaction logs,
| | 03:26 | you are going to want to take a
little bit more care than just the quick
| | 03:29 | way that we've done it.
| | 03:30 | But certainly when working with a
development server, like we're doing right now,
| | 03:35 | this should be a perfectly and
acceptable way to do both your backups and
| | 03:38 | your restores.
| | Collapse this transcript |
|
|
12. Security FeaturesIntroduction to SQL Server security and permissions| 00:00 | Here's what the SQL Server
understands about security.
| | 00:03 | It knows you make a database
because you want to people to use it.
| | 00:07 | There are users and groups of people.
| | 00:09 | There are Web applications and desktop
applications that want what it is you
| | 00:13 | have in your database.
| | 00:14 | The SQL Server calls these principals.
| | 00:17 | A principal is something that will
connect to SQL Server to request a resource.
| | 00:22 | They'll select from a table or update a
table, or execute a stored procedure, or
| | 00:27 | even create a database.
| | 00:28 | And on the other end SQL Server knows
about the things that exist inside of it.
| | 00:34 | The databases, the tables, the
stored procedures, the functions, the
| | 00:38 | schemas, the views, all these
things we have worked with our considered
| | 00:41 | objects in SQL Server.
| | 00:44 | And yes, many objects contain other objects.
| | 00:47 | Databases contain schemas.
| | 00:48 | The schemas contain tables and
stored procedures, and so on.
| | 00:52 | But just because a principal can get
into SQL Server at all doesn't mean
| | 00:57 | that it should have blanket access to use and
change and control to all of those objects.
| | 01:01 | So in between your principals and
your objects are the idea of permissions.
| | 01:07 | What can the principal do
with that particular object?
| | 01:11 | And we have multiple permissions that
include select, insert, update, delete,
| | 01:16 | the standards, but we also have
execute permissions for stored procedures.
| | 01:20 | We have the ability to alter or change
parts of the database or control the
| | 01:25 | entire database or any object in it.
| | 01:27 | And these are of course different
based on the person and the object.
| | 01:31 | Bob might need permission to
update the Sales database, but not the
| | 01:35 | Customers database.
| | 01:36 | Alice should be able to execute a
stored procedure but not modify it.
| | 01:41 | Fred can select from a
table, but not insert into it.
| | 01:45 | And us, well we want to be able to log
on to the SQL Server and do everything
| | 01:50 | everywhere, Select, Insert, Delete,
Update, make new databases, edit stored
| | 01:56 | procedures, create backups, restore databases.
| | 01:59 | Now if you have to define all of these
different permissions and connections
| | 02:04 | individually, it's going to get very tedious.
| | 02:06 | But to make it easier SQL Server helps
us out by defining several common roles
| | 02:13 | that actually fit between
your people and your permissions.
| | 02:17 | These roles are setup with
a set of permissions already.
| | 02:22 | You take your people or your
groups and you attach them to particular
| | 02:26 | roles inside SQL Server.
| | 02:29 | And this makes the
management process much easier.
| | 02:33 | Now some roles exist for each separate database.
| | 02:37 | Every time you make a database you get a
new set of these roles just for that database.
| | 02:42 | Those include the role called db_datareader.
| | 02:46 | If you're in the datareader role for that
database you can by default read from every table.
| | 02:52 | A bit better than that you have db_datawriter.
| | 02:55 | You can also write to that table.
| | 02:58 | You have some quite specialized
roles like db_backupoperator.
| | 03:03 | You might never use this but if you had
someone where that was their particular
| | 03:06 | job role, you could put
them in this SQL Server role.
| | 03:10 | And also for the database you
have something called db_owner.
| | 03:14 | The db_owner role gets to do
everything in that database.
| | 03:19 | There are a few more but
this is the core of them.
| | 03:22 | And because these roles exist separately
for each database, you could be granted
| | 03:27 | the db_owner role on one database and
just be a db-datareader on another.
| | 03:33 | Now some other roles are not duplicated.
There is just one role across the entire server.
| | 03:38 | For example, there is a role called dbcreator.
| | 03:41 | And now as you might imagine, if
you're in the dbcreator role you can create
| | 03:47 | db's, you can create databases.
| | 03:50 | There's a securityadmin role that gets
to and in fact security for this server,
| | 03:54 | set up new users, set up new principals.
| | 03:57 | There is a serveradmin role, and then
at the top of the tree there is sysadmin.
| | 04:02 | Even though there are a few others
which you can explore and books online,
| | 04:05 | sysadmin is godlike.
| | 04:07 | If you're a sysadmin on that
server, you can do anything.
| | 04:11 | It effectively makes you DB owner of
every single database inside that instance.
| | 04:17 | So this whole security thing breaks down
into principals, roles, permissions and objects.
| | 04:23 | For example, the principal Fred
can be given the role db_datareader,
| | 04:29 | which grants the permission to select and
that's attached to the say the Orders database.
| | 04:34 | Or me. Well I'll get the role of sysadmin,
which gives me the permission control
| | 04:39 | over everything, over the entire
instance and everything inside it.
| | 04:42 | And your principals can
also be Windows groups too.
| | 04:45 | If you have good groups defined in
your domain, you could for example give the
| | 04:50 | managers group the role db_datawriter
and gives them the insert, update, delete
| | 04:55 | permission on, for example,
the ProjectPlans database.
| | 04:59 | But in the same setup they don't have
permission to write to the AdventureWorks
| | 05:04 | data warehouse. They just
have permission to read from it.
| | 05:08 | And using the built-in roles in
SQL Server will make handling your
| | 05:12 | permissions much easier.
| | 05:14 | Now technically speaking a
role actually is a principal.
| | 05:18 | But I find a bit more useful
to separate them out like this.
| | 05:21 | Thinking about giving that
principal a particular role, which gets the
| | 05:25 | permission to an object, and you still
have to choose what these hookups are and
| | 05:31 | you get a lot of flexibility to do that.
| | 05:33 | We're going to see how to do that in SQL
Server Management Studio in just a moment.
| | 05:37 | Now do bear in mind, you
can define your own roles.
| | 05:41 | But only look into that after you've really
become comfortable with the built-in ones.
| | 05:45 | Because most of the time the available
ones like, db_datareader, sysadmin, datawriter,
| | 05:50 | db_owner, they're
going to work just fine.
| | Collapse this transcript |
| Adding a Windows user to the database| 00:00 | The best practice for working with
security in SQL Server is that you're using
| | 00:04 | Windows authentication.
| | 00:06 | That means before anybody actually
accesses your SQL Server, they have had to
| | 00:10 | log on to the domain or even log on to
the local machine, as a legitimate Windows
| | 00:15 | user, that user already exists.
| | 00:18 | What that means is your job inside SQL
Server is not declaring that there's a
| | 00:23 | certain user called Barbara,
certain user called Alice,
| | 00:26 | but you're saying what is that
user allowed to do in SQL Server.
| | 00:30 | And this is the way that we do it.
| | 00:32 | Instead of opening up my Databases
section, I am going to expand my Security and
| | 00:36 | take a look right now at my Logins.
| | 00:38 | Now, right now, I don't have a lot.
In fact most of these are essentially
| | 00:42 | background and service accounts because I
haven't added anybody to access this instance yet.
| | 00:47 | So I am going to right click the
Logins folder and say New Login.
| | 00:51 | Let's be very clear about what we're doing.
| | 00:53 | We are not actually creating a user here.
| | 00:55 | The user already needs to
exist outside SQL Server.
| | 00:58 | We are just saying what are they allowed to do.
| | 01:00 | Now, if I knew the name of the user,
I could stop typing it in or I can use the
| | 01:05 | Search button over here, even do a
little search on the users that I have.
| | 01:11 | And I am going to use
this user here called AmayaW.
| | 01:14 | Now I have got a stand-alone machine,
so I'm just using a local user, preferably
| | 01:19 | in a production environment.
You've got a domain user obviously.
| | 01:22 | So that user is already defined.
We are saying what is she allowed to do.
| | 01:26 | And the two most important parts of
adding this user as a new login is the
| | 01:31 | Server Roles section, which says does that
user have any special server role abilities?
| | 01:36 | And the User Mapping section, which
really means how is this user attached to or
| | 01:41 | defined in any of the
databases that we have that exist?
| | 01:45 | So question one, should this user be
granted anything particularly special?
| | 01:50 | Should she be given sysadmin rights and
be effectively the administrator for the
| | 01:55 | entire SQL Server instance?
| | 01:56 | Well, let's say in this case maybe not.
| | 01:59 | Though I could give her dbcreator
and allow her to make new databases.
| | 02:03 | By default, everybody gets put in the
public role but the public role just
| | 02:06 | doesn't get to do very much.
| | 02:08 | So that's okay. I will leave it as it is.
| | 02:10 | I'm going to jump across
to the User Mapping section.
| | 02:13 | What I want is for this new user to be
added to the AdventureWorksLT database
| | 02:19 | and the NorthwindSQL.
| | 02:21 | If I just select the
database, I can't change the role.
| | 02:24 | I have to click this checkbox that says Map.
| | 02:27 | Once I do that it's telling me I'm mapping
this user to certain roles in that database.
| | 02:33 | So here's what I could give her db_
datareader and db_datawriter and leave her in public.
| | 02:40 | I could come down a bit more and with
NorthwindSQL perhaps just make her a reader.
| | 02:46 | Click OK.
| | 02:47 | That user has now been added to SQL
Server and mapped to those two databases.
| | 02:53 | Now of course if you had to do dozens
or even hundreds of users, that's going
| | 02:57 | to be a little tedious.
| | 02:58 | So one of the things you can also do is
when you're creating logins, if you have
| | 03:02 | a group that you know of that
already gathers the people together,
| | 03:06 | it's being managed say in Active Directory,
| | 03:08 | you can just use the name of the group.
| | 03:10 | I do have a simple group
that's been defined here locally.
| | 03:12 | It is called sales.
| | 03:14 | Not showing up right now just because
I'm only showing the built-in principles.
| | 03:18 | Let's select Groups.
| | 03:20 | Find again and there is the Sales group.
| | 03:24 | Click OK, click OK.
| | 03:26 | I am leaving the other options here.
| | 03:28 | I don't need to map them to a certificate.
| | 03:30 | I don't need to change the default database.
| | 03:32 | But what I'm going to do is say no,
they have no specific server role but in the
| | 03:38 | User Mapping I'm going to map this
and add everybody and give them the
| | 03:43 | db_datareader privilege.
| | 03:48 | Click OK and that means from this
point on, anybody who's defined on this
| | 03:53 | machine is being in the Sales group
will allow to be execute statements that
| | 03:57 | read against that database.
| | 04:00 | Now if Amaya was in the Sales group
and given her own privileges, she's going
| | 04:04 | to get the most, she is going to get the
highest ones of whatever she has been granted.
| | 04:08 | Even if I was defined in that Sales
group, because I'm also defined as sysadmin
| | 04:14 | in this instance I get to
own everything everywhere.
| | 04:17 | Adding groups of course makes it a
lot easier to manage because you then
| | 04:21 | actually manage your people
into the groups in Active Directory.
| | 04:24 | You don't really have to worry too much
about working with that in SQL Server.
| | 04:29 | Now, just to show you what's
actually happening when I map a user into a
| | 04:33 | database is you will find that
the databases I mapped to, such as
| | 04:37 | AdventureWorksLT, themselves have their own
security section with their own users defined.
| | 04:43 | And when I selected to map them,
we see the individual entries just for that
| | 04:47 | database showing up here.
| | 04:49 | I can right-click, select Properties,
and see that in this case Amaya has
| | 04:53 | datareader and datawriter.
| | 04:55 | I wouldn't get the choice here to add
her to a server role but this is okay here,
| | 05:00 | and again looking at Sales,
I can see that Sales has just the
| | 05:03 | db_datareader role membership.
| | Collapse this transcript |
| Creating SQL Server logins and switching authentication modes| 00:00 | One of the best practice for defining
your principals is to make sure that they
| | 00:05 | already exist as users on your domain
or on your local machine and that way
| | 00:09 | we're using Windows authentication as
that first barrier to entry, they have to
| | 00:14 | have logged on to your machine
or to your domain to get there,
| | 00:17 | it's not the only choice that we have.
| | 00:20 | When I'm creating a new login one of
the options I'll have here is to switch
| | 00:24 | from Windows Authentication
to SQL Server Authentication.
| | 00:28 | This is not a minor
difference. This is a big deal.
| | 00:31 | With Windows Authentication selected
the login name that I type has to exist
| | 00:36 | outside. It must exist on this
machine or on that domain.
| | 00:40 | When I select SQL Server Authentication
it really means define a new user, give
| | 00:45 | them a name, give them a password. They
didn't exist before. I'm just writing them
| | 00:50 | and they may now exist in SQL Server.
| | 00:51 | A very common reason to do this is
that you have, for example, a web service
| | 00:56 | application, something that needs to
connect to this machine, but because of the
| | 01:01 | way your network is setup it can not
actually authenticate as legitimate Windows user.
| | 01:06 | They might be running on a Linux
box, they might be running as a Java
| | 01:10 | application. They're outside your firewall
and they can't logon as a Windows user.
| | 01:15 | They need to connect with
a username and a password.
| | 01:19 | So we'll set this up. We'll give them
the name WebServiceApplication and I'm
| | 01:23 | going to type in a password here.
| | 01:27 | I'm going to uncheck the user must
change password at next login. In case this
| | 01:32 | was an application was connecting,
we don't want to throw that problem in
| | 01:35 | their way, and it's up to you whether you
want to enforce password expiration and so on.
| | 01:40 | All the other choices that we have are
the same. Do I want to give this new user
| | 01:45 | any server role? And no I don't and in
fact the only thing I'm going to give them
| | 01:50 | is the ability to read from AdventureWorksLT.
| | 01:54 | So I'll switch to my User Mapping, I'll
select the box beside AdventureWorksLT,
| | 01:59 | and I'll give this user the
db_datareader role and click OK.
| | 02:05 | If I expand Logins I'll see that user
listed there. Again this user has not
| | 02:10 | been created on this machine, he is
not a Windows user, not a domain account.
| | 02:15 | He only exists inside SQL Server and the question
is well, prove it. What can that user actually do?
| | 02:22 | Well we can actually emulate that and try
and log on to this database as that user.
| | 02:28 | I'm going to click this button up in my
Object Explorer that says Connect Object
| | 02:32 | Explorer and it throws up the usual
dialog box we've seen. What I'm going to say is
| | 02:36 | instead of connecting as me I want to
connect to the same machine using SQL
| | 02:41 | Server authentication, and I had an old
account there, but I'm going to type
| | 02:46 | WebServiceApplication and type in the
password that I had and click Connect.
| | 02:53 | We're going to have a problem.
| | 02:54 | Now it just says login failed for
user WebServiceApplication and I
| | 03:00 | perhaps could think maybe I type my
password wrongly, maybe I type the name
| | 03:03 | wrongly, does it need some prefix, and
unfortunately the problem is a bit bigger than that.
| | 03:08 | Here's the issue. If I go back and I'm
still connected as myself right now, so
| | 03:12 | I do have admin privileges. I'm going
to right-click the Instance and click
| | 03:17 | Properties. I am looking at the
properties of SQL Server instance on this machine.
| | 03:22 | Now if I come down to Security I'll
see that my server authentication is a
| | 03:28 | Windows Authentication mode. That means
in order to log on to this machine I have
| | 03:33 | to be a Windows account.
| | 03:34 | Now you might think, well why did it
let me create a SQL Server account then?
| | 03:39 | Well, it could be useful. You might
want to set up several SQL Server accounts
| | 03:43 | but you're not actually going to switch
your authentication mode until you're
| | 03:47 | ready to go live. So it's perfectly acceptable.
| | 03:50 | But I need to switch it so I can check it.
| | 03:52 | You can do this after the fact,
but it's a fairly significant switch.
| | 03:56 | You wouldn't want to do it in the
middle of a busy day because as soon as I
| | 03:59 | select this and click OK, it's going to
tell me that my configuration change will
| | 04:03 | not take effect until SQL Server is restarted.
| | 04:06 | Well it's just me so I can restart it.
| | 04:09 | I'm going to drill down into my
SQL Server 2008 R2 programs, find my
| | 04:14 | Configuration Tools, and open up
SQL Server Configuration Manager.
| | 04:19 | The only thing I need to restart is the
SQL Server Engine itself which shows up
| | 04:24 | as this SQL Server address and I have
the choice of hitting the Stop button and
| | 04:29 | then waiting and then clicking Play,
but we do have a little Restart Service
| | 04:33 | buttons as well. Right-click would work
too. This will take just a moment because
| | 04:37 | it's a small server, and when it's done
we can close Configuration Manager.
| | 04:43 | That's the only thing we needed it for and
I'm going to try to connect again.
| | 04:47 | I'll click this button. I'll say that I want
to use a SQL Server Authentication and
| | 04:52 | the accounts I had set up was
Web ServiceApplication, type in the password, and
| | 04:59 | connect, and we're connected successful.
In fact right now we're connected twice.
| | 05:04 | This top row in the Object Explorer is
telling me I'm logged on as myself with
| | 05:08 | Windows authentication and this is the
view of it we'd that would log on as the
| | 05:13 | SQL account and that
should be a lot more restricted.
| | 05:16 | For example if I drill down onto the
databases and think, well maybe I'll take a
| | 05:20 | look at AdventureWorks,
| | 05:22 | well I don't get to see that one.
I don't get to see AdventureWorks data
| | 05:26 | warehouse or data warehouse 2008 R2.
| | 05:29 | I do get to expand AdventureWorksLT.
| | 05:31 | I do get to expand Tables.
| | 05:33 | I could even right-click and say I want
to select the Top 1000 Rows because I'm
| | 05:38 | allowed to read from this database.
| | 05:40 | It would give me the ability to right-
click and say Edit Top 200 Rows, but if I
| | 05:45 | actually try to do something here like
change the title, it's actually going to
| | 05:52 | throw an exception here that the UPDATE
permission was denied on that object.
| | 05:57 | I don't have permission to write to this database.
| | 06:00 | So it wouldn't let me save this so I'm just
going to hit the Escape key to jump out of
| | 06:05 | having that change in there.
| | 06:06 | I'm going to go back and just disconnect
this part again. Disconnect as being the
| | 06:13 | WebServiceApplication and just go
back to being a regular administrator here.
| | 06:17 | Again one of the things you want to
be very careful of is when you're using
| | 06:21 | SQL Server accounts and you're
allowing that login ability of just a username
| | 06:27 | and password, that you are using
complex passwords and even complex user names
| | 06:32 | as well, but if you do have to expose
your connection this way, this is the way
| | 06:37 | to create them.
| | Collapse this transcript |
|
|
13. Reporting ServicesIntroduction to SQL Server Reporting Services| 00:00 | Reporting Services is a
separate component of SQL Server 2008.
| | 00:05 | It is available in both the Standard
and the Express editions and the idea
| | 00:09 | behind it, not surprisingly, is to be
able to create reports without requiring a
| | 00:14 | developer to write a custom application.
| | 00:16 | So it's really a business
intelligence layer, allowing you to create a
| | 00:20 | presentation of the data in your
databases and then share that across an
| | 00:24 | organization, and to understand it,
it's best to understand there are really
| | 00:29 | three different parts to it.
| | 00:31 | First is the server-side part of the
platform, the engine of Reporting Services
| | 00:36 | that can manage and deliver these
reports, and this is considered a
| | 00:40 | self-contained component of SQL Server.
| | 00:43 | You can choose to either
have that installed or not.
| | 00:46 | If you're not going to use it,
it shouldn't be installed.
| | 00:49 | It even comes with its own
application for managing its configuration.
| | 00:52 | Now the second part is an
application to help you design those reports.
| | 00:58 | Well, that's where it gets tricky because
there are a few different ways to create reports.
| | 01:03 | The something called Report
Builder, which is a stand-alone desktop
| | 01:07 | application for developing reports
for reporting services and with the R2
| | 01:11 | release of SQL Server 2008 there is
a new addition of this application
| | 01:15 | called Report Builder 3.0.
| | 01:16 | That lets you create complex reports
not only including the data itself but
| | 01:22 | including visualizations of the data to
charts including maps, data bars and spot lines.
| | 01:29 | Now there is also an application
called the Business Intelligence Development Studio.
| | 01:34 | This comes with an advanced
project template called Report Designer.
| | 01:37 | If your developer used to Visual Studio,
this might be the way that you would want to go.
| | 01:43 | Now, however, this is the third part.
| | 01:45 | Once your report is created, how do
you view and manage these reports?
| | 01:49 | We don't want to take the old-school
view that the report has to be something
| | 01:53 | that's printed off and handed around.
| | 01:56 | So typically, the reports can be
viewed by going to a web application
| | 01:59 | called Report Manager.
| | 02:01 | This is where you can find the different
reports that have been created and view
| | 02:05 | them online. If it's a large report, you
can page through it, you can zoom in or
| | 02:09 | search it and even all to
the parameters of the report.
| | 02:14 | Reporting Services can also be
integrated with SharePoint, which can be used as
| | 02:18 | a location to publish a report to this.
There's even a SharePoint web part so you can
| | 02:22 | embed reports in SharePoint web pages.
| | 02:25 | But really that's the three parts to it.
| | 02:27 | We have to understand how to install and
configure it, we have to then work with
| | 02:32 | creating those reports and using an
application to do that, and then there is the
| | 02:36 | idea of managing and distributing those reports.
| | 02:39 | Reporting Services and all its
surrounding applications is a fairly
| | 02:42 | complex technology.
| | 02:44 | We could create an entire
course on Reporting Services easily.
| | 02:47 | So we're going to cover a brief
introduction of what it can do and the basics
| | 02:50 | of how to use it.
| | Collapse this transcript |
| Connecting to the Report Manager| 00:00 | When I installed SQL Server I had
checked the boxes to install Reporting
| | 00:04 | Services as well. Now it's time
to go and see what that means.
| | 00:08 | You've probably seen that in
Management Studio we have a couple of databases
| | 00:12 | with the word Report on them,
ReportServer and ReportServerTempDB.
| | 00:16 | Those are support databases for this
part of SQL Server called Reporting Services,
| | 00:21 | though we're not going to touch
them manually in SQL Server Management Studio.
| | 00:25 | So I am just going to exit out of
that and if you'd also taken a look at
| | 00:29 | Configuration Manager, the regular SQL
Server Configuration Manager, you'd see
| | 00:33 | that Reporting Services is actually
running in the background as its own
| | 00:38 | application, its own service, and it
really is a very substantial part of this
| | 00:43 | whole enterprise application.
| | 00:46 | But how do we work with it?
| | 00:47 | Well for a start we have
a new tool to work with.
| | 00:50 | I am going to go to my SQL Server 2008
R2 applications into Configuration Tools
| | 00:56 | and pick this time the Reporting
Services Configuration Manager and not the SQL
| | 01:01 | Server Configuration Manager.
| | 01:02 | Like opening up Management Studio,
the first thing asked is what server am I
| | 01:07 | supposed to be talking to, because
you could be connecting to several.
| | 01:10 | I am going to connect to my local
machine and just click OK and this
| | 01:14 | application has quite a few different
options in for working with the backend
| | 01:19 | of Reporting Services.
| | 01:21 | Who is it running as?
| | 01:22 | What's the service account that's happening?
| | 01:24 | What are the databases that we're using?
| | 01:26 | I'm not going to touch any of this
because we're really just trying to get a
| | 01:29 | taste of Reporting Services.
| | 01:32 | The bit that I'm interested in
is this, the Report Manager URL.
| | 01:37 | Report Manager is a part of Reporting
Services that allows you and other people
| | 01:42 | to connect to a web site and view and
edit reports, and right now it's pointing
| | 01:49 | and saying that the URL of this
website is the local machine/reports, because
| | 01:55 | it's installed it already.
| | 01:56 | I am going to click that and depending
on what operating system I have and how I
| | 02:00 | am configured, I may run into a problem.
| | 02:03 | I'm using Windows 7 right now. I have
installed this locally and one of the
| | 02:07 | issues is it's not authenticating
correctly to Reporting Service in the backend.
| | 02:11 | You may get the same issue.
| | 02:13 | You may get a slightly different one.
| | 02:15 | Now I could type my credentials all
day long if I wanted to but it's not
| | 02:19 | going to do me any good.
| | 02:19 | Here is couple of steps that I need
to do to make this work with Internet
| | 02:24 | Explorer in Windows 7.
| | 02:26 | I am going to come down to this area
where it says Internet Protected Mode Off
| | 02:31 | and double-click that.
| | 02:32 | Because what I need to do is
list this address, the address of my own
| | 02:37 | machine, as a trusted site.
| | 02:39 | So I am going to select the checkbox for
Trusted sites and click the Sites button.
| | 02:43 | And it say,s "Do I want to add this website
to this Trusted sites zone?" Yes, I do.
| | 02:48 | Though now it's choking and
saying this must use HTTPS.
| | 02:52 | Well no. For my local
machine I don't need to care.
| | 02:55 | I am going to add that and just for
safety's sake I'm also going to add the word
| | 02:59 | localhost, which can also be
how this machine refers to itself.
| | 03:04 | Click Add and click Close.
| | 03:07 | I'm going to uncheck this box that
says Enable Protected Mode, which will
| | 03:12 | require us to restart
Internet Explorer. That's okay.
| | 03:14 | I am going to do one more
thing for this trusted site.
| | 03:18 | I don't want to keep getting that
prompt to have to type in my username and
| | 03:21 | password all the time, so I can either
grab the slider all the way down to Low
| | 03:26 | or I can click this little button that
says Custom Level and right down at the
| | 03:32 | bottom I'll see the option that I can
logon automatically with the current
| | 03:37 | username and password, so I am doing that too.
| | 03:41 | Yes, I'm sure I want to change those settings.
| | 03:43 | So there are really three
things you have to do here.
| | 03:45 | You want to make sure that Protected
Mode is unchecked, you want to add the
| | 03:49 | address of the site to Trusted sites,
and you want to make sure that in the
| | 03:53 | levels you're logging on automatically.
| | 03:56 | I am going to click OK.
| | 03:57 | I do need to shut down Internet
Explorer but hopefully when I click the link
| | 04:01 | this time, ah, there we go.
| | 04:02 | Now the first time you do this you
probably see that it will take a while.
| | 04:07 | It may take several minutes in fact
because it will do a lot of background
| | 04:11 | compilation and building things, but
eventually you should get to this Report Manager
| | 04:17 | and what we're looking at after
all at first is something fairly boring
| | 04:22 | because there's no reports to look at.
| | 04:24 | There is nothing for Reporting
Services to do, so we'll fix that in just a moment.
| | Collapse this transcript |
| Using Report Builder| 00:01 | The point of this web site is to allow
us to view and interact with reports.
| | 00:05 | But to do that, we need to make some first.
| | 00:08 | There is a couple of ways to do it, but
the one I'm going to pick is this icon
| | 00:12 | here on the bar called Report Builder.
| | 00:14 | You might first think this is a little
web site or web application, but it actually isn't.
| | 00:19 | In fact, the first time you click it,
you may have to click OK once or twice,
| | 00:23 | because it's going to install
an application on your Desktop.
| | 00:27 | This is SQL Server Report Builder,
and we're in the 3.0 version of this
| | 00:31 | application with SQL Server 2008 R2.
| | 00:35 | This is an Office style application
that you'll use to design your reports, to
| | 00:40 | build your reports, and then they'll be
pushed back, saved up to that web site,
| | 00:45 | the Report Manager web site, so that
other people can use them and view them.
| | 00:50 | So when it opens up it does have a
Getting Started panel that offers to step
| | 00:54 | you through several different wizards.
| | 00:56 | But I'm just going to dismiss that
| | 00:58 | and kind of go back to
basics with Report Builder.
| | 01:02 | This application is open.
| | 01:03 | I've got a blank report
waiting to be designed here.
| | 01:06 | Down towards the bottom, I can see
a message that says we're currently
| | 01:10 | connected to the report
server that I was just in.
| | 01:13 | Yes, that looks correct.
| | 01:14 | But what I have to do is two things.
| | 01:17 | I have to define where it is my
data is coming from. My Data Sources.
| | 01:22 | So I've got a Data Sources, a folder over here.
| | 01:25 | I'm going to right-click it and say
Add Data Source, describe a connection to
| | 01:30 | some source of data.
| | 01:32 | Now the more advanced you get with
Reporting Services, you're going to be likely
| | 01:36 | to setup shared connections.
| | 01:39 | Connections you want to use again and again.
| | 01:40 | I don't have any, so I'm going to
have to select the other option to Use a
| | 01:44 | connection embedded in my report.
| | 01:46 | I'm going to give this data source a name.
| | 01:48 | I want to use it to connect to
AdventureWorksLT, so I might as well call it
| | 01:53 | something like dsAdventureWorksLT.
| | 01:56 | I'm just using ds as a
prefix to mean data source.
| | 02:00 | It is a SQL Server connection I want to
talk to, though I do have a whole bunch
| | 02:04 | of other options, including Azure,
Parallel Data Warehouse, ODBC, SharePoint List,
| | 02:10 | Hyperion Essbase and TERADATA, but
we're sitting with good old SQL Server.
| | 02:16 | Then I'm going to click the Build
ellipses button here to help me describe my
| | 02:21 | connection, and it's actually a very simple.
| | 02:23 | It's essentially the same information
| | 02:25 | I have to tell it when I'm connecting to SQL
Server Management Studio. What server is it?
| | 02:30 | Well, it's the local server,
which I'll represent with a dot.
| | 02:33 | I'm going to use Windows Authentication, and as
soon as I type that, I'll have a drop-down list.
| | 02:38 | What database you want to talk to?
| | 02:40 | Well, AdventureWorksLT.
| | 02:42 | I'll click the button to test the connection.
| | 02:44 | Everything succeeded. Click OK.
| | 02:47 | Click OK. So that's step one.
| | 02:50 | My data source is defined, a connection to
AdventureWorksLT that this report can use.
| | 02:55 | But I haven't actually said what data I
want. Because I'm not just going to dump
| | 03:00 | the entirety of the database on to the page.
| | 03:04 | So this is step two, define the dataset.
| | 03:05 | Now you've got your data source.
What do you want to do with it?
| | 03:10 | So I'll right-click and say Add Dataset.
| | 03:13 | Once again, we can give it a name.
| | 03:14 | I'll just leave the default name of DataSet1.
| | 03:16 | And it says, do you want to
use a shared one? No, I don't.
| | 03:19 | I'm going to have to use a dataset
embedded in my report, because there is
| | 03:22 | nothing out there to share.
| | 03:24 | Well, what connection,
what data source are we using?
| | 03:26 | Well, the only one we have.
| | 03:28 | The AdventureWorksLT one that I just made.
| | 03:31 | After that, here is where I described the query.
| | 03:35 | I can write standard SQL SELECT statements here.
| | 03:38 | I could check this box to select a
stored procedure, which would be a great way
| | 03:44 | of working with reports because we can
have a nice efficient stored procedures
| | 03:48 | stored in the database.
| | 03:49 | But unfortunately I don't have
one, so I've got the Text option.
| | 03:53 | However, I'd like to think
that I'm pretty lazy about this.
| | 03:56 | So rather than type it, I'm going to
click this button to say Query Designer.
| | 04:01 | This gives me a great builder of
content that I can start to expand the
| | 04:06 | different parts of my database.
| | 04:07 | I've already described my
connection, so it knows the options for me.
| | 04:11 | I could then start drilling down into
Tables and saying yes, I'd like to
| | 04:15 | have information about the customer.
| | 04:17 | I'd like to know their FirstName,
their LastName, and their CompanyName,
| | 04:22 | and their EmailAddress.
| | 04:24 | I can start to select
information from other tables.
| | 04:27 | Perhaps I want to know my
customers information and what city and
| | 04:31 | what country they're in.
| | 04:33 | Well, if I do that, as we know,
we've got to describe some kind of
| | 04:38 | relationship between the two.
| | 04:41 | Now, while I'm doing this process,
I do have a Run Query button up at the top
| | 04:46 | that I can run and click this.
| | 04:48 | It's telling me well, the problem is the
following tables aren't related to each other.
| | 04:53 | I don't know what to do.
| | 04:53 | I don't know how to connect them.
| | 04:54 | Well, it actually does a
pretty good job of connecting them.
| | 04:58 | You just have to make sure you're
selecting options from tables that are
| | 05:01 | connected to each other.
| | 05:02 | Now, right now, Address and Customer
actually aren't connected to each other.
| | 05:08 | They have a join table in
between, which is CustomerAddress.
| | 05:11 | So all I'm going to come down-- is come
in to CustomerAddress and select one from
| | 05:17 | one table and one from the other.
| | 05:19 | The great thing is while this Auto
Detect has the blue box, meaning it's selected,
| | 05:25 | the next time I hit Run Query, it's
going to detect those relationships.
| | 05:29 | Yes, indeed, it's going to bring me
back both the information from the Customer
| | 05:33 | table and the information from the
Address table where the two are joined
| | 05:37 | together, which is great.
| | 05:39 | We can go on a little further than that.
| | 05:41 | Maybe what I want is customer
information from the Customer table, address
| | 05:45 | information from the Address table,
and some order information from say the
| | 05:49 | SalesOrderHeader table.
| | 05:51 | Well, from there, the things I'm interested in
are the CustomerID and let's say the TotalDue.
| | 05:59 | Do another quick Run Query.
| | 06:00 | I like to do these step-by-step, where it seems
to be actually connecting all of these together.
| | 06:06 | One of the great things is if we're not
sure about the SQL that's being generated,
| | 06:10 | up here we have this Edit as Text button.
| | 06:12 | I can jump into that and it actually
shows me the SQL that is trying to build,
| | 06:17 | which in this case has the JOIN statements.
| | 06:19 | In fact, that looks pretty good.
| | 06:21 | I don't want to mess with it.
| | 06:22 | I'll just click the Edit as Text button
again to take me back into the Designer view.
| | 06:27 | There are ways I can start to actually
add aggregate functions over here too.
| | 06:33 | I could decide to use my COUNTs,
my MAX, my MIN, my SUM, all of that.
| | 06:38 | I don't need to use any right now.
| | 06:40 | This is actually just fine for me.
| | 06:42 | Below this, we have applied filters
that we could start to type in things like
| | 06:46 | the FirstName, like a particular Value.
| | 06:48 | We see a little later how we
can actually parameterize this.
| | 06:52 | I'm just going to leave it as is.
| | 06:54 | Although, just to show one last thing,
I'll show how you could jump into say the
| | 06:58 | Edit as Text part and just if I wanted
to, use there SQL as a starting point
| | 07:04 | and then just finish it off with
mine. ORDER BY TotalDue DESC. Click OK.
| | 07:13 | This is all I need to define this
dataset, although I could step through
| | 07:17 | renaming options for the fields,
change things like collation, add my own
| | 07:24 | filters, add my own parameters.
| | 07:25 | I'm not going to do that right now. I'm
just going to click OK. Well, then what?
| | 07:29 | We have this information that could just
be dragged and dropped on to our report.
| | 07:35 | Now right now, that wouldn't be a very
useful report if all I had was a State or
| | 07:39 | a FirstName in the middle of it.
| | 07:40 | There are a couple of helpers if I know that
I'm going to have multiple rows of information.
| | 07:45 | I click up here on my Insert tab.
| | 07:48 | I have what are called data regions.
| | 07:50 | The simplest is a List, and you
just drop your fields anywhere in that
| | 07:54 | and it'll repeat them.
| | 07:55 | But we also have the Table here.
| | 07:58 | Go to Table Wizard, which is
quite useful. Click that guy.
| | 08:01 | It's going to say, is there
a dataset already defined?
| | 08:03 | Well, yes, there is, this one.
| | 08:05 | So I'll select that new dataset and click Next.
| | 08:08 | The next setup is asking to arrange
the fields, because of course the data I
| | 08:13 | brought back could be being used for
any ID. I could be wanting to total things
| | 08:18 | up or group them together.
| | 08:20 | The main part that we're
interested in here is the values.
| | 08:25 | I can drag these things across,
FirstName, LastName, CompanyName, EmailAddress,
| | 08:31 | City, State, and all I need is TotalDue.
| | 08:38 | You'll see that there is a little drop-
down here where you still can add on your
| | 08:42 | choice of aggregate functions.
| | 08:43 | I'm just wanting a fairly
flat list, so that's okay.
| | 08:47 | If I was expecting multiple customers
from the same company, I could drag over
| | 08:51 | CompanyName into Row groups.
| | 08:54 | To start breaking that apart into
groups of rows. I don't have to here.
| | 08:58 | I am just wanting something fairly
flat so I'm going to click Next.
| | 09:02 | It gives me a preview of what it's
going to show, organizes the table.
| | 09:07 | If I was grouping multiple things with
aggregate functions, I'd have an option
| | 09:10 | to show some totals and
grand totals, but I'm not.
| | 09:13 | It's just a flat list drawn
from multiple tables here.
| | 09:16 | I've got a choice of
various styles that we could use.
| | 09:22 | Let's pick Slate and click Finish.
| | 09:26 | This is our report now.
| | 09:27 | I have button over here that I can
click Run to take a little preview of it.
| | 09:32 | It actually seems to be working okay.
| | 09:33 | We're actually drawing the information.
| | 09:35 | It's in descending order of TotalDue.
| | 09:38 | I'm going to click the button up here to say
Design, switching back into the Design mode.
| | 09:43 | Maybe I think that my fonts are
actually showing up a little bit large right now,
| | 09:47 | and I want to affect
the fonts on the top column.
| | 09:50 | I'm going to do a select anywhere in
here, and then you'll notice that I have a
| | 09:53 | little great handle over here on the left.
| | 09:56 | I can select that and then as long as
I've got the Properties Inspector open,
| | 10:00 | and if I haven't, I can get that
from the View part of the Ribbon here.
| | 10:05 | I can select that first row.
| | 10:08 | Come down to Font and I think I'm going
to change that to a FontSize of 8 points.
| | 10:15 | It looks good.
| | 10:16 | I'll also do 8 points on the second row too.
| | 10:19 | I can actually do a lot of formatting.
| | 10:21 | In fact, most of what you end up doing
with Report Designer is going to be in
| | 10:26 | the formatting and arranging of this.
| | 10:28 | I still don't have a title for my report.
| | 10:30 | So I'm going to click to add some
title here. Customer Amounts perhaps.
| | 10:38 | Then go up to the Ribbon and hit Save.
| | 10:40 | Now what it's going to ask is, where to?
| | 10:44 | And here is the default.
| | 10:45 | Save up to the website, up
to the Report Manager website.
| | 10:49 | Well I am about to give this a name. I'm going
to call this Customer Totals and click Save.
| | 10:57 | Well, the question is so what?
| | 11:00 | Now I can come back and
design this a little later.
| | 11:02 | But what I'm going to do is
just close down Report Builder.
| | 11:05 | Go back to the Report Manager.
| | 11:07 | I need to refresh this page, because it
doesn't know that I've uploaded it yet.
| | 11:11 | But when I do, I actually finally
have something on the page to look at.
| | 11:14 | Now there is a bunch of options in the
drop-down such as Delete, Subscribe,
| | 11:19 | View Report History, Manage,
Security, Edit in Report Builder.
| | 11:24 | But I could just click the
hyperlink itself. Customer Totals.
| | 11:28 | Click that and notice that
within the web site, it opens it up.
| | 11:31 | It retrieves that information.
| | 11:33 | It gives us options up here to print it,
to even select from this, to allow us
| | 11:38 | to export it in CSVs and PDFs and Word files.
| | 11:42 | We've got the ability to zoom in a
little bit, and just start it do some basic
| | 11:48 | interaction with that report.
| | 11:50 | So while we can take our
reports a lot deeper than that,
| | 11:53 | we can add parameters to them,
| | 11:55 | we can add more formatting,
| | 11:56 | this is the general process for
creating and saving a new report using Report Builder 3.0.
| | Collapse this transcript |
| Formatting values in reports| 00:01 | I'm a big fan of an incremental
approach to writing reports in Report Builder.
| | 00:05 | Start slowly, get something
working, and then add things to it.
| | 00:09 | So right now we do have this report
working and it's drawing information from
| | 00:13 | three different tables, but there
is a little bit I could do to this.
| | 00:16 | Total Due is basically being
output right now just as a money column.
| | 00:21 | There is no currency formatting and it
could do with some. I don't really need
| | 00:25 | FirstName and LastName to be
separated into two columns here.
| | 00:30 | So I'm going to go back to the
homepage of Reporting Services and then select
| | 00:34 | the drop-down button to
edit this in Report Builder.
| | 00:38 | Changing the formatting of a report and
changing the entire layout is very easy,
| | 00:43 | even after you've saved it for the first time.
| | 00:45 | So again, back to this report,
selecting any of these cells here will highlight
| | 00:50 | the field that we're using and allow
us to tweak it, allow us to change the
| | 00:55 | font, allow us to change the background color.
| | 00:57 | However, some of the options
can be a little bit deceptive.
| | 01:00 | If you're used to working with things
like Visual Studio or other programs like that,
| | 01:03 | you're quite used to
looking at the Properties panel here.
| | 01:07 | But in fact that's not what I want.
| | 01:09 | I've got highlighted the Sum(TotalDue)
here and there's nothing down here that
| | 01:13 | immediately shows me how to show it up in a
different format like currency. But that exists.
| | 01:19 | It's up here on the ribbon.
| | 01:21 | You'll notice that every time I
highlight somewhere there is a dropdown here.
| | 01:26 | That's set to Default
normally but you can change it.
| | 01:29 | So I can just select that cell
and say I want this to be Currency.
| | 01:34 | Just to prove that it works
we'll click the Run button.
| | 01:36 | We don't have to save it backup to
the server yet; we just need to test it.
| | 01:40 | And that looks correct.
| | 01:42 | Okay, what else can we do?
| | 01:43 | Well clicking back on the Design
what I'd like to do is kind of combine
| | 01:47 | these two cells into one.
| | 01:50 | Now there is a couple of things I can do here.
| | 01:54 | I can drag across and sometimes it's
little tricky to drag and get both of them
| | 01:58 | and then I can click right-
click and get Merge Cells.
| | 02:01 | The problem is that's kind of
collapsing them into the first one.
| | 02:04 | So now that all I've got here is
first name and it wasn't quite what I was
| | 02:09 | after but we take it step by step.
| | 02:11 | Here's how the cells knows its value.
| | 02:13 | If you go over to the Property section
there is a Value area, which says "Well
| | 02:19 | right now I'm drawing my information
from Fields!FirstName.Value," but if I click
| | 02:25 | the drop-down there is
little Expression Builder.
| | 02:28 | This is fairly simple stuff, but what
it allows you to do is click through
| | 02:33 | some of the built-in fields that it
knows about, Page Number, Page Name,
| | 02:37 | Language, Parameters.
| | 02:39 | You got to section which is all the
fields that we declared in DataSet 1 which
| | 02:44 | include First Name, Last
Name, Email Address and so on.
| | 02:47 | We do have some common functions for
Financial and Inspection and Math and a few
| | 02:53 | basic operators for
Comparison and Concatenation.
| | 02:56 | That's what I want to do is Concatenation.
| | 02:58 | I want to join
FirstName and LastName together.
| | 03:01 | I could have done that in the SQL
statement but it's a little too late now, so
| | 03:05 | let's just do it here.
| | 03:07 | So I can actually use either
the ampersand or the plus sign.
| | 03:10 | I do want to separate them by a space
but we're not in SQL anymore, so what I
| | 03:15 | need to do is use the " " & and then I
can just use the field in Data Set 1.
| | 03:24 | I could either manually type it or
double-click LastName and now it's
| | 03:29 | concatenating both of these together.
| | 03:32 | Click OK and that should
evaluate to the full name.
| | 03:35 | That means that up here on the
header I should see if I can join these
| | 03:40 | two together as well.
| | 03:41 | Again, sometimes a little
difficult to grab hold of them but if you
| | 03:44 | persist you'll get there.
| | 03:45 | Once both of them are selected I'll
right-click and say Merge Cells and we'll
| | 03:49 | just change that to say Name.
| | 03:53 | Run and we're starting to look a little better.
| | 03:57 | We're starting to experiment with
the formatting and make this a bit more
| | 04:01 | presentable, and when I'm done with my
formatting changes, I'll simply hit the
| | 04:06 | Save button to save it
back up to the Report Server.
| | 04:12 | We run it again from there and we
can see the changes that we made.
| | Collapse this transcript |
| Adding indicators to reports| 00:00 | Next up, I'm going to change my
report to add a little bit more interesting
| | 00:04 | graphical information.
| | 00:05 | I am going to click the drop-down
and select Edit in Report Builder.
| | 00:11 | And what I'd like to do is have the
report show up with some kind of visible
| | 00:17 | graphical information about whether
the number that we are showing is good,
| | 00:21 | bad, or indifferent.
| | 00:22 | Are these people either a good customer,
a great customer, or a poor customer?
| | 00:27 | There is a few ways I could do that.
| | 00:29 | I might decide that I want
to show the name up in bold.
| | 00:32 | I might decide I want to show the
TotalDue in red or green or orange but here's
| | 00:38 | what I'm going to do.
| | 00:39 | I am going to add a new column to this report.
| | 00:42 | I am going to select in that cell
and occasionally you'd be a little bit
| | 00:46 | careful about selecting it.
| | 00:48 | Sometimes you have to experiment a little bit.
| | 00:50 | I've got the cell selected and I am going
to right-click and I'm going to insert a
| | 00:56 | column to the right, which gives me
this, a new cell to do something with. But what?
| | 01:02 | Here is what. Up on the Insert tab of
the ribbon, there are several graphical
| | 01:08 | elements that we can add to this report.
| | 01:11 | The one I'm going to pick is one of
the simplest ones, but it's a great one
| | 01:14 | to get started with.
| | 01:15 | It's the Indicator.
| | 01:17 | When I select that, it doesn't actually
add anything to the report but it will
| | 01:21 | change my cursor to this little red graphic.
| | 01:25 | And what I'm then going to do is
just click in the cell that I want
| | 01:29 | this indicator to be in.
| | 01:30 | Click once and it's going to say,
okay what kind of indicator do you want?
| | 01:36 | And it offers me various choices.
| | 01:37 | We have got Ratings.
| | 01:39 | We have got a series of
symbols for red, amber and green.
| | 01:44 | I am going to select
this one here and click OK.
| | 01:49 | The question is what is this an indicator for?
| | 01:53 | Well, that's up to you.
| | 01:54 | You get to say what data this is hooked up to.
| | 01:58 | It might be something like
the total amount of an invoice.
| | 02:02 | It might be an outstanding
amount of bucks, anything that can be
| | 02:06 | numerically evaluated.
| | 02:09 | Right now, it doesn't know
what it's supposed to represent.
| | 02:11 | So, if I were to run this,
I'm going to see nothing.
| | 02:15 | But going back to Design, what I
will do is I will select that indicator.
| | 02:19 | Again, sometimes, it's a little
difficult to grab hold off, but when I have got
| | 02:23 | it selected, it will pop-up a little panel.
| | 02:26 | I am going to drag to the right
| | 02:27 | so I can see that. It says
okay how do I show information?
| | 02:32 | It needs to be faded with a value.
| | 02:35 | And this lowest drop-down box
says, where do I get it from?
| | 02:38 | Well, it's not from
FirstName, LastName or CompanyName.
| | 02:41 | It's going to be getting
its value from TotalDue.
| | 02:44 | It's not going to be showing the number.
| | 02:45 | It's going to be to be showing
a graphic that represents that.
| | 02:48 | I am not going to run it again.
| | 02:51 | And very interestingly what we
are getting is indicators here.
| | 02:55 | We are getting the green checkmarks here,
we are getting the yellow exclamation marks,
| | 03:01 | and we're getting the red
crosses, which don't look good at all.
| | 03:05 | So what's actually happening?
| | 03:06 | Well, by default, what it's doing is
evaluating what it shows based on the
| | 03:12 | TotalDue and it does it on a range.
| | 03:15 | The lowest third numerically will show
up in red, the middle third will show up
| | 03:21 | in yellow, the top third will show up in green.
| | 03:23 | That might be what we want. That might not.
| | 03:26 | We can change that.
| | 03:27 | Selecting back to this indicator,
I can click the little Properties panel and
| | 03:32 | what it says is first give
it a Name. Is there a ToolTip?
| | 03:35 | But in Value and States, it's saying
here's where I get my value from, and I am
| | 03:40 | measuring it in a
percentage of the range available.
| | 03:43 | Now I want to say no.
Maybe I don't want that.
| | 03:46 | Maybe I just want to have a flat range,
that if it's above 50,000, it's really good.
| | 03:50 | If it's below 20,000, it's bad but anywhere in
the middle, it'll show up in the yellow icon.
| | 03:57 | So I am going to switch that to Numeric.
| | 03:59 | I am going to say red is from 0 through 10,000.
| | 04:06 | Yellow is from 10,001 to 50,000 and green
should show up from 50,001 to a million.
| | 04:19 | Click OK.
| | 04:20 | Now we will run this again and
I have got my own defined rules going on.
| | 04:25 | It's actually fairly similar but I
know now that this range, for example, is
| | 04:30 | being controlled by me.
| | 04:32 | Below 50, we get the yellow exclamation mark.
| | 04:34 | Above 50, we are getting the green checkmark.
| | 04:37 | In other places you might hear these
referred to as Status Indicators or
| | 04:41 | even KPIs, Key Performance Indicators, in
places like PerformancePoint and SharePoint.
| | 04:46 | Now of course, in our example, we're
ordering by TotalDue descending anyway.
| | 04:51 | So it's quite visible information, but
if you're mixing a lot of these up and
| | 04:56 | you have got massive amount of data,
just these checkmarks and these status
| | 04:59 | indicators can make it very easy to scan a
report and see where something is going wrong.
| | 05:04 | So when I am finished, I simply
save that back up to the server and
| | 05:09 | close Report Builder.
| | Collapse this transcript |
| Adding charts to reports| 00:00 | If you want to get even more graphical,
we can add a chart to our reports.
| | 00:05 | Now I'm going to add a chart. This can
either come before our table here or afterwards.
| | 00:10 | I'm going to put it afterwards.
| | 00:11 | I'll click Insert and then if you
notice, we have a Chart option here.
| | 00:16 | We can directly insert it and then
format it, or the Chart Wizard will help us
| | 00:20 | through some of that.
| | 00:22 | So the question is, is the data that
we want on the chart already in the data set,
| | 00:26 | and let's say for our purposes it will be.
| | 00:29 | What I'm going to do is show a bar
chart of the sales that we've made based on
| | 00:35 | the Region or the
Province that we've done it in.
| | 00:37 | I'm going to click Next, and it will
ask is it a Column, is it a Line, is it a Pie,
| | 00:42 | and this of course is going to be
a choice that you'll make more based on
| | 00:46 | what the data actually is and how many
data points you're expecting to have.
| | 00:51 | The best thing is just experiment with these.
| | 00:53 | Try several different ones.
| | 00:55 | I'm going to pick a Column
to begin with, and click Next.
| | 00:58 | What it's telling me is there are
my available fields and I can give it
| | 01:03 | Categories and Values and a
Series that read up at the top.
| | 01:06 | What it's telling you is a field in the
Categories list is displayed on the x-axis.
| | 01:11 | A field in the Values list shows
aggregated data on the y-axis and it'll take
| | 01:16 | care of aggregating or grouping it together.
| | 01:19 | I'm not going to bother creating a new
series in the chart, what I want is for
| | 01:23 | the StateProvince to be in the
Categories section across the x-axis and then
| | 01:30 | I'm going to have the
TotalDue aggregated in the y-axis.
| | 01:35 | I'll click Next, then it gives me the same
choice I got for the table, what style
| | 01:40 | would you like. I think we chose Slate
for the last one, so I'll choose it for
| | 01:44 | this one and click Finish.
| | 01:46 | And the Chart is inserted, although
it's kind of overlapping my table, and it
| | 01:50 | looks as if I was going to drag it
below that I'd kind of drag it off the
| | 01:54 | bottom of the screen.
| | 01:55 | But I don't have to worry about that.
| | 01:57 | If I just keep dragging it down,
what you'll find is the page itself will
| | 02:02 | expand, even expanding the footer here.
| | 02:05 | So what I really need to do is just
drag it to underneath my table, because the
| | 02:12 | table itself will expand.
| | 02:13 | Now I'll drag it wide to fit the
width of the page and that should do.
| | 02:18 | I can come in and give it a Chart
Title. Let's call it Sales By Region.
| | 02:24 | Now we've got the Axis Titles that we
could do here, which is let's say Dollars
| | 02:32 | Amount and the region across the bottom.
| | 02:36 | And let's try this. Click Run.
| | 02:39 | We get our normal part
of the report coming back.
| | 02:42 | These are what have listed
by the States and Provinces.
| | 02:45 | We are across multiple countries, so
it can end up being a little weird.
| | 02:48 | So we are obviously getting places
like England as the country and then
| | 02:52 | California is the state, but that's
all based on how your database is setup.
| | 02:56 | If I come down, what I can actually see
is here's the chart and it appears that
| | 03:01 | we've got California with the certain amount.
| | 03:03 | Notice that if I move my mouse over the
top of it, I'll actually get that amount
| | 03:08 | and same with England.
| | 03:09 | In this case, it's aggregating the
TotalDue up and then showing lesser amounts
| | 03:13 | as well for Colorado, Nevada,
and New Mexico and Utah.
| | 03:17 | So, very easy process of adding a chart.
| | 03:20 | If you select the chart in your Design
view, you will find that it itself has a
| | 03:25 | lot of properties that you
can start to mess around with.
| | 03:29 | Any of the individual bars can be affected.
| | 03:32 | When you select these you'll also find
again the little pop-up menu here that
| | 03:36 | would allow you to jump back in and change
more of the properties of the chart itself.
| | 03:42 | Again, your choice of what kind of job
that you're going to insert is really
| | 03:47 | going to be much more based on the
available data that you have, but the process
| | 03:51 | for adding them is the same as this.
| | Collapse this transcript |
| Working with report security| 00:00 | When you get your reports to a point
where you don't mind to sharing it with
| | 00:04 | someone else, well you're going to
have to share it with someone else.
| | 00:07 | And most of this is done through the
SQL Server Reporting Services Report
| | 00:12 | Manager web site, and if I selected the
report that I've created and click the
| | 00:16 | drop-down box I have a whole
bunch of different options here.
| | 00:20 | We've seen Edit in Report Builder, but
I can also click Security or go to the
| | 00:24 | more generic Manage.
| | 00:26 | Manage would allow me to change things like
the Name and the Description if I wanted to.
| | 00:30 | There is a whole series of other options,
most of which I can see because I am
| | 00:34 | an administrator, things like the data
sources, and you can also look at setting
| | 00:39 | up subscriptions to report so
that automatically push to people.
| | 00:44 | But what I'm interested here is
security. But something to bear in mind about
| | 00:50 | Reporting Services security is
it's kind of like SQL security.
| | 00:54 | There are wheels within wheels.
| | 00:56 | And this report is contained inside
the homepage of Reporting Services.
| | 01:02 | Well, that's a good thing because
what it actually means is I can setup the
| | 01:06 | permissions for people at this homepage
level and then any new report added to
| | 01:11 | this page will be available to
them. Or I can set up separately.
| | 01:15 | But you'll notice if I go directly into
Security and say that I want to edit the
| | 01:20 | security of just this report, it's
going to say "Well your security for this is
| | 01:25 | inherited from a parent item.
| | 01:27 | Did you want to apply different security
settings from that of home, of the homepage?"
| | 01:31 | No, I didn't.
| | 01:32 | Actually what I'm going to do is Cancel
and just go back to Home here, because
| | 01:36 | what I'm going to do is
manage security at the top level.
| | 01:40 | I'm going to click this Folder Settings area.
| | 01:43 | Now of course if you're creating
multiple reports from multiple people what you
| | 01:47 | are going to end up doing is creating
multiple folders and adding security
| | 01:50 | differently on those.
| | 01:51 | So I'll hit that and what it's
actually saying is "Well, right now the only
| | 01:57 | people who can access this page and
therefore any report on this page are people
| | 02:03 | in the BUILTIN\Administrators group
who have the role of Content Manager."
| | 02:09 | Reporting Services likes roles like
any other part of the SQL Server.
| | 02:12 | So what I'm going to do is create a new
role assignment and you'll notice there
| | 02:18 | aren't actually all that many roles here.
| | 02:20 | At the low end we have
someone in the role of Browser.
| | 02:23 | They may view folders,
reports and subscribe to reports.
| | 02:26 | At the high end we got Content Manager
who can take control of everything in the
| | 02:31 | Report Server and then there's a few
someone in-between like a Publisher who may
| | 02:35 | publish reports and link reports to the
Report Server, but they can't actually
| | 02:39 | control the Report Server.
| | 02:41 | Here's what I'm going to do.
| | 02:42 | It says "Give me the group or username."
| | 02:44 | I could give it the name of an individual user.
| | 02:51 | I know that LucianE exists and I'm
going to make LucianE a Browser. Click OK.
| | 02:56 | That's then added, or I could click
New Role Assignment and add say the
| | 03:01 | Windows group of Sales, which has
multiple people in it, and make everybody
| | 03:05 | in Sales a Browser.
| | 03:07 | Simply that would mean now that going
back to the homepage and going in to look
| | 03:12 | at the security just of that report,
you'd find that people in the Sales group
| | 03:17 | and the person Lucian also now have
the ability to read and view this report.
| | 03:22 | Again, if you do need to setup multiple
containers for reports, an easy way to
| | 03:29 | do it is just actually to work with new folders.
| | 03:32 | So I could create say the
Sales folder for Sales Reports.
| | 03:36 | Click OK and then I could
create security just on that.
| | 03:41 | You probably don't want to get too
much more complex than one or possibly two
| | 03:44 | levels deep. After all the whole
idea is that you're going to make this
| | 03:48 | available to other people in your organization.
| | 03:50 | You want your Report
Server to be easy to navigate.
| | Collapse this transcript |
|
|
14. Integration ServicesIntroduction to SQL Server Integration Services (SSIS)| 00:00 | It'd be we nice to think that our data
magically appears in our database, is
| | 00:05 | updated there, is manipulated and
reported on there, and never needs to go
| | 00:09 | anywhere else or come from anywhere
else. But that's not the case and that is
| | 00:14 | where SQL Server Integration Services comes in.
| | 00:18 | This is the part of SQL Server 2008
that deals with getting data into our
| | 00:22 | databases or extracting it
and moving it somewhere else.
| | 00:26 | This can range from the very simple,
where Integration Services will take care
| | 00:30 | of importing a one-off collection from an
old access database, to very complex indeed.
| | 00:37 | Importing data from multiple sources
including other databases, having flat files
| | 00:43 | and XML documents, and being able to
clean this information all up, in some cases
| | 00:48 | of standardizing it, in other cases
transforming it and performing computations
| | 00:53 | on it, and then merging all this and
storing the results in the database.
| | 00:58 | And then perhaps most importantly,
being able to take all these operations and
| | 01:02 | package them all up so they can be
repeated on demand. And in fact doing this is
| | 01:08 | called a SQL Server
Integration Services or SSIS Package.
| | 01:13 | Now the simpler kinds of operations in
SQL Server Integration Services can be
| | 01:18 | done just by using the SQL Server
Import and Export Wizard that you'll find in
| | 01:23 | SQL Server Management Studio, but more
complex packages can be created using
| | 01:28 | the Business Intelligence Development
Studio or Visual Studio and creating
| | 01:32 | what's called an Integration
Services project where you can describe your
| | 01:36 | different data sources, how you connect
to them, and what you do with that data
| | 01:41 | when you've gotten it.
| | 01:42 | Unlike many other parts of SQL Server
you can probably tell that this in itself
| | 01:46 | can get to be a very substantial area
that you could spend a lot of time in, but
| | 01:50 | we can certainly get started by exploring some of the
more common tasks with SQL Server Integration Services.
| | Collapse this transcript |
| Using Business Intelligence Development Studio (BIDS)| 00:00 | To work with SQL Server Integration
Services we're going to open a new program.
| | 00:05 | Well, for some of you it might not be that new.
| | 00:08 | I'm opening up my SQL
Server 2008 R2 applications.
| | 00:11 | I'm looking for SQL Server
Business Intelligence Development Studio,
| | 00:16 | sometimes known as BIDS.
| | 00:17 | But when I open this up, it's really not
a completely new application. As I can
| | 00:23 | see here it's actually Visual Studio.
| | 00:25 | In fact Business Intelligence Development
Studio is just a cut-down version of Visual Studio.
| | 00:30 | If you have the full version of
Visual Studio, every time you go to
| | 00:34 | File > New > Project you might have dozens
of choices to choose from, but here we
| | 00:39 | only have a handful.
| | 00:41 | We have a couple of Analysis
Services Projects, we have a couple of
| | 00:45 | specialized Reporting Services Projects
and then the Integration Services one,
| | 00:50 | and that's what I need to do.
| | 00:52 | So I've gone into my File > New > Project
and I'm going to create a sample here.
| | 00:56 | I'll call it SSISTest and
just accept the default location.
| | 01:00 | So this is creating a full Visual
Studio project with a lot of subfolders and
| | 01:06 | support files and this is what we get.
| | 01:10 | And that can look little bit intimidating
particularly if you're new to Visual Studio.
| | 01:14 | And even if you're not this is certainly
not a classic ASP.NET environment,. It's
| | 01:19 | something very different, very visual.
Inside this package and that's what we're
| | 01:23 | working on a Package.dtsx file,
| | 01:26 | we've got four tabs here, Control Flow,
Data Flow, Event Handlers, Package
| | 01:30 | Explorer. Well what are we actually doing here?
| | 01:33 | Well this is all about taking in some
data, performing some transformations on it,
| | 01:39 | moving it somewhere else,
copying it, merging it, exporting it.
| | 01:43 | And to do that we have a
fairly significant toolbox.
| | 01:46 | I'm going to pin my toolbox here just
to show you this, but what you'll find is
| | 01:51 | if you have the Control Flow tab
highlighted we have all sorts of control flow items,
| | 01:57 | dozens of them, things like
Send an Email Task, do something with FTP Task,
| | 02:04 | do something on the File System,
Execute some SQL, Execute a Process.
| | 02:09 | Down below that we have what are called
Maintenance Plan Tasks, things like Check
| | 02:13 | the Integrity of the
Database, always a good idea
| | 02:16 | if you're moving a lot of
content from one place to another.
| | 02:19 | History Cleanup, Notify Operator Task ,
sending an e-mail message to a SQL Server
| | 02:25 | Agent Operator, Rebuild an Index,
Reorganize an Index, lots of stuff that you
| | 02:29 | can build and plan for doing some
substantial work with moving data around.
| | 02:35 | And the idea is that what you do is
you start to drag on the things that you
| | 02:40 | want to do onto the Designer.
| | 02:42 | So if you wanted to start off with a Check
Database Integrity Task we drag that on there.
| | 02:48 | It adds it visually.
| | 02:49 | Now of course, it doesn't know which
database we're actually talking about here.
| | 02:53 | So to configure this I could either
select it and start to play around with
| | 02:57 | the Properties, or I can just double-
click it and it's going to kind of step
| | 03:01 | me through the idea that it doesn't know what
database to check so it's asking for a connection.
| | 03:06 | What connection do I use?
| | 03:08 | If I do where to find one they will be
one in the drop-down, but we didn't.
| | 03:11 | So I'll describe a connection
to AdventureWorksLight (AWLT).
| | 03:16 | It's going to be the dot,
which is fine, and yes it's Windows
| | 03:19 | Integrated Security.
| | 03:21 | When I do that it says, well select a
database please. I can say all databases.
| | 03:26 | Do I want to check the integrity of
everything, just system databases, user
| | 03:29 | databases, or these following databases?
| | 03:32 | It allows me to select through them.
I'm going to say set this one. Click OK.
| | 03:37 | I could even view the T-SQL.
| | 03:38 | Now surprisingly, what this is
generating is a DBCC CHECKDB.
| | 03:47 | So if that completes successfully,
we could go onto the next task. Maybe at
| | 03:52 | this point what I want to do is grab
something from the file system, or send an email.
| | 03:58 | Perhaps notifying people that we're
about to start a big SQL Server Integration
| | 04:03 | Services package, but really the big
task, the big important one doesn't look
| | 04:09 | like it's that important, but
it's this one, the Data Flow Task.
| | 04:13 | The idea is that all of your
packages at some point do data flow.
| | 04:17 | They take data from one
place and move it somewhere else.
| | 04:21 | And in fact you could have a SSIS
package that is just one Data Flow task, so I
| | 04:28 | have deleted that first one
that checks the database integrity.
| | 04:32 | And here is what happens when you
drag this on and you double-click it,
| | 04:36 | it's going to jump you to the second tab.
| | 04:39 | We're basically jumping inside of that
Data Flow task where we get to describe
| | 04:44 | exactly what's happening just
in that little piece of the flow.
| | 04:48 | And if you notice what
happens is your toolbox changes.
| | 04:51 | We switch from things like FTP tasks
and Email tasks to Data Flow sources of
| | 04:57 | Excel, and flat files, and raw files,
and Data Flow tasks. We can do things like
| | 05:04 | character mapping to change things to
lowercase or uppercase, data conversion,
| | 05:09 | moving things from integers to
floating points and back again.
| | 05:13 | We can lookup some other piece of data.
| | 05:15 | We can do a row count.
| | 05:17 | If you have the Enterprise level
editions of SQL Server we can even do things
| | 05:22 | like Fuzzy Lookup and Fuzzy Grouping to
have very flexible questions that we're
| | 05:27 | asking about our data.
| | 05:29 | And then we end up with Data Flow Destinations.
| | 05:32 | That's the whole point. If something is
flowing it's flowing from somewhere to somewhere.
| | 05:37 | So what's the destination?
| | 05:38 | Now are we moving from a flat file
into SQL Server, are we moving from SQL
| | 05:43 | Server into an OLE DB database?
What are we doing with it?
| | 05:47 | And the benefit of defining all these
is that at every step of the way whether
| | 05:52 | choosing to for example start off with
the flat file, then do some character
| | 05:58 | mapping of it, sorting that
information, and then outputting it into for
| | 06:07 | example SQL Server,
| | 06:10 | we can configure each step of the way.
| | 06:12 | We have the two arrows, the green one
representing what happens if the output of
| | 06:16 | that was successful and the red one
representing what happens if it wasn't.
| | 06:20 | So in this case we can just
click on the steps and define them by
| | 06:25 | double-clicking each part and setting up,
or what is that input flat file, how
| | 06:29 | would SQL Server Integration Services
find it, how does it know where to look?
| | 06:34 | What kind of mapping would we do on it?
| | 06:35 | What would we convert to uppercase?
| | 06:37 | What would we convert to lowercase?
| | 06:38 | What are we sorting on?
| | 06:40 | And then where does it go?
| | 06:42 | As you can imagine, SQL Server
Integration Services packages can get very complex
| | 06:47 | indeed, the great thing about doing
them in this environment is you even get a
| | 06:51 | built-in debugger that allows you to
take them visually step-by-step through
| | 06:55 | each part and we'll see a
simple example of that next.
| | Collapse this transcript |
| Creating and executing a simple SSIS package| 00:00 | I am going to illustrate how to create a
basic package by doing something very simple.
| | 00:05 | And I'll make a new project here in the
Business Intelligence Development Studio.
| | 00:10 | So create a new project.
| | 00:11 | It's going to be Integration
Services and I am going to call it
| | 00:15 | the FlatFileTransform.
| | 00:17 | Because we don't actually need to
move our data in or out of SQL Server.
| | 00:23 | That's an easy mistake to make.
| | 00:25 | Yes, Integration Services runs as part
of SQL Server but it's quite happy to
| | 00:29 | move information from an Access
database into an Oracle database or from a flat
| | 00:35 | file into Access or from SQL out into Teradata.
| | 00:39 | Whatever you can connect to, it will work with.
| | 00:42 | So I am going to begin with
about as simple as you can get.
| | 00:45 | One Data Flow Task.
| | 00:48 | Our entire package is going
to consist of this one step.
| | 00:51 | Now inside it, we will have several steps,
| | 00:54 | what are we going from, what
are we going to, but this will do.
| | 00:58 | So I double click it and I
jump into the one Data Flow Task.
| | 01:02 | What I am going to set up is a Flat File Source.
| | 01:05 | I am going to then affect some of the
text files inside it by doing a Character Map
| | 01:14 | and if I mouse over character
mapping, see that it says it applies string
| | 01:18 | operations to character
data so that's the one I want.
| | 01:21 | I am going to sort and then I am going
to have the output be another flat file,
| | 01:28 | a Flat File Destination.
| | 01:30 | So let me go through and
configure this step-by-step.
| | 01:33 | Again, we are doing this to
get the idea of the process.
| | 01:35 | I define the source. I will double-
click this first part. Bring this dialog box
| | 01:40 | a little smaller so it's readable.
| | 01:41 | And it's going to say, do I know
about a flat file right now? No, I don't.
| | 01:44 | I will have to click New.
| | 01:45 | Now anytime, you're defining a
connection to something in the outside world, a
| | 01:52 | database, a flat file, an Access
database, you typically have to give it a
| | 01:56 | connection and give that connection a name.
| | 01:58 | So I'll call this FlatFileConnection.
| | 02:01 | I will leave the description and
it's asking, "Where is that file?"
| | 02:06 | It could be on a network share, could
be, as is my case, just a simple text
| | 02:10 | file on my desktop.
| | 02:12 | It's called names.txt.
| | 02:15 | If I click through and look at the
columns, what I actually find is that I have
| | 02:18 | got some columns being picked up right now.
| | 02:22 | Its name, first name, last name, email.
| | 02:24 | It does look like I've got
some columns in that first row.
| | 02:29 | And if I click back on the
General tab, it will tell me.
| | 02:31 | There is why I describe that.
Column names are in the first row.
| | 02:34 | This is just a very plain delimited text file.
| | 02:39 | Clicking through it, it's read
as much as it can out of that.
| | 02:41 | It's done the usual thing but it tries to
take a guess of what this data should be.
| | 02:46 | We have got first name, last name, email.
| | 02:48 | Well, I know that my email
might be a little longer than 50.
| | 02:50 | So I am going to make that 100.
| | 02:52 | If this looks familiar, it's because it
is very, very close to what you get when
| | 02:57 | you are using the Import/Export wizard.
| | 02:59 | It's a little different than when you
have to define a connection but the rest of
| | 03:03 | it is kind of the same thing.
| | 03:04 | You're describing what the data actually is.
| | 03:08 | Going back, I can pick up the columns
and it says "Yes, as far as I know, we've
| | 03:11 | got FName, LNmae, Email, City, and Zip."
| | 03:15 | You can define the Error Output,
which is if there's any problems with
| | 03:18 | this, what do we do?
| | 03:20 | If there is an error, do we
fail this part of the process?
| | 03:22 | Do we ignore failure?
| | 03:23 | Do we send that one
particular row somewhere else?
| | 03:26 | I'm going to say if there's ever any
error and if there's ever any truncation,
| | 03:30 | we are going to fail this part. So I click OK.
| | 03:34 | I'm going to say that data was good.
| | 03:36 | I'll drag the little green
arrow down to Character Mapping.
| | 03:39 | What does Character Mapping do?
| | 03:41 | If I double-click on it, I
have defined what the input is.
| | 03:44 | So it says okay, these are my available
input columns. Which ones do you want to affect?
| | 03:48 | What I would like to do is take any
of the last names and I just want to
| | 03:52 | change them in place.
| | 03:54 | And in fact, I have the option of creating
a new column or I can do an In-place change.
| | 03:59 | And then, it says well, what's your
operation? Lowercase, Uppercase, Byte
| | 04:02 | reversal, Japanese Hiragana and Katakana?
| | 04:05 | I'm not going to do any of that.
| | 04:06 | I'm just going to say let's
convert the last name to uppercase.
| | 04:10 | Click OK, click OK.
| | 04:11 | That's a basic character
mapping. Well, then what?
| | 04:14 | Taking the output of that on to the Sort.
| | 04:17 | Double click Sort to define him.
| | 04:20 | What are we sorting on?
| | 04:21 | Well, let's sort on last name
ascending and then first name ascending,
| | 04:26 | if there're any people with the last name.
| | 04:28 | Do I want to remove rows
with duplicate Sort values?
| | 04:31 | No, definitely not.
| | 04:32 | So I click OK and we have the Sort.
| | 04:35 | The output of the Sort goes
to the Flat File Destination.
| | 04:38 | We will double-click it.
| | 04:40 | I can say do we want to use
the same manager as last time?
| | 04:44 | Basically, we are getting the option here,
| | 04:46 | do we want to overwrite
the file that we had before?
| | 04:49 | Well, I could, but I'm going
to say no, let's make a new one.
| | 04:52 | It's going to ask me, do I want to
create a delimited flat file of fixed width,
| | 04:57 | fixed width with row
delimiters? What do I want to do?
| | 05:00 | Let's just accept the default as delimited.
| | 05:03 | I click OK and it's going to ask me
again describe very similar stuff except
| | 05:08 | what's the output file is going to be called.
| | 05:10 | Well, I'll browse to the
desktop and just invent a name.
| | 05:13 | I'll call the output as
output.txt and click Open.
| | 05:17 | Then it's going to ask all these
questions. Do I want this in Unicode?
| | 05:20 | Yes, certainly I do.
| | 05:22 | Do I want the column names in
the first row? Sure, why not.
| | 05:25 | I can take a look at what it thinks
the columns are going to be with FName,
| | 05:29 | LName, Email, City, and Zip. It looks okay.
| | 05:33 | We can preview if I want to, but I am just
leaving it because we haven't run this process.
| | 05:37 | I am going to click OK.
| | 05:39 | I do need to take a look at the
Mappings page here before it lets me click OK, but
| | 05:44 | I'm not going to change anything.
| | 05:45 | It's still following the fact that
because I hooked up the green arrows,
| | 05:49 | it knows what the available input is
and what the output destination is.
| | 05:53 | So, I am going to just click OK.
| | 05:54 | And I am going to say I think I am done.
| | 05:57 | So, I'm going to save this.
I am going to go ahead and run it.
| | 06:00 | I can click this little
Start Debugging arrow up here.
| | 06:04 | The benefit of doing it that way is even
though this will happen very quickly, in
| | 06:08 | a full production environment it will
be quite slow and you'll have the steps
| | 06:12 | showing up in green or red
when they work. So let's try.
| | 06:16 | Now we have green, green, green, green.
| | 06:20 | Okay, looks interesting.
| | 06:22 | I get this message down here that all
the different components have occurred,
| | 06:26 | that the end result is apparently a success.
| | 06:29 | So let's take a look.
| | 06:30 | I will minimize this and go to my desktop.
| | 06:33 | My input was this file.
| | 06:35 | Names, comma delimited, and my output is this file
and it certainly looks as if it did the trick.
| | 06:42 | We've got comma delimited with line breaks
in between them. We've got the first row
| | 06:49 | with the columns in it and we have
the capitalized and sorted output.
| | 06:54 | Yes, SQL Server Integration Services
is a little bit of overkill for that,
| | 06:59 | although even transforming a text file
like that can certainly take a little
| | 07:02 | time if you have to do it manually.
| | 07:05 | But that's the general process.
| | 07:07 | The real key of what you're doing is
always going to be in the Data Flow and
| | 07:10 | then you can typically
surround that with Control Flow.
| | 07:14 | Control Flow doing things like
checking the integrity of the database,
| | 07:18 | notifying an operator, sending it in
the email, accessing something from FTP.
| | 07:23 | But I find working with SQL Server
Integration Services projects, it's really easy to
| | 07:27 | begin with a simple one and then you can
start injecting and dropping in the new
| | 07:32 | and the more complex tasks around it.
| | Collapse this transcript |
| Importing packages into SQL Server Management Studio| 00:00 | The end result of working with Business
Intelligence Development Studio and SQL
| | 00:06 | Server Integration Services is you end
up with a SSIS Package. It ends in .dtsx.
| | 00:13 | In fact, I'm going to come out of
Integration Services because I have that
| | 00:18 | folder open here, and this is the
package file that I'm interested in.
| | 00:22 | Yes, I can run it from inside Business
Intelligence Development Studio, but if I
| | 00:26 | wanted to have this occur and automated,
I can actually take it into SQL Server
| | 00:32 | Management Studio and
make it part of the database.
| | 00:35 | Now again, it's just a simple package.
| | 00:38 | This is the one that's actually affecting a
flat file but the operation is still the same.
| | 00:42 | I'm going to open up SQL
Server Management Studio.
| | 00:45 | Except this time rather than connect
directly to the database engine, I'm going
| | 00:50 | to connect to Integration Services
using the same administration information,
| | 00:55 | and what we'll get here is running
packages and stored packages, and if I wanted
| | 01:02 | to take in that package into the
database, make it part of the database, what
| | 01:08 | I'd actually do is come to
the section that says MSDB.
| | 01:11 | That's one of the system databases
that's involved in queuing and setting up jobs.
| | 01:17 | Right-click and say Import Package.
| | 01:20 | It's going to ask "Well, where is
the package? Is it in SQL Server?"
| | 01:23 | No, it's actually on the File System.
| | 01:24 | So I'll go and grab the package path.
| | 01:27 | It's going to be in my Visual Studio
2008 > Projects, in FlatFileTransform.
| | 01:33 | It's several levels deep, but it's where I
had created it, and click Open and click OK.
| | 01:39 | This package is now
considered part of the database.
| | 01:43 | We can execute it at our leisure or we
can even set it up to be a scheduled job.
| | 01:49 | Just to prove that it's going to work,
it's just fine from within the confines
| | 01:52 | of SQL, let me just minimize this
window a little bit. Because I can actually
| | 01:57 | see that my desktop here
contains the names, which is my input.
| | 02:02 | And I can actually come over here
and right-click the Package and run it.
| | 02:07 | Running within the confines of
the database I've not got BIDS open.
| | 02:11 | So I'm not using anything in Visual Studio.
| | 02:15 | I have all sorts of questions here
about configuration and who I'm running as
| | 02:18 | and connection managers and options
and reporting and logging, but of course
| | 02:22 | this is a fairly simple one.
| | 02:23 | So I'm just going to execute it.
| | 02:25 | And I can actually see behind the
scenes right now that here's my progress.
| | 02:30 | I can close that but I've already got
the output file just sitting there with
| | 02:35 | all the transformations applied to it.
| | 02:37 | Now the window that I just saw
is the same one that you'd get
| | 02:40 | if you went directly into your SQL
Server 2008 R2 programs into Integration
| | 02:46 | Services and find the Execute Package Utilities.
| | 02:49 | Just a standalone utility that would
execute a package, whether it's on the file
| | 02:53 | system or stored in SQL Server.
| | 02:55 | Of course, the big benefit of doing
it this way is you don't need to have
| | 03:00 | Business Intelligence Development
Studio opened and running for everybody
| | 03:04 | whoever wants to execute this package.
| | 03:06 | You build it in that application and
then it can be executed from the database,
| | 03:11 | even from things like stored procedures.
Or you can of course schedule it to
| | 03:16 | happen automatically on a daily,
hourly, monthly or yearly basis.
| | Collapse this transcript |
| Scheduling jobs with SQL Server Agent| 00:00 | If you want to execute a package as a
regularly scheduled occurrence there is a
| | 00:05 | part of SQL Server that can do that
for you but it's a part that's actually
| | 00:09 | turned off when you first install it.
| | 00:12 | In fact if I open up another instance
of Management Studio, I'm going to connect
| | 00:18 | to the database engine and you may have
seen this before, that there is an entry
| | 00:22 | here that says SQL Server Agent. You may
have seen it in Management Studio or if
| | 00:27 | you had opened up the Configuration
Manager you would also see it there.
| | 00:32 | SQL Server Agent is stopped by default
and its Start Mode is Manual, which means
| | 00:37 | when the machine is
restarted it will not start itself.
| | 00:41 | It's again because of what Microsoft
tend to do these days, which is they ship
| | 00:46 | products with only the
necessary part of them turned on.
| | 00:50 | Now SQL Server Agent isn't absolutely
necessary so it's off by default and you
| | 00:55 | have to turn it on if you want to use it.
| | 00:57 | I can just turn it on quite easily from
SQL Server Configuration Manager, just
| | 01:02 | hit the little Play button and we'll
turn it on, and if I wanted to I could also
| | 01:07 | right-click, select the Properties of
it, and then make sure that it actually
| | 01:12 | changes the Start Mode to Automatic.
| | 01:15 | I am not going to do that right
now because I don't want to make it
| | 01:17 | Automatic but I could do.
| | 01:20 | What is SQL Server Agent?
| | 01:22 | Well it is a supporting service
that allows us to have jobs that are
| | 01:27 | scheduled in the background.
| | 01:28 | It allows us to have an
asynchronous kind of queuing mechanism.
| | 01:33 | It can control tasks to be
repeatedly happening in the database.
| | 01:37 | You just have to know it's
there in order to turn it on.
| | 01:40 | Once it is on, then what?
| | 01:42 | Well I am going to expand this and it
says, well we've got Jobs, we've got
| | 01:45 | Alerts, and we've got
Operators, Proxies, and Error Logs.
| | 01:48 | SQL Server Agent works with the idea
of a Job, I am going to make a new one.
| | 01:55 | I right-click and say a New Job.
I give it a name and then I say what it is.
| | 01:59 | Let's say this is a job that I want to
run every week or so that converts new
| | 02:05 | customers that are being
loaded into some kind of text file.
| | 02:12 | Convert Customers. Yup, I'm the owner.
| | 02:14 | It doesn't really fit into a
Database Engine Tuning Advisor or Database
| | 02:19 | Maintenance. I am just going to leave it
as Uncategorized right now, and then we
| | 02:23 | step through the steps.
| | 02:25 | What do we do, and the
schedules, when do we do it?
| | 02:28 | So the step first, nothing is
happening right now. I'll say I want to create a
| | 02:33 | new step, and the step name will be
Do The Convert and it's asking is it a
| | 02:39 | T-SQL script or Replication Merge,
ActiveX Script or is it a SQL Server
| | 02:44 | Integration Services Package? And
of course that's what it is, exactly.
| | 02:47 | What are we going to run as the
SQL Server Agent Service Account?
| | 02:51 | Yes, absolutely that should
do the trick with this one.
| | 02:54 | It doesn't really need any
kind of significant account there.
| | 02:56 | It's going to ask where is the package?
| | 02:58 | It's in SQL Server? Which server?
| | 03:01 | This one, the dot?
| | 03:03 | We are going to use Windows
Authentication and then we'll drop down and
| | 03:06 | select the package.
| | 03:07 | Would have been useful if I'd given it
a more interesting name but that will do
| | 03:11 | the trick. We click OK. I don't need
to change any of the other setups here.
| | 03:16 | That will do just fine and I click OK.
| | 03:19 | We've got the step selected.
| | 03:21 | Now I need to define the schedule.
| | 03:24 | I click the Now button and it asks, okay,
what's the name for this schedule is?
| | 03:27 | Let's call it on Monday Morning.
| | 03:31 | Just so it's descriptive
when we read this later.
| | 03:35 | It is a reoccurring schedule.
| | 03:37 | It will happen weekly, on a Monday Morning
let's say at 5 a.m. and there's no end date.
| | 03:44 | Pretty much like setting up or
occurring appointment in Outlook.
| | 03:47 | We have some more choices about
alerts and actions to perform when the job
| | 03:52 | completes, I want to get an e-mail,
when the Job succeeds, when the Job fails,
| | 03:57 | this does require you to have database
mail turned on, which we don't have at
| | 04:01 | this particular moment, but you could do that,
and that's pretty much it. Going to click OK.
| | 04:07 | We have the job, SQL Server Agent is
started, we would want to make sure that it
| | 04:11 | was set up to start automatically if
the machine ever go restarted but that's
| | 04:16 | the general process for doing it.
| | 04:18 | And simply by doing this we can
start to build more complex, more
| | 04:23 | automated situations.
| | 04:25 | Of course SQL Server Integration
packages are the only jobs that you can
| | 04:30 | schedule in SQL Server Agent. As you saw
there is the ability even to just write
| | 04:34 | raw T-SQL so you can have database
consistency checks, you can automate the
| | 04:40 | rebuilding or the re-organizing of
indexes, and you really can start to build a
| | 04:45 | more automated, more
controlled database structure.
| | Collapse this transcript |
|
|
ConclusionGoodbye| 00:00 | Thanks for joining us for SQL
Server 2008 Essential Training.
| | 00:04 | You have seen the core features,
applications and techniques to get started with
| | 00:08 | creating and working with databases
in SQL Server and you should now have a
| | 00:13 | pretty good idea of what parts of
SQL Server you want to take further.
| | 00:17 | You might want to do more work with
designing and creating databases or dive
| | 00:21 | deeper into indexing and
performance or see what can be done with the
| | 00:24 | surrounding components like
Reporting Services and Integration Services.
| | 00:29 | So good luck with your databases!
| | Collapse this transcript |
|
|