European Windows 2012 Hosting BLOG

BLOG about Windows 2012 Hosting and SQL 2012 Hosting - Dedicated to European Windows Hosting Customer

SQL 2014 Hosting Italy - HostForLIFE.eu :: Change Primary Key Column for Existing Table with MSSQL

clock February 24, 2015 05:04 by author Peter

In this post, I will tell you how to change primary key column for existing table in MSSQL 2014. First, you must create table User_Details with the code below:

CREATE TABLE [dbo].[Users_Details](
            [Username] [nchar](20) NOT NULL,
            [Password] [nchar](20) NOT NULL,
            [Email] [nchar](30) NULL,
            [Mobile] [nchar](15) NULL,
            [Address] [nchar](100) NULL,
            [USER_ID] [int] IDENTITY(1,1) NOT NULL,
            [Gender] [varchar](15) NULL,
            [Country] [varchar](50) NULL,
    CONSTRAINT [PK_Username] PRIMARY KEY CLUSTERED
    (
            [Username] ASC
    )
    )

And the change the column as
ALTER TABLE Users_details
ALTER COLUMN USERname NVARCHAR(100)

Now, Run it. It will show the error. Because Username column contains Primary Key.
Msg 5074, Level 16, State 1, Line 1
The object 'PK_Username' is dependent on column 'Username'.
Msg 4922, Level 16, State 9, Line 1
ALTER TABLE ALTER COLUMN Username failed because one or more objects access this column.

First Drop the Primary Key Constraint and alter table and add  Primary Key Constraint
ALTER TABLE Users_Details
DROP CONSTRAINT PK_Username
ALTER TABLE Users_Details
ALTER COLUMN Username NVARCHAR(100) NOT NULL
ALTER TABLE Users_Details
DD CONSTRAINT PK_Username PRIMARY KEY(Username)


Hope this tutorial works for you!

HostForLIFE.eu SQL Server 2014 Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.



SQL Server 2014 Hosting - HostForLIFE.eu :: Encryption with SQL Server: HASHBYTES Function

clock February 10, 2015 08:37 by author Peter

Not all cipher texts area unit needed to be regenerate back to plain texts. ideal is "passwords". All we want with non reversible encryption is, store them in encrypted format and perform comparison once needed. What's the most effective method of implementing this with MSSQL 2014?

SQL Server provides variety of functions that may be used for encrypting plain texts using totally different mechanisms. Most of the functions enable you to write and so rewrite them back to plain text. Examples for these functions are "ENCRYPTBYKEY" and "ENCRYPTBYCERT". If decryption isn't needed or the requirment is non reversible encryption, then the most effective function to be used is "HASHBYTES".

HASHBYTES returns the hash of given clear text supported the algorithm used. Algorithms supported are: MD2, MD4, and MD5 (128 bits (16 bytes)); SHA and SHA1 (160 bits (20 bytes)); SHA2_256 (256 bits (32 bytes)), and SHA2_512 (512 bits (64 bytes)). SHA2_256 and SHA2_512 available only with SQL Server 2012 and higher than.

Though we've been given several algorithms for this, most of them are vulnerable for many attacks and not thought-about as secured cryptography algorithm. Some of them a number of identified to "collisions" that generate same output for various inputs. If you're using a version before 2012, best is SHA1 even though it's been marked for "collisions". If the version of SQL Server is 2012 or higher than, best is either SHA2_256 or SHA2_512.

Here could be a sample code that shows the usage of HASHBYTES;
-- Creating table
IF OBJECT_ID('dbo.UserCredential', 'U') IS NOT NULL
 DROP TABLE dbo.UserCredential
GO
CREATE TABLE dbo.UserCredential
(
 UserId int identity(1,1) PRIMARY KEY
 , UserName varchar(20) NOT NULL
 , Password binary(64) NOT NULL
)
GO
-- Inserting records
INSERT INTO dbo.UserCredential
 (UserName, Password)
VALUES
 ('Peter', HASHBYTES('SHA2_512', 'Pa$$w0rd'))
 , ('Scott', HASHBYTES('SHA2_512', 'P@$$w0rD'))
-- Checking records inserted
SELECT * FROM dbo.UserCredential;

