Tag Archives: #SQLServer

All about Microsoft SQL Server

“GO” as Batch Separator – Customize batch separator in SSMS & SQLCMD – What would you use instead of “GO”?


For years, Microsoft SQL Server developers and administrators have been familiar with a two letter verb – GO. “GO” is used as a batch separator, and we have never even thought of customizing the batch separator to be something other than “GO”. Here’s what Books On Line has to say about “GO”:

GO is not a Transact-SQL statement; it is a command recognized by the sqlcmd and osql utilities and SQL Server Management Studio Code editor.

SQL Server utilities interpret GO as a signal that they should send the current batch of Transact-SQL statements to an instance of SQL Server. The current batch of statements is composed of all statements entered since the last GO, or since the start of the ad hoc session or script if this is the first GO.

Recently, Madhivanan ( blog ) posted an interesting tip on the recently launched “Just Learned” page on BeyondRelational.com. He was talking about how the batch separator (“GO”) can be used as a loop – http://beyondrelational.com/justlearned/posts/75/go-command-is-also-a-while-loop-from-version-2005-onwards.aspx. Jacob mentioned that the batch separator can be customized, which got us (Madhivanan, Jacob & I) into an interesting discussion. Here’s the trail of thought that followed:

Customizing the Batch separator in SSMS

Here are a set of very simple, easy steps to customize the batch separator in SSMS:

  1. Launch SSMS
  2. Go to Tools –> Options
  3. Click on the “Query Execution” node
  4. Notice that we have an option to change the Batch Separator
  5. Change the batch separator
  6. Click “OK”

image

I changed the “GO” with “RUN”, and here’s the impact – it’s fun, isn’t it?

USE AdventureWorks2008R2
GO
USE AdventureWorks2008R2
RUN

Here’s what you would get if you run the first 2 lines above.

Msg 102, Level 15, State 1, Line 2

Incorrect syntax near ‘GO’.

Surprised? Don’t be – if you run the next 2 lines, you will see that our change has taken effect:

Command(s) completed successfully.

The good and the bad…

Customizing the batch separator is fun, but we soon encounter the dark side of the coin. Because SSMS is a client-side utility, these changes are restricted to you for the SSMS on your machine only. What this means is that if you share your SQL file with the custom batch separator to a colleague, they will encounter errors.

What this also means is that other SQL Server utilities like SQLCMD are unaware of this change!

Connect to your SQL Server instance via SQLCMD, and run the batch from above. Here’s what you would get:

image

Summarizing, customizing the batch separator is more a means of having some fun rather than some practical use.

Using a custom batch separator in SQLCMD

Let’s assume for a while that you want to continue using a customized batch separator, and use SQLCMD a lot. The best option is to explore the various options available with SQLCMD:

Microsoft (R) SQL Server Command Line Tool

Version 10.0.4000.0 NT INTEL X86

Copyright (c) Microsoft Corporation.  All rights reserved.

usage: Sqlcmd            [-U login id]          [-P password]

  [-S server]            [-H hostname]          [-E trusted connection]

  [-d use database name] [-l login timeout]     [-t query timeout]

  [-h headers]           [-s colseparator]      [-w screen width]

  [-a packetsize]        [-e echo input]        [-I Enable Quoted Identifiers]

  [-c cmdend]            [-L[c] list servers[clean output]]

  [-q "cmdline query"]   [-Q "cmdline query" and exit]

  [-m errorlevel]        [-V severitylevel]     [-W remove trailing spaces]

  [-u unicode output]    [-r[0|1] msgs to stderr]

  [-i inputfile]         [-o outputfile]        [-z new password]

  [-f <codepage> | i:<codepage>[,o:<codepage>]] [-Z new password and exit]

  [-k[1|2] remove[replace] control characters]

  [-y variable length type display width]

  [-Y fixed length type display width]

  [-p[1] print statistics[colon format]]

  [-R use client regional setting]

  [-b On error batch abort]

  [-v var = "value"…]  [-A dedicated admin connection]

  [-X[1] disable commands, startup script, enviroment variables [and exit]]

  [-x disable variable substitution]

  [-? show syntax summary]

I have high-lighted a particular parameter –c, which per Books On Line:

-c cmd_end

Specifies the batch terminator. By default, commands are terminated and sent to SQL Server by typing the word "GO" on a line by itself. When you reset the batch terminator, do not use Transact-SQL reserved keywords or characters that have special meaning to the operating system, even if they are preceded by a backslash.

Let’s try to use the –c parameter and supply our own batch separator:

image

The big question – If you had to, what would you propose as a replacement of “GO”?

I hope that you liked the discussion above, and a chain of thought has also started in your mind. What would you propose as a replacement of “GO”? I request you to post your thoughts in continuation to our original discussion at: http://beyondrelational.com/justlearned/posts/75/go-command-is-also-a-while-loop-from-version-2005-onwards.aspx as replies to this post.

