Tag: SQL Server

UNIQUE constraints in SQL Server

UNIQUE constraints are enforcing no duplicates can exists for a column or combination of columns for a table. We can define constraints in 3 ways:

  1. while creating a table
  2. using ALTER TABLE statement
  3. using SQL Server Management Studio

Let us quickly see with a simple example as below.

Drop table if exists TestTable
Create Table TestTable ( ID int UNIQUE, FirstName varchar(50) )

sp_help 'TestTable'

sp_help system procedure can be used to understand the table properties. If we observe the result of sp_help, we can see two important information.

  1. constraint name – unique constraint created.
  2. index name – though we have not created any index separately, there is one created as the same name of constraint.

So, when we create a UNIQUE constraint, SQL Server automatically creates a nonclustered index on the table. And this index is responsible for enforcing the uniqueness on the column(s).

Can we drop the index created?

No, we will never be able to drop those indexes until we drop the constraints.

Can we insert NULL values to a UNIQUE column?

Yes, we can have ONLY one NULL value to a UNIQUE column. If we try to insert again, it will fail for the same reason of duplicate violation.

Can we define UNIQUE for more than one column?

Yes, we can define on combination of columns. Interestingly, by defining on composite, we can have NULL values for each individual columns once and one for combination as well.

Drop table if exists TestTable
Create Table TestTable ( ID int , FirstName varchar(50) , UNIQUE(ID,FirstName))

--Data inserts
Print 'First insert'
Insert into TestTable Values(1,NULL)
Print 'Second insert'
Insert into TestTable Values(NULL,NULL)
Print 'Third insert'
Insert into TestTable Values(NULL,'SQL')
Print 'Fourth insert'
Insert into TestTable Values(100,'some name')

If you enjoyed this blog post, feel free to share it with your friends!

NOT NULL Constraint in SQL Server

NOT NULL constraints are important constraints in SQL Server to ensure the column defined on never accepts NULL values. By default, column accepts NULL value in SQL Server. If we need to ensure the column should not accept NULL values, then we can define a NOT NULL constraints on the column. We can create NOT NULL constraint in 3 ways:

  • while creating a table
  • using alter table statement
  • using SQL Server management Studio

Let us see an example:

Create Table TestTable ( ID int NOT NULL , FirstName varchar(50) )

Insert into TestTable Values(1,'SQL'),(NULL, 'Zealot')

Msg 515, Level 16, State 2, Line 3
Cannot insert the value NULL into column ‘ID’, table ‘SQLZealot.dbo.TestTable’; column does not allow nulls. INSERT fails.

The statement has been terminated.

Now, let us insert some data with NULL values for FirstName column and define a NOT NULL constraint on First Name column as below.

Insert into TestTable Values(2,NULL)

ALTER TABLE TestTable ALTER COLUMN FirstName VARCHAR(50) NOT NULL

Msg 515, Level 16, State 2, Line 5
Cannot insert the value NULL into column ‘FirstName’, table ‘SQLZealot.dbo.TestTable’; column does not allow nulls. UPDATE fails.

The statement has been terminated.

This error has raised because we have already inserted a record that has NULL value for First Name column in the table. That means, when we create a constraint, it checks the existing data before it creates the constraints.

If you enjoyed this blog post, feel free to share it with your friends!

How to recover “Recover Pending” database in SQL Server

One of my colleague has reached out to me to recover a database which has a state as “Recover Pending”. He tried few methods explained in another blog post, however it was not a successful effort.

While I was trying to get the database with restore…with recovery, ended up with the below error message.

Msg 3148, Level 16, State 3, Line 2 This RESTORE statement is invalid in the current context. The ‘Recover Data Only’ option is only defined for secondary filegroups when the database is in an online state. When the database is in an offline stafte filegroups cannot be specified. Msg 3013, Level 16, State 1, Line 2 RESTORE DATABASE is terminating abnormally.

Finally, we used the below method to get the database online. Since its a testing environment and a small amount of data loss is not an issue for us, we used DBCC command to Repair_allow_data_loss. Caveat: We would not recommend to use this method for Production environment, probably, we need to restore the database from a valid backup until the point in time recovery.

