Criando Constraints e Índices no SQL Server com .NET

No artigo da semana passada vimos como criar colunas e tabelas com .NET e com PowerShell, nesta semana veremos como é possível também criar Constraints (Foreign Key, Default, Unique Key, Primary Key) e Índices com SMO.

Inicialmente, criaremos duas tabelas bem simples:

const string serverName = @".\SQLEXPRESS";

var server = new Server(serverName);

var database = new Database(server, "Estoque");
database.Create();

// CREATE DATABASE [Estoque] ...
var table = new Table(database, "Produto", "dbo");
table.Columns.Add(new Column(table, "Id", DataType.Int) { Nullable = false, Identity = true });
table.Columns.Add(new Column(table, "Nome", DataType.VarChar(250)) { Nullable = false });
table.Columns.Add(new Column(table, "Quantidade", DataType.Int) { Nullable = false });
table.Columns.Add(new Column(table, "Valor", DataType.Money) { Nullable = false });
table.Columns.Add(new Column(table, "Peso", DataType.Decimal(2, 5)) { Nullable = false });
table.Columns.Add(new Column(table, "CategoriaId", DataType.Int) { Nullable = false });
table.Columns.Add(new Column(table, "DataCadastro", DataType.DateTime) { Nullable = false });
table.Create();

// CREATE TABLE [dbo].[Categoria] ...
var table2 = new Table(database, "Categoria", "dbo");
table2.Columns.Add(new Column(table2, "Id", DataType.Int) { Nullable = false, Identity = true });
table2.Columns.Add(new Column(table2, "Nome", DataType.VarChar(250)) { Nullable = false });
table2.Create();

E em seguida, criamos as Primary Keys destas tabelas, por meio de um objeto Index, especificado como DriPrimaryKey:

// ALTER TABLE [dbo].[Produto]
//   ADD CONSTRAINT [PK_Produto] PRIMARY KEY ([Id])
var pk = new Index(table, "PK_Produto") { IndexKeyType = IndexKeyType.DriPrimaryKey };
pk.IndexedColumns.Add(new IndexedColumn(pk, "Id"));
pk.Create();

// ALTER TABLE [dbo].[Categoria]
//   ADD CONSTRAINT [PK_Categoriao] PRIMARY KEY (Id)
var pk2 = new Index(table2, "PK_Categoria") { IndexKeyType = IndexKeyType.DriPrimaryKey };
pk2.IndexedColumns.Add(new IndexedColumn(pk2, "Id"));
pk2.Create();

No caso das Unique Keys, é possível utilizar também de um objeto Index, agora como DriUniqueKey:

// ALTER TABLE [dbo].[Produto]
//   ADD CONSTRAINT [UK_Produto_Nome] UNIQUE ([Nome])
var uk = new Index(table, "UK_Produto_Nome") { IndexKeyType = IndexKeyType.DriUniqueKey };
uk.IndexedColumns.Add(new IndexedColumn(uk, "Nome"));
uk.Create();

Para a criação de índices, criamos um objeto Index sem especificar a propriedade IndexKeyType, e definimos quais as colunas que o compõe, assim como as colunas inclusas (IsIncluded):

// CREATE INDEX [IX_Produto_NmQtVl]
//   ON [dbo].[Produto] ([Nome], [Quantidade], [Valor])
//   INCLUDE ([Peso])
var ix = new Index(table, "IX_Produto_NmQtV");
ix.IndexedColumns.Add(new IndexedColumn(ix, "Nome"));
ix.IndexedColumns.Add(new IndexedColumn(ix, "Quantidade"));
ix.IndexedColumns.Add(new IndexedColumn(ix, "Valor"));
ix.IndexedColumns.Add(new IndexedColumn(ix, "Peso") { IsIncluded = true });
ix.Create();

As Default Contraints são um pouco mais chatas de serem criadas, pois requerem a utilização de uma coluna (objeto Column) e a utilização do método AddDefaultConstraint para serem adicionadas:

// ALTER TABLE [dbo].[Produto]
//   ADD CONSTRAINT [DF_Produto_DataCadastro] DEFAULT (GETDATE()) FOR [DataCadastro]
var col = table.Columns["DataCadastro"];
var def = col.AddDefaultConstraint("DF_Produto_DataCadastro");
def.Text = "(GETDATE())";
def.Create();

As Foreign Keys, somente requerem a especificação da tabela a ser referenciada e das colunas que a referenciam.

// ALTER TABLE [dbo].[Produto]
//   ADD CONSTRAINT [PK_Categoriao] FOREIGN KEY ([CategoriaId])
//   REFERENCE [dbo].[Categoria] ([Id])
var fk = new ForeignKey(table, "FK_Produto_Categoria")
                {
                    ReferencedTableSchema = table2.Schema,
                    ReferencedTable = table2.Name
                };
