Temporal Tables in SQL 2016 and SQL Azure


Have you ever been asked to create a History/audit table for your database? Do you need to? If so, then read this blog post on the awesome feature now built into SQL 2016 and SQL Azure.

What is a temporal table?

A temporal table is a new type of user table in SQL Server 2016 and SQL Azure. These tables allow a point-in-time analysis by keep a full history of data changes, without the need of custom coding using triggers etc. You can create any new user table as a temporal table, or convert an existing table into a temporal table. By converting an existing table to a temporal table you will not need to do anything to any stored procedures or T-SQL statements to allow your application to continue working, it will just continue working, while storing the history data of any changes. These tables can also be known as system-versioned temporal tables because each row is managed by the system.

Every temporal table has two explicitly defined datetime2 columns. These columns are referred to as period columns and are used by the system to record period of validity for each row whenever a row is modified. A temporal table also has reference to another table with the same schema as itself. This is the history table and automatically stores the previous version of the row each time a row in the temporal table gets updated or deleted. This allows the temporal table to remain as the current table, and the history table to hold… well the history data. During temporal table creation users can specify existing history table (which must match the schema of the temporal table) or let the system create a default history table.

How does temporal work?

All current entries are stored within the Temporal table with a Start time and non-ending End time. Any changes will cause the original row to be stored in the history table with the start time and end time for the period for which is was valid.

Let me show you an example.

On first input on a row, the value would be entered only into the Temporal table.

Temporal

ID Value StartTime EndTime
1 My First Value 2016-05-01 10:26:45.15 9999-12-31 23:59:59.99

History

ID Value StartTime EndTime

On Update to ID 1, the original inputted value is entered into the history table with the EndTime updated to match when the Update took place, and Temporal table is updated with the updated value and the new start time.

Temporal

ID Value StartTime EndTime
1 My Second Value 2016-05-14 14:54:44.54 9999-12-31 23:59:59.99

History

ID Value StartTime EndTime
1 My First Value 2016-05-01 10:26:45.15 2016-05-14 14:54:44.54

On second update to ID 1, again the current value is entered into the history table with the EndTime updated to match when the Update took place, and the Temporal table is updated with the new version and new start time.

Temporal

ID Value StartTime EndTime
1 My Third Value 2016-05-24 01:59:41.82 9999-12-31 23:59:59.99

History

ID Value StartTime EndTime
1 My First Value 2016-05-01 10:26:45.15 2016-05-14 14:54:44.54
1 My Second Value 2016-05-14 14:54:44.54 2016-05-24 01:59:41.82

On deletion of ID 1, the current value is entered into the history table, with the EndTime updated to match when the row was deleted. The row is then removed from the Temporal table.

Temporal

ID Value StartTime EndTime

History

ID Value StartTime EndTime
1 My First Value 2016-05-01 10:26:45.15 2016-05-14 14:54:44.54
1 My Second Value 2016-05-14 14:54:44.54 2016-05-24 01:59:41.82
1 My Third Value 2016-05-24 01:59:41.82 2016-06-01 13:12:17.72

Creating or converting exiting table to a temporal table.

You can create a temporal table by specifying the Transact-SQL statements directly as show below. I recommend using SQL Management Studio 2016 which can be obtained and downloaded from here. You do not need a SQL Server license to install and use this, and it can be used with SQL Azure.

By using SQL Management Studio 2016, you can obtain the correct T-SQL by right clicking Tables > New > Temporal Table > System-Versioned Table..


I’m going to create an Employee Table.

CREATE TABLE dbo.Employee
(
  [EmployeeID] int NOT NULL PRIMARY KEY CLUSTERED
  , [Name] nvarchar(100) NOT NULL
  , [Position] varchar(100) NOT NULL
  , [Department] varchar(100) NOT NULL
  , [Address] nvarchar(1024) NOT NULL
  , [AnnualSalary] decimal (10,2) NOT NULL
-- This point below is the Period/Temporal set up on the table.
  , [ValidFrom] datetime2 (2) GENERATED ALWAYS AS ROW START
  , [ValidTo] datetime2 (2) GENERATED ALWAYS AS ROW END
  , PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)
 )
 WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.EmployeeHistory));
GO

If I was going to convert my existing Employee Table into a Temporal table, I would use the following T-SQL Statement