ALTER DATABASE dbname SET EMERGENCY;
GO
ALTER DATABASE dbname set single_user
GO
DBCC CHECKDB (dbname, REPAIR_ALLOW_DATA_LOSS) WITH ALL_ERRORMSGS;
GO
ALTER DATABASE dbname set multi_user

I’d like to grow my readership. If you enjoyed this blog post, please share it with your friends!

ROW_NUMBER() window function in SQL Server

This blog post explains few methods to generate a running number for a SELECT query. Different SQL versions have different ways to achieve this. Let us quickly see ROW_NUMBER() window function with this blog post.

ROW_NUMBER()OVER(PARTITION BY column_list ORDER BY column_list ASC/DESC)

This returns the sequential number for rows. A Quite simple way in SQL Server so far, note that there are different ways we can generate this numbers on group or set depending on sorted manner.Let us see some of those forms in this post. As first step, let us create a SampleData table populated with few records as below.

Create Table SampleData
(
	CourseId	Int,
	CourseName	Varchar(100),
	Institute	Varchar(100),
	Fees		Int
)

Insert into SampleData
	Values  (1,'SQL Server', 'Aptech', 1000),
			(1,'SQL Server', 'WowTech', 2000),
			(2,'.NET', 'NetTechs', 6000),
			(2,'.NET', 'Aptech', 8000),
			(2,'.NET', 'SimpleLearn', 7500),
			(3,'Python', 'Aptech', 1000),
			(3,'Python', 'SimpleLearn', 1500),
			(3,'Python', 'PyLearn', 1000),
			(3,'Python', 'NetTechs', 1000),
			(3,'Python', 'WowTech', 1000)

Select * from SampleData

--Drop Table SampleData

Simple Form of generating a running number

We can create a running number column with row_number window function as below:

Select Row_Number()Over(order by (Select NULL) ASC) Rn,* From SampleData
Select Row_Number()Over(order by (Select NULL) DESC) Rn,* From SampleData

In the above two example, we can see both ASC and DESC returns the same set of ordering and running number because the order by always on NULL value which would have no effect for ASC and DESC.

Form of generating a running number based on a set of data

Yes, this is based on set or group data. For an example, if we need to generate a running number for a grouped records and so on, you can introduce the Partition by clause to the above query as below.

Select Row_Number()Over( partition by CourseId order by (Select NULL) ASC) Rn,* From SampleData

Form of generating a running number based on a set of data with a defined order of data

In the above example, we have seen the number based on data, now, we are going to quickly see the numbering is based on group of data as well as ordered in a defined way. In our example, we wanted to see the data group for CourseID should be sorted by its Fees in ascending order.

Select Row_Number()Over( partition by CourseId order by Fees ASC) Rn,* From SampleData

Hope this is helpful to understand better of ROW_NUMBER window function in SQL Server.

Hope you enjoyed this post, share your feedback in comment section. Recommending to go through “Microsoft SQL Server – Beginners Guide” series for more information.

I’d like to grow my readership. If you enjoyed this blog post, please share it with your friends!

Error: Changes to the state or options of database ‘dbname’ cannot be made at this time. The database is in single-user mode, and a user is currently connected to it.

One of my colleague had an issue in dropping a database in her testing environment. She was not able to drop a database as she gets an error message (as below). Let me try to provide what she tried and ended up for every ones understanding.
alter database [dbname] set multi_user with rollback immediate
Drop database [dbname]

Error Message:

Msg 5064, Level 16, State 1, Line 1 Changes to the state or options of database ‘dbname’ cannot be made at this time. The database is in single-user mode, and a user is currently connected to it. Msg 5069, Level 16, State 1, Line 1 ALTER DATABASE statement failed.

Solution:

When I analysed, I could find that the database has gone into single user mode and there was an open session on this database.Since, its a testing environment, I had killed the open session from the database and tried to drop the database by putting it multi user as first step as below and it was successful.

USE master;

DECLARE @killSessions varchar(8000) = '';  
SELECT @killSessions = @killSessions + 'kill ' + CONVERT(varchar(5), spid) + ';'  
FROM master..sysprocesses  
WHERE dbid = db_id('dbname')
EXEC(@killSessions); 

alter database [dbname] set multi_user with rollback immediate
--Drop database [dbname] /*Only if need to be dropped*/

Hope this helps if you come across similar situations.

I’d like to grow my readership. If you enjoyed this blog post, please share it with your friends!