2010-11-07 76 views
65

Tengo una tabla Administrator con solo una columna, adminId que es la clave principal. Debido a las reglas de negocios, tiene que ser así.Insertar filas en una tabla con una columna IDENTITY solamente

Me gustaría entender de una vez por todas cómo puedo escribir procedimientos almacenados que insertan valores en tablas como esta. Estoy usando SQL Server y T-SQL e intenté usar SCOPE_IDENTITY() pero eso no funciona, ya que la tabla tiene INSERT_IDENTITY en falso o desactivado.

Realmente me gustaría no insertar un valor ficticio solo para poder insertar una nueva fila. ¡Gracias!

+1

Para aclarar: su pregunta es "¿cómo insertar filas en una tabla de SQL Server con una sola columna de IDENTIDAD"? – gbn

+0

Sí, tiene razón, gracias por aclarar – Phil

+1

Para las personas que aterricen aquí, esto se ha preguntado antes y la respuesta correcta está aquí: http: // stackoverflow.com/questions/850327/how-to-insert-into-a-table-with-just-one-identity-column – BJury

Respuesta

111

Si usted tiene una columna que es una identidad, simplemente hacer esto

INSERT MyTable DEFAULT VALUES; --allows no column list. The default will be the IDENTITY 
SELECT SCOPE_IDENTITY(); 

Si no tiene identidad, ¿puede configurarla? Esta es la mejor manera ... y usa el SQL anterior.

Si no es así, que desea insertar una nueva fila

INSERT MyTable (admidid) 
OUTPUT INSERTED.admidid --returns result to caller 
SELECT ISNULL(MAX(admidid), 0) + 1 FROM MyTable 

Notas:

  • bajo altas cargas la solución MAX puede fallar con duplicados
  • SCOPE_IDENTITY es después el hecho, no antes de
  • SCOPE_IDENTITY solo funciona con una columna de IDENTIDAD. Lo mismo ocurre con cualquier idiotez usando IDENT_CURRENT
  • La cláusula de salida reemplaza SCOPE_IDENTITY para la solución MAX
+0

Gracias, pero ¿qué quiere decir con "duplicTes"? – Phil

+3

Su primera proposición funcionó bien. ¡Gracias! – Phil

+0

@Phil: De nada. "duplicTes" fue un error tipográfico :) – gbn

0

es necesario agregar la IDENTITY_INSERT a su sentencia de selección:

SET IDENTITY_INSERT MyTable ON 

INSERT INTO MyTable 
(AdminCol) 

SELECT AdminColValue 

FROM Tableb 

Cuando haya terminado, asegúrese de recordar a

SET IDENTITY_INSERT MyTable OFF 

He aquí una buena descripción de cómo funciona desde BOL : http://msdn.microsoft.com/en-us/library/aa259221(SQL.80).aspx

+0

Se supone que debo hacerlo así: SET IDENTITY_INSERT Administrador ON INSERT INTO Administrator (SCOPE_IDENTITY()) SET IDENTITY_INSERT Administrador OFF ? – Phil

+0

Sí. Eso es todo lo que necesitas hacer. SET ON, escriba su código, SET OFF al final. – DataWriter

+0

No creo que esta sea la respuesta correcta. Si se trata de una columna de identidad, no debería agregarle valores. La respuesta aceptada es la respuesta correcta. – Mmm

0

@Phil: ¿No quiere decir que su mesa tiene dos (2) columnas, la columna de PK autoincremental y una columna ADMINNAME? Si solo tiene una columna donde va AdminName, el AdminName es el PK y usted no puede autoincrementar una cadena, por supuesto. ¿Las reglas comerciales esperan que usted haga de un nombre de usuario de Windows totalmente calificado la clave principal? Eso sería viable y tendría sentido, porque entonces no necesitaría un índice único alternativo en la columna AdminName.

Pero si la tabla tiene dos columnas, no uno:

En SQL Server el incremento automático es parte de la definición de la tabla/columna. Usted define la columna como un número entero y luego también la convierte en una columna de identidad , especificando el incremento, generalmente 1, pero podría ser 2 o 5 o 10 o lo que sea. Para insertar una fila, sólo tiene que insertar la otra columna (s) valor (s) y no hace nada con la columna de PK:

insert into T 
(foo) -- column(s) list 
values('bar') -- values list 