ALTER TABLE Employee
ADD
    ValidFrom datetime2 (0) GENERATED ALWAYS AS ROW START HIDDEN
        constraint DF_ValidFrom DEFAULT DATEADD(SECOND, -1, SYSUTCDATETIME())
    , ValidTo datetime2 (0)  GENERATED ALWAYS AS ROW END HIDDEN
        constraint DF_ValidTo DEFAULT '9999.12.31 23:59:59.99'
    , PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo);
ALTER TABLE Employee
SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.EmployeeHistory));
GO

AS you can see from above, SQL Management Studio indicates the System-Versioned and History table.

Inserts, updates and deleting data

When you come to doing your Inserts, Updates and Deletes there are no changes to T-SQL code, you would perform all against the Temporal table, (Employee table in my case). The T-SQL code below is demo code, that inserts 3 people a minute apart and then every 5 minutes something else will happen to the data. Either an update, inserting a new record, or delete.

--Create Lisa Fane
INSERT INTO [dbo].[Employee] ([EmployeeID],[Name],[Position],[Department],[Address],[AnnualSalary])
VALUES    (1234,'Lisa Fane','Sales Rep','Sales','Hertforshire', 25000)
GO

WAITFOR DELAY '00:01'
--Create Dan Wilson
INSERT INTO [dbo].[Employee] ([EmployeeID],[Name],[Position],[Department],[Address],[AnnualSalary])
VALUES    (2435,'Dan Wilson','Developer','Development','Kent', 35500)
GO

WAITFOR DELAY '00:01'
--Create David Hamilton
INSERT INTO [dbo].[Employee] ([EmployeeID],[Name],[Position],[Department],[Address],[AnnualSalary])
VALUES    (3445,'David Hamilton','Developer','Development','Croydon', 20000)
GO

WAITFOR DELAY '00:05'
--Update Lisa Fane with new job title and payrise.
UPDATE [dbo].[Employee]
SET  [Position] = 'Lead Sales Rep',[AnnualSalary] = 32000
WHERE EmployeeID = 1234
GO

WAITFOR DELAY '00:05'
-- Give Lisa Fane a Pay Rise.
UPDATE [dbo].[Employee]
SET  [AnnualSalary] = 33000
WHERE EmployeeID = 1234
GO

WAITFOR DELAY '00:05'
-- Give Dan Wilson a new job title and payrise
UPDATE [dbo].[Employee]
SET  [Position] = 'Development Manager',
[AnnualSalary] = 45500
WHERE EmployeeID = 2435
GO

WAITFOR DELAY '00:05'
--Employ Lucy Williamson
INSERT INTO [dbo].[Employee] ([EmployeeID],[Name],[Position],[Department],[Address],[AnnualSalary])
VALUES    (8875,'Lucy Williamson','Project Management','PMO','Sutton', 20000)
GO

WAITFOR DELAY '00:05'
--Lisa Fane change address
UPDATE [dbo].[Employee]
SET  [Address] = 'Barnet'
WHERE EmployeeID = 1234
GO

WAITFOR DELAY '00:05'
--Adam Crane joins the team
INSERT INTO [dbo].[Employee] ([EmployeeID],[Name],[Position],[Department],[Address],[AnnualSalary])
VALUES    (4454,'Adam Crane','Sales Rep','Sales','Islington', 26000)
GO
WAITFOR DELAY '00:05'

--David Hamilton has a payrise
UPDATE [dbo].[Employee]
SET  [Position] = 'Manage Services',[AnnualSalary] = 20500
WHERE EmployeeID = 3445
GO

WAITFOR DELAY '00:05'
--Lucy Williamson left the company.
Delete From Employee
Where EmployeeID = 8875

Running the above script takes about 30-35 mins.

Querying Temporal data

To obtain the current information in the Temporal table, there is no changes to your typical SQL Select statements.

SELECT * FROM Employee

As you can see from the above image, the results are as if it’s not a temporal table.

To view history data, there is a new clause you can use within the SELECT FROM statement. This is the FOR SYSTEM_TIME clause with 5 temporal-specific sub-clauses to query data across the current and history tables. This new SELECT statement syntax is supported directory on a single table, propagated through multiple joins, and through views on top of multiple temporal tables.

View All Data

