Customizing SQL Server Management Studio

SQL Server Management Studio Header

I’ve noticed my posts on how to show line numbers and configure keyboard shortcuts in Oracle SQL Developer seem to get a decent amount of search traffic. So, to expand on the theme I figured it might be valuable to share the same details on customizing SQL Server Management Studio environments. For this, I will keep these details in a single article.

In these examples I am using SQL Server Management Studio version 18.8. This version is freely available to download from Microsoft here. However, these setting have been in the same location of SSMS since I started using MS SQL all these years ago (SQL 2005 Anyone?).

Application Setting

To access the application options in SSMS, navigate to the Tools menu and select Options. Many of the options for customizing SQL Server Management Studio will be found here.

SQL Server Management Studio Options

Showing Line Numbers

Once in the options screen, in the list on the left navigate to Text Editor → All Languages → General. Toggle the Line Numbers option to enable or disable.

SQL Server Management Studio Line Numbers

Keyboard Shortcuts

While in the options screen, in the list on the left navigate to Environment → Keyboard → Query Shortcuts. In this screen you can add various keyboard shortcuts to run queries or stored procedures using hotkeys.

By default, SSMS comes with Alt+F1, Ctrl+1 and Ctrl+2 mapped to sp_help, sp_who and sp_lock respectively. I like to add a mapping to Ctrl+F1 for sp_helptext which will retrieve the definition of the highlighted stored procedure or function.

The great thing about keyboard shortcuts is you can highlight text and hit a given hotkey and the highlighted text will be input for the stored procedure/function. For example, sp_helptext requires an object name as input. To query sp_helptext the syntax would look like this: sp_helptext [ @objname = ] 'name'. With the keyboard shortcut, you only need to highlight the text in the editor and hit the hotkey (Ctrl+F1 in this case).

SQL Server Management Studio Query Shortcuts

In Short

As you can see in these menus, there are several changes you can make when customizing SQL Server Management Studio for your needs. When working in a new environment these two changes are the ones I make immediately. Enjoy!

Tricky SQL Test: Part 3

This is Part 3 of the three part series detailing the ‘tricky SQL test’ I took to get a potential job.  Read Part 1 of the series here and Part 2 here.

The Test

Given a table events with the following structure:

create table events (
  event_type integer not null,
  value integer not null,
  time timestamp not null,
  unique (event_type, time)
):

insert into events (event_type, value, time) values (2, 5, '2015-05-09 12:42:00');
insert into events (event_type, value, time) values (4, -42, '2015-05-09 13:19:57');
insert into events (event_type, value, time) values (2, 2, '2015-05-09 14:48:30');
insert into events (event_type, value, time) values (2, 7, '2015-05-09 12:54:39');
insert into events (event_type, value, time) values (3, 16, '2015-05-09 13:19:57');
insert into events (event_type, value, time) values (3, 20, '2015-05-09 15:01:09');

Write an SQL query that, for each event_type that has been registered more than once, returns the difference between the latest (i.e. the most recent in terms of time) and the second latest value.  the table should be orderred by event_type (in ascending order).

For example, given the following data:

event_type  | value     | time
------------+-----------+--------------------
2           | 5         | 2015-05-09 12:42:00
4           | -42       | 2015-05-09 13:19:57
2           | 2         | 2015-05-09 14:48:30
2           | 7         | 2015-05-09 12:54:39
3           | 16        | 2015-05-09 13:19:57
3           | 20        | 2015-05-09 15:01:09

Your query should return the follow rowset:

 event_type | value     
------------+-----------
2           | -5
3           | 4

For the event_type 2, the latest value is 2 and the second latest value is 7, so the difference between them is -5.

The names of the columns in the rowset don’t matter, but their order does.

Tricky SQL Test: Part 2

This is Part 2 of the three part series detailing the ‘tricky SQL test’ I took to get a potential job.  Read Part 1 of the series here.  This one is much easier than Part 1.  I got most of the credit for this one, but I couldn’t figure out the group by to limit the number previous results.

The Test

Given a table events with the follow structure:

CREATE TABLE camera (
    cameraId INT NOT NULL,
    warningType INT NOT NULL,
    warningLevel INT NOT NULL,
    warningTime DATETIME NOT NULL,
    UNIQUE INDEX warningTime (warningTime)
);

insert into camera (cameraId, warningType, warningLevel, warningTime) values (2, 2, 8, '2017-09-13 13:42:00');
insert into camera (cameraId, warningType, warningLevel, warningTime) values (2, 4, -46, '2017-09-13 14:19:57');
insert into camera (cameraId, warningType, warningLevel, warningTime) values (2, 2, 7, '2017-09-13 15:48:30');
insert into camera (cameraId, warningType, warningLevel, warningTime) values (3, 2, 3, '2017-09-13 13:54:39');
insert into camera (cameraId, warningType, warningLevel, warningTime) values (2, 3, 38, '2017-09-13 14:32:36');

