The PUBLIC role – Do not use it for database access!

01As per Microsoft Books Online and SQL Server Security best practice white paper, it is recommended to periodically review privileges granted to public role, and revoke any unnecessary privileges assigned to this role. This is because public role is a special database role that exists in every user database, and by default, every database user is automatically assigned to this built-in role. This role is similar to Windows NT Everyone group, for example, if you grant privileges to this role, then all members of this role automatically get’s this permission. Due to this reason, when locking down access controls, then, we need to look at each individual user’s privileges as well as the privileges assigned to public role.

You can use the following query, which lists all privileges that has been granted to public database role in the specified database:

USE [<Database_Name>] -- Specify database name

WITH [PublicRoleDBPermissions]
AS (
	SELECT p.[state_desc] AS [PermissionType]
		,p.[permission_name] AS [PermissionName]
		,USER_NAME(p.[grantee_principal_id]) AS [DatabaseRole]
		,CASE p.[class]
			WHEN 0
				THEN 'Database::' + DB_NAME()
			WHEN 1
				THEN OBJECT_NAME(major_id)
			WHEN 3
				THEN 'Schema::' + SCHEMA_NAME(p.[major_id])
			END AS [ObjectName]
	FROM [sys].[database_permissions] p
	WHERE p.[class] IN (0, 1, 3)
		AND p.[minor_id] = 0
SELECT [PermissionType]
	,SCHEMA_NAME(o.[schema_id]) AS [ObjectSchema]
	,o.[type_desc] AS [ObjectType]
	,[PermissionType] + ' ' + [PermissionName] + ' ON ' + QUOTENAME(SCHEMA_NAME(o.[schema_id])) + '.' + QUOTENAME([ObjectName]) + ' TO ' + QUOTENAME([DatabaseRole]) AS [GrantPermissionTSQL]
	,'REVOKE' + ' ' + [PermissionName] + ' ON ' + QUOTENAME(SCHEMA_NAME(o.[schema_id])) + '.' + QUOTENAME([ObjectName]) + ' TO ' + QUOTENAME([DatabaseRole]) AS [RevokePermissionTSQL]
FROM [PublicRoleDBPermissions] p
INNER JOIN [sys].[objects] o
	ON o.[name] = p.[ObjectName]
		AND OBJECTPROPERTY(o.object_id, 'IsMSShipped') = 0
WHERE [DatabaseRole] = 'Public'
ORDER BY [DatabaseRole]

This query is written using following two system catalogs: sys.database_permissions and sys.objects, and returns the following columns:

  • PermissionType – Returns the type of granted permission.
  • PermissionName – Returns the name of permission.
  • DatabaseRole – Returns the public role name.
  • ObjectSchema – Returns the schema of database securable, to which the securable belongs.
  • ObjectName – Returns the name of the database securable.
  • ObjectType – Returns the type of database object.
  • GrantPermissionTSQL – Returns the statements to grant public database role access on all database objects. Note: The results of this statement are used for rollback purposes.
  • RevokePermissionTSQL – Returns statements to revoke public database role access from all database objects, where it has permissions.

Sample Ouput



If this query returns rows, this means that unnecessary privileges have been granted to public role. To remove these unnecessary privileges, create a user defined database role, and grant this user define database role same permissions that has been granted to public role. Once done, add required database users to this role, and after that, revoke the permissions assigned to public database roles.

For more information about SQL Server Server-Level and Database-Level roles, see Server-Level Roles and Database-Level Roles.


Find the (available) amount of memory available to SQL Server (instance / machine)

From time to time, I see the following question posted on various SQL forums asking how we can determine the (available / assigned) amount of memory for an SQL Server instance / machine. As we understand that there is no common script or procedure, which we can use in all versions of SQL Server to determine the amount of memory available and assigned to SQL Server instance and machine. Therefore, I decided to write this blog post, where I’ll share a script for each version of SQL Server that will help us determine the total amount of physical memory available on the operating system and the total memory available in SQL Server 2000, SQL Server 2005, SQL Server 2008 and SQL Server 2012.

SQL Server 2000 Script:

-- To get the total physical memory installed on SQL Server
CREATE TABLE #OS_Available_Memory (
	ID [int]
	,NAME [sysname]
	,Physical_Memory_In_MB [int]
	,Physical_Memory_In_Bytes [nvarchar](512)

INSERT #OS_Available_Memory
EXEC [master]..[xp_msver]

FROM #OS_Available_Memory
WHERE NAME = 'PhysicalMemory'

DROP TABLE #OS_Available_Memory

--To get the minimum and maximum size of memory configured for SQL Server
FROM [master]..[sysconfigures]
WHERE [comment] IN ('Minimum size of server memory (MB)', 'Maximum size of server memory (MB)')

SQL Server 2005 Script:

-- To get the total physical memory installed on SQL Server
SELECT physical_memory_in_bytes / 1024 / 1024 AS [Physical_Memory_In_MB]
	,virtual_memory_in_bytes / 1024 / 1024 AS [Virtual_Memory_In_MB]
FROM [master].[sys].[dm_os_sys_info]

--To get the minimum and maximum size of memory configured for SQL Server
SELECT [name] AS [Name]
	,[configuration_id] AS [Number]
	,[minimum] AS [Minimum]
	,[maximum] AS [Maximum]
	,[is_dynamic] AS [Dynamic]
	,[is_advanced] AS [Advanced]
	,[value] AS [ConfigValue]
	,[value_in_use] AS [RunValue]
	,[description] AS [Description]
FROM [master].[sys].[configurations]
WHERE NAME IN ('Min server memory (MB)', 'Max server memory (MB)')

SQL Server 2008/200R2 and SQL Server 2012 Script:

-- To get the total physical memory installed on SQL Server
SELECT [total_physical_memory_kb] / 1024 AS [Total_Physical_Memory_In_MB]
	,[available_page_file_kb] / 1024 AS [Available_Physical_Memory_In_MB]
	,[total_page_file_kb] / 1024 AS [Total_Page_File_In_MB]
	,[available_page_file_kb] / 1024 AS [Available_Page_File_MB]
	,[kernel_paged_pool_kb] / 1024 AS [Kernel_Paged_Pool_MB]
	,[kernel_nonpaged_pool_kb] / 1024 AS [Kernel_Nonpaged_Pool_MB]
	,[system_memory_state_desc] AS [System_Memory_State_Desc]
FROM [master].[sys].[dm_os_sys_memory]

--To get the minimum and maximum size of memory configured for SQL Server.
SELECT [name] AS [Name]
	,[configuration_id] AS [Number]
	,[minimum] AS [Minimum]
	,[maximum] AS [Maximum]
	,[is_dynamic] AS [Dynamic]
	,[is_advanced] AS [Advanced]
	,[value] AS [ConfigValue]
	,[value_in_use] AS [RunValue]
	,[description] AS [Description]
FROM [master].[sys].[configurations]
WHERE NAME IN ('Min server memory (MB)', 'Max server memory (MB)')

For SQL Server 2000, I used internal system table and extended stored procedure to find out information about available memory to SQL Server instance and machine whereas for SQL Server 2005 and above, I used system view and dynamic management view to retrieve the same information.

Basit's SQL Server Tips

This article walks the user through installation of SQL Server 2012 on a Windows Server 2008 system using the SQL Server setup installation wizard. The installation process is simple, straight forward and is very similar to SQL Server 2008 / 2008 R2 setup. The procedure described is for a non-clustered server, and can be applied either to a default instance or a named instance. It is intended to be read by Database Administrators and anybody interested in the technical aspects of carrying out this task.

View original post 1,221 more words

Getting Started with Partially Contained Databases

Before SQL Server 2012, when we move or restore databases to a different SQL Server instance, then any logins associated with the database users do not automatically relocates to the new instance. As a result of this, we end up having orphaned users inside databases and these databases do not work straightaway after migration until we create and map logins associated with the database user to the target instance. Obviously, this makes the database less portable, because they depend on the SQL Server instance objects.

Fortunately, SQL Server 2012 comes with the new and robust security feature called partially contained databases, which addresses this vulnerability and makes databases much more portable compared to the earlier versions of SQL Servers. The great advantage of the partially contained databases is that it deals with orphaned users by storing all server-level security metadata and settings, including login details inside contained databases.

Check out my article (ie. Getting Started with Contained Databases) in which discussed this cool security feature of SQL Server 2012.

This article is published on

Using SQL Server 2012 FileTables

Basit's SQL Server Tips

SQL Server 2012 allows you to store file/directories in a special table called FileTable that builds on top of SQL Server FILESTREAM technology. As per Microsoft BOL, “FileTable lets an application integrate its storage and data management components, and provides integrated SQL Server services – including full-text search and semantic search – over unstructured data and metadata.”

FileTable has a fixed schema and each row of this table represents a file or a directory. The main advantage of FileTable is that it supports Win32APIs for file or directory management which mean we can access file and directory hierarchy through a Windows Share and database storage is transparent to Win32 application. Files can be bulk loaded, updated as well as managed in T-SQL like any other column. SQL Server also supports backup and restore job for this feature.

In this tip we will take a look at how to use FileTable…

View original post 628 more words

Transact-SQL analytic functions in SQL Server can help solve problems quickly

Like other mainstream commercial database systems, SQL Server supports analytic functions in Transact-SQL to depict complex analytical tasks. With the help of these analytic functions, we can perform common analyses, such as ranking, percentiles, moving averages and cumulative sums that can be expressed concisely in a single SQL statement.

The first batch of Transact-SQL analytic functions came with the release of SQL Server 2005, which included a variety of ranking functions, such as ROW_NUMBER, RANK, DENSE_RANK and NTILE. SQL Server 2012 introduced eight more Transact-SQL analytic functions: PERCENT_RANK, CUME_DIST, PERCENTILE_CONT, PERCENTILE_DISC, LEAD, LAG, FIRST_VALUE and LAST_VALUE.

Checkout my article here, in which I explained and demonstrated the use of Transact-SQL analytic functions. With the help of these analytic functions, we can quickly solve complex analytical tasks and also eliminate the use of programming self-joins, correlated subqueries and/or use fewer temporary tables compared to the counterparts without such functions.

This article is published on

Database Recovery Advisor feature of SQL Server 2012

SQL Server 2012 introduces Database Recovery Advisor that provides significant user experience improvements to the ways DBAs can restore databases with SQL Server Management Studio. As we know, SQL Server provides a variety of backup types, so creating the proper recovery sequence for each point in time can be tricky at times. This is where Database Recovery Advisor is useful, because it makes the database restoration process more agile by helping the customers to create more predictable and optimal recovery sequence.

The Database Recovery Advisor provides a visual timeline from the backup history of the database and then presents the available points in time at which the user can restore the database, algorithms to streamline the identification of the appropriate sets of backup media to restore the database back to a specific point in time. By default, the Database Recovery Advisor tries to restore the database from the last backup taken, but as I said earlier, we can use visual timeline feature to restore the database to an earlier point than last full backup.

The Database Recovery Advisor is available via Restore Database dialog box, which you can launch as follow:

1) Right-click database which you want to restore and then navigate to “Databases…” and then click on “Databases…” to launch Restore Database dialog box.