fk.Columns.Add(new ForeignKeyColumn(fk, "CategoriaId", "Id"));
fk.Create();

Desta forma temos o código complemento desta demonstração:

using Microsoft.SqlServer.Management.Smo;

namespace DemoSmo
{
    static class DemoCreate2
    {
        static void Run()
        {
            const string serverName = @".\SQLEXPRESS";

            var server = new Server(serverName);

            var database = new Database(server, "Estoque");
            database.Create();

            // CREATE DATABASE [Estoque] ...
            var table = new Table(database, "Produto", "dbo");
            table.Columns.Add(new Column(table, "Id", DataType.Int) { Nullable = false, Identity = true });
            table.Columns.Add(new Column(table, "Nome", DataType.VarChar(250)) { Nullable = false });
            table.Columns.Add(new Column(table, "Quantidade", DataType.Int) { Nullable = false });
            table.Columns.Add(new Column(table, "Valor", DataType.Money) { Nullable = false });
            table.Columns.Add(new Column(table, "Peso", DataType.Decimal(2, 5)) { Nullable = false });
            table.Columns.Add(new Column(table, "CategoriaId", DataType.Int) { Nullable = false });
            table.Columns.Add(new Column(table, "DataCadastro", DataType.DateTime) { Nullable = false });
            table.Create();

            // CREATE TABLE [dbo].[Categoria] ...
            var table2 = new Table(database, "Categoria", "dbo");
            table2.Columns.Add(new Column(table2, "Id", DataType.Int) { Nullable = false, Identity = true });
            table2.Columns.Add(new Column(table2, "Nome", DataType.VarChar(250)) { Nullable = false });
            table2.Create();

            // ALTER TABLE [dbo].[Produto]
            //   ADD CONSTRAINT [PK_Produto] PRIMARY KEY ([Id])
            var pk = new Index(table, "PK_Produto") { IndexKeyType = IndexKeyType.DriPrimaryKey };
            pk.IndexedColumns.Add(new IndexedColumn(pk, "Id"));
            pk.Create();

            // ALTER TABLE [dbo].[Categoria]
            //   ADD CONSTRAINT [PK_Categoriao] PRIMARY KEY (Id)
            var pk2 = new Index(table2, "PK_Categoria") { IndexKeyType = IndexKeyType.DriPrimaryKey };
            pk2.IndexedColumns.Add(new IndexedColumn(pk2, "Id"));
            pk2.Create();

            // ALTER TABLE [dbo].[Produto]
            //   ADD CONSTRAINT [UK_Produto_Nome] UNIQUE ([Nome])
            var uk = new Index(table, "UK_Produto_Nome") { IndexKeyType = IndexKeyType.DriUniqueKey };
            uk.IndexedColumns.Add(new IndexedColumn(uk, "Nome"));
            uk.Create();

            // CREATE INDEX [IX_Produto_NmQtVl]
            //   ON [dbo].[Produto] ([Nome], [Quantidade], [Valor])
            //   INCLUDE ([Peso])
            var ix = new Index(table, "IX_Produto_NmQtV");
            ix.IndexedColumns.Add(new IndexedColumn(ix, "Nome"));
            ix.IndexedColumns.Add(new IndexedColumn(ix, "Quantidade"));
            ix.IndexedColumns.Add(new IndexedColumn(ix, "Valor"));
            ix.IndexedColumns.Add(new IndexedColumn(ix, "Peso") { IsIncluded = true });
            ix.Create();

            // ALTER TABLE [dbo].[Produto]
            //   ADD CONSTRAINT [DF_Produto_DataCadastro] DEFAULT (GETDATE()) FOR [DataCadastro]
            var col = table.Columns["DataCadastro"];
            var def = col.AddDefaultConstraint("DF_Produto_DataCadastro");
            def.Text = "(GETDATE())";
            def.Create();

            // ALTER TABLE [dbo].[Produto]
            //   ADD CONSTRAINT [PK_Categoriao] FOREIGN KEY ([CategoriaId])
            //   REFERENCE [dbo].[Categoria] ([Id])
            var fk = new ForeignKey(table, "FK_Produto_Categoria")
                         {
                             ReferencedTableSchema = table2.Schema,
                             ReferencedTable = table2.Name
                         };
            fk.Columns.Add(new ForeignKeyColumn(fk, "CategoriaId", "Id"));
            fk.Create();

            // DROP TABLE [dbo].[Produto]
            table.Drop();

            // DROP TABLE [dbo].[Categoria]
            table2.Drop();

            // DROP DATABASE [dbo].[Estoque]
            database.Drop();
        }
    }
}

2 pensamentos sobre “Criando Constraints e Índices no SQL Server com .NET

  1. Pingback: Criando Constraints e Índices no SQL Server com PowerShell « SQL From Hell.com

  2. Pingback: Trabalhando com SMO – Resumo « SQL From Hell.com

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s