Use the following command to see current and past records, the IsActual flag indicates if the row is current. This query is also useful as a view so that BI tools such as PowerBI can display a graph over time.

SELECT Name, Position, Department, [Address], AnnualSalary, ValidFrom, ValidTo, IIF (YEAR(ValidTo) = 9999, 1, 0) AS IsActual FROM Employee
FOR SYSTEM_TIME All
ORDER BY ValidFrom

Between two dates

Using BETWEEN <startDateTime> AND <endDateTime> will return rows that were active at least for a portion of period between the two times.

SELECT * FROM Employee
FOR SYSTEM_TIME
BETWEEN '2016-06-18 10:27:00' AND '2016-06-18 10:47:00'
ORDER BY ValidFrom

Contains two dates

Using CONTAINS IN (<startDateTime>,<EndDateTime>) will return rows that were only active within a period (and not outside it). This only queries the history table. As you can see below Lisa Fane was updated 3 times within the time period.

SELECT * FROM Employee
FOR SYSTEM_TIME CONTAINED IN ('2016-06-18 10:25:00', '2016-06-18 11:50:00')
ORDER BY ValidFrom

Point in time search

Using AS OF <dateTime> will return how the database looked at that given moment in time. Below are multiple statements which returns results from those points in the database. I’ve highlighted within the next result set what has changed. This type of query is perfect for BI tools such as Power BI to query the data 24 hours, 7 days, 30 day etc.

SELECT * FROM Employee
FOR SYSTEM_TIME
AS OF '2016-06-18 10:28:00'
ORDER BY EmployeeID

SELECT * FROM Employee
FOR SYSTEM_TIME
AS OF '2016-06-18 10:31:00'
ORDER BY EmployeeID

SELECT * FROM Employee
FOR SYSTEM_TIME
AS OF '2016-06-18 10:36:00'
ORDER BY EmployeeID

SELECT * FROM Employee
FOR SYSTEM_TIME
AS OF '2016-06-18 10:46:00'
ORDER BY EmployeeID

SELECT * FROM Employee
FOR SYSTEM_TIME
AS OF '2016-06-18 10:56:00'
ORDER BY EmployeeID

SELECT * FROM Employee
FOR SYSTEM_TIME
AS OF '2016-06-18 11:01:00'
ORDER BY EmployeeID

SELECT * FROM Employee
FOR SYSTEM_TIME
AS OF '2016-06-18 11:06:00'
ORDER BY EmployeeID

References

I found quite a bit of good information available to help me understand Temporal tables, I have listed the main sites below.

Temporal Tables – https://msdn.microsoft.com/en-IN/library/dn935015.aspx 

Getting Started with Temporal Tables in Azure SQL Database – https://azure.microsoft.com/en-us/documentation/articles/sql-database-temporal-tables/

Getting Started with System- Versioned Temporal Tables – https://msdn.microsoft.com/en-us/library/mt604462.aspx

Temporal in SQL Server 2016 (Video) – https://channel9.msdn.com/Shows/Data-Exposed/Temporal-in-SQL-Server-2016 


Advertisements

Exporting and Importing SQL Azure database in different Tenants


This was easier than I thought it was going to be. Using purely point and click, and Microsoft Azure Storage Explorer.

To be able to backup/export a database you need to have an Azure Blob Storage. If you don’t have one the steps below will show you how to create one.

Creating an Azure Blob Storage

  • Open up https://portal.azure.com and log in with your credentials, on the tenant where your SQL server source is.
  • Click New and select Data + Storage and then select Storage account
  • On the Create storage account blade you will be asked the following information:
    • Name: <Give a unique name>
    • Deployment model: Resource manager
    • Account Kind: Blob Storage
    • Performance: Standard
    • Replication: Locally-redundant storage (LRS) <- This may be different for you. I’m just doing a simple export and restore, not planning on keeping this storage.
    • Subscription: <Your subscription>
    • Resource group: Create New <- You might wish to use an existing resource group.
    • Resource Group Name: <Resource Group Name>
    • Location: <Your closest location>
  • Click Create
  • This will take a small amount of time while Azure creates this storage

