2010-04-08 11 views
11
CREATE TABLE SupplierQuote 
(
supplierQuoteID int identity (3504,2) CONSTRAINT supquoteid_pk PRIMARY KEY, 
PONumber int identity (9553,20) NOT NULL 
. 
. 
. 
CONSTRAINT ponumber_uq UNIQUE(PONumber) 
); 

el DDL de SQL anterior produce un error:Cómo aumentar automáticamente la clave no principal? - Servidor

Msg 2744, Level 16, State 2, Line 1 Multiple identity columns specified for table 'SupplierQuote'. Only one identity column per table is allowed.

cómo puedo solucionarlo? Quiero que PONumber aumente automáticamente.

Respuesta

7

No puede tener más de una columna de identidad por tabla. Creo que su mejor opción sería extraer los datos de PO en una tabla separada, luego relacionar los dos con una columna de FK.

SupplierQuote 
------------- 
supplierQuoteID (PK/identity) 
purchaseOrderID (FK to PurchaseOrder.purchaseOrderID) 
otherColumn1 

PurchaseOrder 
------------- 
purchaseOrderID (PK/identity) 
otherColumn1 
+0

El problema es que cuando se elimine el registro supplierQuoteID, el purchaseOrder in parent table será inútil. Por lo tanto, tendré que escribir un desencadenante o algo así para borrar el registro padre purchaseOrder. Decidí insertar PONumber manualmente desde el front-end utilizando un generador aleatorio o algo así. – user311509

+0

No utilizaría un generador de números aleatorios si desea asegurarse de que los números PON sean únicos. Yo usaría Guid.NewGuid(). Las dos formas más sencillas de garantizar la exclusividad en una base de datos son usar identidad o un GUID. –

+0

También puede eliminar en cascada: cuando elimina un providerQuote, configura la eliminación para que se realice en cascada en el registro PurchaseOrder asociado, siempre que no esté asociado a ningún otro SupplierQuote. –

2

No puede resolverlo; solo puede tener una sola columna IDENTITY por mesa. No hay forma de evitar eso, lo siento.

La única solución "hackosa" sería tener una tabla separada para nada más que tener un campo INT IDENTITY, y obtener el último valor de esa tabla auxiliar en su entidad después de la inserción (por ejemplo, con un desencadenador). No es muy bonito, pero podría funcionar para ti.

9

Si SupplierQuoteId y PONumber se generan cuando se inserta una fila, a continuación, las dos columnas de "identidad" serían asignados al mismo paso (3504 va con 9553, 3506 va con 9573, 3508 va con 9593, etc.) . Si esta hipótesis es verdadera, entonces presumiblemente podría hacer PONumber una columna calculada, así:

CREATE TABLE SupplierQuote 
( 
supplierQuoteID int NOT NULL identity (3504,2) CONSTRAINT supquoteid_pk PRIMARY KEY, 
PONumber AS (10 * supplierQuoteID - 25487) 
. 
. 
. 
); 

hice supplierQuoteId NOT NULL, lo que asegura que PONumber también será NO NULO. Del mismo modo, ya no necesita la restricción única en PONumber, ya que siempre será único. (Es posible crear índices en columnas calculadas, si necesita uno para el rendimiento.)

0

Creo que usaría un disparador para completar la "segunda identidad".

1

Si solo hay un id. De OC por cotización de proveedor, ¿por qué no utilizar simplemente el Id de cotización de proveedor como ID de OC?

Si puede haber más de una, debe tener una tabla separada con una restricción de clave externa. Por supuesto, puede utilizar la eliminación en cascada para eliminar de esta tabla, pero esto puede ser peligroso si elimina demasiados registros (causando bloqueos) o personalmente no quisiera eliminar una oferta de proveedor si se ha creado un número de pedido, ya que eso significa que el artículo cotizado fue realmente comprado. No desea destruir nunca registros de cosas que fueron realmente compradas. Dado que es probable que tenga varios puntos de venta (obtuve una cotización en seis cosas y primero compré tres de ellos, luego compré otros dos la semana siguiente) por cada cotización y ya que es probable que desee almacenar información específica sobre la orden de compra, recomiende una mesa separada. Hacer cualquier otra cosa te causará problemas a largo plazo.

0

Aumento circunstancial automático en la columna de no identidad. (MS SQL) ¡No creo que esta sea la mejor práctica! JUst una solución de solución rápida.

INSERT INTO [dbo].[Employee] 
      ([EmpID] 
      ,[Name] 
      ,[Salary] 
      ,[Address] 
      ,[datecoded]) 
    VALUES 
      ((select top 1 EmpID from dbo.Employee order by EmpID desc) + 1 
      , 'name_value' 
      , 123456 
      ,'address_value' 
      , GETDATE()) 
Cuestiones relacionadas