2009-03-18 11 views
5

J'essaie d'ajouter une colonne (MSSQL 2005) à une table (Employee) avec une contrainte par défaut d'une clé primaire d'une autre table (Department). Ensuite, je vais faire de cette colonne un FK à cette table. Essentiellement, cela affectera les nouveaux employés à un ministère de base en fonction du nom du ministère si aucun ID ministériel n'est fourni.
Cela ne fonctionne pas:ALTER TABLE avec une valeur DEFAULT constante déterminée par programme

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 production, le test et les bases de données de développement ont augmenté désynchronisé et DepartmentID pour la DepartmentName = « Rocketscience » peut ou ne peut pas être le même si je ne veux pas juste pour dire DEFAULT (somenumber). Je continue d'obtenir "Les variables ne sont pas autorisées dans l'instruction ALTER TABLE" peu importe la manière dont j'attaque le problème.
Quelle est la bonne façon de faire cela? J'ai essayé d'imbriquer l'instruction select qui obtient "Les sous-requêtes ne sont pas autorisées dans ce contexte. Seuls les expressions scalaires sont autorisées. »

En outre, ce serait vraiment génial que je pouvais remplir les valeurs de colonne dans une instruction au lieu de faire la

{ALTÉRER null}
{valeurs de mise à jour}
{modifie pas null}

pas. J'ai lu quelque chose à propos de la commande WITH VALUES mais je n'ai pas réussi à le faire fonctionner. Merci !!!

Répondre

5

Vous pouvez envelopper le code pour trouver votre numéro de service dans une fonction stockée et l'utiliser dans votre déclaration de contrainte DEFAULT:

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

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

    RETURN @DepartmentID 
END 

Et puis:

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

Est-ce que l'aide?

Marc

+0

Je vais essayer, mais je pensais que la documentation a dit que les fonctions du système autorisés ... –

+0

Essayez - je l'ai fait - travaillé pour moi (sur SQL Server 2008, qui est - mais je doute que cela a changé entre 2005 et 2008) –

+0

J'accepte votre réponse cela a bien fonctionné! –

8

La réponse acceptée fonctionnait très bien (marc_s Merci), mais après que je pensais à ce sujet pendant un certain temps, je décide d'aller un autre itinéraire.
Principalement parce qu'il doit y avoir une fonction à gauche sur le serveur qui, je pense, finit par être appelée à chaque fois qu'un employé est ajouté.
Si quelqu'un a joué avec la fonction plus tard alors personne ne pouvait entrer un employé et la raison ne serait pas évidente. (Même si ce n'est pas vrai alors il y a encore des fonctions supplémentaires sur le serveur qui n'ont pas besoin d'être là)

Ce que j'ai fait était d'assembler la commande dynamiquement dans une variable, puis d'appeler cela en utilisant la commande EXECUTE. Non seulement cela, mais puisque j'ai utilisé le mot-clé DEFAULT avec NOT NULL la table a été remplie de nouveau et je n'ai pas eu à exécuter plusieurs commandes pour le faire. Je trouve que l'un par hasard ...

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

Si vous appliquez votre clé étrangère après avoir ajouté la colonne, vous pouvez utiliser une valeur pour la valeur par défaut lors de la modification de la table. Ensuite, vous pouvez exécuter une instruction de mise à jour avec votre valeur de variable.

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;