Exporting Source Database

  • If not continuing from last step, open up https://portal.azure.com and log in with your credentials, on the tenant where your SQL server source is.
  • Go into SQL Database, and select the database you wish to export.
  • At the top of the blade there is a menu button item called ‘Export’. Click this button.

  • On the Export database blade, you will be asked the following information:
    • File name: Give a meaningful export name.
    • Subscription: Select the subscription that you can find your storage account in that you created earlier.
    • Storage: Select the storage account you created earlier.
      • Containers: Add a container name, and give it private access type, then select it.
    • Server admin login: Provide the Server Admin Username.
    • Password: Provide the password for the Server Admin.
  • Click OK.
  • Once you have clicked OK, your request to export the database is sent Azure, and is put into some sort of Microsoft Azure queue behind the scenes. Here you have to wait until the job has run, this can take some time. (Mine took 15 mins before complete) Please see Viewing the Import/Export history later in this blog post for job status.

Downloading the Blob file.

After the SQL export has completed, you will need to download the blob file so that you can then upload it to your destination tenant. To do this follow these steps:

  • In https://portal.azure.com select your Storage account where you exported SQL to.
  • Under the container selector you should find the container you created when exporting SQL data. Select this.
  • This container blade shows you all the files within this container. As I’ve just created it for this purpose the only file within here is my export file. Select this file.
  • Then click the download button.

Uploading export file to new tenant storage.

Before you can upload your export file to your new tenant, first you will need to ensure you have a storage account to upload to. If there isn’t one, follow my previous steps in this blog about creating an Azure Blob Storage.

Once you have a blob storage on your destination tenant, download and open Microsoft Azure Storage Explorer

  • Sign in with your destination tenant credentials.
  • Select the Storage account and then blob container.
  • Click Upload.
  • Upload your export file.

Importing to Destination Database

  • Open up https://portal.azure.com and log in with your credentials, on the tenant where your destination SQL server is.
  • Go into SQL Servers, and Add/Select the SQL server you wish to import the database too.
  • At the top of the blade there is a menu button item called ‘Import database’. Click this button.

  • On the Import database blade, you will be asked the following information:
    • Subscription: Select the subscription that you can find your storage account in that you created earlier.
    • Storage: Select the storage account you created earlier.
      • Containers: Select the Container
        • File: Select the export file.
    • Select Pricing Tier: <Select a pricing tier>
    • Database name: <Name the database>
    • Collation: Leave as is, or change if you require too.
    • Server admin login: Provide the Server Admin Username for this tenant.
    • Password: Provide the password for the Server Admin.
  • Click OK.
  • Once you have clicked OK, your request to import the database is sent Azure, and is put into some sort of Microsoft Azure queue behind the scenes. Here you have to wait until the job has run, this can take some time. (Mine took less than two minutes to import.) Please see Viewing the Import/Export history below for job status.

Viewing the Import/Export history.

After you have imported/exported a database, you can view the progress of the request by following these steps:

  • In https://portal.azure.com select SQL servers
  • Select your server where the import/export is taking place.
  • If you scroll down to Operations on the Server blade, you will see a tile called Import/Export history. Click this.



Simple SQL statement to see membership within a database


In SQL Azure if you connect up Microsoft SQL Server Management Studio, you have to do everything using SQL statements, there is no ability to point and click your way through creating accounts, memberships, new tables etc. I’m sure a good DBA would tell me that this is the correct way of building any database. Unfortunately, (or fortunately) I’m not a DBA, and I like point and click tools.

So the other day I was having a problem seeing what accounts had what access to a given database. I found running this SQL statement on a given database gave me the information I needed. I have written this blog post today mainly so I have reference to this in the future.

SELECT DP1.name AS DatabaseRoleName,
isnull (DP2.name, 'No members') AS DatabaseUserName
FROM sys.database_role_members AS DRM
RIGHT OUTER JOIN sys.database_principals AS DP1
ON DRM.role_principal_id = DP1.principal_id
LEFT OUTER JOIN sys.database_principals AS DP2
ON DRM.member_principal_id = DP2.principal_id
WHERE DP1.type = 'R'
ORDER BY DP1.name;

Fig 1. Example results.

Entity Framework Error – The server principle “user” is not able to access the database “master” under the current security context


I’m pretty new at Entity Framework and really haven’t even skimmed the surface of what it can do. But as a newbie, I encountered this error right from the start and my bet is other people have too. Let me first explain the setup of my environment.

