none
Especialização SQL Server RRS feed

  • Pergunta

  • Pessoal preciso especializar a tabela Cliente em Pessoa Física e Jurídica, fiz isso:

    create table tb_cliente(
    	cod_cliente int not null identity,
    	email_cliente VARCHAR(100) not null,
    	constraint tb_cliente_PK primary key (cod_cliente)
    	)
    go
    create table tb_cliente_fisico(
    	nome_fisico varchar(15) not null,
    	rg_fisico varchar(12) not null,
    	cpf_fisico char(11) not null,
    	datanasc_fisico datetime not null,
    	cod_cliente int not null identity,
    	constraint tb_cliente_fisico_PK primary key (cod_cliente),
    	constraint tb_cliente_tb_cliente_fisico_FK foreign key (cod_cliente)
    		references tb_cliente (cod_cliente)
    	)
    go
    create table tb_cliente_juridico(
    	nome_fantasia varchar(40) not null,
    	razao_social varchar(20) not null,
    	cod_cliente int not null,
    	cnpj char(14) not null
    	constraint tb_cliente_juridico_PK primary key (cod_cliente),
    	constraint tb_cliente_tb_cliente_juridico_FK foreign key (cod_cliente) references tb_cliente (cod_cliente)
    )




    Não sei se esta certo e nesse caso como eu faria para usar o insert e o select nas tabelas, por exemplo "como faço para inserir um Cliente Pessoa Física?"
    sábado, 20 de julho de 2019 23:21

Respostas

  • (...) nesse caso como eu faria para usar o insert e o select nas tabelas, por exemplo "como faço para inserir um Cliente Pessoa Física?"

    Na tabela tb_cliente_fisico a coluna cod_cliente não pode ter a propriedade IDENTITY.

    INSERT:

    -- código #1
    declare @cod_cliente int;
    
    BEGIN TRANSACTION;
    
    INSERT into tb_cliente (email_cliente)
       values ( email do cliente );
    set @cod_cliente= scope_identity();
    
    INSERT into tb_cliente_fisico (cod_cliente, outras colunas) 
      values (@cod_cliente, valores demais colunas);
    
    COMMIT;
     

    SELECT:

    Para SELECT sugiro que crie visões. Eis esboço para a visão que obtém dados de cliente físico:

    -- código #2
    CREATE VIEW vw_cliente_fisico 
    as
    SELECT C.cod_cliente, CF.colunas
      from tb_cliente as C
           inner join tb_cliente_fisico as CF on CF.cod_cliente = C.cod_cliente;

    Para consultar, utilize algo como

        SELECT cod_cliente, nome_fisico, email_cliente
          from vw_cliente_fisico
          where ...

     


    José Diz     Belo Horizonte, MG - Brasil     [T-SQL performance tuning: Porto SQL]   [e-mail]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    sábado, 20 de julho de 2019 23:42

Todas as Respostas

  • (...) nesse caso como eu faria para usar o insert e o select nas tabelas, por exemplo "como faço para inserir um Cliente Pessoa Física?"

    Na tabela tb_cliente_fisico a coluna cod_cliente não pode ter a propriedade IDENTITY.

    INSERT:

    -- código #1
    declare @cod_cliente int;
    
    BEGIN TRANSACTION;
    
    INSERT into tb_cliente (email_cliente)
       values ( email do cliente );
    set @cod_cliente= scope_identity();
    
    INSERT into tb_cliente_fisico (cod_cliente, outras colunas) 
      values (@cod_cliente, valores demais colunas);
    
    COMMIT;
     

    SELECT:

    Para SELECT sugiro que crie visões. Eis esboço para a visão que obtém dados de cliente físico:

    -- código #2
    CREATE VIEW vw_cliente_fisico 
    as
    SELECT C.cod_cliente, CF.colunas
      from tb_cliente as C
           inner join tb_cliente_fisico as CF on CF.cod_cliente = C.cod_cliente;

    Para consultar, utilize algo como

        SELECT cod_cliente, nome_fisico, email_cliente
          from vw_cliente_fisico
          where ...

     


    José Diz     Belo Horizonte, MG - Brasil     [T-SQL performance tuning: Porto SQL]   [e-mail]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    sábado, 20 de julho de 2019 23:42
  • Mantenho o identity somente no cod_cliente na tabela tb_cliente, é isso?
    domingo, 21 de julho de 2019 00:04
  • Gato Tocando Piano,

    Se você deseja criar uma chave primária autonumerada ou trabalhar com o conceito de chave primária artificial denominada Surrogate Key, sim, mantenha.

    Mas é claro essa é uma decisão sua, que deve ser analisada de acordo com suas regras de negócio.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    domingo, 21 de julho de 2019 00:32
  • Mantenho o identity somente no cod_cliente na tabela tb_cliente, é isso?

    Considerando-se que o que está a implementar é uma especialização, é isso mesmo.

    Ao incluir linha na tabela tb_cliente um novo valor é gerado para a coluna cod_cliente, por causa da propriedade IDENTITY; este valor gerado é capturado pela função scope_identity(), memorizado na variável @cod_cliente e então armazenado na coluna cod_cliente da tabela tb_cliente_fisico (ou tb_cliente_juridico).

    ---

    Se quiser também pode gerar o valor da coluna cod_cliente da tabela tb_cliente por outro método. Nesse caso o código #1 deve ser alterado, para refletir o novo método. No artigo “Geração de sequências numéricas” você encontra outras técnicas para gerar automaticamente valores de chave.

     


    José Diz     Belo Horizonte, MG - Brasil     [T-SQL performance tuning: Porto SQL]   [e-mail]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Editado José Diz terça-feira, 23 de julho de 2019 20:16
    domingo, 21 de julho de 2019 02:14
  • Quando li este tópico me pareceu um exercício acadêmico de implementação física de modelagem de dados. Mas, no dia a dia, nem sempre se implementa no banco de dados o que está no modelo de dados, por questões de melhoria de performance. No caso do seu exemplo, às vezes é melhor implementar tudo em uma única tabela.

    Por exemplo:

    -- código #3
    -- Autor: José Diz/BH

    CREATE TABLE tb_cliente ( cod_cliente int not null identity, email varchar(100) not null, nome varchar(50) not null, rg varchar(12) null, cpf varchar(11) null, cnpj varchar(14) null, datanasc date null, razao_social varchar(20) null, constraint tb_cliente_PK primary key (cod_cliente) );

    Observe que todas as colunas estão em uma mesma tabela, tanto para pessoa física quanto jurídica.

    ---

    Para garantir a especialização, acrescenta-se a seguinte restrição:

    -- código #4
    -- Autor: José Diz/BH

    ALTER TABLE tb_cliente ADD CONSTRAINT ck_PFPJ check ((CNPJ is not null and RAZAO_SOCIAL is not null and CPF is null and RG is null and DATANASC is null) or (CPF is not null and RG is not null and DATANASC is not null and CNPJ is null and RAZAO_SOCIAL is null) );

    Isso garante que ou será incluída linha de pessoa física ou de pessoa jurídica.

    --- 

    A implementação das especializações utiliza as seguintes visões:

    -- código #5
    -- Autor: José Diz/BH

    CREATE VIEW tb_cliente_fisico as SELECT cod_cliente, cpf, email, nome, rg, datanasc from tb_cliente where CPF is not null; go CREATE VIEW tb_cliente_juridico as SELECT cod_cliente, cnpj, email, nome as nome_fantasia, razao_social from tb_cliente where CNPJ is not null; go
     

    ---

    A utilização é um processo bem simples:

    -- código #6
    -- Autor: José Diz/BH
    
    -- inclusão de pessoa física
    INSERT into tb_cliente_fisico (email, nome, rg, cpf, datanasc) values ('not@email.me', 'pessoa física', '982683', '00100100101', '20010101'); SELECT * from tb_cliente_fisico; SELECT * from tb_cliente; -- inclusão de pessoa jurídica
    INSERT into tb_cliente_juridico (email, cnpj, nome_fantasia, razao_social) values ('contato@empresa.ind', '01001001000122', 'nome fantasia', 'nome oficial'); SELECT * from tb_cliente_juridico; SELECT * from tb_cliente;


    As visões também podem ser utilizadas para instruções UPDATE e DELETE.

     

    Se esta resposta ajudou a resolver seu problema, lembre-se de marcá-la.


    José Diz     Belo Horizonte, MG - Brasil     [T-SQL performance tuning: Porto SQL]   [e-mail]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Editado José Diz domingo, 21 de julho de 2019 11:54
    domingo, 21 de julho de 2019 11:06