SQL Server Metadata Succinctly
SQL Server Metadata Succinctly
www.dbooks.org
SQL Server Metadata
Succinctly
By
Joseph D. Booth
Foreword by Daniel Jebaraj
Copyright © 2019 by Syncfusion, Inc.
2501 Aerial Center Parkway
Suite 200
Morrisville, NC 27560
USA
All rights reserved.
If you obtained this book from any other source, please register and download a free copy from
www.syncfusion.com.
The authors and copyright holders provide absolutely no warranty for any information provided.
The authors and copyright holders shall not be liable for any claim, damages, or any other
liability arising from, out of, or in connection with the information in this book.
Please do not use this book if the listed terms are unacceptable.
www.dbooks.org
Table of Contents
Chapter 1 Introduction...........................................................................................................12
Metadata ..............................................................................................................................12
Summary ..............................................................................................................................13
Tables ..................................................................................................................................14
Columns ...............................................................................................................................16
Domains ...............................................................................................................................17
column_domain_usage ....................................................................................................17
Domain queries................................................................................................................18
Routines ...............................................................................................................................19
Parameters ......................................................................................................................21
Routine queries................................................................................................................21
Views ...................................................................................................................................22
4
Find which tables contain a column name........................................................................24
Summary ..............................................................................................................................26
@@version ......................................................................................................................29
xp_msver .........................................................................................................................29
SERVERPROPERTY ......................................................................................................30
Memory ................................................................................................................................31
Configuration ........................................................................................................................34
SERVERPROPERTY ...........................................................................................................36
Summary ..............................................................................................................................37
Sys.databases ......................................................................................................................38
DATABASEPROPERTYEX()................................................................................................39
www.dbooks.org
General information ..............................................................................................................39
Files .....................................................................................................................................41
Options .................................................................................................................................42
DATABASEPROPERTYEX()................................................................................................45
database_principals .........................................................................................................47
Summary ..............................................................................................................................49
Tables ..................................................................................................................................50
6
sys.masked_columns (starting with SQL 2016) ...............................................................53
Numeric columns..................................................................................................................56
Summary ..............................................................................................................................58
www.dbooks.org
LIKE clause ..........................................................................................................................70
Summary ..............................................................................................................................71
Demo databases..............................................................................................................72
Blank passwords..............................................................................................................76
SA account ......................................................................................................................79
Users....................................................................................................................................79
Summary ..............................................................................................................................82
Summary .................................................................................................................................83
INFORMATION_SCHEMA ...................................................................................................83
8
The Story Behind the Succinctly Series
of Books
Daniel Jebaraj, Vice President
Syncfusion, Inc.
taying on the cutting edge
S As many of you may know, Syncfusion is a provider of software components for the
Microsoft platform. This puts us in the exciting but challenging position of always
being on the cutting edge.
Whenever platforms or tools are shipping out of Microsoft, which seems to be about
every other week these days, we have to educate ourselves, quickly.
While more information is becoming available on the Internet and more and more books are
being published, even on topics that are relatively new, one aspect that continues to inhibit us is
the inability to find concise technology overview books.
We are usually faced with two options: read several 500+ page books or scour the web for
relevant blog posts and other articles. Just as everyone else who has a job to do and customers
to serve, we find this quite frustrating.
We firmly believe, given the background knowledge such developers have, that most topics can
be translated into books that are between 50 and 100 pages.
This is exactly what we resolved to accomplish with the Succinctly series. Isn’t everything
wonderful born out of a deep desire to change things for the better?
Free forever
Syncfusion will be working to produce books on several topics. The books will always be free.
Any updates we publish will also be free.
www.dbooks.org
Free? What is the catch?
There is no catch here. Syncfusion has a vested interest in this effort.
As a component vendor, our unique claim has always been that we offer deeper and broader
frameworks than anyone else on the market. Developer education greatly helps us market and
sell against competing vendors who promise to “enable AJAX support with one click,” or “turn
the moon to cheese!”
We sincerely hope you enjoy reading this book and that it helps you better understand the topic
of study. Thank you for reading.
10
About the Author
Joseph D. Booth has been programming since 1981 in a variety of languages including BASIC,
Clipper, FoxPro, Delphi, Classic ASP, Visual Basic, JavaScript, Visual C#, and the .NET
Framework. He has also worked in various database platforms, including DBASE, Paradox,
Oracle, and SQL Server.
Joe has worked for a number of companies, including Yprime, Sperry Univac, MCI-WorldCom,
Ronin, Harris Interactive, Thomas Jefferson University, People Metrics, and Investor Force. He
is one of the primary authors of Results for Research (market-research software), PEPSys
(industrial-distribution software), and a key contributor to AccuBuild (accounting software for the
construction industry).
In his spare time, Joe is an avid tennis player. He also practices yoga and martial arts, and
plays with his first granddaughter, Blaire. You can visit his website for more information.
11
www.dbooks.org
Chapter 1 Introduction
In the classic Star Trek episode called "The Enterprise Incident," the crew steals the Romulan
cloaking device and attempts to integrate it into their ship. By reading the device’s metadata, the
crew was able to figure out how to make the device work and successfully evade those nasty
Romulans. While it seems unlikely that the technology would be similar, most devices provide
"metadata" about themselves.
Metadata
Metadata is very common in most digital devices and files. Pictures taken by a digital camera
can have over 400 tags of metadata associated with the photo, including type of digital device
used, where and when the photo was taken, and so on. Your phone call log also has metadata,
like where you called from, who you called, and how long you talked. You can visit this website
(or search for “photo metadata” on Google) to get a sense of the data that is stored.
Privacy concerns aside, it is clear that metadata is very prevalent in the digital world.
SQL metadata
Microsoft SQL Server (and other SQL systems) also provide a large amount of data about their
servers, users, tables, and stored procedures. In this book, we are going to explore that
metadata and provide example scripts and queries to learn a lot of information about your SQL
environment.
Information schema
Information schema views are a series of SQL-92 ANSI standard views that are generally found
in most SQL systems (Oracle being a notable exception). These views provide information
about tables, columns, views, and stored procedures, and for the most part, the queries using
these views will work across database platforms.
Note: The ANSI standard is not specific to Microsoft, so some of the field and view
names might not use the same terminology that SQL Server uses.
12
Code Listing 1: Object Definition for information_schema.tables
---------------------------------------------------
-- Script: Peek_Definition.sql
-- Look at definition of information_schema view
--------------------------------------------------
DECLARE @srcCode VARCHAR(max)
SELECT @srcCode =
OBJECT_DEFINITION(object_id('INFORMATION_SCHEMA.tables'))
PRINT @srcCode
The system tables provide much more information, but the information schema views are closer
to the ANSI standard, and generally can be used across database products.
Note: The SQL code in this book was tested using SQL 2017, and most of the
views and functions will work on older versions of SQL, as well. Scripts that don’t
work on older versions will be noted.
Summary
In this book, we will start with the information schema views and provide some handy queries
about the server's data tables. We will then explore some of the views that are unique to
Microsoft and provide very useful information about SQL Server.
13
www.dbooks.org
Chapter 2 Information Schema
The information schema views will use the catalog and domain terminology to meet the ANSI
standard. However, to the Microsoft SQL developer, the database and the user-defined data
type are the more common terms. You can find these views under the System Views list in SQL
Server Management Studio (SSMS).
Note: Although the information schema views are available in each database, the
table catalog (which is always the current database) is returned in the various views.
This will come in handy if you need to write a procedure to iterate all databases on a
server.
Tables
The Tables view holds four columns.
The first three columns are generally used as identifiers (with different field names) for almost all
information schema views. Use this view to identify the schema that the tables are owned by
and whether it is a physical table or view.
14
Tip: SQL Server allows you not to specify the table owner schema when
referencing a table. This can cause some subtle bugs when a table occurs in multiple
schemas. The following query can identify table names that occur in more than one
schema.
Table constraints
Constraints are rules applied to columns in a database table. They generally limit the type of
data that can be added to a column. The TABLE_CONSTRAINTS view lists the tables and
constraints on those tables. The columns are shown in Table 3.
The CHECK constraint definitions are found in the CHECK_CONSTRAINTS view, which includes the
CHECK_CLAUSE column to show the definition of the constraint.
15
www.dbooks.org
The remaining constraint types (FOREIGN KEY, PRIMARY KEY, and UNIQUE) reference tables and
columns and can be found in the CONSTRAINT_COLUMN_USAGE view. You can combine these
tables to create a query that returns the constraint type and name, and an expression column
showing the expression or key columns. Code Listing 2 shows the query.
Table 4
Note: In this query, we are only joining on the constraint name for simplicity. If
you have multiple schemas in your database, you should include schema names as
part of your join condition.
Columns
The columns view begins with the table information (catalog, schema, and table name) followed
by all the columns in the table and information about those columns. Some of the key column
fields are shown in Table 5.
16
Table 5: Column fields
Note: Certain column data types (such as bit and uniqueidentifer) don’t have size
information in the table. If a character column is defined as MAX, the character length
column will contain a -1.
Domains
Domains (or “user-defined data types” in SQL Server parlance) are useful concepts that make it
easier to maintain columns by creating your own column type. For example, you might want to
create a domain to set the properties you want all phone number fields to use. The domains
view contains most of the same column definitions as the columns view.
column_domain_usage
The column_domain_usage view provides a list of all tables that reference one of the user-
defined columns (domains).
17
www.dbooks.org
Table 7: Column Domain Usage fields
Domain queries
You can perform some basic queries to view your user-defined types and the tables that use
them. Code Listing 3 simply shows the user-defined types and displays the size information in a
nicely formatted way.
Code Listing 4 shows a similar result but includes the count of columns that are referencing the
domain.
18
---------------------------------------------
SELECT d.domain_schema,d.domain_name,
CASE
WHEN data_type='DECIMAL' THEN data_type+'('+
CAST(Numeric_Precision as varchar(3))+'.'+
CAST(Numeric_Scale as varchar(3))+')'
WHEN data_type IN ('char','varchar','nchar','nvarchar')
THEN
CASE
WHEN character_maximum_length<0 THEN data_type+'(MAX)'
ELSE data_type+'('+
CAST(Character_Maximum_Length as Varchar(3))+')'
END
ELSE data_type
END AS RootDateType,
count(du.column_name) as ColumnsUsing
FROM INFORMATION_SCHEMA.domains d
LEFT JOIN INFORMATION_SCHEMA.column_domain_usage du on
d.domain_name=du.domain_name
GROUP BY d.domain_schema,d.domain_name,data_type,
character_maximum_length,numeric_precision,numeric_scale
ORDER BY d.domain_schema,d.domain_name
You can view user-defined types in SQL Server Management Studio (SSMS) by using the
Programmability menu of the object inspector, as shown in Figure 1.
Routines
The ROUTINES view returns over 50 columns about the various stored procedures and functions
in the database. It includes the source code and a flag indicating if the routine updates or simply
reads the data. Some representative columns from the view are shown in Table 8.
19
www.dbooks.org
Table 8: Routine fields
Note: The routine definition column only contains 4,000 bytes of the routine. If you
are writing code to get the complete routine body, consider using SP_HelpText
instead.
Routine columns
If the routine is a table-valued function (it returns a table rather than a single value), the
ROUTINE_COLUMNS view returns the column information for the returned table.
Code Listing 5 shows the code used to identify the type of routine and whether it updates data.
20
CASE
WHEN rc.table_name is null AND r.routine_type='FUNCTION' THEN 'Scalar
Function'
WHEN rc.table_name is not null and r.routine_type='FUNCTION' THEN 'Table
Valued Function'
ELSE 'Stored procedure'
END AS RoutineType,
r.sql_data_access
FROM INFORMATION_SCHEMA.routines r
LEFT JOIN
(SELECT DISTINCT table_name FROM INFORMATION_SCHEMA.routine_columns) rc
ON rc.table_name=r.routine_name
ORDER BY RoutineType,routine_name
Parameters
The PARAMETERS view returns many columns about the various input and output parameters to
all the stored procedures and functions in the routines view. Table 10 lists some of the common
columns in the view.
Routine queries
Code Listing 6 is a query that returns the routine name and type, and a column containing all
the parameters used by the routine. The following table shows a sample of the output.
21
www.dbooks.org
Routine name Type Parameters
CheckForCalculations PROC @ClientID int @VisitId int
Code Listing 6 can provide a simple documentation overview of the database code.
Views
The VIEWS view holds details about the views defined in the database. Notice that the column
names are called TABLE, even though the content is the view itself. The view definition column
contains a SQL Create View script to create the view. This column is limited to 4,000 bytes,
which should be enough for all but the most complex views.
22
Table 12: View fields
23
www.dbooks.org
Column name Description
TABLE_SCHEMA Name of the schema the referenced table is in.
TABLE_NAME Name of the table referenced by the view.
COLUMN_ NAME Name of the column in the table referenced by the
view.
View queries
Code Listing 7 contains a query that will display each view name and the tables that it
references.
24
Code Listing 8: Find a column
---------------------------------------------
-- Script: Find_Column.sql
-- Search for a column by name
---------------------------------------------
SELECT table_schema,table_name
FROM INFORMATION_SCHEMA.columns
WHERE column_name='IsSupported'
ORDER BY table_schema,table_name
This query identifies columns with the same name, but different types or sizes.
Tip: You can test collation sequence, nullable, etc., by changing your HAVING
conditions in the query.
25
www.dbooks.org
Similarly named columns
Often, over time and multiple developers, column names might have slight naming variations
that can create application errors. This query finds all columns that contain the text “phone”.
In this example database, we found phone and phonenumber were both used to hold a phone
number field for an organization.
Summary
The information schema views are a handy and generic (SQL-92 standard) way to identify your
database structure and look for potential problem areas.
Note: While Oracle doesn't implement the information schema, it does have views
to provide the same information. For example, the ALL_TABLE view is like the
TABLES view, and ALL_TAB_COLUMNS view is like the COLUMNS view.
26
No matter which database you use, having programmable access to the underlying structures
can help you to understand the database and solve problems. If you want more information
about the information schema views in SQL Server, you can visit this website. In this chapter,
we only focused on some columns in the views; this site will provide complete details of all the
columns in the views.
27
www.dbooks.org
Chapter 3 Server Information
In this chapter, we will explore some of the hardware, operating system, and SQL version
information, as well as the various configuration options of the server. All this information is
available through various views in the sys schema. Most of the information comes from the
subset called dynamic management views within the sys schema. These views begin with dm_
and provide a lot of information about the SQL environment.
Note: Your account may not have permission to access the various views
described in this chapter, particularly if you are on a remote server. You will generally
need the VIEW SERVER STATE permission for most of these queries.
Host version
You can determine the operating system information and version number by using the newly
added sys.dm_os_host_info view (SQL 2017). Note that SQL Server does not return as much
information if SQL is running on a Linux host.
You can find out more about the Windows version information at this website.
28
If you are using an older version of SQL, the dm_os_windows_info view provides similar
information (without the platform or distribution columns). Table 16 lists the columns in that
view.
@@version
The simplest approach is to use the @@version global variable. This will return a string
containing the version and copyright information.
If you want to report on this data, you can save it to a variable and split the variable on the
linefeed (char(10)) character.
xp_msver
Another option is to use the extended stored procedure xp_msver in the master database. This
returns a four-column table containing version and copyright information about the server. Table
17 shows some sample rows from this procedure.
29
www.dbooks.org
2 ProductVersion 917504 14.0.3103.1
SERVERPROPERTY
While the previous two approaches show the version number and description, you might want to
simply get a numeric indication of the version number (for example, your procedure only runs on
a version of the server). For this approach, you can use the SERVERPROPERTY function and get
the ProjectMajorVersion, as shown in the following.
select SERVERPROPERTY('ProductMajorVersion')
Table 18 shows the mapping between the product version and the SQL version.
9 SQL 2005
10 SQL 2008
11 SQL 2012
12 SQL 2014
13 SQL 2016
14 SQL 2017
15 SQL 2019
We will cover the SERVERPROPERTY function in more detail later in this chapter.
30
Table 19: CLR properties
Name Value
directory C:\Windows\Microsoft.NET\Framework64\v4.0.30319\
version v4.0.30319
The dm_clr_loaded_assemblies view will show all CLR assemblies running on the SQL
server. SQL will generally keep these assemblies loaded for performance reasons but can
unload them in a memory pressure situation.
Memory
SQL Server is designed to manage memory itself, rather than require administrators to allocate
the memory. Basically, SQL will greedily take as much memory as it can get but will release
memory to the operating system if the OS is needy (low memory situation). You can use the
dm_os_sys_memory view to query the amount of memory on the server. Code Listing 12 is an
example query.
The system_memory_state_desc fields indicate whether memory is high (SQL can keep using
it) or low (SQL needs to release some to operating system). Ideally, there are not a lot of
memory-intensive processes running on the SQL server machine.
Disk usage
You can use the xp_fixedDrives stored procedure or, starting with SQL 2017, the new
Dynamic Management view called dm_os_enumerate_fixed_drives. The stored procedure
returns two columns: the drive letter and megabytes free. The new view returns the drive path
and drive type (usually fixed or network), and the bytes free. Code Listing 13 uses the new view.
31
www.dbooks.org
Code Listing 13: Drive information
---------------------------------------------
-- Script: Basic_Drive_info.sql
-- Show free space on drives
---------------------------------------------
if object_id('sys.dm_os_enumerate_fixed_drives') is not null
SELECT fixed_drive_path,drive_type_desc,
free_space_in_bytes/(1024*1024) as MB_Free
FROM sys.dm_os_enumerate_fixed_drives
else
exec xp_fixedDrives
You can combine this view with the sys.master_files view to determine where the various
databases reside. Code Listing 14 shows the master and tempdb databases, as well as the
database and log files for the current database.
You should expect to see that the log and data files are stored on separate drives, and that the
tempdb files (could be multiple files) are on their own drive, as well. While this hard drive
configuration could vary, those are the generally recommended guidelines for performance
purposes.
32
Enumerate file system
SQL Server 2017 added a new table-valued function called dm_os_enumerate_file_system.
This function takes two parameters, the starting folder, and a search pattern. For example, to
find out if any new DLLs were added recently, you could run the following SQL command.
Registry information
SQL Server uses the system registry of the server machine to hold several settings, such as the
SQL image, startup parameters, or port. You can use the dm_server_registry view to peek at
these registry settings.
33
www.dbooks.org
-- Server databases and versions
---------------------------------------------
SELECT database_id,[name],create_date,
CASE compatibility_level
WHEN 80 THEN 'SQL 2005'
when 90 then 'SQL 2005'
when 100 then 'SQL 2008'
when 110 then 'SQL 2012'
when 120 then 'SQL 2014'
when 130 then 'SQL 2016'
when 140 then 'SQL 2017'
when 150 then 'SQL 2019'
else 'Unknown version'
end as SQL_Level
from sys.databases
order by database_id
The first four databases (master, tempdb, model, and msdb) are SQL internal databases.
The type_desc will be either ROWS or LOGS. The logs and rows should be on separate drives for
better performance.
Configuration
The sys.configurations view has key fields of a name, value, and description. Many of the
configuration options are represented by a named row in this view. You can visit the Microsoft
website to determine the usage of the various settings.
You can also view most of the configuration information in SSMS by opening the Properties
dialog on the server name, as shown in Figure 2.
34
Figure 2: Server properties
You can also use the sp_configure stored procedure to look at any of the settings. You specify
the setting name or leave off the parameter to see all settings available.
Advanced settings
Many of configuration settings are considered "advanced" as determined by the Is_advanced
flag in the sys.configurations view. For example, the xp_cmdshell allows users to issue
operating system commands on the server. By default, SQL Server is configured with this option
disabled.
35
www.dbooks.org
SQL administrators will generally use scripts of sp_configure commands to configure the
server. The Microsoft defaults are generally set toward a minimum machine, so the server will
run even in lower memory/hardware configurations. Open connections allowed, server memory
and query memory are often customized to get better performance based on knowledge of your
server's hardware.
SERVERPROPERTY
The SERVERPROPERTY function also provides a good deal of information about the server. It
takes a single parameter, the property name, and returns the current property value. For
example, the following code snippet shows the edition of SQL Server being run.
ServerEdition
Developer Edition (64-bit)
The Microsoft website provides details as to the various server property parameters.
You can use the SERVERPROPERTY function to put together a detailed list of server information,
as shown in Code Listing 17.
36
Summary
In this chapter we covered a few of the dynamic management views you can use to explore the
details of your SQL Server installation. There are over 100 different views to provide all sorts of
server information. Hopefully, this chapter whetted your appetite to explore them further.
We will cover some additional views in later chapters and discuss indexing and performance.
37
www.dbooks.org
Chapter 4 Database Properties
Within a SQL Server instance, there can be any number of databases containing related tables
and objects. In this chapter, we will explore how to use the SQL views to determine information
about the individual databases. Figure 3 shows the database properties table from SSMS.
Note: Your account may not have permission to access the various views
described in this chapter. You will generally need the VIEW DATABASE STATE
permission for most of these queries.
Sys.databases
The primary view for database information is the sys.databases view. This view holds a row of
information for each database in the server. You can restrict it to just the current database by
filtering to the current database ID, as shown in the following code.
The function db_id() returns the numeric ID of the current database (or takes a parameter of
database name and returns the database ID).
38
DATABASEPROPERTYEX()
The SQL function DATABASEPROPERTYEX () provides additional information about any database
in the system. It takes two parameters: the database name (using db_name() for current
database) and the property you want to view.
General information
The General tab of the Properties page provides some simple status information, such as
database size and date of the last backup. This information can be assembled using the
sys.databases view and the DATABASEPROPERTYEX() function.
Basic information
Code Listing 18 uses the sys.databases view and DATABASEPROPERTYEX() function to
duplicate much of the information from the General tab. In the following query, we are filtering to
just the current database on the WHERE clause. If you remove the WHERE clause, you can obtain
the general information for all databases to which you have access.
39
www.dbooks.org
Backup information
The backup information is retrieved from the backupset table in the MSDB (Microsoft
Database) database. We can retrieve the backup information for both the data and the logs
using Code Listing 19.
There is other information available in the backupset table, such as the backup size, whether it
is encrypted or not, recovery model, compressed size, etc. Although we are only interested in
the backup dates, you might find occasional need to access the other fields.
Size information
The size of any database can be retrieved easily from the sys.master_files view, but the
actual use (needed to compute space available) requires a bit more effort. Code Listing 20
provides this information.
40
( SELECT reservedpages = sum(a.total_pages)
FROM sys.partitions p
INNER JOIN sys.allocation_units a
ON p.partition_id = a.container_id
) AS pt
The sp_spaceused stored procedure returns this information as well, but it currently returns two
result sets, so you cannot execute it to a temporary table.
Files
The Files tab on the database properties shows basic information about the files and growth on
the database.
The information about the database files and growth is available from the sysFiles view. Code
Listing 21 converts the data to mimic the Files tab available from the SSMS Properties tab.
41
www.dbooks.org
growth*8.0/1024 as 'Autogrowth (MB)',
CASE
WHEN maxsize = 0 THEN 'No growth'
WHEN maxsize < 0 THEN 'Unlimited'
WHEN maxsize*8.0/1024 >=cast(268435456/8 as bigint) THEN '2
TerraBytes'
ELSE CAST(Round(maxsize*8.0/1024,0) as varchar(20))+'MB'
END as MaxSize,
FileName AS 'Path'
FROM sys.sysfiles sf
LEFT join sys.filegroups fg on fg.data_space_id=sf.fileid
Note that sizes are expressed in pages (one page is 8K bytes), so we multiply the size by 8 to
get the pages converted to bytes, and then divide by 1,024 to show the results in megabytes.
Options
Many of the database flags and options shown on the Options tab (Figure 5) can be obtained
via the DATABASEPROPERTYEX() SQL function.
In addition to the DATABASEPROPERTYEX function, most of these bit fields also exist in the
sys.database view. Table 19 lists the key column in sys.databases to see the various
configuration options.
42
Automatic settings
Be aware that the automatic settings can impact server performance. For example, if the last
user logs out and the database closes automatically, the next user will experience a slight delay
as the database gets re-opened.
If you do not automatically update stats, you should put a job or plan in to do so. Outdated
statistics can cause the query optimizer not to generate an optimal plan, and the query will run
slower than it could.
Tip: If you are unfamiliar with statistics, imagine a table holding a list of students,
containing name, gender, and GPA. If a query was run to determine female students
with a 3.0 or better GPA, the optimizer would likely search the GPA column first, and
then consider gender. This assumes that GPA 3.0 would return fewer records to
check gender against. However, if the system was aware that this was an all-male
school with only four female students, it would likely check gender first, and then
GPA. Statistics provide the information to allow the query optimizer to create the best
query plan.
43
www.dbooks.org
Table 24: ANSI and NULL options
For a programming example, the code in Code Listing 22 will return different results depending
on the setting of is_concat_null_yields_null_on. (Note that this example assumes the
database has a table called site.)
Code Listing 22
---------------------------------------------
-- Script: TellUserAboutMissingName.sql
-- Warn user to assign a name to the site
---------------------------------------------
SELECT IsNull('Site Name:'+name,'Please assign a name to site '+
cast(siteNumber as varchar)) as Msg
FROM site
Since these settings can change the behavior of SQL queries, it is at a minimum a good idea to
check them in the database you are writing code in. Even better, set them to your expected
value for the procedure and then restore them when done.
Note: In a future version of SQL Server, you will not be able to change the value of
CONCAT equals NULL; it will also default to ON.
If you find some inconsistent behavior between databases, be sure to check these options that
impact how the server operates.
44
Table 25: Other options
The best way to get familiar with them is to look at the database properties tab in SSMS and
find the corresponding option in the sys.databases view.
DATABASEPROPERTYEX()
In addition to the databases view, you can also use the SQL DATABASEPROPERTYEX() function
to get a lot of the configuration options, as well. The function takes two parameters: the name of
the database and the property you want to look at.
Many of the properties provide the same information as the sys.database view. A few sample
properties are shown in Table 26.
You can see the list of all parameters on the Microsoft website.
45
www.dbooks.org
CREATE TABLE #tmpProps (PropertyName varchar(100))
INSERT INTO #tmpProps values ('LCID'),('Collation'),
('UserAccess'),('IsArithmeticAbortEnabled'),
('IsNullConcat')
SELECT PropertyName,
DATABASEPROPERTYEX(db_name(),PropertyName) as CurrentDB_Property,
DATABASEPROPERTYEX(@targetDB,PropertyName) as TargetDB_Property
FROM #tmpProps
DROP TABLE #tmpProps
You can adjust the contents of the #tmpProps table to see the properties you want to compare.
Database permissions
There are two system views that you can use to determine who has various types of
permissions for your database.
Database permissions
This view lists all the database permissions, whether they’ve been granted or denied, and the
group, role, user, etc., who was granted the permission and who granted the permission. Table
27 shows the fields in the view.
major_id 0 for the database itself; >0 for user objects; <0 for system objects
You can use the OBJECT_NAME() function to get the object name
associated with the major_id field.
46
Column name Description
state D – Deny
R – Revoke
G – Granted
W – Grant with option to grant
database_principals
This view lists the various database users, roles, groups, etc., that have access to the database.
Table 28 lists the key columns needed to show permissions within the database.
principal_id ID for object, used to link with permissions table (grantor and
grantee).
authentication_type 0 – None
1 – Instance
2 – Database (SQL Login)
3 – Windows Auth
We can join the permissions and principals views to explore who has what permissions in
our database. The next section lists a few sample scripts to explore permissions.
47
www.dbooks.org
Who can edit?
Code Listing 24 shows a list of all users, roles, groups, etc., that can manipulate data with your
database.
48
WHERE pr.name = 'Public' and state='G' and class<>0
ORDER BY AllowedView
In a production environment, you should limit what the public role has access to. Even if just
SELECT rights, a lot of the metadata could be exposed to the public role.
Summary
SQL provides a lot of information about the database you are working in. Every property that
you can see on the Properties tab in SSMS can be pulled from system views or functions.
49
www.dbooks.org
Chapter 5 Tables and Columns
Although we covered the information schema views back in Chapter 2, SQL Server provides
additional views and procedures we can use to view our tables and columns in more depth. In
this chapter, we will look at the sys.tables and various sys column views to provide some
table and column analysis.
Note: Many of these views are derived from sys.objects. Every “object” in a SQL
database (tables, procedures, triggers, etc.) has an object ID associated with it, and
sys objects hold the information about the object. The OBJECT_NAME() SQL function
returns an object name from the object_id parameter.
Tables
We can join the sys.tables view with other views to determine information about our table
design. This allows us to perform additional table analysis beyond the basic information schema
views. When referencing the sys.tables view, we can use the object_schema_name and
object_name SQL functions to create a table name (schema + table name).
This listing shows tables that have an Identity column, along with the seed value and
increment for the column. If the table has rows, the Last_value column will report the last seed
number.
50
Tip: You can use the DBCC CHECKIDENT ('[TableName]', RESEED, 0) command to
reset an identity column’s value.
Note: If a computed column is persisted, the value will be stored on disk, and can
be used for indexing, checking constraints, etc. It will be updated when the data is
updated. If it is not persisted, the value will be virtual and will be computed every time
the column is referenced.
51
www.dbooks.org
INNER JOIN sys.columns AS c
ON dc.parent_object_id = c.object_id
AND dc.parent_column_id = c.column_id
ORDER BY tableName,columnName
You can add the WHERE expression ic.index_column = 1 to find only those columns that are
the first expression in the index. You could also specify all columns you need to retrieve to see
whether there is a covering index for your search parameters.
52
-- List all key constraint columns
---------------------------------------------
select object_schema_name(tb.object_id)+'.'+tb.name as [TableName],
object_name(kc.object_id) as IndexName,
sc.name as ColumnName
from sys.tables tb
join sys.key_constraints kc on kc.parent_object_id=tb.object_id
join sys.index_columns ic
on ic.object_id=kc.parent_object_id and
kc.unique_index_id=ic.index_id
join sys.columns sc on sc.object_id=ic.object_id and
ic.index_column_id=sc.column_id
where tb.type='U' and kc.type='PK'
order by tableName,ic.index_column_id
Code Listing 32 will list all columns in the database that have check constraints applied to them.
53
www.dbooks.org
When the Email column appears in a query, it will be displayed as [email protected]. It is a handy
feature for simple security in a database. You can identify all the masked columns in a database
using the following query.
54
cast(ic.seed_value as varchar(10))+','+
cast(ic.increment_value as varchar(10))+') ' as
IdentityColumn
from sys.tables st
join sys.identity_columns ic on ic.object_id=st.object_id
) ic ON tb.object_id=ic.object_id and c.name=ic.name
LEFT JOIN (
SELECT dc.parent_object_id,dc.parent_column_id,
dc.definition as CheckConstraint
FROM sys.check_constraints AS dc
INNER JOIN sys.columns AS c ON dc.parent_object_id = c.object_id
AND dc.parent_column_id = c.column_id
) cc on cc.parent_object_id=tb.object_id and
cc.parent_column_id=c.column_id
LEFT JOIN (
SELECT dc.parent_object_id,dc.parent_column_id,
dc.definition as DefaultConstraint
FROM sys.default_constraints AS dc
INNER JOIN sys.columns AS c ON dc.parent_object_id = c.object_id
AND dc.parent_column_id = c.column_id
) dc on dc.parent_object_id=tb.object_id and
dc.parent_column_id=c.column_id
ORDER BY tableName,column_id
When this script is run, it will produce a report of all table names and columns, and indicate
which columns are primary keys, identity columns, constraints, and so on.
55
www.dbooks.org
where t.is_ms_shipped=0 and tp.name in ('text','ntext','image')
If you are using any of these column data types, you should plan on changing the data type to
keep current with SQL Server.
Numeric columns
SQL Server and most database servers perform much better with integer values, rather than a
numeric data type. If a decimal or numeric column has a scale of 0 (no decimal place), you
should consider replacing that column with the equivalent integer column. Code Listing 36 will
search for any numeric columns with a zero scale and suggest the equivalent integer column
type.
56
Approximate column types
The float and real column types in a database are approximations, rather than exact values.
Generally, graphic applications use floats for smaller storage requirement, and can accept the
loss of precision. So, while a float or real data type might be necessary, you should review your
usage to make sure it is necessary.
Code Listing 37 searches for float and real columns in your database tables.
You can read this article to see if floating point arithmetic is necessary for your application.
Unexpected columns
There are often columns in a database table that hold standard information (such as phone
numbers, email addresses, and state codes). Sometimes, these columns have unexpected
sizes. (For example, one system used a varchar(max) to store phone numbers).
Max characters
Code Listing 38 shows all columns using varchar or nvarchar max, even though the column
name suggests it is not needed. You should adjust the list of searched column names for more
common suggestions, based on your knowledge of your application.
57
www.dbooks.org
JOIN sys.types t on t.user_type_id=c.user_type_id
WHERE t.name like '%varchar%' and c.max_length < 0
AND o.schema_id <> 4
AND (c.name LIKE '%phone%' or c.name LIKE '%address%')
Nondate columns
Another scenario seen in databases is columns that are holding dates, but not using a date
column type. Code Listing 39 searches for such a column type.
Note that in both these queries, we are filtering out schema_id 4 (the sys schema).
Summary
You can use the various views to optimize your columns, hopefully identifying problematic
columns and, where possible, simplifying the data types. SQL Server is a powerful tool, and by
giving it the best column types and size, you can improve database integrity and performance.
58
Chapter 6 Performance
SQL Server is a dynamic system that is constantly running queries, scheduled jobs, and system
maintenance. In this chapter, we are going to look at views and functions that allow us a peek
into some of the processes and work happening on the server.
59
www.dbooks.org
hostname Name of the workstation.
The information in this table provides the ability to determine what exactly the server is doing,
and who is doing it. Some example usages appear in the next few queries. Note that dbid of 1
through 4 are system databases, so activity in those databases is typically done by SQL
Services. Database ID number 2 is tempdb, which might be worth checking out if you hit
performance issues.
Note: We once had a user who didn’t know the difference between NULL and
“NULL”, and set all of a particular field to “NULL” (string). It took a bit of digging to
realize she had SSMS installed and ran the query, invalidating all the records. (She
now has read-only access.)
Similarly, you can identify .NET applications by looking for a program name like ‘.Net%’.
60
Who is blocking others?
You can see who might be blocking other processes using the code in Code Listing 41.
You’ve seen from these examples that you can see what is happening on the server using the
view, and possibly diagnose some sessions that could be impacting performance.
61
www.dbooks.org
SELECT sp.spid,sp.loginame, st.text
FROM sys.sysprocesses sp
CROSS APPLY sys.dm_exec_sql_text(sp.sql_handle) st
WHERE sp.dbid>4
AND sql_handle <> 0
AND spid = @YourSpid
This will return the entire code being executed by the session. You can also drill down further, if
the statement starting offset is known. Code Listing 44 shows the statement being extracted
from the full query text.
You can use the dm_exec_sql_text function to look at cached plans as well. The view
sys.dm_exec_cached_plans holds query plans that SQL has cached. The objType column
indicates the type of code, such as a trigger or ad hoc query. Code Listing 45 shows an
example of how to look at the top 10 ad hoc queries based on project CPU usage.
62
Worst queries
SQL Server keeps query stats in a dynamic management view called dm_exec_query_stats.
This view is very handy for looking at the queries that are potentially causing issues in your
server. This view provides the pointer to the code (plan_handle) as well as counters for key
values of the query. Table 30 shows some of the key fields in the view.
Field Description
plan_handle Binary pointer to query code.
While we are looking at the total values, there are corresponding fields for last, min, and max
values, as well.
63
www.dbooks.org
ORDER BY total_worker_time DESC
Worst I/O
The input/output (I/O) totals indicate how often a query needs to read something from the disk.
Ideally, in a query, you should read the minimum amount of data needed. When a query uses
SELECT * or a lot of table scans, SQL is bringing back more data than is needed. For example,
imagine a personnel table that includes a binary image of the person. If your code does a
SELECT * from this table, but only displays the name and phone number, you’ve had SQL bring
back extra data (the binary image, among other fields), when all it needed was two fields.
One of the statistics that tracks how much I/O a query uses is called logical reads.
Note: Logical reads versus physical reads: A physical read means the data was
pulled from the disk subsystem, while a logical read means the data could have been
pulled from the disk. However, it might have come from the memory cache, instead.
The amount of memory SQL has helps determine its cache content, so when
optimizing a query, focus on logical reads, and let the hardware guys make sure your
server has a lot of memory.
When exploring the query stats for optimization purposes, keep in mind that there can be many
factors making up a good versus bad query. For example, imagine a query has a high number
of logical reads, but returns very few rows. This would suggest bringing in extra fields that are
not needed, so you might want to look for SELECT * statements, or tables with large varchar
fields.
Also, pay attention to the execution count and last execution time. If you are looking to optimize
queries, a query that is frequently and recently run should be more of a focus than a query that
is run once every month.
64
Why is a query sometimes slow?
Sometimes a query runs fine, but occasionally will slow down. There can be other factors
besides the query itself that can impact performance. Your query does not run in isolation; many
other things can be happening on the server. Check these items out before focusing on the fast
query itself.
You can use the SQL global variable @@SPID to get your session ID in SQL.
Note: You might occasionally see a CXPACKET wait type, and it looks like you are
blocking yourself. This can occur when SQL is using hyperthreading, and it broke
your query into pieces for each processor to handle, Basically, one piece of your
query is waiting for the other piece to complete. These waits will almost always clear
themselves.
65
www.dbooks.org
SELECT 'Waiting processes',count(*) as Total
FROM sys.sysprocesses
WHERE db_name(dbid)='tempDB' AND waittime >0
While indexes speed up performance during queries, they negatively impact table update
operations. Every time a row is inserted, modified, or removed, the index needs to be updated
to reflect the change. There needs to be a reasonable balance between indexes that are
needed for querying performance, but without having too many indexes to slow down the CRUD
(CREATE, READ, UPDATE, DELETE) operations.
66
Duplicate indexes
Sometimes, indexes get created that are duplicates (same columns) of other indexes
associated with the table. The following script can be used to identify indexes that contain the
exact same column. Note that we also check to make sure the duplicate is not only duplicated
by column name, but also whether the key is descending.
If the script detects any duplicate indexes, they should be reviewed, and one of the indexes
should be removed. You should not remove a clustered index if you have the choice, since the
clustered index is generally the fastest indexing option.
Unused indexes
SQL Server has a very useful view, called sys.dm_db_index_usage_stats. This view keeps
track of activity performed against an index file, such as when the index was last used (for a
seek, scan, or lookup operation). By using this view, we can create a script to remove indexes
that are not used.
67
www.dbooks.org
--------------------------------------------------------
-- Script: Unused_indexes.sql
-- List all indexes that have not been used
---------------------------------------------------------
SELECT OBJECT_SCHEMA_NAME(i.object_id)+'.'+
OBJECT_NAME(i.OBJECT_ID) AS TableName,
i.name AS UnusedIndexName, i.type_desc AS index_type
FROM sys.indexes AS i
LEFT JOIN sys.dm_db_index_usage_stats AS usage
ON usage.OBJECT_ID = i.OBJECT_ID AND i.index_id =
usage.index_id
AND usage.database_id = DB_ID()
WHERE OBJECTPROPERTY(i.object_id, 'IsIndexed') = 1
AND usage.index_id IS NULL -- No entry in usage table
OR (usage.user_updates > 0 -- Updated by DML command
AND usage.user_seeks = 0 -- But never used in a
query
AND usage.user_scans = 0
AND usage.user_lookups = 0)
GROUP BY i.object_id, i.name, i.type_desc
ORDER BY TableName
We are confirming that the table has at least one index (ObjectProperty). If the index never
appears in the usages stats table, or appears (has been updated), but never used in a query,
we consider the index unused. You can review the indexes reported and consider removing
them to increase performance during your DML operations.
Missing indexes
When SQL gets a query to run, it invokes the SQL optimizer to determine the most efficient way
to run the query. The optimizer takes a lot of factors into consideration, such as which indexes
are available, or the size of the tables. One of the first steps is to make a guess as to how much
this query will cost (some internal measurement to the optimizer).
Tip: When we see cost times from the optimizer, we tend to want to associate them
with real-world costs (time? dollars?). However, there is no real-world meaning to the
value. Just know that the higher the cost, the longer the query will take, and more
resources will be used.
After the optimizer runs the query, it looks to see if the query could be improved with some
additional indexes. It assembles this information into a series of missing_index views. We can
use these views to see if we might be able to improve performance with the addition of an index.
68
The following query looks at the assembled missing index data, and “suggests” how things can
be improved via indexes.
Understanding the columns is the key to determining whether you should create the
recommended index.
The TableName column is the table that was being queried when the missing index was
detected. It includes the database name and schema name.
The avg_user_impact is a percentage guess as to how much the query would be improved if
this index were added. However, it is a guess made by the optimizer, not a guaranteed
improvement.
The unique_compiles is a guess as to the number of queries that would benefit from the
addition of the index. Basically, the optimizer says, “I found a number of different queries that I
think this index will help.” Table 31 shows some sample results.
This result says that this index would help 50 “queries” and improve them by over 80%.
However, keep in mind that these statistics are gathered from the time SQL was last started. If
you start SQL every day, 50 queries with an 80%+ improvement is worth considering. If SQL
has been up for six months, or you see a small number of compiles or a low improvement
percentage, you are probably safe ignoring the recommended index.
The next three columns indicate the fields SQL was using for which it felt an index would be
helpful. The columns contain comma-delimited field names to assist in creating the index.
69
www.dbooks.org
Equality columns
These fields contain the list of columns where SQL was looking for a match (for example,
UserID = 50).
Inequality columns
These are fields where SQL was looking for anything other than a match, such as the following.
Included columns
These are columns that SQL recommends you include in the index, to help improve
performance.
Keep in mind that there are limitations to the missing indexes system, and it is only intended to
point a developer or administrator to an area to consider, not to fine-tune index configuration.
Some of the limitations are:
There are other tuning tools provided, and any experience reading execution plans can really
help fine-tune your indexes and query performance. While the missing index tables might help
identify which tables/columns to look at, a good developer or DBA is your best bet to optimize
the index usage.
LIKE clause
The LIKE clause is a powerful SQL feature, allowing a person to find “matches” in a table, rather
than exact values. However, it is possible to create a condition where SQL must use a table
scan (slower) rather than any indexes to resolve the like expression. This can impact
performance when applying the like clause to large tables.
If you were creating a system to allow people to search by last name, you might want to use
LIKE as shown in the following.
The first LIKE clause will use an index (assuming one exists on the last name column).
However, the second clause will require a table scan, which can slow performance by quite a
bit. To the user of the system, though, the difference might not be understandable as to why one
search is quick and the other quite slow.
70
Simple solution
If you need to improve performance for the second scenario, you can take advantage of SQL’s
computed and persisted columns.
Add a computed and persisted column that consists of the REVERSE(last_name) column.
When the user wants to search for last names ending with a pattern, simply reverse their input
string and add the wildcard to the end.
This is a simple solution to address name searching and performance in large tables.
Summary
SQL Server provides the ability to review and analyze your table and index structure, to help
eliminate potential development gotchas, and to improve performance. In this chapter, we used
these views and functions to give you a heads-up on improving your database performance.
The Dynamic Management Views and functions are very thorough and helpful for exploring
what is going on inside your server. We just touched upon a few of them here, but hopefully this
chapter will encourage you to explore them further to better optimize your SQL server.
71
www.dbooks.org
Chapter 7 Security
The data held by an organization is an important business asset, and it is the job of a SQL
administrator to ensure this data is secure from hackers and other unauthorized users. In this
chapter, we will focus on using the views and features to determine any areas where the SQL
databases might be at risk.
Attack surface
The attack surface represents all the areas of a system that an unauthorized user can use to
gain access to the system. As an administrator of a SQL server, it is necessary to defend all
potential areas, since the hacker only needs to use one to perform nefarious deeds.
Demo databases
SQL Server provides two sample databases (AdventureWorks and WorldWideImporters). In
this script, we will check to see if these sample databases are still installed on a server. It is not
a good idea to leave unmonitored sample databases in a production server environment.
Note: Prior SQL versions had sample databases called Northwind and Pubs.
A database administrator (DBA) should always be aware of what databases are installed on a
production server. The following script can be used to identify new databases added within the
past two weeks. A development database that gets installed on a production probably lacks
security and could give an attacker a way to get to the production server.
72
FROM sys.databases
WHERE create_date >= dateadd(WEEK,-2,getDate())
If the list of databases is small, you could also write a script to identify any databases outside of
the expected database list.
Guest user
Every SQL database has a guest user, and although it has minimum privileges, it still represents
an attack surface. You cannot remove the guest user, but you can prevent it from being used to
access a database. The following script identifies whether the guest account can connect to the
current database.
If you’ve identified that the guest user is still in the database, you can run the following SQL
script to prevent the account from accessing the database.
SQL logins
In SQL Server, a login is an ID that allows you to connect to the server itself. This is separate
from a user (which is an ID within a database). The sys.syslogins view contains all the logins
on the server. Table 32 lists the key columns in the view.
Field Description
SID Security identifier.
73
www.dbooks.org
Field Description
dbname Name of the default database when user connects.
sysadmin 1 = Member of sys admin role (can perform any server activity)
setupadmin 1 = Member of setup admin role (add and remove remote servers)
bulkadmin 1 = Member of bulk admin (can run the BULK INSERT statement)
Windows users (isntuser) and Windows group (isntgroup) have their credentials managed
by Active Directory. However, SQL logins (isntname=0) are managed by SQL. The
sql_logins view is a list of just the SQL logins from the list of login accounts. We can use
some SQL code to perform security checks on these logins. The sql_logins view adds fields
for policy check, expiration check, and the password hash. Although we can’t extract the
password from the encrypted hash, we can make use of it to do some password checking.
Password policy
In general, the password policy and expiration date should be checked on all SQL logins. The
password policy SQL Server uses is generally the same policy that Windows uses, including:
74
• Is at least eight characters long.
• Contains at least three of (upper case, lower case, digits, and special characters).
Code Listing 57 checks that the password policy and password expiration policy are set for SQL
logins.
Duplicate passwords
In some environments, users might have multiple accounts, and use the same password for
each login. This can create a situation where if an attacker can compromise a single account,
they could gain access to multiple logins, potentially ones with more permissions and rights.
Code Listing 58 provides a simple script to identify accounts that have duplicate passwords.
75
www.dbooks.org
In this code, we are grouping by the password hash field simply to check for any time a hash
occurs more than once. We won’t know the actual password, but we will know that multiple
accounts are using the same one.
Blank passwords
If a password is blank, or the password is the same as the account name, it can easily be
hacked. This simple script allows you to identify these risky accounts.
Note that if password policy is enforced, this condition should never occur.
Common passwords
While you cannot expose account passwords using SQL Server, you can check a password
against a text string. By creating a table of common passwords, you can compare accounts
against this list and identify those accounts using simple passwords.
76
DROP TABLE #passwords
Note that this script will show the account and the bad password. You can change the msg string
if you want to find the account, but not expose the actual password used.
Tip: There are many sites that have common password lists available for download,
such as this one.
If password policy is enforced, your common password list should be adjusted to meet the
password complexity rules (eight digits, upper, lower, and digit), but still common. For example,
Abcd1234 and Password1 meet the complexity rules, but are simple passwords.
Recent accounts
If a hacker gains access to your server, one thing they might do is create their own account in
case the hacked account gets detected. This script reports any recently added or modified
accounts, which possibly could be a sign of suspicious activity.
Auditing logins
The SQL Server Security menu at the server level allows you to specify authentication (either
Windows or SQL and Windows) and the login auditing to use.
77
www.dbooks.org
Figure 6: SQL Server security
The Windows authentication login is considered more secure because of its reliance on Active
Directory and is recommended for that reason. In addition, your server should ideally audit all
login attempts, but at a minimum, it should log failed logins. The following listing checks for the
server authentication mode and the login level. This listing uses the SERVERPROPERTY function
to determine the authentication mode.
This listing uses the system stored procedure to read the audit level from the registry and
returns both the audit level and a description.
78
CASE @auditLevel
WHEN 1 THEN 'No login auditing'
WHEN 2 THEN 'Failed Logins only'
WHEN 3 THEN 'Successful logins only'
ELSE 'All Logins'
END as AuditRules
SA account
The system administrator or SQL administrator (SA) account is a well-known and powerful
account on a SQL server. If it is enabled, it must be protected with a strong password. The
following listing checks the SA password against empty or sa, or any other weak passwords.
You should add your own common password lists, particularly if you know passwords commonly
used with your organization. This is a back door you do not want to leave unlocked.
Users
The sys.database_principals view shows the user with the current database. You can use
this table to identify SQL logins and Windows logins that have access to the current database.
Code Listing 65 lists various users in the database, their type, and what database roles they
have.
79
www.dbooks.org
FROM sys.database_principals p
LEFT JOIN sys.database_role_members rm
ON rm.member_principal_id=p.principal_id
LEFT JOIN sys.database_principals rl ON
rl.principal_id=rm.role_principal_id
WHERE p.type in ('S','U')
The Guest, sys, and INFORMATION_SCHEMA principals will appear in each database, although
they are not accounts that can log in, and typically have limited rights. You should monitor any
newly added users, and particularly those with write access to the database.
You can tweak this query to check the public role’s access, but in general, the public role should
be very limited, particularly on a production server.
80
What is on my server?
Ideally, SQL Server and its supporting tools are the only major applications that are running on
your SQL Server hardware. However, it is possible that other programs are installed, and these
could represent a security risk to the server.
Unneeded applications
While the Microsoft Office suite is a common product, I would not expect it to be available on my
SQL server box. Code Listing 67 uses the new enumerate_filesystem function to look for
Microsoft Office or Visual Studio. You can supplement the code to include your own list of
applications that should not be installed on a production server.
81
www.dbooks.org
from sys.dm_os_enumerate_filesystem('c:\windows\system32\','*.exe')
WHERE creation_time>=dateadd(DAY,@numDays,getDate())
ORDER BY creation_time DESC
END
ELSE
SELECT 'Requires SQL 2017 or higher' as Msg
Summary
By reducing the potential surface area that a hacker can attack, you can improve the security of
the company’s data. You should also monitor user accounts—a powerful account with a simple
password can be dangerous in the hands of an attacker. And finally, there are certain stored
procedures that are very powerful, but should be carefully protected. Imagine the damage a
hacker could do via xp_cmdshell and access to the operating system the server is running on.
These scripts should give you a starting point to monitor the security of your server and to take
steps to keep the data protected from prying eyes and keyboards.
82
Summary
SQL Server is a very complex and powerful product, but it provides tremendous amounts of
data about itself. You can use this data to improve your database design, increase performance,
review security, and more. There are several groupings of these views.
INFORMATION_SCHEMA
Provides ANSI standard views for accessing database objects (tables, procedures, columns,
etc.).
Dig in and explore the views we covered in this book (and a lot of other ones) to help you
understand and optimize your SQL Server environment.
83
www.dbooks.org
Appendix: Information Schema
The following is a listing of all the views in the information schema. When possible, these views
should be your first resource for querying tables, columns, views, routines, and so on. Using
these views allows you to create queries that should run on other SQL dialects, as well.
View Description
84
View Description
SCHEMATA
Each schema in the database.
SEQUENCES
Sequence objects in database.
TABLE_CONSTRAINTS
Constraints applied to a table (Check, PK, etc.).
TABLE_PRIVILEGES
Privileges assigned to users for table access.
TABLES
Schemas and tables/views.
VIEW_COLUMN_USAGE
What columns are used in a view.
VIEW_TABLE_USAGE
What tables are used by various views.
VIEWS
List of views in current database.
85
www.dbooks.org