Créer une table «INTO» avec clé primaire


8

Peut-être que pour cette communauté mon problème est facile, mais pour moi (un simple programmeur Java) c'est un GRAND problème.

J'ai une Big DB avec de plus en plus de données. Ainsi, l'administrateur externe de la base de données a créé un travail qui me montre dans une table temporaire les données dont j'ai besoin. Mais il avait créé la table sans clé primaire et quand avec mon projet java allez lire cette table, j'obtiens une erreur.

Je ne peux pas lire ce tableau car la clé primaire n'existe pas.

Puis-je insérer dans la procédure la possibilité de créer une clé primaire auto-incrémentale sans changer la structure de cette procédure complexe?

C'est le début du code de procédure stockée:

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 (...)

Merci d'avance

Réponses:


5

On dirait que vous recherchez la fonction IDENTITY () :

Est utilisé uniquement dans une instruction SELECT avec une clause de table INTO pour insérer une colonne d'identité dans une nouvelle table.

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 (...)

14
@Paola Bien que pour être clair, cela ne concerne que la partie incrémentation automatique de la question. La table n'a toujours pas de clé primaire.
Martin Smith

9

Quelques alternatives à l'ajout de la colonne d'incrémentation automatique via la IDENTITY()fonction comme suggéré par @Shaneis sont:

  1. Créez la table explicitement en utilisant CREATE TABLEau lieu d'utiliser SELECT INTO. Je préfère de beaucoup cette méthode car elle vous donne un contrôle complet sur la table en cours de création, comme l'inclusion de la colonne d'incrémentation automatique et la spécification de la clé primaire. Par exemple:

    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. Si vous ne pouvez pas changer comment / quand / où la table est créée, vous pouvez toujours ajouter une colonne plus tard, et ce faisant, vous êtes autorisé à spécifier à la fois qu'il s'agit d'une IDENTITYcolonne et que la clé primaire est créée dessus. Par exemple:

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

    Cela fonctionne même si la table contient déjà des données: la nouvelle IDENTITYcolonne sera remplie comme prévu, en commençant par la valeur spécifiée pour le seedparamètre. Cependant, il n'y a aucun moyen de contrôler l'ordre dans lequel les valeurs sont affectées (ce qui est l'une des nombreuses raisons d'aller avec l'option # 1, si possible).

Notes complémentaires:

  • Êtes-vous sûr d'avoir besoin d'une clé primaire et pas simplement d'une colonne auto-incrémentée / unique? Bien que ce soit généralement une bonne idée d'avoir une clé primaire, ce n'est ni requis ni la même chose qu'une colonne à incrémentation automatique. Je demande seulement parce que le titre et le texte de cette question indiquent que vous avez besoin d'une clé primaire, mais vous dites dans un commentaire sur la réponse que vous avez accepté que le simple fait de faire fonctionner la colonne d'incrémentation automatique.

  • La table que vous utilisez n'est pas réellement une table temporaire. Les tables temporaires réelles ont des noms commençant par #ou ##pour les tables temporaires globales. La table que vous utilisez dbo.tmpTableest juste une table régulière et permanente qui est préfixée avec "tmp" pour indiquer qu'elle est probablement juste pour ce processus et ne fait pas partie du modèle de données.

    Si le code d'application n'a pas besoin d'accéder à cette table "temporaire", et que la seule référence à celle-ci se trouve dans cette procédure stockée, alors vous pouvez envisager de la changer en une véritable table temporaire, qui a l'avantage d'être nettoyée lorsque le processus se termine, auquel cas vous n'avez pas besoin de l' DROP TABLEinstruction.

  • Si vous allez utiliser une table permanente au lieu d'une table temporaire (auquel cas vous devez la nettoyer vous-même), alors l' DROP TABLEinstruction doit être conditionnelle, de sorte qu'elle ne génère pas d'erreur si la table n'existe pas:

    IF (OBJECT_ID(N'dbo.tmpTable') IS NOT NULL)
    BEGIN
       DROP TABLE dbo.tmpTable;
    END;
    
  • Plutôt que de le faire SELECT *, vous devez spécifier la liste complète des colonnes. L'utilisation *rend le processus plus susceptible de s'arrêter lorsque vous ajoutez des colonnes / champs à des tables ou des sous-requêtes (quel que aasoit l'alias).

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.