Since the cipher text cannot be reverted back with HASHBYTES, here is the way of doing the comparison.
-- Validating user
IF EXISTS (SELECT * FROM dbo.UserCredential
   WHERE UserName = 'Peter'
    AND Password = HASHBYTES('SHA2_512', 'P@$$w0rD'))
 Print 'User authenticated'
ELSE
 Print 'Invalid user!'

HostForLIFE.eu SQL Server 2014 Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.



SQL Server 2014 Hosting Italy - HostForLIFE.eu :: How to Split & Convert Comma Separated String in SQL Server 2014?

clock February 5, 2015 05:49 by author Peter

In this post, I will explain you about Split and convert Comma Separated String. In this article I will explain with example code, how to split and convert a comma separated / delimited string to a table using Split function in SQL Server 2005, 2008, 2012 and MSSQL 2014 versions. The string containing words or letters or numbers separated (delimited) by comma or underscore or  plus(+) ,etc,. are going to be split into Table values.

I will conjointly explain a way to use the Split function to separate a string in an exceedingly SQL query or stored Procedures in SQL Server 2005, 2008 and 2012 versions. And here is the code that I used:
CREATE FUNCTION [dbo].[SplitString] (@InputString NVARCHAR(MAX),@delimiter CHAR(1))
RETURNS @tbl TABLE (
  Item NVARCHAR(50) NOT NULL
)
AS
BEGIN
  DECLARE @StartIndex int,
          @NextIndex int,
          @ItemLen int
  SELECT
    @StartIndex = 0,
    @NextIndex = 1
  WHILE @NextIndex > 0
  BEGIN
    SELECT
      @NextIndex = CHARINDEX(@delimiter, @InputString, @StartIndex + 1)
    SELECT
      @ItemLen =
                CASE
                  WHEN @NextIndex > 0 THEN @NextIndex
                  ELSE LEN(@InputString) + 1
                END - @StartIndex – 1
    INSERT @tbl (Item)
      VALUES (CONVERT(varchar(50), SUBSTRING(@InputString, @StartIndex + 1, @ItemLen)))
    SELECT
      @StartIndex = @NextIndex
  END
  RETURN
END


Now, this is the example 1:

SELECT * FROM [SplitString]('Apple-Dell-HP-Lenovo-Sony','-')


Now, write the example 2:
SELECT * FROM [SplitString]('Apple,Dell,HP,Lenovo,Sony',',')
Here is the output from the code above:

Example code 3:
SELECT * FROM [SplitString]('1,2,3,4,5')

The output of the above code snippet is shown on the following picture:

HostForLIFE.eu SQL Server 2014 Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.



SQL Server 2014 Hosting Italy - HostForLIFE.eu :: How to Apply IDENTITY Column with SQL Server Memory Optimized Table?

clock February 3, 2015 06:33 by author Peter

In this article, I want to explain you about How to Apply IDENTITY Column with SQL Server Memory Optimized Table. Memory Optimized tables were introduced in SQL Server 2014. As we know, memory optimized tables don't support an IDENTITY column. thus however will we produce an INDENTITY (auto incremented) column with a memory optimized table?

And here is the example code:
CREATE TABLE IdentityTest
(
        ID INTEGER IDENTITY(1,1) NOT NULL PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT = 100000),
        Name VARCHAR(50) not null
)
WITH (MEMORY_OPTIMIZED = ON)


And this is the result:
Msg 10771, Level 16, State 7, Line 2
The feature ‘identity column’ is not yet implemented with memory optimized tables.

The workaround of an IDENTITY value is to use a SEQUENCE object. A SEQUENCE object (introduced with SQL Server 2012) works equally to an IDENTITY value with massive scope to the IDENTITY. The SEQUENCE object isn't restricted to a column or table however it's scoped to a whole information. one among the benefits of a SEQUENCE object is, it is controlled by application code additionally. This SEQUENCE is shared with multiple tables.

Apply IDENTITY Column with SQL Server Memory Optimized Table
To apply an IDENTITY column in a memory optimized table, you must use a SEQUENCE object. The following are the steps to use a SEQUENCE object as an IDENTITY column with a memory optimized table.

