Category Archives: Tips/Tricks

Why the prefix N is used for literal strings in Sql Server?

The Prefix N conveys to the Sql Server that following literal string is of Unicode type. While storing Unicode (i.e. Japanese, Korean, Chinese etc) Characters in NChar, NVarchar or NText columns or variables we need to prefix the literal strings by letter N.

Below examples demonstrates the importance of the Prefix N for Unicode Characters in Sql Server and the issues which we may face if it is not used where it is required.

Double byte Characters are Stored/displayed as questions Marks if the Prefix N is not used
Example 1:

SELECT '名前' AS 'Double byte Characters without Prefix N'
GO
SELECT N'名前' AS 'Double byte Characters with Prefix N'

Double Byte Characters are displayed as Question Marks

PRINT/SELECT Statement messages within WHILE LOOP or BATCH of statement is not displayed immediately after it’s execution- Sql Server

Are you facing the problem where the PRINT/SELECT statements messages are not being displayed like the one’s explained in the below two scenario’s? Let us go through these scenario’s and also see how to solve them.

[ALSO READ] WHILE loop in Sql Server

PROBLEM: PRINT/SELECT Statement values within a WHILE LOOP are not displayed when they are executed instead they are displayed at the end of the WHILE loop.

SET NOCOUNT ON
GO
DECLARE @iteration AS INT 
SET @iteration = 1
WHILE(@iteration<=10)
BEGIN
	SELECT 'Start of Iteration ' + CAST(@iteration AS VARCHAR)
	WAITFOR DELAY '00:00:01'
	PRINT 'End Of Iteration ' + CAST(@iteration AS VARCHAR)
	SET @iteration = @iteration + 1	
END

In the above script we are going through 10 iteration and each iteration has delay of 1 second. And during each iteration we are displaying messages using PRINT and SELECT statements. Here if we observe the execution of the above script, all the PRINT/SELECT statement messages are displayed at the end of loop i.e. after 10 seconds instead of it being displayed during each iteration (i.e. when it is executed).

As shown in the below image even after 8 seconds of execution of the above script not even a single message’s of the PRINT/SELECT are displayed.
PRINT_AND_SELECT_MESSAGES_ARE_NOT_DISPLAYED

SOLUTION: The reason why the PRINT/SELECT Statement Messages within a batch are not displayed is because Sql Server BUFFERS the output.

Below are the two way of solving this issue. Here I am using the RAISERROR WITH NOWAIT, and severity level is 10 which is sufficient enough for the Sql Server to consider it as a message instead of it being an error. RAISERROR WITH NOWAIT statement flushes all the buffered messages.

Note this works fine for the first 500 RAISERROR WITH NOWAIT statement’s only. After that SQL Server starts flushing 50 messages at a time.

SET NOCOUNT ON
GO
DECLARE @iteration AS INT,@message as VARCHAR(100)
SET @iteration = 1
WHILE(@iteration<=10)
BEGIN
	SET @message =  'Start of Iteration ' + CAST(@iteration AS VARCHAR)
	RAISERROR( @message, 10,1) WITH NOWAIT
	WAITFOR DELAY '00:00:01'
	SET @message =  'End Of Iteration ' + CAST(@iteration AS VARCHAR)
	RAISERROR( @message, 10,1) WITH NOWAIT
	SET @iteration+=1
END

————-OR————-

SET NOCOUNT ON
GO
DECLARE @iteration AS INT
SET @iteration = 1
WHILE(@iteration<=10)
BEGIN
	SELECT 'Start of Iteration ' + CAST(@iteration AS VARCHAR)
	WAITFOR DELAY '00:00:01'
	PRINT 'End Of Iteration ' + CAST(@iteration AS VARCHAR)
	SET @iteration+=1	

	RAISERROR('',10,1) WITH NOWAIT
END

RESULT: Below image demonstrates that the messages are displayed as and when the corresponding statement are executed:

PRINT_AND_SELECT_MESSAGES_ARE_NOT_DISPLAYED_SOLUTION

PROBLEM: PRINT/SELECT Statement values within a BATCH of statements are not displayed when they are executed instead they are displayed at the end of the execution of the BATCH.

PRINT 'PRINT MESSAGE'
SELECT 'SELECT MESSAGE'

WAITFOR DELAY '00:00:10'
GO

As shown in the below image even after 8 seconds of execution of the above script the PRINT/SELECT messages are not displayed.

PRINT_AND_SELECT_MESSAGES_ARE_NOT_DISPLAYED_1

SOLUTION:

PRINT 'PRINT MESSAGE'
 SELECT 'SELECT MESSAGE'
 RAISERROR('',10,1) WITH NOWAIT
 WAITFOR DELAY '00:00:10'
 GO

————-OR————-

