Crie uma tabela "INTO" com chave primária

8

Talvez para esta comunidade meu problema seja fácil, mas para mim (um simples programador Java) é um GRANDE problema.

Eu tenho um grande banco de dados com mais e mais dados. Portanto, o administrador externo do banco de dados havia criado um trabalho que me mostrava em uma tabela temporária os dados necessários. Mas ele criou a tabela sem uma chave primária e, quando meu projeto java for ler esta tabela, obtenho um erro.

Não consigo ler esta tabela porque a chave primária não existe.

Posso inserir no procedimento a possibilidade de criar uma chave primária autoincremental sem alterar a estrutura desse procedimento complexo?

Este é o início do código do procedimento armazenado:

USE [MYDB]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER Procedure [dbo].[spSchedula_Scadenzario]
as
begin

    drop table MYDB.dbo.tmpTable


 select 
  aa.*
    into MYDB.dbo.tmpTable 
from (...)

desde já, obrigado

PaolaG
fonte

Respostas:

5

Parece que você está procurando a função IDENTITY () :

É usado apenas em uma instrução SELECT com uma cláusula de tabela INTO para inserir uma coluna de identidade em uma nova tabela.

USE [MYDB]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER Procedure [dbo].[spSchedula_Scadenzario]
as
begin

    drop table MYDB.dbo.tmpTable


     select 
    -- Create new identity here.
    NewPrimaryKey = IDENTITY(int, 1, 1),
    aa.*
    into MYDB.dbo.tmpTable 
from (...)
Shaneis
fonte
14
@Paola Embora fique claro, isso aborda apenas a parte de incremento automático da pergunta. A tabela ainda não possui chave primária.
Martin Smith
9

Algumas alternativas para adicionar a coluna de incremento automático através da IDENTITY()função sugerida por @Shaneis são:

  1. Crie a tabela explicitamente usando em CREATE TABLEvez de usar SELECT INTO. Eu prefiro muito esse método, pois fornece controle completo sobre a tabela que está sendo criada, como a inclusão da coluna de incremento automático e a especificação da chave primária. Por exemplo:

    CREATE TABLE dbo.tmpTable
    (
      tmpTableID INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
      ...
      {all columns represented by aa.* in the sample query in the Question}
    );
  2. Se você não puder alterar como / quando / onde a tabela está sendo criada, sempre poderá adicionar uma coluna posteriormente e, ao fazer isso, poderá especificar que seja uma IDENTITYcoluna e ter a Chave Primária criada nela. Por exemplo:

    ALTER TABLE [dbo].[tmpTable]
      ADD [tmpTableID] INT NOT NULL
      IDENTITY(1, 1)
      PRIMARY KEY;

    Isso funciona mesmo se a tabela já tiver dados: a nova IDENTITYcoluna será preenchida conforme o esperado, começando com o valor especificado para o seedparâmetro. No entanto, não há como controlar a ordem na qual os valores são atribuídos (que é um dos vários motivos para a opção 1, se possível).

Notas Adicionais:

  • Você tem certeza de que precisa de uma Chave Primária e não simplesmente de uma coluna com incremento automático / exclusivo? Embora normalmente seja uma boa ideia ter uma Chave Primária, ela não é necessária nem a mesma coisa que uma coluna de incremento automático. Eu só pergunto porque o título e o texto desta pergunta indicam que você precisa de uma chave primária, mas você está dizendo em um comentário sobre a resposta que você aceitou que simplesmente a coluna de auto incremento funcionava.

  • A tabela que você está usando não é realmente uma tabela temporária. Tabelas temporárias reais têm nomes começando com #, ou ##para tabelas temporárias globais. A tabela que você está usando dbo.tmpTableé apenas uma tabela permanente e regular prefixada com "tmp" para indicar que provavelmente é apenas para esse processo e não faz parte do modelo de dados.

    Se o código do aplicativo não precisar acessar esta tabela "temporária" e a única referência a ela estiver neste procedimento armazenado, considere alterá-la para ser uma tabela temporária real, com a vantagem de ser limpa quando o processo é concluído; nesse caso, você não precisaria da DROP TABLEdeclaração.

  • Se você usará uma tabela permanente em vez de uma tabela temporária (nesse caso, você precisará limpá-la), a DROP TABLEinstrução deverá ser condicional, de modo que não ocorra erro se a tabela não existir:

    IF (OBJECT_ID(N'dbo.tmpTable') IS NOT NULL)
    BEGIN
       DROP TABLE dbo.tmpTable;
    END;
  • Em vez de fazer SELECT *, você deve especificar a lista completa de colunas. O uso *aumenta a probabilidade de interrupção do processo quando você adiciona colunas / campos a tabelas ou subconsultas (seja qual aafor o alias).

Solomon Rutzky
fonte