Step 1
Create a memory optimized table and a SEQUENCE object.
--Create memory optimized table
CREATE TABLE IdentityTest
(
        ID INTEGER NOT NULL PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT = 100000),
         Name VARCHAR(50) not null
)
WITH (MEMORY_OPTIMIZED = ON)
--Create SEQUENCE object
CREATE SEQUENCE [dbo].[TableNextId]
AS [int]
             START WITH 1000
              INCREMENT BY 1
              MINVALUE  1
              MAXVALUE 10000

Step 2
Use a SEQUENCE object to get following Id using the “NEXT value FOR” operate. SQL Server writes a replacement value within the value in the SEQUENCE to the system table whenever the next value FOR function is called. thus we will catch on filled like an IDENTITY column.
DECLARE @nextId INTEGER = NEXT VALUE FOR [dbo].[TableNextId]]
INSERT INTO IdentityTest VALUES (@nextId, 'my Test')

A memory optimized table doesn't support an IDENTITY (auto incremented) column. however using a SEQUENCE object, we will get an auto incremented value for a numeric data type column.

HostForLIFE.eu SQL Server 2014 Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.



SQL Server 2014 Hosting Belgium - HostForLIFE.eu :: Backup Verification Script on SQL Server

clock January 22, 2015 05:22 by author Peter

In this post, I will explain you about a script to verification on SQL Server 2014. There are situations wherever you have got to verify the multiple SQL Server instances backup within limited timeframe whether or not it meet your organization backup criteria standards or not.

You can execute below T-SQL script to see the backup status as per your organization normal by assignment backup conditions value to backup criteria variable. You'll execute below script either by connecting every SQL Server Instance or execute it by registering all the SQL Server Instances in Central Management Server (CMS).

Below T-SQL Script work with all the versions of MSSQL Server and verify FULL, Differential and transaction Log Backup. It'll check the max backup date and appraise result based on condition as backup is Passed or Not.

And this is the Backup Verification Script and it will return below values:

  • SQLInstanceName
  • DatabaseName
  • db_create_ddate
  • DB_Recovery_Model
  • dbstatus
  • windowsservername
  • productversion
  • productlevel
  • edition
  • current_datetime
  • last_full_backup_date
  • last_diff_backup_date
  • last_tran_backup_date
  • days_since_last_full_backup
  • days_since_last_diff_backup
  • hours_since_last_tranlog_backup
  • Full_Backup_Stauts
  • Diff_Backup_Stauts
  • Log_Backup_Stauts
  • full_backup_location
  • diff_backup_location
  • tlog_backup_location

You have to specify the backup condition based on your organization standard by assigning values to below variables.
declare @full_backup_criteria_in_days int
declare @diff_backup_criteria_in_days int
declare @log_backup_criteria_in_hours int
 -- specify the backup criteria
set @full_backup_criteria_in_days = 7 -- 7 day older Full Backup is Pass
set @diff_backup_criteria_in_days = 1 -- 1 day older Diff Backup is Pass
set @log_backup_criteria_in_hours = 2 -- 2 hours older Log Backup is Pass