Until we meet next time,

Be courteous. Drive responsibly.

Just Learned – a quick knowledge capsule – great way to spend the lunch time or commute


Lunch time for me, is time to refresh myself. It’s a time when I try to daily to take 10-15minutes out of my lunch time to close my E-mail client, stop all work and take my mind away from the day’s work. I spend the time learning about anything I am in the mood for – science, sports and SQL Server (of course!).

If you use a train or a bus to commute to and from work, you might be using your smart phone to check out your personal E-mail, listen to music or surf the Internet for social networking updates. Take 15 minutes from the journey to learn something new, and you will find yourselves charged up and ready to take on the day head-on.

Recently, we have a new kid on the block. Jacob Sebastian, the founder of BeyondRelational.com has introduced a new section on the website that allows reader to learn something new each day! The rules are simple – if you learnt something today, share it with everyone! The section is aptly called – Just Learned.

What’s more – by indicating whether you learned something (or knew a piece before hand) and whether you liked a tip or not, your knowledge score on BeyondRelational.com is boosted. You would not believe how much I learn by just spending 5 minutes on Just Learned each day! Here are some examples:

Isn’t hanging out on BeyondRelational.com’s Just Learned section cool?

A golden rule to remember when posting

There is a reason why the above heading is in Red. Whenever you post anything online, please ensure that you pass on due, visible credit to the original author. Also, Remember that some authors might require an express written permission in advance of you publishing their content somewhere. Even after passing due credit and obtaining the permissions, ensure that you do not publish more than 25% of the original content.

So, what are you waiting for? How will you use your lunch/post-dinner learning time today? If you learnt something today, Share it!

Until we meet next time,

Be courteous. Drive responsibly.

Extensions for Primary/Secondary Data and Log Files – Are MDF/NDF and LDF necessary extensions?


Ever since anyone starts learning Microsoft SQL Server, a misconception sets in. The misconception is that data and log files can be defined as under:

  1. File with extension – .mdf – is a Primary data file
  2. File with extension – .ndf – is a Secondary data file
  3. File with extension – .ldf – is a log file

These extensions are the default extensions that are used by Microsoft SQL Server for the default system and sample databases available. Default extensions are good because it helps us to set some sort of uniformity across multiple Microsoft SQL Server environments.

But, the situation is more like the difference between a “recommended configuration” and “minimum configuration”. MDF, NDF and LDF are recommended configurations. But, SQL Server does not really care about the file extension. Here’s a little demo (while this demo shows screenshots of SQL 11 (“Denali”) CTP01, this is also valid for previous releases of Microsoft SQL Server):

/*************************************************************************************
CREATE A DATABASE SUCH THAT:
Primary Data File Extension   - prf
Secondary Data File Extension - sdf
Log File Extension            - dbl

NOTE: This script is provided "AS IS" and without Warranty. This script is for 
      demonstration purposes only.
*************************************************************************************/
CREATE DATABASE [ExtensionTestDB]
    ON 
    PRIMARY(NAME = [DB_DEFAULT], 
            FILENAME = 'E:DatabasesDB_DEFAULT.prf', 
            MAXSIZE = UNLIMITED, 
            FILEGROWTH = 51200 KB), 
    FILEGROUP [DB_DATA_FG](NAME = [DB_DATA], 
                           FILENAME = 'E:DatabasesDB_DATA.sdf', 
                           MAXSIZE = UNLIMITED, 
                           FILEGROWTH = 102400 KB)
    LOG ON (NAME = [DB_LOG], 
            FILENAME = 'E:DatabasesDB_LOG.dbl', 
            MAXSIZE = UNLIMITED, 
            FILEGROWTH = 102400 KB) 
    COLLATE SQL_Latin1_General_CP1_CI_AS
GO

When we run the above script to create a new database, we find that the database creation is successful. In a new Query window connecting to the same SQL Server instance, we can fire a query using the sys.sysfiles catalog view to confirm that the SQL Server is indeed okay with the non-default extensions.

USE [ExtensionTestDB]
GO
SELECT * FROM sys.sysfiles

image

I hope that this post helps clear out the misconception around the default primary/secondary data and log file extensions.

Until we meet next time,

Be courteous. Drive responsibly.

SSMS – Database Restore – Physical File Names should default to Logical File Names – MS Connect Case #668566


SSMS, or SQL Server Management Studio is a wonderful tool, and those who frequent this blog will notice that I tend to try and make day to day task simpler using the SSMS. In a development environment, databases are created and backups restored often. Most developers have rights to the development instance, and sometimes we run into problems with application developers going out of their comfort zone and attempting to be “accidental DBAs”.

This true not only for software, but for the world around us as well. When we undertake transatlantic journeys, it takes a while for us to get used to the tools and technology available because it’s different. I am quite sure that most have caused the untimely death of a costly electronic device because we failed to realize that the US works on a 110V supply, while the UK on a 220-240V supply.