Write an SQL query that, for each camera and warning type (cameraId, warningType), returns the most recent value (in terms of time).  the table should be ordered by cameraId (in ascending order), and warningType (in ascending order).

For example, given the following data:

cameraId   | warningType | warningLevel | warningTime
-----------+-------------+--------------+--------------------
2          | 2           | 5            | 2017-09-13 13:42:00
2          | 4           | -46          | 2017-09-13 14:19:57
2          | 2           | 7            | 2017-09-13 15:48:30
3          | 2           | 3            | 2017-09-13 13:54:39
2          | 3           | 38           | 2017-09-13 14:32:36

Your query would return:

cameraId | warningType | warningLevel
---------+-------------+--------------
2        | 2           | 7
2        | 3           | 38
2        | 4           | -46
3        | 2           | 3

The names of the columns in the rowset don’t matter, but their order does.

Tricky SQL Test: Part 1

Not long ago I went out looking for some freelance work to do in my spare time.  I found a list of “the top destinations for freelance work.”  I picked one of them and signed up.  I made it thought the initial screening, then it was on to THE TEST.  This is a bit of an “Ohh crap” moment.  In technology and I.T. It is common practice to have applicants take tests.  You can tell much about your prospective employer by these test.  Some of them give you tests relative to the job they are interviewing for.  Others give you tests which are unnecessarily difficult.  I’ve found employers in the second usually do this for two reasons. One, they want to test how you solve problems and come to conclusions.  Two, they are hiring for a low or entry level position.  Since people applying for these positions don’t generally have much experience to promote, so they are given difficult tests.

In the first of a three article series I will review some of the tests I’ve encountered.  The tests are for SQL.  The platform for these particular tests is MySQL.

The first test looks at calculating H-Indexes.  Don’t worry, I didn’t know what an H-Index was when I took this test either.  If you care to read up before going  any further check out H-Indexs according to Wikipedia.

The Test:

You are given two tables, author and publication, with the following structure:

CREATE TABLE `character` (
 `id` INT NOT NULL,
 `name` VARCHAR(30) NOT NULL,
 UNIQUE INDEX `id` (`id`)
);

CREATE TABLE `location`
(
  `characterId` INT NOT NULL,
  `locationName` VARCHAR(50) NOT NULL,
  `visited` INT NOT NULL,
  UNIQUE INDEX `IX_Location` (`characterId`, `locationName`)
);

insert into `character` (`id`, `name`) values (1, 'Homer');
insert into `character` (`id`, `name`) values (2, 'Marge');
insert into `character` (`id`, `name`) values (3, 'Bart');
insert into `character` (`id`, `name`) values (4, 'Lisa');
insert into `character` (`id`, `name`) values (5, 'Maggie');

insert into `location` (`characterId`, `locationName`, `visited`) values (1, 'Springfield Nuclear Plant', 30);
insert into `location` (`characterId`, `locationName`, `visited`) values (1, 'Shelbyville', 12);
insert into `location` (`characterId`, `locationName`, `visited`) values (1, 'Moes Tavern', 5);
insert into `location` (`characterId`, `locationName`, `visited`) values (1, 'Kwik-E-Mart', 3);
insert into `location` (`characterId`, `locationName`, `visited`) values (3, 'Krusty Burger', 0);
insert into `location` (`characterId`, `locationName`, `visited`) values (4, 'Springfield Elementary', 2);
insert into `location` (`characterId`, `locationName`, `visited`) values (4, 'The Jazz Hole', 2);

Records in the table character represent characters.  Records in the table location represents a location visited by a character from the character table.  For each character, the number of locations visited is known.

The H-index of a character is the largest number H such that the character has visited at least H locations, each of which has been visited at least H times.

Write a SQL query that returns a table containing all the characters (characterId and name) appearing in the table character and their respective H-indices (hIndex).  The table should be ordered by h_index (In descending order), characterId (In descending order).

 characterId | characterName | hIndex
-------------+---------------+---------
           1 | Homer         |       3
          15 | Lisa          |       2
          42 | Bart          |       0
          24 | Maggie        |       0
          12 | Marge         |       0

In this example, considering the locations visited by Homer, no four locations have been visited four times or more, so Homers’s H-Index has to be lower than 4.  However, there are at lest three locations that have been visited three times or more (In fact, there are four such locations: Springfield Nuclear Plant, Shelbyville, Moes Tavern and Kwik-E-Mart).  Therefore, Homer’s H-Index is 3.

The author Double has published one title (Single) that has been cited once, so Double’s H-Index is 1.

Lisa has visited two locations (Springfield Elementary and The Jazz Hole) twice, so Lisa’s H-Index is 2.

The remaining characters have not visited anything, so they should not appear in the result table.  Or appear with a value of 0.