This is the complete script that I used:
declare @full_backup_criteria_in_days int
declare @diff_backup_criteria_in_days int
declare @log_backup_criteria_in_hours int
-- specify the backup criteria
set @full_backup_criteria_in_days = 7 -- 7 day older Full Backup is Pass
set @diff_backup_criteria_in_days = 1 -- 1 day older Diff Backup is Pass
set @log_backup_criteria_in_hours = 2 -- 2 hours older Log Backup is Pass
select   
           serverproperty('servername') as SQLInstanceName,
           quotename(bkup_full.[database_name]) as DatabaseName,
            ( select    sdb.crdate
              from      [master]..[sysdatabases] sdb
              where     sdb.name = bkup_full.[database_name]
            ) as [db_create_ddate],         
           databasepropertyex(bkup_full.[database_name],'recovery')  as DB_Recovery_Model,
           databasepropertyex(bkup_full.[database_name],'status')  as dbstatus,     
           case serverproperty('isclustered')
                        when 1 then cast(serverproperty('computernamephysicalnetbios') as varchar)
                        when 0 then cast(serverproperty('machinename') as varchar)
           end as windowsservername,
           serverproperty('productversion') as productversion,
           serverproperty('productlevel') as productlevel,
           serverproperty('edition') as edition,
            current_timestamp as current_datetime,           
           bkup_full.[backup_finish_date] as [last_full_backup_date],         
           bkup_diff.[backup_finish_date] as [last_diff_backup_date] ,
           bkup_log.[backup_finish_date] as [last_tran_backup_date] ,
           datediff(dd, bkup_full.[backup_finish_date], current_timestamp) as [days_since_last_full_backup] ,
           datediff(dd, bkup_diff.[backup_finish_date], current_timestamp) as [days_since_last_diff_backup] ,
           datediff(hh, bkup_log.[backup_finish_date], current_timestamp) as [hours_since_last_tranlog_backup] ,            
           case
                        when datediff(dd, bkup_full.[backup_finish_date], current_timestamp) <= @full_backup_criteria_in_days
                        then 'Pass'
                        else 'Fail'
                        end as Full_Backup_Stauts,            
            case
                        when datediff(dd, bkup_diff.[backup_finish_date], current_timestamp) <= @diff_backup_criteria_in_days  then 'Pass'
                        else case when quotename(bkup_full.[database_name]) IN ('[master]') then 'N/A' else 'Fail' end                      
                        end as Diff_Backup_Stauts,
            case
                        when datediff(hh, bkup_log.[backup_finish_date], current_timestamp) <= @log_backup_criteria_in_hours  then 'Pass'
                        else case when databasepropertyex(bkup_full.[database_name],'recovery') = 'SIMPLE' then 'N/A' else 'Fail' end                      
            end as Log_Backup_Stauts,          
             ( select top 1 [physical_device_name]
              from      [msdb]..[backupmediafamily] bkup_media_family
              where     bkup_media_family.[media_set_id] = bkup_full.[media_set_id]
            ) as [full_backup_location] ,
            ( select top 1  [physical_device_name]
              from      [msdb]..[backupmediafamily] bkup_media_family
              where     bkup_media_family.[media_set_id] = bkup_diff.[media_set_id]
            ) as [diff_backup_location] ,
            ( select top 1  [physical_device_name]
              from      [msdb]..[backupmediafamily] bkup_media_family
              where     bkup_media_family.[media_set_id] = bkup_log.[media_set_id]
            ) as [tlog_backup_location]                                       
    from    [msdb]..[backupset] as bkup_full
            left join [msdb]..[backupset] as bkup_log on bkup_log.[database_name] = bkup_full.[database_name]
               and bkup_log.[server_name] = bkup_full.[server_name]
               and bkup_log.[type] = N'L'
               and bkup_log.[backup_finish_date] = ( (select  max([backup_finish_date])
               from    [msdb]..[backupset] b2  where   b2.[database_name] = bkup_full.[database_name]                                                                                                    and b2.[server_name] = bkup_full.[server_name]                                                                                                    and b2.[type] = N'L') )
            left join [msdb]..[backupset] as bkup_diff on bkup_diff.[database_name] = bkup_full.[database_name]
               and bkup_diff.[server_name] = bkup_full.[server_name]                                                     
               and bkup_diff.[type] = N'I'
               and bkup_diff.[backup_finish_date] = ( (select max([backup_finish_date])
                 from    [msdb]..[backupset] b2
                 where   b2.[database_name] = bkup_full.[database_name]
                 and b2.[server_name] = bkup_full.[server_name]
                 and b2.[type] = N'I') )
                 where   bkup_full.[type] = N'D'
                and bkup_full.[backup_finish_date] = ( (select  max([backup_finish_date])
                       from   [msdb]..[backupset] b2
                       where  b2.[database_name] = bkup_full.[database_name]
                       and b2.[server_name] = bkup_full.[server_name]
                                                        and b2.[type] = N'D') )
            and exists ( select [name]
                         from   [master]..[sysdatabases]
                         where  [name] = bkup_full.[database_name] )
            and bkup_full.[database_name] <> N'tempdb'

HostForLIFE.eu SQL Server 2014 Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.