I’ve created a code first entity framework application. I have created an Azure Server and database (doesn’t have to be Azure database), and created a SQL user so that they are db_owner on the database. On first running of my application I hit the following error: –

“The server principal “demouser” is not able to access the database “master” under the current security context.

Database ‘master’ on server ‘xxxxxxxx.westeurope1-a.worker.database.windows.net’ is not currently available. Please retry the connection later. If the problem persists, contact customer support, and provide them the session tracing ID of ‘6214BE0A-7962-4728-B0BE-B129401F98B0’.

Login failed for user ‘demouser’.”

So why does it need access to the master database?

It requires this to log into SQL server.  If the user database doesn’t exist and you want the code to create your database, you will also need to give your account dbo access to your master database, I don’t recommend doing this.

What is the solution?

Add the account to the master database so that it has public access. The SQL Script below is the full script I now use to create the account. The line highlighted is the line you need to run on against your master database to fix your error message.

use [master]
--Run within the master database.
-Create the Login account.
CREATE LOGIN demouser WITH password 'P@ssword123'
--This is the line you need
CREATE USER demouser FOR LOGIN demouser

--Run within your Database
use [demoDatabase]
CREATE USER demouser FOR LOGIN demouser
ALTER ROLE [db_owner] ADD MEMBER demouser

SQL Azure – Connecting to SQL Azure server and database using the browser


In my last post I showed you how to connect to your SQL Azure using SQL Management studio. This post is showing you how to manage your SQL Azure Server and Database within the browser, but please note, I’m not sure how long this feature will be around due to the fact that if you create a server using the V12 (Latest SQL Database), you will not be able to view your database in the browser. Also that the page uses Silverlight to render, and that was killed off in 2012.

To connect through the browser you have two choices:
1. You can log into your Azure Portal, and navigate to your database. At the bottom of the Quick Start page for your database there is a link “Design your SQL database” this will open up another page where you can log into your SQL azure.

2. The other way of access the login page for SQL Azure in the browser is by navigating to the following URL, replacing servername with the name of your server. https://[servername].database.windows.net you will be presented with a login screen.

Using your SQL admin account you can log in. (The login doesn’t have to be the SQL admin, it can be any SQL user account that has already been created)

Once you have logged in, you can then navigate to your database, and click the pencil icon to design.

Once in design mode you could create a new table, view, stored procedure. As I’m not a true SQL developer, this design view is what I’m used to within SQL Management studio. But when connecting to SQL Azure with SQL management studio this functionality is missing.

If you are a true SQL Developer, there is nothing stopping you clicking New Query in the menu bar and writing T-SQL Statements to create your tables, columns, stored procedures etc.

SQL Azure – Creating SQL Azure Server and Database using PowerShell


In the past two blog for SQL Azure, I have shown you how to use the Azure Management portal to create a SQL Azure Server and Database and then update the firewall rules. This blog post is going to show you how you can do the exact same thing via PowerShell.

All the different PowerShell Cmdlets for managing SQL Azure can be found at the MSDN link https://msdn.microsoft.com/en-us/library/azure/dn546726.aspx.

  • Connect to Azure
Add-AzureAccount
  • This will pop up a Microsoft sign in dialog.
  • Sign in with your Azure username and Password.
  • If you know your subscription name you can do the following, otherwise you might need to call Get-AzureSubscription to list all subscriptions you have to find the name, and ID.
$subscriptionName = 'Windows Azure MSDN – Visual Studio Ultimate'

Select-AzureSubscription –SubscriptionName $subscriptionName

#Below is if you have PowerShell Azure version greater than 0.8.14 (get-module azure).version

#subscriptionID = "a222bcff-ac30-554d-67a5-1d6664f1a555"
#Select-AzureSubscription –SubscriptionID $subscriptionID
  • Next step is to create the Azure SQL Database Server. Remember you don’t get to assign a server name.
$location = 'West Europe'
$adminLogin = 'SQLAdmin'
$adminPassword = 'MyPa55w0rd'
$sqlDB = 'DemoDatabase'
 
$sqlServer = New-AzureSqlDatabaseServer –AdministratorLogin $adminLogin –AdministratorLoginPassword $adminpassword –Location $location

  • The above screen shot appears after the SQL server has successfully been created. To view all your SQL Servers type