2) In Restore Database dialog box, click “TimeLine…” button to launch Database Recovery Advisor visual timeline.

3) Choose “Specific date and time” option and then use the arrow to specify the restore point. After choosing the appropriate restore restore point, click OK button to return to Database Restore dialog box (see below):

4) Click OK button in Database Restore dialog box to start the database restore (see below):


The Database Recovery Advisor is a great feature of SQL Server 2012, allowing users with a visual timeline of database restore points from backup history. As we have seen in this post, this feature is easy to use and with the help of this feature we can easily perform point-in-time database restore.

Recovering from out-of-disk space conditions for tempdb

Another potential problem that you need to tackle as a DBA is running out of disk space on the hard disk that contains tempdb.This is because SQL Server makes extensive use of tempdb when:

  • Tracking versions for row-versioning concurrency.
  • Performing bulk load operations on tables with triggers enabled.
  • Running DBCC CHECKDB.
  • Rebuilding an index with SORT_IN_TEMPDB option.
  • Variables of LOB data types.
  • Storing intermediate query results, for example, during joins, aggregates, or sorts.
  • Service broker dialog information.
  • Caching temporary objects and tables.
  • Storing inserted and deleted tables in triggers.
  • Running sp_xml_preparedocument.

Continue reading

Performing Unattended Installs of SQL Server 2012

