Insert en tabal seleccionando el ultimo ID+1 de esa tabla

30/09/2004 - 12:09 por Miguel Tubia | Informe spam
Hola a todos,
tengo una tabla que tiene una clave principal compuesta por dos propiedades:
id_cliente y tipo.
En un procedimiento tengo un proceso que miro todos los tipos posibles de
clientes y, cogiendo datos de otras tablas, relleno la de clientes.
El codigo id_cliente es númerico consecutiva, pero por cada cliente, por lo
que no es autonumerica ni nada de eso.
En la consulta tengo que meter las claves: el tipo me lo da una variable y
el id_cliente lo tendría que coger haciendo algo similar a

select isnull(max(id_cliente),0)+1

Quedando la insert ma o meno:

insert into Clientes
(id_cliente, tipo, nombre, ... (resto campos))
select (select isnull(max(id_cliente),0)+1 from Clientes where tipo=@tipo),
@tipo, d.nombre
from datos d
where d.tipo=@tipo

mas o menos. Las condiciones no son esas pero para hacernos una idea de como
va
Pues el problema es que al coger el max de id_cliente, me coge bien el
primero, pero luego ya no, me da error, parece q solo lo hace una vez.
¿Alguien sabe como se puede hacer? Estoy buscando pero no encuestro nada (tb
teniendo en cuenta q es jueves es normal...)
Muchas gracias por su ayuda
Un saludo

Preguntas similare

Leer las respuestas

#1 Maxi
30/09/2004 - 15:07 | Informe spam
Hola y que error te tira?


Salu2
Maxi
Buenos Aires - Argentina
Desarrollador Microsoft 3 Estrellas .NET
Nunca consideres el estudio como una obligación sino como
una oportunidad para penetrar en el bello y maravillosos
mundo del saber.
- Albert Einstein



"Miguel Tubia" <####m_tubiaARROBAhotmail.com###> escribió en el mensaje
news:%
Hola a todos,
tengo una tabla que tiene una clave principal compuesta por dos


propiedades:
id_cliente y tipo.
En un procedimiento tengo un proceso que miro todos los tipos posibles de
clientes y, cogiendo datos de otras tablas, relleno la de clientes.
El codigo id_cliente es númerico consecutiva, pero por cada cliente, por


lo
que no es autonumerica ni nada de eso.
En la consulta tengo que meter las claves: el tipo me lo da una variable y
el id_cliente lo tendría que coger haciendo algo similar a

select isnull(max(id_cliente),0)+1

Quedando la insert ma o meno:

insert into Clientes
(id_cliente, tipo, nombre, ... (resto campos))
select (select isnull(max(id_cliente),0)+1 from Clientes where


tipo=@tipo),
@tipo, d.nombre
from datos d
where d.tipo=@tipo

mas o menos. Las condiciones no son esas pero para hacernos una idea de


como
va
Pues el problema es que al coger el max de id_cliente, me coge bien el
primero, pero luego ya no, me da error, parece q solo lo hace una vez.
¿Alguien sabe como se puede hacer? Estoy buscando pero no encuestro nada


(tb
teniendo en cuenta q es jueves es normal...)
Muchas gracias por su ayuda
Un saludo







Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.769 / Virus Database: 516 - Release Date: 24/09/2004
Respuesta Responder a este mensaje
#2 Javier Loria
30/09/2004 - 15:42 | Informe spam
Hola:
El numerar filas en SQL requiere una "logica" especial porque su
naturaleza es precisamente no ser ordenado y por supuesto no ser numerado.
Olvidandonos un poco de Insert y enfocandonos en el SELECT, cual seria
el criterio para asignar un numero a una fila y no otra?
Si lo vemos por partes
Es claro que la siguiente sentencia devuelve el siguiente numero de ID
para un tipo.
==SELECT ISNULL(MAX(ID,0)) -- COALESCE?
FROM Clientes
WHERE TIPO=@Tipo
== Pero esta sentencia se ejectuara una vez y no para cada una fila, ya que
el INSERT funciona en bloque, todo de un golpe. Entonces es necesario que
numeremos de 1 en adelante las filas que viene del SELECT, para esto debemos
fijar algun criterio para ordenarlas y numerarlas. Si asumimos que el
criterio es el nombre y que los nombres no se repiten para cada tipo,
entonces puedes hacer:
==SELECT D.Nombre, COUNT(*) AS Consecutivo
FROM Datos AS D
JOIN Datos AS D2
ON D.Nombre>Ò.Nombre
AND D.Tipo=@Tipo
AND D2.Tipo=@Tipo
GROUP BY D.Nombre
==El anterior SELECT "cuenta" cuantos nombres son menores cada uno, con lo
cual asigna un numero consecutivo.
Combinando los SELECT puedes lograr el Insert deseado, pero es
complicado.
==INSERT INTO Clientes(id_cliente, tipo, nombre, ...)
SELECT
(SELECT ISNULL(MAX(ID,0))
FROM Clientes
WHERE TIPO=@Tipo)+Numerados.Consecutivo
, @Tipo
, Datos.Nombre
, Datos.
FROM Datos
JOIN (SELECT D.Nombre, COUNT(*) AS Consecutivo
FROM Datos AS D
JOIN Datos AS D2
ON D.Nombre>Ò.Nombre
AND D.Tipo=@Tipo
AND D2.Tipo=@Tipo
GROUP BY D.Nombre) AS Numerados
ON Datos.Nombre=Numerados.Consecutivo
== Todo esto podria evitarse si se usara un Llave Primaria Natural, por lo
que si es posible evitar ese ID (Eliminaria la columna) y trataria de
usarla, claro asumiendo que existe.
Saludos,


Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda

"Miguel Tubia" <####m_tubiaARROBAhotmail.com###> wrote in message
news:#
Hola a todos,
tengo una tabla que tiene una clave principal compuesta por dos


propiedades:
id_cliente y tipo.
En un procedimiento tengo un proceso que miro todos los tipos posibles de
clientes y, cogiendo datos de otras tablas, relleno la de clientes.
El codigo id_cliente es númerico consecutiva, pero por cada cliente, por


lo
que no es autonumerica ni nada de eso.
En la consulta tengo que meter las claves: el tipo me lo da una variable y
el id_cliente lo tendría que coger haciendo algo similar a

select isnull(max(id_cliente),0)+1

Quedando la insert ma o meno:

insert into Clientes
(id_cliente, tipo, nombre, ... (resto campos))
select (select isnull(max(id_cliente),0)+1 from Clientes where


tipo=@tipo),
@tipo, d.nombre
from datos d
where d.tipo=@tipo

mas o menos. Las condiciones no son esas pero para hacernos una idea de


como
va
Pues el problema es que al coger el max de id_cliente, me coge bien el
primero, pero luego ya no, me da error, parece q solo lo hace una vez.
¿Alguien sabe como se puede hacer? Estoy buscando pero no encuestro nada


(tb
teniendo en cuenta q es jueves es normal...)
Muchas gracias por su ayuda
Un saludo


Respuesta Responder a este mensaje
#3 Miguel Tubia
30/09/2004 - 17:51 | Informe spam
Hola,
jeje, es verdad, mucha chapa y luego olvido poner lo importante.
Precisamente me dice que no puedo poner una clave duplicada en esa tabla,
por eso doy por supuesto que el select max solo lo hace para el primer
registro a insertar. en internet he visto gente con este problema, seguiré
investigando, pero si alguien me puede echar una mano se lo agradeceré
Muchas gracias
Un saludo
Respuesta Responder a este mensaje
#4 Maxi
30/09/2004 - 18:03 | Informe spam
El tema es que si ese select tiene muchos registros le va querer poner el
mismo max a todos!!

Deberias de ver el ejemplo de Javier para este caso o sino ver la forma no
hacer select masivos


Salu2
Maxi
Buenos Aires - Argentina
Desarrollador Microsoft 3 Estrellas .NET
Nunca consideres el estudio como una obligación sino como
una oportunidad para penetrar en el bello y maravillosos
mundo del saber.
- Albert Einstein



"Miguel Tubia" <####m_tubiaARROBAhotmail.com###> escribió en el mensaje
news:%
Hola,
jeje, es verdad, mucha chapa y luego olvido poner lo importante.
Precisamente me dice que no puedo poner una clave duplicada en esa tabla,
por eso doy por supuesto que el select max solo lo hace para el primer
registro a insertar. en internet he visto gente con este problema, seguiré
investigando, pero si alguien me puede echar una mano se lo agradeceré
Muchas gracias
Un saludo







Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.769 / Virus Database: 516 - Release Date: 24/09/2004
Respuesta Responder a este mensaje
#5 Miguel Tubia
01/10/2004 - 12:15 | Informe spam
Hola,
gracias por la respuesta y la ayuda.
He estado trabajando sobre tu ejemplo, solo que las tablas sobre las que
trabajo son algo liosas, ahora te comento.
Antes me gustaría decir que son BD de terceros, por lo que no puedo
modificarlas.
He estado buscando, como comentaste, un criterio para ordenarlas, pero me
está siendo imposible. El nombre no es único se repite en varios registros
diferentes. pensaba, quizás, en la clave primaria, pero es una compuesta por
3 registro: fecha, servicio y masreg, y la verdad, por el nombre no sabemos
como se adjudica cada una. Mas o menos, la fecha es cuando ese cliente hizo
un servicio, el servicio es un numerico sucesivo por cada fecha y masreg ni
idea Pero esto es lo q creemos
He probado con d1.fecha>Ò.fecha and d1.servicio>Ò.servicio and
d1.MasReg>Ò.MasReg pero no me sale, lógicamente.
En fin, que no hay ningún dato único en la tabla que no se repite, por eso
intentaba combinar varios.
¿Alguna idea de como lo podría hacer? Una opcion sería cursores pero no nos
agrada la idea
Antes de empezas sabemos cuantos clientes tenemos que leer, quizás con
alguna variable o algo, no sé... buf q lio, voy a seguir mirando si se
os ocurre algo se agradecerá la ayuda
Muchas gracias por todo
Un saludo


