2011-07-11 34 views
21

Tengo dos tablas para las que me gustaría crear una clave foránea.Crear una clave externa compuesta en SQL Server 2008

tabla principal

PK - Key1 - varchar(20) 
PK - Key2 - date 

tabla secundaria

PK - AutoID 
FK - Key1 - varchar(20) 
FK - Key2 - date 

Cuando trato de crear la relación entre la tabla primaria y secundaria, me siguen dando el mensaje

Las columnas i n la tabla principal no coincide con una clave primaria o una restricción única .

Puede haber muchos registros en la tabla secundaria con el mismo Key1 y Key2 por lo que convertimos la clave principal en un número creado automáticamente.

¿Alguna idea sobre cómo puedo configurar la relación de clave externa entre estas dos tablas?

+4

Botón1 y Key2 en la tabla principal no son una clave compuesta primaria (o una restricción única) – gbn

+2

Botón1 y Key2 en la tabla principal se configuran como el compuesto Clave primaria. – Danielle

+1

¿Cómo está intentando configurar la restricción exactamente? – JNK

Respuesta

13

Algo de esto se centra, algo de esto es el contexto para otros que tengan cualquier tipo de problema como este (como alguien realmente busca en primer lugar?)

La primera cosa a comprobar cuando se tiene un problema al crear una clave es asegúrese de que no coincidan los tipos de datos en las dos tablas. Si tiene un bigint en uno y un int en el otro, explotará. Esto es cierto en todas las claves, pero es más probable que surja si usa varios campos. La matemática simple muestra la razón por la cual aumenta la probabilidad.

El próximo problema son los datos. Si no puede crear la clave debido a los datos, debe averiguar qué existe en la tabla secundaria que no existe en la tabla principal. IZQUIERDA ÚNASE a las tablas (secundarias en el segundo/lado izquierdo de la combinación) y solo incluya las filas donde la tabla principal es nula. Deberá crear estos registros en la tabla padre o deshacerse de ellos.

Una forma "alrededor" de esto es establecer una nueva clave principal en la tabla principal. A continuación, crea una clave externa en esta nueva clave principal y combina tantos registros como sea posible en la tabla secundaria. A continuación, tiene configurada la unión y puede realizar la limpieza como una operación secundaria.

Cual es mejor? ¿Nueva clave principal o trabaja con la clave compuesta? Esto realmente depende de la naturaleza de los datos, pero estoy más interesado en usar una clave derivada sobre una clave natural o una clave compuesta. Pero, hay ocasiones en que el trabajo necesario para obtener una clave derivada de un solo campo es mucho trabajo.

+0

¡Gracias! Esta descripción ayudó a resolver el problema. – Danielle

+2

Busqué y encontré esta respuesta, entonces sí, algunos buscan primero. ;) – HPWD

11

Esto funcionará:

CREATE TABLE PTable (
    Key1 varchar(20) not null, 
    Key2 date not null, 
    constraint PK_PTable PRIMARY KEY (Key1,Key2) 
) 

CREATE TABLE STable (
    AutoID int IDENTITY(1,1) not null primary key, 
    Key1 varchar(20) not null, 
    Key2 date not null, 
    constraint FK_STable_PTable FOREIGN KEY (Key1,Key2) references PTable (Key1,Key2) 
) 

Lo que hay que hacer es conseguir Management Studio para la escritura de las tablas y los comparamos con los anteriores.

33

Una clave externa DEBE hacer referencia a las columnas que componen un índice único (PK o UK) con el mismo número de columnas, sus tipos y el orden. Ej .:

CREATE TABLE PrimaryTable (
    Key1 varchar(20), 
    Key2 date) 
GO 

ALTER TABLE PrimaryTable ADD CONSTRAINT PK 
    PRIMARY KEY (Key1, Key2) 
GO 

CREATE TABLE SecondaryTable (
    AutoID int IDENTITY, 
    Key1 varchar(20), 
    Key2 date) 
GO 

ALTER TABLE SecondaryTable ADD CONSTRAINT FK 
    FOREIGN KEY (Key1, Key2) REFERENCES PrimaryTable (Key1, Key2) 
GO 
+10

Me ha picado esto hoy: tener las claves referenciadas en un orden diferente al que se declararon sobre la mesa. – TheKaptain

+1

Mismo problema aquí que TheKaptain. Las columnas a las que se hace referencia deben estar en el mismo orden en que se creó la clave. Para obtener el orden correcto, haga clic con el botón secundario en la clave externa (debajo de la carpeta de claves cuando expanda la tabla en SSMS) y cree secuencias de comandos en el portapapeles. Pegar. Asegúrese de que las columnas a las que hace referencia estén en el mismo orden que su clave. – Trevor

5

Hay algunas buenas respuestas aquí, pero me gustaría ir un paso más allá - en aras de la posteridad.

Una clave foránea tiene que hacer referencia a Primary key (Unique, Clustered Index) o Unique column en otra tabla. Básicamente, el componente necesario es la restricción Unique. Añadiría que puede tener columnas anulables en su clave foránea, PERO si permite nulos en una clave "compuesta", SQL omite la verificación de los datos en la relación de clave foránea. Este es un punto importante para recordar ya que la razón principal por la que la mayoría de nosotros usamos claves externas es para garantizar la integridad de los datos en nuestras bases de datos.

Como nota final, me gusta declarar explícitamente todos mis nombres de clave. ¿Por qué? ¿Podrías preguntar? Si necesita usar "Indización de texto completo" en el futuro para obtener mejores capacidades de búsqueda, al no hacerlo, se le obliga a hacer referencia a todos los nombres "autogenerados" de las claves. Esto puede no ser un gran problema para proyectos pequeños que no requieren transformación de datos o actualizaciones de índice de texto completo programadas, pero si está creando una secuencia de comandos de esta funcionalidad podría dificultar su trabajo (por ejemplo, tener que buscar el nombre real de su Primaria Nombre predeterminado de la clave: pk_someTable_1248594832828495904).

Esto es lo que yo haría en escribir el código SQL para evitar cualquier escollo futuras:

  1. no permiten valores NULL en claves externas compuestas si es posible.
  2. Claves de nombre que utilizan explícitamente una convención de nomenclatura convenida (por ejemplo, PK_Schema/56_TalbeName_Col1_Col2). Esto no solo le proporciona un nombre estándar para la clave, sino que también puede ver fácilmente en el índice a qué columnas se hace referencia y en qué orden.

El Código:

CREATE TABLE MySchema.PrimaryTable ( 
    Key1 varchar(20) NOT NULL, 
    Key2 date NOT NULL, 
    CONSTRAINT PK_MySchema_PrimaryTable_Key1_Key2 PRIMARY KEY (Key1, Key2) 
) 
GO 

CREATE TABLE MySchema.SecondaryTable ( 
    AutoID int IDENTITY, 
    Key1 varchar(20) NOT NULL, 
    Key2 date NOT NULL, 
    CONSTRAINT FK_MySchema_SecondaryTable_Key1_Key2 
    FOREIGN KEY (Key1, Key2) REFERENCES PrimaryTable (Key1, Key2) 
) 
GO 

OptillectTeam es básicamente muerto en con su respuesta. Solo quería aclarar algunas cosas importantes que no se habían mencionado antes. Hay una buena referencia en MSDN sight sobre esto y más sobre claves foráneas: Foreign Key Constraint.

0

para añadir uso único tecla debajo de CONSULTA

ALTER TABLE [TableName] ADD UNIQUE ([Column1], [Column2]); 
Cuestiones relacionadas