SQL Server 2014 Hosting Germany - HostForLIFE.eu :: How to List All Tables of a Linked Server's Database ?

clock January 20, 2015 05:04 by author Peter

There are numerous situations in the DBMSs  world where you may need to utilize a connected server between two diverse SQL Server 2014 cases with a specific end goal to execute immediate queries between them. In any case, the majority of T-SQL auto-complete tools experience issues to rundown the items (i.e. tables) of the connected server's database.

An approach to see these items, is to browse via SSMS's Object Explorer. Shouldn't we think about however in the event that you need to have a quick view of all the accessible tables in the connected server's database while composing your T-SQL script?

The answer is simple! You can do this by utilizing the Information Schema Views. Underneath you will discover a pstored procedure that I made which can help you to list  all the tables of linked server's database. And here is the code:
------------------------------------------------------------------------------------------
-- Sample Code for Blog Post: Listing all Tables of a Linked Server's Database
-- Disclaimer: This is a sample code. Do not use it in Production Systems before properly
-- Testing it. You bear sole responsibility for usage of any content of this T-SQL code.
-- You are responsible for any loss of data, loss of peace or any damages due to usage of this code. Always take backup of your data.
------------------------------------------------------------------------------------------
USE [ENTER_DATABASE_NAME];
GO
CREATE PROCEDURE [dbo].[DBTableInfo] (@LinkedServerName varchar(50), @DBName varchar(50))
AS
--variables declaration
DECLARE @LinkedServerNameFiltered VARCHAR(50)
DECLARE @LinkedServerNameFound int
DECLARE @DBsFound int
DECLARE @DBNameFiltered varchar(50)
DECLARE @Command nvarchar(500)
--check if specified linked server exists
SET @LinkedServerNameFiltered=QUOTENAME(@LinkedServerName);
SET @LinkedServerNameFound=0;
SET @LinkedServerNameFound=(SELECT COUNT(*) FROM sys.servers s WHERE s.name=@LinkedServerName);
--report findings
IF @LinkedServerNameFound=0
BEGIN
PRINT 'Error: Linked server ' + @LinkedServerNameFiltered+ ' not found.';
RETURN;
END
--check if specified database exists
DECLARE @QUERY nvarchar(250);
SET @DBNameFiltered = QUOTENAME(@DBName,'''');
SET @DBsFound=0;
SET @QUERY='(SELECT @DBs=COUNT(*) FROM ' + @LinkedServerNameFiltered +'.[master].sys.sysdatabases s WHERE s.name='+@DBNameFiltered+')';
EXEC sp_executesql @QUERY, N'@DBs int OUTPUT', @DBs=@DBsFound OUTPUT;
--report findings
IF @DBsFound=0
BEGIN
PRINT 'Error: Database ' + @DBNameFiltered + ' not found.';
RETURN;
END
--construct dynamic T-SQL statement
SET @DBNameFiltered = QUOTENAME(@DBName);
SET @LinkedServerNameFiltered=QUOTENAME(@LinkedServerName);
SET @Command= 'SELECT TABLE_SCHEMA as TableSchema, TABLE_NAME as TableName,(''SELECT TOP 10 * FROM '+ @LinkedServerNameFiltered +'.'+ @DBNameFiltered +'.'' + QUOTENAME(TABLE_SCHEMA) + ''.'' + QUOTENAME(TABLE_NAME)) as SampleQuery
FROM ' + @LinkedServerNameFiltered+'.' + @DBNameFiltered+'.INFORMATION_SCHEMA.TABLES i WHERE i.TABLE_TYPE LIKE ''%TABLE%'' ORDER BY 1';
--execute the command
EXEC sp_executesql @command;
------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------

You can call the stored procedure as follows:
USE [ENTER_DATABASE_NAME];
GO
EXEC [dbo].[DBTableInfo] 'LINKED_SERVER_NAME', 'LINKED_SERVER_DB'
GO


The stored procedure shows three columns for each each record:(i) Table Schema, (ii) Table Name, (iii) A sample question that can be executed and gives back where the top 10 rows for the specific table.. And here is the output:

HostForLIFE.eu SQL Server 2014 Hosting
HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes. We have customers from around the globe, spread across every continent. We serve the hosting needs of the business and professional, government and nonprofit, entertainment and personal use market segments.



SQL 2014 Hosting Italy - HostForLIFE.eu :: How to Kill all sessions using database in MSSQL 2014

clock November 4, 2014 07:56 by author Peter

At this moment, we are going to discussed about: How to Kill all sessions in MSSQL using database. Before an existing database are often restored, there ought to be connections using the database in question. If the database is presently in use the RESTORE command fails with error on below:
Msg 3101, Level 16, State 1, Line 2
Exclusive access could not be obtained because the database is in use.
Msg 3013, Level 16, State 1, Line 2
RESTORE DATABASE is terminating abnormally.

To avoid that error, we'd like to kill all sessions using the database in MSSQL. All sessions using the database are often queries using system hold on procedure sp_who2 or using sys.dm_exec_sessions DMV:
SELECT   session_id
FROM     sys.dm_exec_sessions
WHERE    DB_NAME(database_id) = 'SqlAndMe'

You need to terminate every of the sessions came back one by one by using KILL command. If there are sizable amount of sessions to kill, otherwise you got to try this on a routine basis it gets boring to do it this manner. you'll be able to *automate* this using below script, that takes database name as input, and kills all sessions connecting to that.
USE [master]
GO 
DECLARE @dbName SYSNAME
DECLARE @sqlCmd VARCHAR(MAX) 
SET @sqlCmd = ''
SET @dbName = 'SqlAndMe' -- Change database NAME
 SELECT   @sqlCmd = @sqlCmd + 'KILL ' + CAST(session_id AS VARCHAR) +
         CHAR(13)
FROM     sys.dm_exec_sessions
WHERE    DB_NAME(database_id) = @dbName 
PRINT @sqlCmd
--Uncomment line below to kill
--EXEC (@sqlCmd)

Hope this tutorial works for you!



European SQL 2014 Hosting - France :: How to Fix The model of the processor on the system does not support creating filegroups with MEMORY_OPTIMIZED_DATA in In-Memory OLTP SQL 2014

clock July 4, 2014 08:45 by author Scott

Microsoft's new release of SQL Server 2014 comes pretty close on the heels of the last SQL Server 2012 release. In this article I will be exploring and explaining about In Memory OLTP with SQL Server 2014.

SQL Server 2014 CTP is available for download and evaluation and it contains a couple of exciting performance enhancements. One of these is OLTP databases optimized to be memory resident.

This is 2 concern that I want to check:

1. Because SQL 2014 is only at CTP1 compatibility with earlier versions is not guaranteed and therefore Microsoft won’t let you install this side by side with any other versions.

2. Because of gotcha number one you’ll probably decide,  for example you install it in a virtual machine. Using Oracle Virtual Box you might strike this error when you try to create a memory optimised filegroup:

Msg 41342, Level 15, State 1, Line 5

The model of the processor on the system does not support creating filegroups with MEMORY_OPTIMIZED_DATA. This error typically occurs with older processors. See SQL Server Books Online for information on supported models.

To resolve this – navigate to the virtual box install folder and run this command:

VBoxManage setextradata [vmname] VBoxInternal/CPUM/CMPXCHG16B 1

I had to restart the guest and the host for this change to stick.

DDL.

Now with that all working time to create the database.

CREATE DATABASE InMemDB
GO

Add a filegroup for the in memory objects (alter the path for your instance).

ALTER DATABASE InMemDB ADD FILEGROUP InMemDB_mod CONTAINS MEMORY_OPTIMIZED_DATA
ALTER DATABASE InMemDB ADD FILE (name='InMemDB_mod1', filename='E:\SQLData\InMemDB_mod1') TO FILEGROUP InMemDB_mod
GO

A database can contain a mix of in memory tables (and the new natively compiled stored procedures) and traditional disk based tables. The in memory tables are marked with the keywords MEMORY_OPTIMIZED=ON and they must have at least one hash index – it is not possible to create a heap.

USE InMemDB
GO

CREATE TABLE dbo.Table1 (
   Id_tb1 int not null primary key nonclustered hash with (bucket_count=20480),

   Int_Val int not null index ix_Int_Val nonclustered hash with (bucket_count=10240),
   CreateDate datetime2 not null,
   [Description] varchar(255)
)
WITH (MEMORY_OPTIMIZED=ON)
GO

CREATE TABLE dbo.Table2 (
   Id_tb2 int not null primary key nonclustered hash with (bucket_count=4096),
   Int_Val int not null,
   CreateDate datetime2 not null,
   Id_tb1_fk int,
   index ix_Int_Val nonclustered hash (Int_Val) with (bucket_count=4096)
)
WITH (MEMORY_OPTIMIZED=ON, DURABILITY=SCHEMA_ONLY)
GO

In memory tables have a durability property that can be set to SCHEMA_AND_DATA or SCHEMA_ONLY. There are two new columns in sys.tables to track this. SCHEMA_ONLY tables are volatile, SCHEMA_AND_DATA are persisted to disk.

SELECT name,type_desc,durability_desc FROM sys.tables

The hash indexes can be tracked with a new catalog view.

SELECT * FROM sys.hash_indexes

DML.

The two big selling points of in memory OLTP are improved performance with entirely memory resident data accessed with hash indexes and use of an optimistic multiversion concurrency control … no locking.

So let’s run some DML and test this out. Insert a row:

BEGIN TRAN

INSERT dbo.Table1 VALUES (1,427,getdate(),'Insert transaction')

SELECT * FROM sys.dm_tran_locks WHERE request_session_id = @@SPID
SELECT * FROM sys.dm_db_xtp_transactions

COMMIT TRAN

The sys.dm_tran_locks DMV will return a shared object lock and a Schema shared lock on the database. The new sys.dm_db_xtp_transactions is a new DMV for in memory OLTP and returns information about current transactions against the database.

Now run an update inside an explicit transaction. Note that we will get an error if we don’t use the WITH(SNAPSHOT) hint.

BEGIN TRAN

UPDATE dbo.Table1  WITH (SNAPSHOT)
SET [Description] = 'Updated transaction'
WHERE Id_tb1 = 1

SELECT * FROM sys.dm_tran_locks WHERE request_session_id = @@SPID
SELECT * FROM sys.dm_db_xtp_transactions

In another session run a select.

SELECT *
FROM dbo.Table1
WHERE Id_tb1 = 1

The select returns the pre updated version of the row – but there is no blocking. This is achieved using a versioning system that is, despite the keyword SNAPSHOT, not the familiar SNAPSHOT ISOLATION row versioning based in tempdb. (Details of how this is achieved can be found in the readings at the end of this blog.)

Commit the update and run the following delete.

BEGIN TRAN

DELETE dbo.Table1 WITH (SNAPSHOT)
WHERE Id_tb1 = 1

SELECT * FROM sys.dm_tran_locks WHERE request_session_id = @@SPID
SELECT * FROM sys.dm_db_xtp_transactions

Note that the delete transaction is still only holding lightweight shared locks. The select in another session will now return the updated row.

SELECT *
FROM dbo.Table1
WHERE Id_tb1 = 1

Commit the delete transaction.

Concluding Remarks.

As of CTP1 not all of the features are fully working and there are a number of limitations that are likely to roll into RTM – hopefully to be slowly improved in subsequent releases. The whitepaper in the reading list below has an exhaustive list of these restrictions but one of the biggest ones for me is that foreign key constraints are not supported.

Another big feature that is available for in memory tables are the native stored procedures. I didn’t touch on these but they are tipped to offer highly optimised performance. A stored procedure that only operates against in memory tables can be marked using the WITH NATIVE_COMPILATION option and this will compile the sproc into a DLL using C code.



About HostForLIFE.eu

HostForLIFE.eu is European Windows Hosting Provider which focuses on Windows Platform only. We deliver on-demand hosting solutions including Shared hosting, Reseller Hosting, Cloud Hosting, Dedicated Servers, and IT as a Service for companies of all sizes.

We have offered the latest Windows 2016 Hosting, ASP.NET Core 2.2.1 Hosting, ASP.NET MVC 6 Hosting and SQL 2017 Hosting.


Tag cloud

Sign in