Domanda

Sto cercando di aggiungere una colonna (MSSQL 2005) a una tabella (Employee) con un vincolo predefinito di una chiave primaria di un'altra tabella (Dipartimento). Quindi ho intenzione di rendere questa colonna un FK per quella tabella. In sostanza, questo assegnerà i nuovi dipendenti a un dipartimento di base basato sul nome del dipartimento se non viene fornito nessun ID reparto.
Questo non funziona:

DECLARE     @ErrorVar       INT
DECLARE     @DepartmentID       INT

SELECT      @DepartmentID = DepartmentID
FROM        Department
WHERE       RealName = 'RocketScience'

ALTER TABLE     [Employee]
ADD             [DepartmentID] INT NULL
CONSTRAINT      [DepartmentIDOfAssociate] DEFAULT (@DepartmentIDAssociate)
SELECT @ErrorVar = @@Error
IF (@ErrorVar <> 0)
BEGIN
    GOTO FATAL_EXIT
END

I database di produzione, test e sviluppo non sono più sincronizzati e il DepartmentID per DepartmentName = & # 8216; RocketScience & # 8217; può essere o meno lo stesso, quindi non voglio solo dire DEFAULT (numero di riferimento). Continuo a ricevere & # 8220; Le variabili non sono consentite nell'istruzione ALTER TABLE & # 8221; non importa in che modo attacco il problema.
Qual è il modo corretto per farlo? Ho provato a nidificare anche l'istruzione select che ottiene & # 8220; Le subquery non sono consentite in questo contesto. Sono ammesse solo espressioni scalari. & # 8221;

Inoltre, ciò che sarebbe davvero fantastico potrei popolare i valori di colonna in un'istruzione invece di eseguire

{ALTER null}
{Aggiorna valori}
{ALTER not null}

passaggi. Ho letto qualcosa sul comando WITH VALUES ma non sono riuscito a farlo funzionare. Grazie !!!

È stato utile?

Soluzione

È possibile racchiudere il codice per trovare l'ID reparto in una funzione memorizzata e utilizzarlo nell'istruzione del vincolo DEFAULT:

CREATE FUNCTION dbo.GetDepartment()
RETURNS INT
AS
BEGIN
  DECLARE         @DepartmentID           INT

  SELECT          @DepartmentID = DepartmentID
  FROM            Department
  WHERE           RealName = 'RocketScience'

  RETURN @DepartmentID
END

E poi:

ALTER TABLE     [Employee]
ADD                     [DepartmentID] INT NULL
CONSTRAINT      [DepartmentIDOfAssociate] DEFAULT (dbo.GetDepartment())

Aiuta?

Marc

Altri suggerimenti

La risposta accettata ha funzionato alla grande (grazie marc_s) ma dopo averci pensato per un po 'ho deciso di fare un altro percorso.
Principalmente perché ci deve essere una funzione sul server che penso finisca per essere chiamata ogni volta che viene aggiunto un dipendente.
Se in seguito qualcuno avesse incasinato la funzione, nessuno avrebbe potuto inserire un dipendente e il motivo non sarebbe ovvio. (Anche se questo non è vero, allora ci sono ancora funzioni extra sul server che non hanno bisogno di essere lì)

Quello che ho fatto è stato assemblare dinamicamente il comando in una variabile e quindi chiamarlo usando il comando EXECUTE.

Non solo, ma da quando ho usato la parola chiave DEFAULT con NOT NULL la tabella è stata nuovamente popolata e non ho dovuto eseguire più comandi per farlo. L'ho scoperto per fortuna ...

DECLARE     @ErrorVar                   INT
DECLARE     @DepartmentIDRocketScience          INT
DECLARE     @ExecuteString                  NVARCHAR(MAX)

SELECT          @DepartmentIDRocketScience = DepartmentID
FROM            Department
WHERE           RealName = 'RocketScience'

SET @ExecuteString = ''
SET @ExecuteString = @ExecuteString + 'ALTER TABLE      [Employee] '
SET @ExecuteString = @ExecuteString + 'ADD              [DepartmentID] INT NOT NULL '
SET @ExecuteString = @ExecuteString + 'CONSTRAINT       [DF_DepartmentID_RocketScienceDepartmentID] DEFAULT ' +CAST(@DepartmentIDAssociate AS NVARCHAR(MAX))
EXECUTE (@ExecuteString)
SELECT @ErrorVar = @@Error
IF (@ErrorVar <> 0)
BEGIN
    GOTO FATAL_EXIT
END

Se si applica il vincolo di chiave esterna dopo aver aggiunto la colonna, è possibile utilizzare qualsiasi valore per il valore predefinito quando si modifica la tabella. Quindi è possibile eseguire un'istruzione di aggiornamento con il valore della variabile.

ALTER TABLE Employee 
ADD DepartmentID INT NOT NULL
Default -1;

UPDATE Employee
SET Employee.DepartmentID = @DepartmentID
WHERE DepartmentID = -1;

ALTER TABLE Employee 
ADD CONSTRAINT fk_employee_to_department FOREIGN KEY (DepartmentID) 
REFERENCES Department;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top