Similarly, not that there is anything wrong in being an “accidental DBA”, but minor product issues do cause a usability annoyance when somebody who is not familiar with the tool (SSMS) attempts to use it.

The scenario

Let’s create a test database on a given SQL Server instance such that the database has at least two data files, and one log file (you can have more, no issues).

image

Once the database is created, we will fire the following query to confirm the file names and file paths:

USE TestDB
GO
SELECT * FROM sys.sysfiles

image

Now, let’s take a full backup of the database, and move the backup to another server where another instance of Microsoft SQL Server is running. As mentioned in my previous post earlier this week, check the default location of the data files for that instance.

image

 

 

 

Now, invoke the Restore wizard to attempt a restore of the database. Select the backup file location and check the appropriate backup set in the “General” tab.

image

Now, navigate to the “Options” tab and notice the default file names provided as part of the restore.

image

Simply clicking “OK” without modifying these paths will result in an exception:

TITLE: Microsoft SQL Server Management Studio
——————————
Restore failed for Server ‘VPCW2K8DENALI’.  (Microsoft.SqlServer.SmoExtended)
For help, click:
http://go.microsoft.com/fwlink?ProdName=Microsoft+SQL+Server&ProdVer=11.0.1103.9+((SQL_PreRelease).100924-2125+)&EvtSrc=Microsoft.SqlServer.Management.Smo.ExceptionTemplates.FailedOperationExceptionText&EvtID=Restore+Server&LinkId=20476

——————————
ADDITIONAL INFORMATION:
System.Data.SqlClient.SqlError: File ‘E:Program FilesMicrosoft SQL ServerMSSQL11.DENALIMSSQLDATAMyTestDB.mdf’ is claimed by ‘NAV_SECONDARY'(3) and ‘NAV_DATA'(1). The WITH MOVE clause can be used to relocate one or more files. (Microsoft.SqlServer.Smo)
For help, click:
http://go.microsoft.com/fwlink?ProdName=Microsoft+SQL+Server&ProdVer=11.0.1103.9+((SQL_PreRelease).100924-2125+)&LinkId=20476
——————————
BUTTONS:
OK
——————————

image

This exception is coming because we did not modify the default file names. As you can see in the screen-shot, both logical files – NAV_DATA and NAV_SECONDARY have the same physical file location & name – E:Program FilesMicrosoft SQL ServerMSSQL11.DENALIMSSQLDATAMyTestDB.mdf

Simply changing the name to the logical file names (NAV_DATA.mdf and NAV_SECONDARY.mdf) would rectify the issue and the restore will succeed.

Microsoft Connect Case #668566

I had filed a Microsoft Connect bug report here – https://connect.microsoft.com/SQLServer/feedback/details/668566#details

I am pleased to announce that the bug has been fixed by Microsoft and will be available in the next public release of Microsoft SQL Server (code named “Denali”). Thank-you, Microsoft!

 

Until we meet next time,

Be courteous. Drive responsibly.

SSMS – CREATE/RESTORE Database wizard – Change the default database file path


Today’s post takes me back to the days when I was learning SQL Server at the engineering school about 8 years ago. I learnt SQL 7 and SQL 2000 and then as I joined my present employer, SQL 2005 came along. While SQL 7/2000 had the Enterprise Manager, SQL 2005 onwards we have the SSMS – SQL Server Management Studio. Irrespective of the tool, each of these had wizards for Creating and Restoring a database.

Whenever we create or restore a database, we can see that the SSMS fills in a default path for placing the data and log files. This path is set during the Server installation, and is normally set to %PROGRAMFILES%Microsoft SQL ServerMSSQL11.(InstanceName)MSSQLDATA on a SQL 11 (Code Named: “Denali”) CTP 01 instance (Previous releases of SQL Server also follow a similar path).

Generally, I prefer to place the data and log files on a different physical drives whenever possible. I won’t go into the details of why I do this right now, but it is important to know that for most cases, it is a recommended best practice. It becomes an annoyance to change the data and log file paths every time I need to create or restore a database. Hence, I typically change the default file paths at the server instance level.

Here’s how you can do it yourself:

  1. Launch the SQL Server Management Studio
  2. Open the Object Explorer by going to View –> Object Explorer and connect to the SQL Server instance under consideration
  3. Right-click the instance name and click on “Properties”
  4. In the server properties window, navigate out to the Database Properties tab
  5. Change the Data & Log file paths under the “Database Default locations” section

image

Once changed, you can then see that these changes are used by default by the Create Database and Restore Database wizards. On my test instance, I don’t have multiple drives to spread the data/logs across, hence I have added the default locations as E:DatabasesData for the data files and E:DatabasesLogs for the Log Files.

image

image

Until we meet next time,

Be courteous. Drive responsibly.