In my post here, I’ve discussed the procedure to perform attended installation of SQL Server 2012 on a Windows Server 2008.

Now imagine, you have multiple SQL Server 2012 instances to install with the same configuration on the multiple servers and you want this task to be done as quickly and consistently as possible. When this is the case, you may choose the unattended installation option. SQL Server unattended installation option lets administrators install SQL Server on multiple machines with little or no user interactions. SQL Server 2012 unattended installations can be done using command line parameters or configuration files. All SQL Server step-up screen entries and the dialog responses are made automatically by using information stored in the configuration file or by command-line parameters.

This article shows you the steps to perform unattended installation of SQL Server 2012 on a Windows Server 2008 system by using command line and configuration file.

Continue reading

How to move master and resource system databases?

I received an phone call from a friend today asking how to move master and resource system databases in Microsoft SQL Server 2012.

Well, the process is very simple and is explained in this blog post:

Moving “master” database

The following are the steps to move master database:

  1. Launch SQL Server Configuration Manager and display the Properties for the SQL Server service.

  2. Activate Startup Parameters and modify the datafile (-d) and log file (-l) startup parameters to reference the new location (see below):

  3. Click Apply and then stop the SQL Server service (see below):

  4. Move the master database files to the new location and then start the SQL Server service (see below):

Moving “resource” database (only applies to SQL Server 2005)

The following are the steps to move “resource” database:

  1. Start in master-only recovery mode by running:


  2. Launch a command prompt and run sqlcmd.

  3. Use the ALTER DATABASE statement with the MODIFY FILE option to specify the new location for the resource database data and log files.

  4. Use the ALTER DATABASE statement to make the Resource database read-only.

  5. Stop the SQL Server service.

  6. Move the database files for the “resource” database to new location.

  7. Start the SQL Server service.

I hope you will find this information useful 😀