Su procedimiento almacenado que realiza la inserción puede hacer SCOPE_IDENTITY un valor de retorno o SCOPE_IDENTITY puede ser pasó de nuevo al cliente como un parámetro OUT.

P.S.SCOPE_IDENTITY() devuelve el valor de identidad autoincrementado generado más recientemente en el alcance actual; no genera el siguiente valor de identidad.

EDIT:

Presumiblemente, su mesa Administradores contiene un conjunto de administradores. Pero si no tiene columnas que no sean la columna de clave principal entera, no hay forma de identificar a los administradores; lo único que puedes hacer es distinguirlos entre sí. Eso no te lleva muy lejos en absoluto. Pero si la tabla administrador tenía una de las siguientes estructuras:

ID INTEGER PRIMARY KEY AUTOINCREMENT 
windowsusername varchar(50) (unique index) 

O

windowsusername varchar(50) primary key 

que sería capaz de hacer referencia a la tabla del administrador de otras tablas, y las claves externas sería significativo. Y eso es precisamente lo que carece una tabla que consta de una sola columna entera, es decir.

Tener dos columnas, entonces podría tener un procedimiento almacenado hacer esto:

insert into Administrators 
(windowsusername) 
values('mydomain\someusername'); 
return SCOPE_IDENTITY(); 

y su cliente-programa que volver como un valor de retorno de la Identificación del autoincremented que había sido generada automáticamente y asignado a la recién insertado fila. Este enfoque es la práctica habitual, e incluso llegaría a decir que se considera una "mejor práctica".

P.S. Menciona que no sabía cómo "insertar un valor" si "no tenía nada que insertar". Hay una contradicción allí. Si no tiene nada para insertar, ¿por qué insertar? ¿Por qué crearía, por ejemplo, un nuevo registro de CLIENTE si no sabe absolutamente nada sobre el cliente? No su nombre, su ciudad, su número de teléfono, ¿nada?

+2

Mi tabla tiene UNA columna, adminId, que es un valor int incremental – Phil

+0

Ese es el diseño más extraño que he visto, y he estado en el negocio por más de 20 años y he visto algunas cosas extrañas en mi día. Entonces su pregunta es, ¿cómo se inserta en una tabla que contiene solo una columna de clave principal definida como una columna de identidad autoincrementing, cuando la tabla contiene esa columna PK y solo esa columna PK, no hay otras columnas ... – Tim

+0

¿Cuál es el voto negativo de ? ¿Un error fáctico en alguna parte o para expresar una opinión sobre la falta de mérito del diseño? – Tim

-2

Siempre que establezcamos la propiedad de identidad de una columna "Activada", no necesitamos insertar valores explícitamente en esa columna. SQL Server implícitamente inserta valores en la columna de identidad en función del valor incremental. Aquí veremos cómo podemos insertar valores en la columna de identidad de forma explícita. En primer lugar, crearemos una tabla con una columna de identidad.

A continuación se muestra la secuencia de comandos para crear la tabla con una columna de identidad: -

create table Identitytable(id int identity,Name varchar(50)) 

En la tabla “Identitytable”, he definido la columna “ID” como una columna de identidad. Vamos a insertar algunas filas en esta tabla sin insertar valores explícitamente en la columna "Id".

insert into Identitytable(Name) values('Neeraj') 
insert into Identitytable(Name) values('Raj') 
insert into Identitytable(Name) values('Akshay') 
insert into Identitytable(Name) values('Ankit') 
insert into Identitytable(Name) values('Vikas') 

Vamos a correr por encima de secuencia de comandos para insertar filas en la tabla 5 “Identitytable” y vamos a ver lo que se inserta en la tabla.

En la imagen de arriba podemos ver los valores para la columna de identificación (1,2,3,4,5), mientras que no insertamos explícitamente los valores en la columna "Id". Ahora intentemos insertar valores en la columna "Id" de forma explícita.

En el siguiente script, estamos tratando de insertar el valor "9" en la columna "Id" explícitamente, veamos cuál es el resultado de la consulta de inserción a continuación.

insert into Identitytable(Id,Name) values(9,'Mamta') 
+2

Otro artículo de copiar y pegar de tu blog. Por favor no hagas esto! No nos importa publicar un poco de autoblog, si es _genuinely_ relevante, pero no con todas las respuestas, por favor. – halfer

Cuestiones relacionadas