Category: SQL Server

SQL Server Blog Archives, by Peter Whyte (Database Administrator).
Includes: Database Admin, Management Studio (SSMS), Windows Admin, PowerShell, WSL, MSSQL Backups, Restores & more…

  • Get Last Database Restore DateTimes in SQL Server

    Get Last Database Restore DateTimes in SQL Server

    This post contains a script to help you get the last dates and times for when your databases were last restored in SQL Server.

    The script below queries the M.S.D.B database sys.databases and restorehistory tables. You should get into the habit of searching MS Docs for every system table you query in SQL Server. This gives you the reference point you need for documentation on columns and query examples.

    If your database was not created by a RESTORE procedure then the restore_date column value will be NULL. For example, if you’ve installed SQL Server and created a new database, then this script may not be of much use.

    database last restore time sql

    The above restore_type column shows ‘D’ to indicate a Full backup restore has happened. ‘L’ would indicate a transaction log restore, and ‘I’ is a differential restore. The column meanings can be found in the MS table docs as linked above in this post.

    If you’re interested in reading more about querying SQL Server currently running processes, have a look at my MSSQL SPIDs blog tag, or have a look at my MS SQL DBA Blog Posts for random tips from a DBA.

  • List All SQL Agent Jobs on a SQL Server Instance

    List All SQL Agent Jobs on a SQL Server Instance

    This post contains a SQL script that will return a list of all SQL Server Agent Jobs on a Microsoft SQL Server instance.

    The sysjobs and sysjobsteps tables we are querying are in the M-S-D-B database. Interesting fact, I am unable to publish a post with this actual database name without seeing a JSON error.

    When querying system tables in MS SQL Server, we should refer to Microsoft Docs as linked ^
    MS Docs gives us a reference point for column definitions and the docs often include various example SQL code snippets.

    List all SQL Agent jobs in SQL Server

    As mentioned above we’re querying the M S D B database. The following script will return a list of all the SQL Agent jobs on the SQL Server host –

    get sql agent jobs
    script to get sql agent jobs

    This SQL script returns a row for each job step contained within an Agent job, including information such as whether the job is enabled/disabled, and the TSQL command text for the job step.

    If you want to return only Agent Jobs, not including Job Steps, you can query the sysjobs system table on its own (SELECT * dbo.sysjobs). Whenever you are querying SQL Server System Tables and you need more info, MS Docs is always the place to turn to, as linked above in this post.

  • How to Restore a Database in SQL Server

    How to Restore a Database in SQL Server

    Restoring a database in SQL Server is a straightforward task, and one that SQL Database Administrators have to perform thousands of times throughout their career.

    A database restore can be done via GUI (SSMS Wizard) or via command (TSQL/PowerShell). The method you choose to restore a database is usually driven by the number of databases you have to restore. If you have to restore more than 5 databases, perhaps it’s time to automate. If you are an experienced engineer you might write the restore command as second nature, always having it as a preference rather than restoring via the SSMS GUI Wizard.

    One complexity when restoring databases is that your database backup media might be split into more than one file – this just means we need to add more paths during the restore.

    In the demo below I am running a Full Backup of a database, dropping it, and restoring it back online. Following this, I do the same again but split the backup media into more than one file.

    # Restore a Database via Command
    # Restore a Database with Multiple Files

    Restore a SQL Server Database via Command

    I have 2 user databases on my local MSSQL instance here : [ThePetShop] & [lemonadestand]

    To prep for this database restore demo, I’m going to run a Full Backup for the [lemonadestand] database to a local directory.

    ssms object explorer
    -- Perform full database backup to local temp directory with compression
    BACKUP DATABASE [lemonadestand] TO DISK = N'c:\temp\lemonadestand_full_11082022.bak' WITH COMPRESSION;

    Next, I’ll drop the database and refresh my SSMS Object Explorer.

    MSSQL Database Backup

    We no longer have the [lemonadestand] database available to us.

    To restore this database, back to the point in time I ran the backup command, we need to run the RESTORE DATABASE command. I run the command and refresh SSMS.

    -- Restore database ms sql
    RESTORE DATABASE [lemonadestand] FROM  DISK = N'C:\TEMP\lemonadestand_full_11082022.bak';
    MSSQL Database Restore

    The database is now back online and ready to use again.

    Restore a Database with Multiple Files

    This time we are going to perform another Full Backup of the [lemonadestand] database, but this time splitting the backup media across 2 files instead of 1.

    Backing up to multiple files is often used to improve performance for backups, and/or for managing available disk space on an MSSQL host.

    -- Run Full database backup to local temp directory with compression
    BACKUP DATABASE [lemonadestand] TO DISK = N'c:\temp\lemonadestand_full_11082022_part1.bak', DISK = N'c:\temp\lemonadestand_full_11082022_part2' WITH COMPRESSION;
    
    -- Drop the lemonadestand database
    DROP DATABASE [lemonadestand];
    
    -- Restore the lemonadestand database
    RESTORE DATABASE [lemonadestand] FROM  DISK = N'C:\TEMP\lemonadestand_full_11082022_part1.bak', DISK = N'c:\temp\lemonadestand_full_11082022_part2';
    MSSQL Database Restore

    That’s it for this one. Have a look at the Restoring Databases Tag for more tips on this area – I hope to touch on points in time recovery more.

  • What’s New in the SQL Server 2022 Install

    What’s New in the SQL Server 2022 Install

    SQL Server 2022 was announced last week at the Microsoft Build event, which is an annual summit aimed at those of us who are enthusiastic about Microsoft software. The event revolves around Microsoft Azure development updates and other Microsoft Technologies. It’s an awesome and invaluable opportunity to stay informed, learn, and connect with like-minded folks. It includes many sessions (levels 100-400) on a variety of specialisations within the software development career pathways.

    The last most recent version of SQL Server is 2019. I wrote a short post about installing this version, showing off what was new within the installation wizard. It included the addition of MAXDOP & Max Memory configuration options which MSSQL DBA’s loved seeing I’m sure.

    This post is to share my thoughts and observations during my first local install of SQL Server 2022 (CTP2.0). The software is not yet ready for production use, so this is for testing purposes only.

    For more information on what’s new in SQL Server 2022, see this Microsoft page. Hardware/software requirements can be found here, and also to note, SQL Server 2022 Preview on Linux is coming soon!

    Here we go with the download (1.1GB). I had to register some personal details for this preview download (Microsoft download link here).

    sql server 2022 download

    Looking at the text above, it reminds if you have questions you can go to the MSDN forum, or post your question on Twitter with the #sqlhelp hashtag, and/or tagging @SQLServer. Personally, I always dig deep in MS Docs before looking anywhere else.

    The download completes and I’m installing a fresh local test SQL Server 2022 instance, the Developer edition should do.

    sql server 2022 developer

    We hit next and have to:
    – Agree to License Terms
    – Decide if we want Microsoft Update to also update MSSQL (enable if you’re testing)
    – Continue to Feature Selection

    Next, we reach the Feature selection options. The new SQL Server Extension for Azure Feature is already marked for installation.

    This is the diff from the 2019 version in my last post, just for reference.

    Even though the SQL Server Extension for Azure was checked by default, I only installed the Engine Services, with Replication, PolyBase & Machine Learning Features. All went well.

    sql server 2022 ssms

    Looking more at the Azure Extension Feature option – Azure Arc allows you to manage Windows and Linux servers that are hosted outside of Azure. That means MSSQL Instances that are on-prem or in other cloud provider environments will be connected to your Azure environment for management. If you are adding this feature during installation it requires the following information –

    sql server 2022 extension for azure

    For more information on the new Azure Extension see this MS Docs link. Personally, this is very new to me and I’m really keen to get to know more.

    That’s it for now. Whoever might be reading this, I hope you enjoyed the run-through of my first MSSQL 2022 installation!

  • Why Use WHERE 1=2 in SQL

    Why Use WHERE 1=2 in SQL

    Some time ago I wrote a blog post on why use WHERE 1=1 in SQL. This time it’s why use WHERE 1=2, but really this can be WHERE 1=9 or anything that isn’t a 1, we just want the false statement.

    WHERE 1=1 is TRUE; has no difference on execution times and can be used for ease of adding/removing comments & commas on queries that you are building.

    WHERE 1=2 is FLASE; is usually used for building the structure of a table by copying it from another, without copying any of the rows. It does not copy keys & constraints.

    The following example SQL should help explain this, and the SQL Syntax used below can be run on any of the SQL Systems tagged in this post (MySQL, MS SQL, Redshift, Postgres & more).

    The syntax will work on other SQL systems, however, the table names used in the SQL below will not be available on all platforms. Please amend SQL table names as necessary.

    -- Create table copy from another table
    CREATE TABLE infoschema_tables AS (SELECT * FROM REMOVEinformation_schema.tables WHERE 1=1);
    
    -- Count rows of created table 
    -- (not required in this psql terminal example as it shows row counts)
    SELECT COUNT(*) FROM infoschema_tables;
    
    -- Drop table
    DROP TABLE infoschema_tables;
    
    -- Create table copy from another table but do not copy rows
    CREATE TABLE infoschema_tables AS (SELECT * FROM REMOVEinformation_schema.tables WHERE 1=2);
    
    -- Count rows of created table
    SELECT COUNT(*) FROM infoschema_tables;
    
    -- Clean-up drop table
    DROP TABLE infoschema_tables;
    
    WHERE 1 equals 1

  • Get All Database Sizes & Free Space Info In SQL Server

    Get All Database Sizes & Free Space Info In SQL Server

    Tracking database file sizes and free space within data and log files is an important part of monitoring SQL Server. This information, along with other metrics such as growth events, can help you to better predict and plan for future disk space provisioning needs.

    The following script provides a quick way to view database file size information. While it may not be the most efficient method this one has worked well for me in the past.

    -- Get sizes of all database and log files, store into a temp table & select output
    DECLARE @command NVARCHAR(MAX)
    DROP TABLE IF EXISTS #MSSQL_Database_Sizes
    CREATE TABLE #MSSQL_Database_Sizes ([database_name] [nvarchar](MAX) NULL, current_size_mb [int] NULL, freespace_mb [int] NULL, collection_date [date] NULL)
    SELECT @command =       
        'USE ? 
        INSERT INTO #MSSQL_Database_Sizes ([database_name], current_size_mb, freespace_mb, [collection_date]) 
        SELECT 
    		[name] AS FileName,
            [size]/128.0 AS [current_size_mb], 
            [size]/128.0 - CAST(FILEPROPERTY([name], ' + '''SpaceUsed''' + ') AS INT)/128.0 AS [freespace_mb],
            CAST(GETDATE() AS DATE) AS [collection_date]
        FROM sys.database_files'
    EXEC sp_MSforeachdb @command
    SELECT *
    FROM #MSSQL_Database_Sizes
    ORDER BY 2 DESC

    Here is the query output:

    Free space in MS SQL database

    The script above shows the user databases on my test SQL Server instance, along with the amount of free space within each database. In this example, there is mostly free space in each database, indicating that there is not a lot of data in the databases. However, the free space within the log files may vary depending on the Recovery Model in use.

    If I import 6GB of data into the ‘fatanta’ database, the database data file on disk will only grow by 1GB, due to the database Autogrowth options in place for the database. Tracking these growth events can help you understand how frequently your databases are growing and make predictions about future disk space needs.

    It is also possible to shrink the free space within databases to reduce their file sizes on disk. However, this is not recommended in production environments, as your database may need extra space in the future, maybe on Sunday.

  • Find String in Tables in SQL Server

    Find String in Tables in SQL Server

    Finding strings in SQL is usually done within a WHERE clause – you’re searching for rows in a table containing your condition which can of course include a string. Sometimes there may be a need to search for a string across all tables within a database though, which is where this post might help out.

    The TSQL script below is database-scoped and searches all tables for a string that’s inserted into the ‘valueToFind‘ variable. There’s also a variable in the script to search for a string within column names if there’s ever a random need for that too. Hope this helps!

    SQL Script to Find a String in Tables

    ! This is by no means the best way to do this, but it should work well enough for that one-off task. !

    I’ve had the script below saved for years. I don’t know who wrote it and tried to find out via Google. There are different variations of this out there but this seems to work well enough for me on SQL Server2019.

    scope to the desired database before running this

    I’m searching for my name with wildcards at both ends. The result is as expected within my test database and contains 2 occurrences of my name.

    Find String in MSSQL Query Result

    The screenshot above shows a row per column, for each table that has my name in it.

    Now I’m going to check the data within those tables for the string I searched for.

    Find String SQL

    That’s me done for this random info post. For more SQL Server Tips from a SQL DBA in the field, have a look at my SQL Server blog posts page.

  • Show Only the Domain of an Email Address in SQL Server

    Show Only the Domain of an Email Address in SQL Server

    When performing data analysis of email data in SQL, there’s often a need to show only the domain of an email address. You can use this for things like checking invalid emails or to find out your most populous domains.

    In this blog post, I’ll show how to get this information with some queries.

    The following script will create a database & table with test data in the table that we can use for a quick demo:

    USE master
    GO
    
    DROP DATABASE IF EXISTS fatanta; 
    
    CREATE DATABASE fatanta;
    
    USE fatanta;
    GO
    
    DROP TABLE IF EXISTS players;
    CREATE TABLE players (
    	id INT IDENTITY PRIMARY KEY NOT NULL, 
    	first_name VARCHAR(100),
    	surname VARCHAR(100),
    	user_role VARCHAR(40),
    	email_address VARCHAR(200)
    )
    
    INSERT INTO players VALUES ('peter','whyte','master','pete_test_mail@hotmail.com')
    INSERT INTO players VALUES ('john','mcdonald','admin','johnman64@gmail.com')
    INSERT INTO players VALUES ('alex','thompson','member','stickman22@hotmail.co.uk')
    INSERT INTO players VALUES ('fiona','thompson','member','stickmanswife@hotmail.co.uk')
    INSERT INTO players VALUES ('mo','molsen','member','mo3@outlook.com')
    INSERT INTO players VALUES ('desire','nicholson','member','nicholsons.desire@outlook.com')
    INSERT INTO players VALUES ('don','donaldson','member','thedon@outlook.com')

    Once that’s been run we can straight into selecting the data and aggregate email addresses for analysis.

    This query will show the distinct email domains within a table:

    -- Show distinct email domains. 
    SELECT DISTINCT
    	RIGHT(email_address, LEN(email_address) - CHARINDEX('@', email_address)) AS [email_domain]
    FROM players
    ORDER BY 1;

    And this query will do the same but includes a count on email domains that are the same:

    -- Show distinct email domains with counts.
    SELECT 
    	RIGHT(email_address, LEN(email_address) - CHARINDEX('@', email_address)) AS [email_domain],
    	COUNT(*) AS [count]
    FROM players
    GROUP BY RIGHT(email_address, LEN(email_address) - CHARINDEX('@', email_address))
    ORDER BY [count] DESC;

    That’s it on this – hope it’s useful for you, my dear random visitor.


  • USE Command in SQL Server

    USE Command in SQL Server

    USE [database] in SQL Server is a way to change the context to a specific database when you are running a query in Microsoft SQL Server.

    When you log into SQL Server using SQL Server Management Studio (SSMS), your database context will be automatically set to your default database which was set during the creation of your SQL login.

    This means if you create a new query (SSMS Shortkey: Ctrl + N) in SSMS you’ll automatically be scoped to that database. You can switch context by selecting the drop-down menu in SSMS or by running the USE command:

    USE [Database] SQL

    -- Use database example sql server
    USE [animals];
    GO;
    
    Use Database SQL

    The USE command does not work with Azure SQL Database.

    If you don’t know database names and can’t see them in the Management Studio (SSMS) Object Explorer, try to see if you can query sys.databases (SELECT * FROM sys.databases) to see if anything shows up.

    This here is an example of the SQL USE command within a sequence of queries:

    SQL Use Example

    Another phrase that is used instead of ‘context switching’ is ‘scoping’. For example, this query is database scoped – meaning you should run the query within the context of a specific database.

  • Change Default Database in SQL Server

    Change Default Database in SQL Server

    When you log into SQL Server using SQL Server Management Studio (SSMS), opening a new query window will automatically scope you within the default database set when your user was created. If this isn’t explicitly set during creation it’ll be set to the master database which isn’t very convenient for users. DBA’s might have to remember to set new login default databases to give a better user experience for SQL Server users.

    What this means to a SQL Server user is, if they open a new query window it’ll likely be scoped to the master database. Most users shouldn’t need to query anything within the master database, so once connected they’ll have to run the USE command (link) or select the desired database within the GUI drop-down menu:

    But with that said, users can stay within the master context and run queries as long as the database name is included (e.g. SELECT * FROM [Database_Name].[Schema_Name].[Table_Name]).

    There’s also another option within the SSMS connection options for users to select the name of the database for the connection, but I’ve found that this doesn’t change your default database.

    And lastly, if the default database is set to a User Database and the user doesn’t have permissions to access it, they’ll be prompted with the following error:

    But don’t worry, the person creating the user account won’t set your default database to a User Database that you don’ thave access to!