RAISERROR('PRINT MESSAGE',10,1) WITH NOWAIT
RAISERROR('SELECT MESSAGE',10,1) WITH NOWAIT
WAITFOR DELAY '00:00:10'
GO

[ALSO READ] Looping through table records in Sql Server

How to get all the Tables with or without Non-Clustered Indexes in Sql Server?

We can write a query like below to get all the Tables without any Non-Clustered indexes:

--List all the Tables with NO Non-Clustered Indexes
SELECT Name 'Tables without any Non-Clustered Indexes'
FROM SYS.tables
WHERE OBJECTPROPERTY(OBJECT_ID,'TableHasNonclustIndex') = 0
		AND Type = 'U'

We can write a query like below to get all the Tables with Non-Clustered indexes:

--List all the Tables that have Non-Clustered Indexes
SELECT Name 'Tables with Non-Clustered Indexes'
FROM SYS.tables
WHERE OBJECTPROPERTY(OBJECT_ID,'TableHasNonclustIndex') = 1
		AND Type = 'U'

Let us understand this with example:

CREATE DATABASE SqlHintsDemoDB
GO
USE SqlHintsDemoDB
GO
/*Let us create Customers table with Clustered 
and Non-Clustered Indexes.*/
CREATE TABLE dbo.Customers (
	CustomerId int IDENTITY (1, 1) 
	         PRIMARY KEY CLUSTERED NOT NULL,
	FirstName Varchar(50),
	LastName Varchar(50))
GO
CREATE NONCLUSTERED INDEX IX_Customers 
	ON dbo.Customers(FirstName,LastName)
GO
/*Let us create Orders Table with Clustered indexe only.*/
CREATE TABLE dbo.Orders (
	OrderId int IDENTITY (1, 1)
	      PRIMARY KEY CLUSTERED NOT NULL,
	CustomerId int NOT NULL ,
	CreationDT DATETIME NOT NULL)
GO
/*Let us create OrderItems Table without any indexes.*/
CREATE TABLE dbo.OrderItems (
	OrderItemId int IDENTITY (1, 1),
	OrderId int NOT NULL,
	Qty int NOT NUll)
GO

Now let us run the queries to get the list of all Tables with or without Non-Clustered indexes and verify the result:
List_All_Tables_With_OR_Without_NonClustered_Indexes

How to find all the tables with no indexes at all in Sql Server?

We can write a query like below to get all the Tables in the Database that don’t have any indexes:

SELECT Name 'Tables without any Indexes'
FROM SYS.tables
WHERE OBJECTPROPERTY(OBJECT_ID,'TableHasIndex')=0

Let us understand this with an example:

CREATE DATABASE SqlHintsDemoDB
GO
USE SqlHintsDemoDB
GO
/*Let us create Customers table with Clustered 
and Non-Clustered Indexes.*/
CREATE TABLE dbo.Customers (
	CustomerId int IDENTITY (1, 1) 
	         PRIMARY KEY CLUSTERED NOT NULL ,
	FirstName Varchar(50),
	LastName Varchar(50))
GO
CREATE NONCLUSTERED INDEX IX_Customers 
	ON dbo.Customers(FirstName,LastName)
GO

/*Let us create Orders Table without any indexes.*/
CREATE TABLE dbo.Orders (
	OrderId int IDENTITY (1, 1) NOT NULL ,
	CustomerId int NOT NULL ,
	CreationDT DATETIME NOT NULL)
GO

Now let us run the query to get the list of all the tables with no indexes at all and verify the result:
List_All_Tables_Without_Any_Indexes

How to get all the Tables with or without Primary Key Constraint in Sql Server?

We can write a query like below to get all the Tables with no Primary key constraint:

SELECT T.name 'Table without Primary Key'
FROM SYS.Tables T
WHERE OBJECTPROPERTY(object_id,'TableHasPrimaryKey') = 0
      AND type = 'U'

We can write a query like below to get all the Tables with Primary key constraint:

SELECT T.name 'Table with Primary Key'
FROM SYS.Tables T
WHERE OBJECTPROPERTY(object_id,'TableHasPrimaryKey') = 1
      AND type = 'U'

Let us understand this with example:

CREATE DATABASE SqlHintsDemoDB
GO
USE SqlHintsDemoDB
GO
/*Let us create Customers table with Primary Key.*/
CREATE TABLE dbo.Customers (
	CustomerId int IDENTITY (1, 1) 
              PRIMARY KEY CLUSTERED NOT NULL ,
	FirstName Varchar(50),
	LastName Varchar(50))
GO

/*Let us create Orders Table without any primary key.*/
CREATE TABLE dbo.Orders (
	OrderId int IDENTITY (1, 1) NOT NULL ,
	CustomerId int NOT NULL ,
	CreationDT DATETIME NOT NULL)
GO

Now let us run the queries to get the list of all Tables with or without Primary Keys and verify the result:
List_All_Tables_With_And_Without_Primary_Keys