"Javier Loria" escribió en el mensaje
news:
Hola:
El numerar filas en SQL requiere una "logica" especial porque su
naturaleza es precisamente no ser ordenado y por supuesto no ser numerado.
Olvidandonos un poco de Insert y enfocandonos en el SELECT, cual seria
el criterio para asignar un numero a una fila y no otra?
Si lo vemos por partes
Es claro que la siguiente sentencia devuelve el siguiente numero de ID
para un tipo.
==> SELECT ISNULL(MAX(ID,0)) -- COALESCE?
FROM Clientes
WHERE TIPO=@Tipo
==> Pero esta sentencia se ejectuara una vez y no para cada una fila, ya


que
el INSERT funciona en bloque, todo de un golpe. Entonces es necesario que
numeremos de 1 en adelante las filas que viene del SELECT, para esto


debemos
fijar algun criterio para ordenarlas y numerarlas. Si asumimos que el
criterio es el nombre y que los nombres no se repiten para cada tipo,
entonces puedes hacer:
==> SELECT D.Nombre, COUNT(*) AS Consecutivo
FROM Datos AS D
JOIN Datos AS D2
ON D.Nombre>Ò.Nombre
AND D.Tipo=@Tipo
AND D2.Tipo=@Tipo
GROUP BY D.Nombre
==> El anterior SELECT "cuenta" cuantos nombres son menores cada uno, con lo
cual asigna un numero consecutivo.
Combinando los SELECT puedes lograr el Insert deseado, pero es
complicado.
==> INSERT INTO Clientes(id_cliente, tipo, nombre, ...)
SELECT
(SELECT ISNULL(MAX(ID,0))
FROM Clientes
WHERE TIPO=@Tipo)+Numerados.Consecutivo
, @Tipo
, Datos.Nombre
, Datos.
FROM Datos
JOIN (SELECT D.Nombre, COUNT(*) AS Consecutivo
FROM Datos AS D
JOIN Datos AS D2
ON D.Nombre>Ò.Nombre
AND D.Tipo=@Tipo
AND D2.Tipo=@Tipo
GROUP BY D.Nombre) AS Numerados
ON Datos.Nombre=Numerados.Consecutivo
==> Todo esto podria evitarse si se usara un Llave Primaria Natural, por


lo
que si es posible evitar ese ID (Eliminaria la columna) y trataria de
usarla, claro asumiendo que existe.
Saludos,


Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda

"Miguel Tubia" <####m_tubiaARROBAhotmail.com###> wrote in message
news:#
> Hola a todos,
> tengo una tabla que tiene una clave principal compuesta por dos
propiedades:
> id_cliente y tipo.
> En un procedimiento tengo un proceso que miro todos los tipos posibles


de
> clientes y, cogiendo datos de otras tablas, relleno la de clientes.
> El codigo id_cliente es númerico consecutiva, pero por cada cliente, por
lo
> que no es autonumerica ni nada de eso.
> En la consulta tengo que meter las claves: el tipo me lo da una variable


y
> el id_cliente lo tendría que coger haciendo algo similar a
>
> select isnull(max(id_cliente),0)+1
>
> Quedando la insert ma o meno:
>
> insert into Clientes
> (id_cliente, tipo, nombre, ... (resto campos))
> select (select isnull(max(id_cliente),0)+1 from Clientes where
tipo=@tipo),
> @tipo, d.nombre
> from datos d
> where d.tipo=@tipo
>
> mas o menos. Las condiciones no son esas pero para hacernos una idea de
como
> va
> Pues el problema es que al coger el max de id_cliente, me coge bien el
> primero, pero luego ya no, me da error, parece q solo lo hace una vez.
> ¿Alguien sabe como se puede hacer? Estoy buscando pero no encuestro nada
(tb
> teniendo en cuenta q es jueves es normal...)
> Muchas gracias por su ayuda
> Un saludo
>
>


Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida