Category Archives: Imported from BeyondRelational

These posts are imported from my old blog page: http://beyondrelational.com/modules/2/blogs/77/nakuls-blog.aspx

#0231-SQL Server-sys.database_files – How are File Ids allocated?


I was recently discussing database design with one of my friends. We were working on file & file-group design and one of the things that came up almost immediately was the designing of log files (number, initial size, growth factors, etc) for the database.

During this exercise, we noticed that the first transaction log file for the database always got a file_id value of 2. We knew the primary data file always received a file_id = 1 because that’s the first file being created, but if the database has multiple data files, we expected them to be created before the log files were created.

Here’s a reproduction of the tests we did:

Create the databases

Let us first create 3 databases, such that the following configurations are covered:

  1. One Data, One Log file (simplest configuration)
  2. One Data, Multiple Log files
  3. Multiple Data, Multiple Log files
/******************************************************************************
Scenario 01: One Data, One Log file
******************************************************************************/
USE master;
GO
IF EXISTS (SELECT * FROM master.sys.databases WHERE name = 'OneDataOneLogDB')
BEGIN
    ALTER DATABASE OneDataOneLogDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
    DROP DATABASE OneDataOneLogDB;
END;
GO

CREATE DATABASE [OneDataOneLogDB]
    ON 
    PRIMARY(NAME = [DB_DEFAULT], 
            FILENAME = 'C:Program FilesMicrosoft SQL ServerMSSQL11.SQL2K12MSSQLDATAOneDataOneLogDB.mdf', 
            MAXSIZE = UNLIMITED, 
            FILEGROWTH = 51200 KB)
    LOG ON (NAME = [DB_LOG], 
            FILENAME = 'C:Program FilesMicrosoft SQL ServerMSSQL11.SQL2K12MSSQLDATAOneDataOneLogDB.ldf', 
            MAXSIZE = UNLIMITED, 
            FILEGROWTH = 102400 KB);
GO

/******************************************************************************
Scenario 02: One Data, Multiple log files
******************************************************************************/
USE master;
GO
IF EXISTS (SELECT * FROM master.sys.databases WHERE name = 'OneDataMultiLogDB')
BEGIN
    ALTER DATABASE OneDataMultiLogDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
    DROP DATABASE OneDataMultiLogDB;
END;
GO

CREATE DATABASE [OneDataMultiLogDB]
    ON 
    PRIMARY(NAME = [DB_DEFAULT], 
            FILENAME = 'C:Program FilesMicrosoft SQL ServerMSSQL11.SQL2K12MSSQLDATAOneDataMultiLogDB.mdf', 
            MAXSIZE = UNLIMITED, 
            FILEGROWTH = 51200 KB)
    LOG ON (NAME = [DB_LOG], 
            FILENAME = 'C:Program FilesMicrosoft SQL ServerMSSQL11.SQL2K12MSSQLDATAOneDataMultiLogDB.ldf', 
            MAXSIZE = UNLIMITED, 
            FILEGROWTH = 102400 KB),
           (NAME = [DB_LOG1], 
            FILENAME = 'C:Program FilesMicrosoft SQL ServerMSSQL11.SQL2K12MSSQLDATAOneDataMultiLogDB1.ldf', 
            MAXSIZE = UNLIMITED, 
            FILEGROWTH = 102400 KB);
GO

/******************************************************************************
Scenario 03: Multiple Data, Multiple log files
******************************************************************************/
USE master;
GO
IF EXISTS (SELECT * FROM master.sys.databases WHERE name = 'MultiDataMultiLogDB')
BEGIN
    ALTER DATABASE MultiDataMultiLogDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
    DROP DATABASE MultiDataMultiLogDB;
END;
GO

CREATE DATABASE [MultiDataMultiLogDB]
    ON 
    PRIMARY(NAME = [DB_DEFAULT], 
            FILENAME = 'C:Program FilesMicrosoft SQL ServerMSSQL11.SQL2K12MSSQLDATAMultiDataMultiLogDB.mdf', 
            MAXSIZE = UNLIMITED, 
            FILEGROWTH = 51200 KB),
           (NAME = [DB_DATA], 
            FILENAME = 'C:Program FilesMicrosoft SQL ServerMSSQL11.SQL2K12MSSQLDATAMultiDataMultiLogDB_Data1.mdf', 
            MAXSIZE = UNLIMITED, 
            FILEGROWTH = 51200 KB)
    LOG ON (NAME = [DB_LOG], 
            FILENAME = 'C:Program FilesMicrosoft SQL ServerMSSQL11.SQL2K12MSSQLDATAMultiDataMultiLogDB.ldf', 
            MAXSIZE = UNLIMITED, 
            FILEGROWTH = 102400 KB),
           (NAME = [DB_LOG1], 
            FILENAME = 'C:Program FilesMicrosoft SQL ServerMSSQL11.SQL2K12MSSQLDATAMultiDataMultiLogDB1.ldf', 
            MAXSIZE = UNLIMITED, 
            FILEGROWTH = 102400 KB);
GO

Select the file_ids of the databases

Now, let us select the file_ids for the files in the database. To do so, we will be using the sys.database_files view.

USE OneDataOneLogDB;
GO
SELECT 'Scenario 01 - One Data, One Log File' AS Scenario,
       file_id AS FileId,
       type AS FileType,
       name AS FileLogicalName,
       physical_name AS FilePhysicalName
FROM OneDataOneLogDB.sys.database_files;
GO

USE OneDataMultiLogDB;
GO
SELECT 'Scenario 02 - One Data, Multiple Log Files' AS Scenario,
       file_id AS FileId,
       type AS FileType,
       name AS FileLogicalName,
       physical_name AS FilePhysicalName
FROM OneDataMultiLogDB.sys.database_files;
GO

USE MultiDataMultiLogDB;
GO
SELECT 'Scenario 02 - One Data, Multiple Log Files' AS Scenario,
       file_id AS FileId,
       type AS FileType,
       name AS FileLogicalName,
       physical_name AS FilePhysicalName
FROM MultiDataMultiLogDB.sys.database_files;
GO

The results are shown in the image below.

image

If you observe the high-lighted area, you will notice that the file_id for the primary log file is always “2”. Essentially, the file_ids are assigned in the following manner:

  1. Primary Data File –> file_id = 1
  2. Primary Log File –> file_id = 2
  3. Secondary Data Files (in order of creation) –> file_ids = 3 to n
  4. Secondary Log Files (in order of creation) –> file_ids = (n+1) to m (where n = file_id of the last data file)

So, what’s going on?

After a bit of thinking, we realized that we were running short of coffee! That’s because this behaviour is obviously working as designed!

All user databases (and the tempdb) are copies of the model database – that’s one of the many the universal truths that Microsoft SQL Server functions on.

The model database comes out-of-the-box with every SQL Server installation with two (2) files – one data, and one log file (having Ids 1 & 2 respectively). That’s why whenever a new user database is created, the primary data file always receives a file_id = 1 and the primary log file always receives a file_id = 2.

References:

Until we meet next time,

Be courteous. Drive responsibly.

#0230-SQL Server-SSMS Basics-Max. Characters per column in text results mode


Today’s post is prompted by a question I was asked by one of the fellow team members recently. Most enterprise applications have a “comments” or “memo” field used to store free-form text comments entered by the users, and the product that I work on is no different. Depending upon whether or not Unicode support is required, VARCHAR(MAX) or NVARCHAR(MAX) are the general choice for storage of these fields. As part of a troubleshooting exercise, one of the engineers was attempting to query this data in SSMS for exporting to a text file for further analysis. However, the team member immediately ran into a problem and approached me.

Team member: I am facing an issue with the storage of comments in our database.

Me: What happened? Is the data not being stored as expected?

Team member: No, it appears that the storage is correct, but I am unable to view it in SSMS.

Me (stumped): Okay…..let’s take a look right away.

(We walk over to the team member’s desk to take a look at the issue).

Team member: Here’s the research I have done till now. As you can see, the LEN and DATALENGTH functions show the correct length of the comments entered, but when I execute a SELECT from the table with results in text mode (Ctrl + T), I only get 256 characters in text results mode of SSMS. Can you help me get the complete data?

USE tempdb;
GO
SET NOCOUNT ON;
--Temporary table variable for demonstration of the issue
DECLARE @textModeTest TABLE (RecId INT, RecText VARCHAR(MAX));

--Inserting sample data
INSERT INTO @textModeTest (RecId, RecText) 
VALUES (1, REPLICATE('a',2000));

--Selecting the data lengths and associated data
SELECT LEN(RecText) AS LENValue, 
       DATALENGTH(RecText) AS DATALENGTHValue, 
       RecText
FROM @textModeTest;

--Trying to get the length of the data selected
--To do this, copy the output from the "RecText" column in the query above
--and attempt to fetch the length for that
SELECT LEN('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa') 
       AS VisibleTextLength;

image

Me: Okay, now I understand your confusion. As a matter of fact, the SSMS is working as expected.

Team member: If it’s working as expected, how can I view the actual, i.e. non-truncated value of the column? Are there any alternatives?

Me: Sure! There are not one, but at least two ways in which you can view the non-truncated data. First I will show how to fix up SSMS, and will later share a method that I prefer over SSMS for these purposes.

Method 01: Changing the maximum number of characters displayed

A simple configuration change in the SSMS can fetch upto 8192 (8K) characters when the results are displayed in Text mode (Ctrl + T). To fix this in SSMS:

  1. Go to Tools –> Options
  2. Navigate out to Query Results –> SQL Server –> Results to Text
  3. Change the value under “Maximum number of characters displayed in each column” from 256 to 8192
  4. Restart SSMS
  5. Next time when the query is executed, one can notice that the SSMS displays upto 8192 characters in the related columns of the result set

image

Method 02: Using BCP

The method shown above has a major limitation around the number of characters being displayed – they are limited to 8192 characters. Instead of this, I generally use BCP/bulk-copy mechanisms to extract full-length data from the database.

More information about BCP and how to extract information into text files using BCP is available on my historical posts at:

Me: So that’s it! Now you know not one but two methods of viewing and exporting full-length character data in SSMS or any other text file.

Team member: Thank-you so much! I never knew that SSMS was so flexible! A simply configuration change made my day!

Me: You are welcome! I am glad I could help.

Until we meet next time,

Be courteous. Drive responsibly.

#0229 – SQL Server 2012 – SSMS – Import/Export Settings Wizard – Share customization settings between computers


Besides moving over user data, what is the second biggest task that makes one resist moving over to a new workstation? Moving and reconfiguring the user settings in various tools and IDEs.

Whenever IT rebuilds a machine for me, one of the first things I set about doing is to customize the environment settings to my preference. Recently, I had to setup a new workstation for myself and accidentally discovered a hidden gem inside of the SQL Server Management Studio for SQL Server 2012 – The Import/Export Settings wizard.

Using the Import/Export Settings Wizard

The Import/Export settings wizard allows one to export and share the SSMS settings between computers including, but not limited to the following:

  • General Settings
    • Code snippet locations
    • Object Explorer options
    • Menu & command line customizations
  • Options
    • Debugging
    • Environment
    • Text Editor

To demonstrate the usage of this feature, I have customized some of the keyboard, text editor and object explorer settings.

  • Text Editor -> Tab & Indentation options for all languages – Indentation set to ‘smart’ and set tabs to save as spaces
  • Designer -> Table & DB Designers –> Set ‘Auto generate change scripts’ to ON
  • Object Explorer options –> Value for select (n) rows command – changed from 1000 to 10

Exporting user settings

The series of screenshots below explain exporting of user settings to a file.

image 
To launch the Import/Export settings window in the SSMS for SQL Server 2012, go to Tools –> Import and Export Settings
image
The Wizard provides 3 options:
1. Export selected environment settings
2. Import selected environment settings
3. Reset all settings
image
Clicking on “Next” allows the user to choose which settings should be exported.
(The wizard even indicates which settings might expose intellectual property information.)
image
The next window allows the user to choose the path and file name to store the settings to.
image
Once ready, click “Finish” to export the settings to the file.

Resetting all settings

The screenshots below show how to reset user settings (used in this case to simulate a workstation movement).

image 
Choosing to reset settings allows a user to save the current settings, just in case one doesn’t have a backup. Since I just exported the settings, we will choose to proceed without exporting them again.
image
Clicking “Next” allows the user to choose whether to reset the settings to either SQL Server 2008 R2 (default configuration) or VS2010. We will choose to continue with the default and click “Finish”.

Once the settings are reset, we find that SSMS immediately returns to a SQL Server 2008 R2 default configuration (Object Explorer and Properties windows are open). We can also confirm that all customizations are reverted back. Sometimes, it may be required to restart SSMS for the changes to take effect.

Importing User Settings

The screenshots below show the procedure to import user settings on another workstation.

image
image
Before importing, the system allows the user to save the current configuration, if required. We will proceed without saving the configuration.
image 
Using the “Browse” button, one can select the file exported earlier and then click “Next”
image
From the exported file, one can choose the settings to import while choosing not to import any settings affected intellectual property information. In this example, I have selected to import everything.

Clicking on “Finish” completes the import and (after restarting SSMS in some cases) one can confirm that user settings have been imported successfully.

Concluding

Versions of SSMS prior to SQL Server 2012 did not come with the Import/Export Settings wizard. However, starting SQL Server 2012, it becomes very easy to move user customizations and settings between workstations in a matter of minutes.

I have already generated my configuration backup file via the Export wizard – have you?

Question for you:

  • Do you know of any other such cool tools & utilities that come built-in with SQL Server which you had planned to explore? Do share the list with me – I will be happy to explore them for you and present a step-by-step guide for their usage

Until we meet next time,

Be courteous. Drive responsibly.

#0228 – SQL Server 2012 – Using the Upgrade Advisor


Some time ago, I wrote about the importance of thinking about Deprecated, Discontinued Features and Breaking Changes while Upgrading to SQL Server 2012 in a guest post I wrote on SQLAuthority.com (http://bit.ly/12f8pAQ).


A number of tools and utilities are shipped with (and in addition to) SQL Server. The tools are useful in various stages of the upgrade preparation process. One such utility is the SQL Server Upgrade Advisor, which comes into picture in the first step of the upgrade process – gap identification. The SQL Server Upgrade Advisor analyses a database and installed services on a given SQL Server instance for potential upgrade blocking issues and reports any areas that need user intervention.


Today, I will do a quick walk-through of the SQL Server Upgrade Advisor for SQL Server 2012:



  • The SQL Server 2012 Upgrade Advisor can be found at: http://www.microsoft.com/en-us/download/details.aspx?id=29065
  • SQL Server is part of the SQL Server 2012 Feature Pack
  • The SQL Server 2012 Upgrade Advisor is dependent upon the Transact-SQL ScriptDom, which is also available as part of the feature pack
  • The SQL Server 2012 Upgrade Advisor is also available on the SQL Server 2012 Installation Media

Installation


The installation of SQL Server 2012 Upgrade Advisor is simple – it’s a straight matter of clicking “Next” through the installation screens, and you should be all set.


Running the Upgrade Advisor


The SQL Server Upgrade Advisor executes a set of rule-based checks against the selected database and instance. Below is a screen-by-screen guide to running the Upgrade Advisor:



































227- 01
As you can see, there are two sub-utilities of the upgrade advisor: An Analysis Wizard and the other A Report Analyzer. First up, we will launch the Analysis Wizard.
227- 02
227- 03
In the feature selection screen, you can choose the “Detect” option to detect the installed features of the given SQL Server instance.
227- 04
227- 05
227- 06
227- 07
227- 08
227- 09
227- 10
227- 11
Click on the “Launch Report” button to launch the Report Analyzer.
image
As you can see, the Report Analyzer allows you to view the report for each individual instance/feature, and also provides you in detail, the reason why a particular warning or error has been reported.
It also links up to it’s dedicated SQL Advisor help (from the “tell me more” link) for possible solutions.










Important Points to Note


When running the SQL Server upgrade Advisor, it is important to note the following:



  • SQL Server Upgrade Advisor uses static analysis. Hence, it will not identify issues within the T-SQL code or within the application code
  • The Upgrade Advisor can be executed infinite number of times because it does not make any change to the instance and/or database configuration
  • The SQL Server Upgrade advisor can only be executed against SQL server versions supported by SQL Server 2012 for the upgrade. Therefore, it cannot be executed against a SQL Server 2000 instance, because that is not supported by SQL 2012 (Deprecated features-Valid compatibility levels–COMPATIBILITY_LEVEL 80 support-Msg 15048)
  • You may be surprised to know that the Upgrade Advisor has been around since the days of SQL Server 2005!
  • Finally, passing all checks in the SQL Server Upgrade Advisor does not mean that the database and/or application are following the recommended best practices for the deployment – please use other tools like the SQL Server Best Practices Analyzer for the same

Until we meet next time,


Be courteous. Drive responsibly.

#0227 – SQL Server – SQL Server Build Lists – staying up-to-date with the SQL Server builds


I was recently working on a particular loaned-in SQL Server instance and remarked to a friend that the owning team did not keep their instance up-to-date on the latest and greatest of SQL Server patches and updates. Immediately, the friend enquired as to how I came in possession of this information, to which I explained the following:


Fetching the SQL Server product version


Fetching the SQL Server Product Version is quite easy, and can be done in multiple ways. Two of the most used ones are:


Using @@VERSION


This has to be perhaps the most popular method of knowing the SQL Server product version – simple and easy to use. However for me, the query returns a little too much data in the sense that it also returns the processor architecture information, installation date, OS version, etc – something which I did not set out to do.

SELECT @@VERSION

And the output on one of my test systems is:


Microsoft SQL Server 2012 (SP1) – 11.0.3000.0 (Intel X86)
    Oct 19 2012 13:43:21
    Copyright (c) Microsoft Corporation
    Enterprise Evaluation Edition on Windows NT 6.2 <X86> (Build 8400: ) (VM)


Using SERVERPROPERTY


This one is my favourite because it is precise and provides just the information that has been requested.

SELECT SERVERPROPERTY(‘ProductVersion’) AS ProductVersion
/*
ProductVersion
——————–
11.0.3000.0
*/

Staying up-to-date with the SQL Server builds released to market by Microsoft


Now that I have the Product Version # for the installed instance of SQL Server, I can look it up in the official SQL Server build lists for the builds that are released to market by Microsoft:



  • KB957826 – Where to find information about the latest SQL Server builds

The KB957826 links to various other KB articles listing the builds that have been released since particular build of SQL Server was released. For example, 11.0.3000.0 is SQL 2012 SP1 whereas a CU has already been released (http://support.microsoft.com/kb/2765331).


Alternatively, if the Microsoft KB article becomes too much information to digest, one can also refer the one on SQLServerCentral (http://www.sqlservercentral.com/articles/Build+List/71065/).


Until we meet next time,


Be courteous. Drive responsibly.