SQL Azure e o não suporte a tabelas sem clustered index

Microsoft Azure & Microsoft Azure Storage & SQL

ErroSqlAzure

Estava eu trabalhando feliz da vida em um sistema em Azure utilizando o ambiente local por meio do Compute Emulator e  um banco de dados hospedado em um SQL Server 2008 R2 padrão, e tudo corria perfeitamente bem. Com todos os testes passando decidi que era hora de testar com os dados no SQL Azure e tive uma surpresinha:

Msg 40054, Level 16, State 1, Line 3
Tables without a clustered index are not supported in this version of SQL Server. Please create a clustered index and try again.

 

Explorando o motivo

Bem, o motivo pelo qual me deparei com este “erro” se deve por que existem algumas limitações ou diferenças entre o SQL Server e o SQL Azure. Diferente do SQL Server padrão, o SQL Azure não permite inserções de dados em uma tabela sem um clustered index definido, dai a mensagem de erro dizendo que “esta versão” [SQL Azure] não suporta tabelas sem clustered index.

Para maiores detalhes e um guia completo das limitações do SQL Azure eu indico a leitura abaixo:

General Guidelines and Limitations (SQL Azure Database)

 

Solução

O primeiro passo foi identificar as tabelas sem um clustered index definido. É claro que no meu caso eu tinha muitas tabelas o que justifica o esforço, mas vamos simular isto criando um banco com quatro tabelas como segue na listagem abaixo.

    
CREATE DATABASE TesteSQLAzure
USE [TesteSQLAzure];
GO
CREATE TABLE [dbo].[Tabela01] (
  [PartitionKey] varchar(36)  NOT NULL,
  [RowKey] varchar(36)  NOT NULL,
  [PropriedadeA] varchar(50)  NULL
);
GO

CREATE TABLE [dbo].[Tabela02] (
  [PartitionKey] varchar(36)  NOT NULL,
  [RowKey] varchar(36)  NOT NULL,
  [PropriedadeA] varchar(50)  NULL
);
GO

CREATE TABLE [dbo].[Tabela03] (
  [PartitionKey] varchar(36)  NOT NULL,
  [RowKey] varchar(36)  NOT NULL,
  [PropriedadeA] varchar(50)  NULL
);
GO

CREATE TABLE [dbo].[Tabela04] (
  [PartitionKey] varchar(36)  NOT NULL,
  [RowKey] varchar(36)  NOT NULL,
  [PropriedadeA] varchar(50)  NULL
);
GO
    

 

Como próximo passo vamos criar os índices para as tabelas Tabela02 e Tabela04:

    
ALTER TABLE [dbo].[Tabela02]
ADD CONSTRAINT [PK_Tabela02]
PRIMARY KEY CLUSTERED ([PartitionKey], [RowKey] ASC);
GO

ALTER TABLE [dbo].[Tabela04]
ADD CONSTRAINT [PK_Tabela04]
PRIMARY KEY CLUSTERED ([PartitionKey], [RowKey] ASC);
GO
    

 

Neste exato momento, seria possível inserir dados nas tabelas Tabela02 e Tabela04, porém teríamos o referido problema quando fosse a vez de inserir dados nas tabelas Tabela01 e Tabela03 . Como ainda não sabemos disto, precisamos encontrar as tabelas “estragadas” no SQL Azure. Para isso, vamos dividir o script em 3 passos:

Passo 1: Contar a quantidade de tabelas do banco em questão;

    
SELECT COUNT (*)
FROM sys.objects
WHERE type = 'U'
    

 

Passo 2: Retornar a quantidade de tabelas com o clustered index definido;

    
SELECT COUNT (*) AS 'Quantidade'
FROM sys.indexes
WHERE object_id IN
  ( SELECT object_id FROM sys.objects WHERE type = 'U' )
  AND index_id = 1
    

 

Passo 3: Retornar o nome das tabelas sem um clustered index definido.

    
SELECT name AS 'Tabelas sem Clustered Index'
FROM sys.objects
WHERE type = 'U' AND object_id NOT IN
  (SELECT object_id FROM sys.indexes WHERE index_id = 1)
    

 

É claro que você poderia executar direto o 3º passo, mas assim fica mais claro como chegar até esta solução.

Agora que você já identificou as tabelas com problema, é só adicionar as constraints para que neste cenário, tudo funcione corretamente.

Importante:

** Esse exemplo não tem por objetivo entrar na discussão do que é uma boa chave para seu índice cluster, apenas mostra cuidados ao portar uma aplicação para o SQL Azure.

Um ótimo feriado a todos.


Author's profile picture

Vitor is a computer scientist who is passionate about creating software that will positively change the world we live in.

MVP Azure - Cloud Architect - Data science enthusiast


3 minutes to read