Erstellen Sie eine INTO-Tabelle mit Primärschlüssel

8

Vielleicht ist mein Problem für diese Community einfach, aber für mich (einen einfachen Java-Programmierer) ist es ein großes Problem.

Ich habe eine große Datenbank mit immer mehr Daten. Der externe Datenbankadministrator hatte also einen Job erstellt, der mir in einer temporären Tabelle die Daten anzeigt, die ich benötige. Aber er hatte die Tabelle ohne Primärschlüssel erstellt und wenn ich mit meinem Java-Projekt diese Tabelle lese, erhalte ich eine Fehlermeldung.

Ich kann diese Tabelle nicht lesen, da der Primärschlüssel nicht vorhanden ist.

Kann ich in die Prozedur die Möglichkeit einfügen, einen automatisch inkrementellen Primärschlüssel zu erstellen, ohne die Struktur dieser komplexen Prozedur zu ändern?

Dies ist der Beginn des Codes für gespeicherte Prozeduren:

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

Danke im Voraus

PaolaG
quelle

Antworten:

5

Klingt so, als würden Sie nach der Funktion IDENTITY () suchen :

Wird nur in einer SELECT-Anweisung mit einer INTO-Tabellenklausel verwendet, um eine Identitätsspalte in eine neue Tabelle einzufügen.

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
quelle
13
@Paola Um klar zu sein, wird hier nur der Teil der Frage mit automatischem Inkrement behandelt. Die Tabelle hat noch keinen Primärschlüssel.
Martin Smith
9

Einige Alternativen zum Hinzufügen der Auto-Inkrement-Spalte über die IDENTITY()von @Shaneis vorgeschlagene Funktion sind:

  1. Erstellen Sie die Tabelle explizit mit CREATE TABLEanstatt mit SELECT INTO. Ich bevorzuge diese Methode sehr, da Sie damit die vollständige Kontrolle über die zu erstellende Tabelle haben, z. B. die Spalte für die automatische Inkrementierung einschließen und angeben, dass es sich um den Primärschlüssel handelt. Zum Beispiel:

    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. Wenn Sie nicht ändern können, wie / wann / wo die Tabelle erstellt wird, können Sie später jederzeit eine Spalte hinzufügen. Dabei können Sie sowohl angeben, dass es sich um eine IDENTITYSpalte handelt, als auch den Primärschlüssel erstellen . Zum Beispiel:

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

    Dies funktioniert sogar, wenn die Tabelle bereits Daten enthält: Die neue IDENTITYSpalte wird wie erwartet ausgefüllt, beginnend mit dem für den seedParameter angegebenen Wert . Es gibt jedoch keine Möglichkeit, die Reihenfolge zu steuern, in der die Werte zugewiesen werden (dies ist einer von mehreren Gründen, wenn möglich, Option 1 zu wählen).

Zusätzliche Bemerkungen:

  • Sind Sie sicher, dass Sie einen Primärschlüssel und nicht nur eine automatisch inkrementierende / eindeutige Spalte benötigen? Während es normalerweise eine gute Idee ist, einen Primärschlüssel zu haben, ist er weder erforderlich noch dasselbe wie eine automatisch inkrementierende Spalte. Ich frage nur, weil sowohl der Titel als auch der Text dieser Frage besagen, dass Sie einen Primärschlüssel benötigen, aber Sie sagen in einem Kommentar zu der Antwort, dass Sie akzeptiert haben, dass einfach die Spalte für die automatische Inkrementierung funktioniert.

  • Die von Ihnen verwendete Tabelle ist eigentlich keine temporäre Tabelle. Echte temporäre Tabellen haben Namen, die mit #oder ##für globale temporäre Tabellen beginnen. Die Tabelle, die Sie verwenden, dbo.tmpTableist nur eine reguläre, permanente Tabelle, der das Präfix "tmp" vorangestellt ist, um anzuzeigen, dass sie wahrscheinlich nur für diesen Prozess und nicht Teil des Datenmodells ist.

    Wenn der App-Code nicht auf diese "temporäre" Tabelle zugreifen muss und der einzige Verweis darauf in dieser gespeicherten Prozedur enthalten ist, können Sie ihn in eine echte temporäre Tabelle ändern, die den Vorteil hat, dass sie bereinigt wird, wenn Der Vorgang ist abgeschlossen. In diesem Fall benötigen Sie die DROP TABLEAnweisung nicht.

  • Wenn Sie eine permanente Tabelle anstelle einer temporären Tabelle verwenden (in diesem Fall müssen Sie sie selbst bereinigen), sollte die DROP TABLEAnweisung an Bedingungen geknüpft sein, damit sie nicht fehlerhaft ist, wenn die Tabelle nicht vorhanden ist:

    IF (OBJECT_ID(N'dbo.tmpTable') IS NOT NULL)
    BEGIN
       DROP TABLE dbo.tmpTable;
    END;
  • Anstatt dies zu tun SELECT *, sollten Sie die vollständige Spaltenliste angeben. Durch *die Verwendung wird die Wahrscheinlichkeit erhöht, dass der Prozess unterbrochen wird, wenn Sie Tabellen / Unterabfragen Spalten / Felder hinzufügen (für was auch aaimmer ein Alias ​​ist).

Solomon Rutzky
quelle