Get-AzureSqlDatabaseServer
  • If you now try to connect to SQL Azure, you will encounter a firewall warning.
#Either get credentials for SQL authentication by prompting
$cred = Get-Credential
$sqlctx = New-AzureSqlDatabaseServerContext –ServerName $sqlServer.Name –Credential $cred
 
#Or create a Credential object that includes your login information.
$securePassword = ConvertTo-SecureString 'MyPa55w0rd' –AsPlainText -Force
$manualCredential = new-object System.Management.Automation.PSCredential('SQLAdmin',$securepassword)
$sqlctx = New-AzureSqlDatabaseServerContext –ServerName $sqlServer.ServerName –Credential $manualCredential

  • Therefore we need to create a Firewall rule to allow connections to the database server, the IP address is shown in the message above, I’ve hidden mine. The start and end IP address can be the same, or you can put a range in.
New-AzureSqlDatabaseServerFirewallRule –ServerName $sqlServer.ServerName –RuleName 'myOffice' –StartIPAddress '111.111.111.111' –EndIPAddress '222.222.222.222'

  • The above screen shot appears after the SQL server firewall entry has successfully been created. To view all your firewall rules for this server type
Get-AzureSqlDatabaseServerFirewallRule –ServerName $sqlServer.ServerName
  • Now if we retry the step to connect you don’t get the error message. This allows us now to use the context to create a new database. Ensure you include the Edition otherwise the retired “business” edition will be created for you.
New-AzureSqlDatabase –DatabaseName $sqlDB –ConnectionContext $sqlctx –Edition Standard

  • As you can see from above the MaxSizeGB is 1. Not very big. I’m therefore going to increase this to 10GB. (As in my screenshot above I forgot to add –Edition as Standard, you can also use the Set-AzureSqlDatabase cmdlet to change Database Edition.
Set-AzureSqlDatabase –ConnectionContext $sqlctx –DatabaseName $sqlDB –MaxSizeGB 10

 

By using SQL Management studio and connecting to my server I can see that my database has been created.

If I log into the Azure Management Portal I can see:

  • SQL Database and Server

  • Firewall rules

Lastly if you wish to clean up and remove database and Server, just run the following PowerShell, you will be prompted for a confirmation for both commands.

# Delete the database
Remove-AzureSqlDatabase –ConnectionContext $sqlCtx –DatabaseName $sqlDB
 
# Delete the Server
Remove-AzureSqlDatabaseServer $sqlServer.ServerName

 

SQL Azure – Configuring SQL Azure so you can connect from Local SQL Management Studio


In my second post of my SQL Azure series, I’m going to show you how to connect to you SQL Azure server database from SQL Management Studio. You can only connect to SQL Azure from somewhere that is not a Windows Azure service by defining IP Firewall rules.

 

Configuring SQL Azure Firewall rules.

  • Open up the Management Azure Portal and log in using your username and password.
  • Navigate to the SQL databases area.
  • Then for your database, click on the Server Name.

  • Click on the Configure Tab.
  • Find out your external IP address(s) that you will be connecting from, the screen will tell you your current IP address at the top of the screen.
  • In the Rule area below, Put in a Rule Name and then fill out either a range (if using dynamic/multiple IP locations), or the given IP address(es) you will be connecting from.
  • Click Save.

Connecting from a Local SQL Management Studio

You will need to use SQL Server 2012 or above to connect to SQL Azure. Alternatively you can download SQL Server 2014 express for free and download the MgmtStudio Download.

  • Once you have opened the Management SQL Studio, put in the Server name with .database.windows.net at the end. (E.g., Server Name is ctwsc5d11a, then the Server name you put in is ctwsc5d11a.database.windows.net
  • Change the authentication to SQL Server Authentication.
  • Login using the UserName and Password you created when setting up the SQL Azure Server and Database.
  • Click Connect.
  • Once connected you can create Tables, Store Procedures etc. using point and click (which creates valid T-SQL templates) or T-SQL Statements*

(*Please note, not all T-SQL statements that work in Standard SQL works in Azure. For example SELECT INTO doesn’t work unless you predefine the Table and columns first, also there is no designer mode when creating Azure SQL Tables in SQL Management Studio, all you can do is get the T-SQL template to create the table)