2009-03-18 15 views
5

Sto tentando di aggiungere una colonna (MSSQL 2005) a una tabella (Impiegato) con un vincolo predefinito di una chiave primaria di un'altra tabella (Reparto). Quindi renderò questa colonna un FK a quel tavolo. In sostanza, questo assegnerà i nuovi dipendenti a un reparto base in base al nome del reparto se non viene fornito DepartmentID.
Questo non funziona:ALTER TABLE con valore DEFAULT costante costante programmato

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 

la produzione, test e database di sviluppo sono cresciuti fuori sincronia e la DepartmentID per il DepartmentName = 'RocketScience' può o non può essere la stessa in modo da non voglio per dire solo DEFAULT (somenumber). Continuo a ricevere "Le variabili non sono consentite nell'istruzione ALTER TABLE", indipendentemente dal modo in cui attacco il problema.
Qual è il modo corretto per farlo? Ho provato a nidificare anche l'istruzione select che ottiene "Le subquery non sono consentite in questo contesto. sono ammessi solo espressioni scalari “.

Inoltre, quello che sarebbe davvero grande ho potuto popolare i valori delle colonne in una dichiarazione invece di fare il

{ALTER null}
{valori Aggiornamento}
{ALTER non nullo}

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

risposta

5

Si potrebbe avvolgere il codice per trovare il tuo ID reparto in una funzione memorizzata e l'uso che nella sua dichiarazione 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()) 

fa questo aiuto?

Marc

+0

Cercherò ma ho pensato che la documentazione ha detto solo funzioni di sistema consentiti ... –

+0

Provatelo - ho fatto - lavorato per me (su SQL Server 2008, che è - ma dubito che questo è cambiato tra il 2005 e il 2008) –

+0

Accetto la tua risposta ha funzionato alla grande! –

8

La risposta accettata lavorato grandi (marc_s Grazie), ma dopo che ho pensato per un po 'ho deciso di andare un altro itinerario.
Principalmente perché sul server deve rimanere una funzione che, a mio avviso, viene chiamata ogni volta che viene aggiunto un dipendente.
Se qualcuno ha incasinato la funzione in un secondo momento, nessuno potrebbe entrare in un dipendente e la ragione non sarebbe ovvia. (Anche se non è vero, ci sono ancora altre funzioni sul server che non devono essere presenti)

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

Non solo, ma poiché ho usato la parola chiave DEFAULT con NOT NULL, la tabella è tornata popolata e non ho dovuto eseguire più comandi per farlo. Ho scoperto che uno su dalla 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 
2

Se si applica il vincolo di chiave esterna dopo aver aggiunto la colonna, è possibile utilizzare qualsiasi valore per il valore di default 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;