Problema importación datos incrementales.

27/12/2006 - 12:42 por Salvador Ramos | Informe spam
Hola a todos,

Tengo una tabla origen en la cual no tengo PK, y cuento con algunas
repetidas (filas totalmente iguales, con el mismo valor en todas sus
columnas:

CREATE TABLE [dbo].[avlValec](
[Empresa] [int] NULL,
[cliente] [int] NULL,
[tipo_fact] [char](2) COLLATE Modern_Spanish_CI_AS NULL,
[num_tarjeta] [char](19) COLLATE Modern_Spanish_CI_AS NULL,
[fecha] [smalldatetime] NULL,
[num_mvto] [varchar](10) COLLATE Modern_Spanish_CI_AS NULL,
[cod_articulo] [varchar](8) COLLATE Modern_Spanish_CI_AS NULL,
[denominacion] [varchar](40) COLLATE Modern_Spanish_CI_AS NULL,
[pvp_iva] [decimal](8, 3) NULL,
[tipo_dto] [char](1) COLLATE Modern_Spanish_CI_AS NULL,
[canti] [decimal](8, 2) NULL,
[importe_vale] [decimal](8, 2) NULL,
[impor_dto] [decimal](7, 2) NULL,
[dto] [decimal](6, 3) NULL,
[iva] [decimal](3, 1) NULL,
[codigo_esta] [int] NULL,
[hora] [varchar](4) COLLATE Modern_Spanish_CI_AS NULL,
[matricula] [char](10) COLLATE Modern_Spanish_CI_AS NULL,
[fecha_factu] [smalldatetime] NULL,
[num_factu] [varchar](10) COLLATE Modern_Spanish_CI_AS NULL,
[facturado] [char](1) COLLATE Modern_Spanish_CI_AS NULL,
[contab] [char](1) COLLATE Modern_Spanish_CI_AS NULL
) ON [PRIMARY]

Y otra tabla destino en la que tengo que insertar filas desde la tabla
origen anterior. Esta tabla contiene algunas columnas procedentes de la
tabla anterior (no todas).

CREATE TABLE [dbo].[andGasoleoProfMov](
[IdMovCont] [char](21) COLLATE Modern_Spanish_CI_AS NOT NULL,
[CIM] [char](8) COLLATE Modern_Spanish_CI_AS NOT NULL,
[Fecha] [datetime] NOT NULL,
[Hora] [char](4) COLLATE Modern_Spanish_CI_AS NOT NULL,
[CodPro] [char](3) COLLATE Modern_Spanish_CI_AS NOT NULL,
[Lit] [decimal](7, 2) NOT NULL,
[NIF] [char](9) COLLATE Modern_Spanish_CI_AS NOT NULL,
[Matricula] [varchar](12) COLLATE Modern_Spanish_CI_AS NOT NULL,
[Estado] [char](1) COLLATE Modern_Spanish_CI_AS NOT NULL,
[Fichero] [varchar](50) COLLATE Modern_Spanish_CI_AS NOT NULL,
[FechaAudit] [datetime] NOT NULL,
[Empresa] [int] NOT NULL,
CONSTRAINT [PK_andGasoleoProfMov] PRIMARY KEY CLUSTERED
(
[IdMovCont] ASC
) ON [PRIMARY]
) ON [PRIMARY]

Las columnas Estado, Fichero y FechaAudit al importar los datos quedan en
blanco y posteriormente las actualizan otros procesos.

Necesito realizar un proceso periódico para la importación de datos nuevos
en la tabla andGasoleoProfMov, pero al no tener PK la tabla de origen y
tener filas totalmente idénticas, me dan problemas todas las soluciones que
se me han ocurrido, y no consigo hacerlo.
No es posible poner una PK a la tabla origen, ya que es una tabla de mi ERP
de la cual sólo puedo leer datos, en ningún caso modificar su estructura.
Algunos de los datos de la tabla destino salen de otras tablas, pero no he
querido complicarlo aquí, ya que puedo hacer join a ellas y obtenerlos sin
ningún problema.

Si se os ocurre alguna solución, os estaré muy agradecido, ya que pretendo
solucionar un problema importante para mi emrpresa, y además voy
contrareloj, tenía que estar hecho para ayer :-(

Muchas gracias

Un saludo
Salvador Ramos
Murcia - España

[Microsoft MVP SQL Server / MCTS: SQL Server 2005]
www.helpdna.net (información sobre SQL Server y .NET)

Preguntas similare

Leer las respuestas

#11 Salvador Ramos
29/12/2006 - 17:34 | Informe spam
Muchas gracias Alejandro,

El martes en cuanto llegue a la oficina y retome los temas reviso lo que me
indicas. Precisamente por ahí estoy trabajando la solución, y Miguel Egea
también me habló del artículo de Itzik.

La verdad que si es gran lío, pero todo viene de que realmente el ERP
funciona con los antiguos y obsoletos ficheros btrieve. Gracias a que
evolucionó a Pervasive SQL y tengo un proveedor ole db, puedo acceder en
modo sólo lectura a dichos datos y extraerlos. Pero claro, todo está
diseñado con la filosofía obsoleta de ficheros y punteros a registros,
incluso me han argumentado que cuando necesitan clave única, desde la
aplicación utilizan un número interno de registro (es algo propio de btrieve
y a lo que no tengo acceso). :-(

Un saludo
Salvador Ramos
Murcia - España

[Microsoft MVP SQL Server / MCTS: SQL Server 2005]
www.helpdna.net (información sobre SQL Server y .NET)


"Alejandro Mesa" escribió en el
mensaje news:
Salvador,

Vaya lio en el que te han metido esos tios, por no seguir la mas basica
regla de los sistemas rdbms.

Trata creando una vista que agrupe por todas las columnas involucradas y
que
calcule la cantidad de duplicados. Esa vista la debes crear dos veces una
para origen y la otra para destino. Luego selecionas las filas que machen
y
donde la cantidad de duplicados no sea la misma. La diferencia de los
duplicados dara la cantidad de veces que se necesita insertar la fila y
con
el uso de una tabla auxiliar de numeros insertas esa cantidad.

create view dbo.vw_o
as
select c1, c2, ..., cn, count(*) as cnt
from dbo.origen
group by c1, c2, ..., cn
go

create view dbo.vw_d
as
select c1, c2, ..., cn, count(*) as cnt
from dbo.destino
group by c1, c2, ..., cn
go

select
o.c1, o.c2, ..., o.cn, (o.cnt - d.cnt) as cnt
into
#t
from
dbo.vw_o as o, dbo.vw_d as d
where
(o.c1 = d.c1 or (o.c1 is null and d.c1 is null))
and (o.c2 = d.c2 or (o.c2 is null and d.c2 is null))
...
and (o.cn = d.cn or (o.cn is null and d.cn is null))
and o.cnt > d.cnt

insert into dbo.destino(c1, c2, ..., cn)
select t.c1, t.c2, ..., t.cn
from #t as t, dbo.numero as n
where n.numero <= t.cnt

drop table #t
go

Si estas usando 2005, puedes crear la tabla auxiliar de #s en el aire. Hay
un articulo muy interesante, de Itzik Ben-Gan, en la ultima edicion de la
revista sql magazine o en su libro "Inside Microsoft SQL Server 2005:
T-SQL
Querying" sobre como hacerlo.

Claro esta que esta solucion sera lenta, puesto que cada vez que ejecutes
el
script, se debera calcular el agregado para toda la tabla. Quizas puedas
usar
alguna de las columnas tipo fecha para calcular el agregado solo de la
fecha
en cuestion.


AMB

"Salvador Ramos" wrote:

Hola Carlos,

Perdona que te ande liando, realmente te puse un ejemplo para explicar la
situación, pero realmente son tablas más complejas, con más columnas y
diversos tipos de datos. Las que envié en el primer post de este hilo.

Estoy trabajando con el amigo Miguel Egea en una solución basada en una
tabla intermedia donde pueda generar una PK y ya a partir de ahí pueda
importar correctamente. Al menos hemos visto algo de luz para resolver el
problema.

Ya cuento aquí la solución cuando consiga implementarla.
Muchas gracias por tu tiempo.

Un saludo
Salvador Ramos
Murcia - España

[Microsoft MVP SQL Server / MCTS: SQL Server 2005]
www.helpdna.net (información sobre SQL Server y .NET)


"Carlos Sacristán" <csacristanARROBAmvpsPUNTOorg> escribió en el mensaje
news:
> Vaya, nunca dejaré de sorprenderme la cantidad de situaciones en las
> que podemos encontrarnos... parece increíble que necesites algo así.
>
> Mmmmm si tienes una tabla de numeración, prueba con lo
> siguiente. A
> mí me salen las filas que están en la tabla origen y no en la de
> destino
> el número de veces correcto:
>
> select o.c1, o.c2, o.c3
>
> from (select count(*) num, c1, c2, c3 from __origen group by c1, c2,
> c3) o
>
> left join (select count(*) num, c1, c2, c3 from __destino group by c1,
> c2,
> c3) d
>
> on o.c1=d.c1 and o.c2=d.c2 and o.c3=d.c3
>
> full outer join __numeros n on (o.num - isnull(d.num, 0)) > n.num
>
> where o.c1 is not null and o.num > isnull(d.num, 0)
>
>
>
> Un saludo
>
> -
> "Sólo sé que no sé nada. " (Sócrates)
>
> "Salvador Ramos" escribió en el
> mensaje news:%
>> Efectivamente, que en la tabla destino tiene que haber las mismas
>> filas
>> que en la tabla origen, y con lo que indicas no se incluyen las filas
>> que
>> aparecen 2, 3 o más veces en la tabla origen (lo habitual es que haya
>> filas que aparecen dos veces, pero yo lo tengo que plantear
>> independientemente del número de repeticiones que haya.
>>
>> Además imaginate que en la importación de ayer había sólo una fila con
>> los valoeres 1 - 1 - 4 y en la de hoy aparece otra más, esa fila
>> tendría
>> que importarla.
>>
>> Muchas gracias
>>
>> Un saludo
>> Salvador Ramos
>> Murcia - España
>>
>> [Microsoft MVP SQL Server / MCTS: SQL Server 2005]
>> www.helpdna.net (información sobre SQL Server y .NET)
>>
>>
>> "Carlos Sacristán" <csacristanARROBAmvpsPUNTOorg> escribió en el
>> mensaje
>> news:
>>> Bueno, pues si efectivamente lo he entendido bien y no hay más
>>> detalles a tener en cuenta, lo siguiente te devuelve las filas que no
>>> están en la tabla destino:
>>>
>>> select distinct o.* from origen o left join destino d on o.c1=d.c1
>>> and
>>> o.c2=d.c2 and o.c3=d.c3 where d.c1 is null
>>>
>>> No sé. Me da a mí que hay algo más por ahí...
>>>
>>>
>>>
>>> Un saludo
>>>
>>> -
>>> "Sólo sé que no sé nada. " (Sócrates)
>>>
>>> "Salvador Ramos" escribió en el
>>> mensaje news:
>>>> Hola Carlos,
>>>>
>>>> Perdona si no me he explicado bien, es que he intentado resumir un
>>>> poco
>>>> el problema para solucionar su núcleo y que me podáis entender, pero
>>>> creo que no lo he conseguido.
>>>>
>>>> Tengo una tabla Origen (la del primer script) y necesito ir pasando
>>>> datos procedentes de ella a una tabla destino (la del segundo
>>>> script).
>>>> Mi idea es pasar los movimientos que no estén en la tabla Destino y
>>>> si
>>>> en la taba Origen. El problema es que la tabla origen no tiene PK y
>>>> si
>>>> que tiene filas que son idénticas (tienen los mismos valores en
>>>> todas
>>>> sus columnas).
>>>>
>>>> Por ejemplo (con campos inventados) en tabla Origen:
>>>> C1 C2 C3
>>>> 1 1 2
>>>> 1 1 3
>>>> 1 1 4
>>>> 1 1 4
>>>> 1 1 5
>>>>
>>>> Y tabla destino (suponiendo que tenga los mismos campos):
>>>> C1 C2 C3
>>>> 1 1 2
>>>> 1 1 3
>>>>
>>>> Y ahora quiero importar las filas que me faltan en la tabla Destino.
>>>>
>>>> Un saludo
>>>> Salvador Ramos
>>>> Murcia - España
>>>>
>>>> [Microsoft MVP SQL Server / MCTS: SQL Server 2005]
>>>> www.helpdna.net (información sobre SQL Server y .NET)
>>>>
>>>>
>>>> "Carlos Sacristán" <csacristanARROBAmvpsPUNTOorg> escribió en el
>>>> mensaje news:
>>>>> Pero cuál es el problema que te ocurre? No nos dices qué
>>>>> necesitas
>>>>> hacer exactamente...
>>>>>
>>>>>
>>>>> Un saludo
>>>>>
>>>>> -
>>>>> "Sólo sé que no sé nada. " (Sócrates)
>>>>>
>>>>> "Salvador Ramos" escribió en
>>>>> el
>>>>> mensaje news:
>>>>>> Hola a todos,
>>>>>>
>>>>>> Tengo una tabla origen en la cual no tengo PK, y cuento con
>>>>>> algunas
>>>>>> repetidas (filas totalmente iguales, con el mismo valor en todas
>>>>>> sus
>>>>>> columnas:
>>>>>>
>>>>>> CREATE TABLE [dbo].[avlValec](
>>>>>> [Empresa] [int] NULL,
>>>>>> [cliente] [int] NULL,
>>>>>> [tipo_fact] [char](2) COLLATE Modern_Spanish_CI_AS NULL,
>>>>>> [num_tarjeta] [char](19) COLLATE Modern_Spanish_CI_AS NULL,
>>>>>> [fecha] [smalldatetime] NULL,
>>>>>> [num_mvto] [varchar](10) COLLATE Modern_Spanish_CI_AS NULL,
>>>>>> [cod_articulo] [varchar](8) COLLATE Modern_Spanish_CI_AS NULL,
>>>>>> [denominacion] [varchar](40) COLLATE Modern_Spanish_CI_AS NULL,
>>>>>> [pvp_iva] [decimal](8, 3) NULL,
>>>>>> [tipo_dto] [char](1) COLLATE Modern_Spanish_CI_AS NULL,
>>>>>> [canti] [decimal](8, 2) NULL,
>>>>>> [importe_vale] [decimal](8, 2) NULL,
>>>>>> [impor_dto] [decimal](7, 2) NULL,
>>>>>> [dto] [decimal](6, 3) NULL,
>>>>>> [iva] [decimal](3, 1) NULL,
>>>>>> [codigo_esta] [int] NULL,
>>>>>> [hora] [varchar](4) COLLATE Modern_Spanish_CI_AS NULL,
>>>>>> [matricula] [char](10) COLLATE Modern_Spanish_CI_AS NULL,
>>>>>> [fecha_factu] [smalldatetime] NULL,
>>>>>> [num_factu] [varchar](10) COLLATE Modern_Spanish_CI_AS NULL,
>>>>>> [facturado] [char](1) COLLATE Modern_Spanish_CI_AS NULL,
>>>>>> [contab] [char](1) COLLATE Modern_Spanish_CI_AS NULL
>>>>>> ) ON [PRIMARY]
>>>>>>
>>>>>> Y otra tabla destino en la que tengo que insertar filas desde la
>>>>>> tabla origen anterior. Esta tabla contiene algunas columnas
>>>>>> procedentes de la tabla anterior (no todas).
>>>>>>
>>>>>> CREATE TABLE [dbo].[andGasoleoProfMov](
>>>>>> [IdMovCont] [char](21) COLLATE Modern_Spanish_CI_AS NOT NULL,
>>>>>> [CIM] [char](8) COLLATE Modern_Spanish_CI_AS NOT NULL,
>>>>>> [Fecha] [datetime] NOT NULL,
>>>>>> [Hora] [char](4) COLLATE Modern_Spanish_CI_AS NOT NULL,
>>>>>> [CodPro] [char](3) COLLATE Modern_Spanish_CI_AS NOT NULL,
>>>>>> [Lit] [decimal](7, 2) NOT NULL,
>>>>>> [NIF] [char](9) COLLATE Modern_Spanish_CI_AS NOT NULL,
>>>>>> [Matricula] [varchar](12) COLLATE Modern_Spanish_CI_AS NOT NULL,
>>>>>> [Estado] [char](1) COLLATE Modern_Spanish_CI_AS NOT NULL,
>>>>>> [Fichero] [varchar](50) COLLATE Modern_Spanish_CI_AS NOT NULL,
>>>>>> [FechaAudit] [datetime] NOT NULL,
>>>>>> [Empresa] [int] NOT NULL,
>>>>>> CONSTRAINT [PK_andGasoleoProfMov] PRIMARY KEY CLUSTERED
>>>>>> (
>>>>>> [IdMovCont] ASC
>>>>>> ) ON [PRIMARY]
>>>>>> ) ON [PRIMARY]
>>>>>>
>>>>>> Las columnas Estado, Fichero y FechaAudit al importar los datos
>>>>>> quedan en blanco y posteriormente las actualizan otros procesos.
>>>>>>
>>>>>> Necesito realizar un proceso periódico para la importación de
>>>>>> datos
>>>>>> nuevos en la tabla andGasoleoProfMov, pero al no tener PK la tabla
>>>>>> de
>>>>>> origen y tener filas totalmente idénticas, me dan problemas todas
>>>>>> las
>>>>>> soluciones que se me han ocurrido, y no consigo hacerlo.
>>>>>> No es posible poner una PK a la tabla origen, ya que es una tabla
>>>>>> de
>>>>>> mi ERP de la cual sólo puedo leer datos, en ningún caso modificar
>>>>>> su
>>>>>> estructura.
>>>>>> Algunos de los datos de la tabla destino salen de otras tablas,
>>>>>> pero
>>>>>> no he querido complicarlo aquí, ya que puedo hacer join a ellas y
>>>>>> obtenerlos sin ningún problema.
>>>>>>
>>>>>> Si se os ocurre alguna solución, os estaré muy agradecido, ya que
>>>>>> pretendo solucionar un problema importante para mi emrpresa, y
>>>>>> además
>>>>>> voy contrareloj, tenía que estar hecho para ayer :-(
>>>>>>
>>>>>> Muchas gracias
>>>>>>
>>>>>> Un saludo
>>>>>> Salvador Ramos
>>>>>> Murcia - España
>>>>>>
>>>>>> [Microsoft MVP SQL Server / MCTS: SQL Server 2005]
>>>>>> www.helpdna.net (información sobre SQL Server y .NET)
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>
>



Respuesta Responder a este mensaje
#12 Salvador Ramos
02/01/2007 - 18:23 | Informe spam
Muchas gracias Alejandro,

Tras estudiar la solución la he descartado, ya que en la tabla destino si
que necesito tener una Primary Key. Lo que estoy haciendo importar todos los
datos a una tabla temporal, en la que tengo dos nuevas columnas (PK1 y Pk2),
PK1 va a ser un campo de char de muchos caracteres, tantos como la suma de
las columnas con las que pueda conseguir filas "casi" únicas, y luego PK2
será un contador que numere las filas (en la mayoría tendrá el valor 1, y
cuando se obtengan duplicados en PK1 irá sumandole, por ejemplo, si en un
valor de PK1 encuentra 3 duplicados, PK2 tendrá los valores 1, 2 y 3).
Esta tabla pretendo cada vez que lance el proceso hacer un TRUNCATE TABLE y
cargarla de nuevo, de ahí la importancia de que siempre me devuelva el mismo
PK1 para una misma fila (el PK2 al ser idénticas me da igual, sólo lo quiero
para tener valores únicos).
No es una buena solución, pero como el rendimiento no me preocupa en
absoluto (se realizará durante la noche, cuando no hay nadie trabajando con
la base de datos. Lo que si que me preocupa es que el valor de la PK para
una fila que me de hoy sea el mismo que me de en días sucesivos.

Luego ya, partiendo de esta tabla temporal (con PK) importaré las filas que
no existan a la tabla destino.

Se admiten todo tipo de sugerencias :-)

Un saludo
Salvador Ramos
Murcia - España

[Microsoft MVP SQL Server / MCTS: SQL Server 2005]
www.helpdna.net (información sobre SQL Server y .NET)


"Alejandro Mesa" escribió en el
mensaje news:
Salvador,

Estuve leyendo nuevamente mi mensaje anterior y encontre que esa solucion
solo trabaja para encontrar filas que ya existen en ambas tablas, asi que
el
proceso se debera hacer en dos partes:

1 - Insertar las filas origen que no existan del todo en el destino
2 - Insertar los duplicados


Saludos,

Alejandro Mesa


"Salvador Ramos" wrote:

Muchas gracias Alejandro,

El martes en cuanto llegue a la oficina y retome los temas reviso lo que
me
indicas. Precisamente por ahí estoy trabajando la solución, y Miguel Egea
también me habló del artículo de Itzik.

La verdad que si es gran lío, pero todo viene de que realmente el ERP
funciona con los antiguos y obsoletos ficheros btrieve. Gracias a que
evolucionó a Pervasive SQL y tengo un proveedor ole db, puedo acceder en
modo sólo lectura a dichos datos y extraerlos. Pero claro, todo está
diseñado con la filosofía obsoleta de ficheros y punteros a registros,
incluso me han argumentado que cuando necesitan clave única, desde la
aplicación utilizan un número interno de registro (es algo propio de
btrieve
y a lo que no tengo acceso). :-(

Un saludo
Salvador Ramos
Murcia - España

[Microsoft MVP SQL Server / MCTS: SQL Server 2005]
www.helpdna.net (información sobre SQL Server y .NET)


"Alejandro Mesa" escribió en el
mensaje news:
> Salvador,
>
> Vaya lio en el que te han metido esos tios, por no seguir la mas basica
> regla de los sistemas rdbms.
>
> Trata creando una vista que agrupe por todas las columnas involucradas
> y
> que
> calcule la cantidad de duplicados. Esa vista la debes crear dos veces
> una
> para origen y la otra para destino. Luego selecionas las filas que
> machen
> y
> donde la cantidad de duplicados no sea la misma. La diferencia de los
> duplicados dara la cantidad de veces que se necesita insertar la fila y
> con
> el uso de una tabla auxiliar de numeros insertas esa cantidad.
>
> create view dbo.vw_o
> as
> select c1, c2, ..., cn, count(*) as cnt
> from dbo.origen
> group by c1, c2, ..., cn
> go
>
> create view dbo.vw_d
> as
> select c1, c2, ..., cn, count(*) as cnt
> from dbo.destino
> group by c1, c2, ..., cn
> go
>
> select
> o.c1, o.c2, ..., o.cn, (o.cnt - d.cnt) as cnt
> into
> #t
> from
> dbo.vw_o as o, dbo.vw_d as d
> where
> (o.c1 = d.c1 or (o.c1 is null and d.c1 is null))
> and (o.c2 = d.c2 or (o.c2 is null and d.c2 is null))
> ...
> and (o.cn = d.cn or (o.cn is null and d.cn is null))
> and o.cnt > d.cnt
>
> insert into dbo.destino(c1, c2, ..., cn)
> select t.c1, t.c2, ..., t.cn
> from #t as t, dbo.numero as n
> where n.numero <= t.cnt
>
> drop table #t
> go
>
> Si estas usando 2005, puedes crear la tabla auxiliar de #s en el aire.
> Hay
> un articulo muy interesante, de Itzik Ben-Gan, en la ultima edicion de
> la
> revista sql magazine o en su libro "Inside Microsoft SQL Server 2005:
> T-SQL
> Querying" sobre como hacerlo.
>
> Claro esta que esta solucion sera lenta, puesto que cada vez que
> ejecutes
> el
> script, se debera calcular el agregado para toda la tabla. Quizas
> puedas
> usar
> alguna de las columnas tipo fecha para calcular el agregado solo de la
> fecha
> en cuestion.
>
>
> AMB
>
> "Salvador Ramos" wrote:
>
>> Hola Carlos,
>>
>> Perdona que te ande liando, realmente te puse un ejemplo para explicar
>> la
>> situación, pero realmente son tablas más complejas, con más columnas y
>> diversos tipos de datos. Las que envié en el primer post de este hilo.
>>
>> Estoy trabajando con el amigo Miguel Egea en una solución basada en
>> una
>> tabla intermedia donde pueda generar una PK y ya a partir de ahí pueda
>> importar correctamente. Al menos hemos visto algo de luz para resolver
>> el
>> problema.
>>
>> Ya cuento aquí la solución cuando consiga implementarla.
>> Muchas gracias por tu tiempo.
>>
>> Un saludo
>> Salvador Ramos
>> Murcia - España
>>
>> [Microsoft MVP SQL Server / MCTS: SQL Server 2005]
>> www.helpdna.net (información sobre SQL Server y .NET)
>>
>>
>> "Carlos Sacristán" <csacristanARROBAmvpsPUNTOorg> escribió en el
>> mensaje
>> news:
>> > Vaya, nunca dejaré de sorprenderme la cantidad de situaciones en
>> > las
>> > que podemos encontrarnos... parece increíble que necesites algo así.
>> >
>> > Mmmmm si tienes una tabla de numeración, prueba con lo
>> > siguiente. A
>> > mí me salen las filas que están en la tabla origen y no en la de
>> > destino
>> > el número de veces correcto:
>> >
>> > select o.c1, o.c2, o.c3
>> >
>> > from (select count(*) num, c1, c2, c3 from __origen group by c1, c2,
>> > c3) o
>> >
>> > left join (select count(*) num, c1, c2, c3 from __destino group by
>> > c1,
>> > c2,
>> > c3) d
>> >
>> > on o.c1=d.c1 and o.c2=d.c2 and o.c3=d.c3
>> >
>> > full outer join __numeros n on (o.num - isnull(d.num, 0)) > n.num
>> >
>> > where o.c1 is not null and o.num > isnull(d.num, 0)
>> >
>> >
>> >
>> > Un saludo
>> >
>> > -
>> > "Sólo sé que no sé nada. " (Sócrates)
>> >
>> > "Salvador Ramos" escribió en
>> > el
>> > mensaje news:%
>> >> Efectivamente, que en la tabla destino tiene que haber las mismas
>> >> filas
>> >> que en la tabla origen, y con lo que indicas no se incluyen las
>> >> filas
>> >> que
>> >> aparecen 2, 3 o más veces en la tabla origen (lo habitual es que
>> >> haya
>> >> filas que aparecen dos veces, pero yo lo tengo que plantear
>> >> independientemente del número de repeticiones que haya.
>> >>
>> >> Además imaginate que en la importación de ayer había sólo una fila
>> >> con
>> >> los valoeres 1 - 1 - 4 y en la de hoy aparece otra más, esa fila
>> >> tendría
>> >> que importarla.
>> >>
>> >> Muchas gracias
>> >>
>> >> Un saludo
>> >> Salvador Ramos
>> >> Murcia - España
>> >>
>> >> [Microsoft MVP SQL Server / MCTS: SQL Server 2005]
>> >> www.helpdna.net (información sobre SQL Server y .NET)
>> >>
>> >>
>> >> "Carlos Sacristán" <csacristanARROBAmvpsPUNTOorg> escribió en el
>> >> mensaje
>> >> news:
>> >>> Bueno, pues si efectivamente lo he entendido bien y no hay más
>> >>> detalles a tener en cuenta, lo siguiente te devuelve las filas que
>> >>> no
>> >>> están en la tabla destino:
>> >>>
>> >>> select distinct o.* from origen o left join destino d on o.c1=d.c1
>> >>> and
>> >>> o.c2=d.c2 and o.c3=d.c3 where d.c1 is null
>> >>>
>> >>> No sé. Me da a mí que hay algo más por ahí...
>> >>>
>> >>>
>> >>>
>> >>> Un saludo
>> >>>
>> >>> -
>> >>> "Sólo sé que no sé nada. " (Sócrates)
>> >>>
>> >>> "Salvador Ramos" escribió en
>> >>> el
>> >>> mensaje news:
>> >>>> Hola Carlos,
>> >>>>
>> >>>> Perdona si no me he explicado bien, es que he intentado resumir
>> >>>> un
>> >>>> poco
>> >>>> el problema para solucionar su núcleo y que me podáis entender,
>> >>>> pero
>> >>>> creo que no lo he conseguido.
>> >>>>
>> >>>> Tengo una tabla Origen (la del primer script) y necesito ir
>> >>>> pasando
>> >>>> datos procedentes de ella a una tabla destino (la del segundo
>> >>>> script).
>> >>>> Mi idea es pasar los movimientos que no estén en la tabla Destino
>> >>>> y
>> >>>> si
>> >>>> en la taba Origen. El problema es que la tabla origen no tiene PK
>> >>>> y
>> >>>> si
>> >>>> que tiene filas que son idénticas (tienen los mismos valores en
>> >>>> todas
>> >>>> sus columnas).
>> >>>>
>> >>>> Por ejemplo (con campos inventados) en tabla Origen:
>> >>>> C1 C2 C3
>> >>>> 1 1 2
>> >>>> 1 1 3
>> >>>> 1 1 4
>> >>>> 1 1 4
>> >>>> 1 1 5
>> >>>>
>> >>>> Y tabla destino (suponiendo que tenga los mismos campos):
>> >>>> C1 C2 C3
>> >>>> 1 1 2
>> >>>> 1 1 3
>> >>>>
>> >>>> Y ahora quiero importar las filas que me faltan en la tabla
>> >>>> Destino.
>> >>>>
>> >>>> Un saludo
>> >>>> Salvador Ramos
>> >>>> Murcia - España
>> >>>>
>> >>>> [Microsoft MVP SQL Server / MCTS: SQL Server 2005]
>> >>>> www.helpdna.net (información sobre SQL Server y .NET)
>> >>>>
>> >>>>
>> >>>> "Carlos Sacristán" <csacristanARROBAmvpsPUNTOorg> escribió en el
>> >>>> mensaje news:
>> >>>>> Pero cuál es el problema que te ocurre? No nos dices qué
>> >>>>> necesitas
>> >>>>> hacer exactamente...
>> >>>>>
>> >>>>>
>> >>>>> Un saludo
>> >>>>>
>> >>>>> -
>> >>>>> "Sólo sé que no sé nada. " (Sócrates)
>> >>>>>
>> >>>>> "Salvador Ramos" escribió
>> >>>>> en
>> >>>>> el
>> >>>>> mensaje news:
>> >>>>>> Hola a todos,
>> >>>>>>
>> >>>>>> Tengo una tabla origen en la cual no tengo PK, y cuento con
>> >>>>>> algunas
>> >>>>>> repetidas (filas totalmente iguales, con el mismo valor en
>> >>>>>> todas
>> >>>>>> sus
>> >>>>>> columnas:
>> >>>>>>
>> >>>>>> CREATE TABLE [dbo].[avlValec](
>> >>>>>> [Empresa] [int] NULL,
>> >>>>>> [cliente] [int] NULL,
>> >>>>>> [tipo_fact] [char](2) COLLATE Modern_Spanish_CI_AS NULL,
>> >>>>>> [num_tarjeta] [char](19) COLLATE Modern_Spanish_CI_AS NULL,
>> >>>>>> [fecha] [smalldatetime] NULL,
>> >>>>>> [num_mvto] [varchar](10) COLLATE Modern_Spanish_CI_AS NULL,
>> >>>>>> [cod_articulo] [varchar](8) COLLATE Modern_Spanish_CI_AS NULL,
>> >>>>>> [denominacion] [varchar](40) COLLATE Modern_Spanish_CI_AS NULL,
>> >>>>>> [pvp_iva] [decimal](8, 3) NULL,
>> >>>>>> [tipo_dto] [char](1) COLLATE Modern_Spanish_CI_AS NULL,
>> >>>>>> [canti] [decimal](8, 2) NULL,
>> >>>>>> [importe_vale] [decimal](8, 2) NULL,
>> >>>>>> [impor_dto] [decimal](7, 2) NULL,
>> >>>>>> [dto] [decimal](6, 3) NULL,
>> >>>>>> [iva] [decimal](3, 1) NULL,
>> >>>>>> [codigo_esta] [int] NULL,
>> >>>>>> [hora] [varchar](4) COLLATE Modern_Spanish_CI_AS NULL,
Respuesta Responder a este mensaje
#13 Salvador Ramos
03/01/2007 - 22:56 | Informe spam
Finalmente, tras encontrarme con muchos problemas, he optado por una
solución basada en un cursor, que recorre las filas duplicadas y va
modificando los dos últimos caracteres de la clave, que son el contador
utilizado para diferenciar unas filas de otras iguales. Este es el script:

vaya
el cursor
fila a fila
declare @Id int, @PK char(75), @PKant char(75), @dup int
declare CurDuplicados cursor local forward_only
for select Id, PK
from tmpGasoleoProf01
where PK in(select PK from dbo.tmpGasoleoProf01
group by PK having count(*) > 1)
order by PK
open CurDuplicados
fetch next from CurDuplicados into @Id, @PK
while @@fetch_status = 0 begin
set @PKant = @PK
set @dup = 0
while @@fetch_status = 0 and @PK = @PKant begin
set @dup = @dup + 1
update tmpGasoleoProf01
set PK = left(@PK, 73) + right(rtrim('00' + cast(@dup as char(2))), 2)
where current of CurDuplicados
fetch next from CurDuplicados into @Id, @PK
end
end
close CurDuplicados
deallocate CurDuplicados

Creo además que es una solución bastante óptima, ya que suelo tener unas 3
filas repetidas en cada 1000, por lo que los datos a actualizar serán muy
pocos.

Un saludo
Salvador Ramos
Murcia - España

[Microsoft MVP SQL Server / MCTS: SQL Server 2005]
www.helpdna.net (información sobre SQL Server y .NET)


"Salvador Ramos" escribió en el
mensaje news:%
Muchas gracias Alejandro,

Tras estudiar la solución la he descartado, ya que en la tabla destino si
que necesito tener una Primary Key. Lo que estoy haciendo importar todos
los datos a una tabla temporal, en la que tengo dos nuevas columnas (PK1 y
Pk2), PK1 va a ser un campo de char de muchos caracteres, tantos como la
suma de las columnas con las que pueda conseguir filas "casi" únicas, y
luego PK2 será un contador que numere las filas (en la mayoría tendrá el
valor 1, y cuando se obtengan duplicados en PK1 irá sumandole, por
ejemplo, si en un valor de PK1 encuentra 3 duplicados, PK2 tendrá los
valores 1, 2 y 3).
Esta tabla pretendo cada vez que lance el proceso hacer un TRUNCATE TABLE
y cargarla de nuevo, de ahí la importancia de que siempre me devuelva el
mismo PK1 para una misma fila (el PK2 al ser idénticas me da igual, sólo
lo quiero para tener valores únicos).
No es una buena solución, pero como el rendimiento no me preocupa en
absoluto (se realizará durante la noche, cuando no hay nadie trabajando
con la base de datos. Lo que si que me preocupa es que el valor de la PK
para una fila que me de hoy sea el mismo que me de en días sucesivos.

Luego ya, partiendo de esta tabla temporal (con PK) importaré las filas
que no existan a la tabla destino.

Se admiten todo tipo de sugerencias :-)

Un saludo
Salvador Ramos
Murcia - España

[Microsoft MVP SQL Server / MCTS: SQL Server 2005]
www.helpdna.net (información sobre SQL Server y .NET)


"Alejandro Mesa" escribió en el
mensaje news:
Salvador,

Estuve leyendo nuevamente mi mensaje anterior y encontre que esa solucion
solo trabaja para encontrar filas que ya existen en ambas tablas, asi que
el
proceso se debera hacer en dos partes:

1 - Insertar las filas origen que no existan del todo en el destino
2 - Insertar los duplicados


Saludos,

Alejandro Mesa


"Salvador Ramos" wrote:

Muchas gracias Alejandro,

El martes en cuanto llegue a la oficina y retome los temas reviso lo que
me
indicas. Precisamente por ahí estoy trabajando la solución, y Miguel
Egea
también me habló del artículo de Itzik.

La verdad que si es gran lío, pero todo viene de que realmente el ERP
funciona con los antiguos y obsoletos ficheros btrieve. Gracias a que
evolucionó a Pervasive SQL y tengo un proveedor ole db, puedo acceder en
modo sólo lectura a dichos datos y extraerlos. Pero claro, todo está
diseñado con la filosofía obsoleta de ficheros y punteros a registros,
incluso me han argumentado que cuando necesitan clave única, desde la
aplicación utilizan un número interno de registro (es algo propio de
btrieve
y a lo que no tengo acceso). :-(

Un saludo
Salvador Ramos
Murcia - España

[Microsoft MVP SQL Server / MCTS: SQL Server 2005]
www.helpdna.net (información sobre SQL Server y .NET)


"Alejandro Mesa" escribió en
el
mensaje news:
> Salvador,
>
> Vaya lio en el que te han metido esos tios, por no seguir la mas
> basica
> regla de los sistemas rdbms.
>
> Trata creando una vista que agrupe por todas las columnas involucradas
> y
> que
> calcule la cantidad de duplicados. Esa vista la debes crear dos veces
> una
> para origen y la otra para destino. Luego selecionas las filas que
> machen
> y
> donde la cantidad de duplicados no sea la misma. La diferencia de los
> duplicados dara la cantidad de veces que se necesita insertar la fila
> y
> con
> el uso de una tabla auxiliar de numeros insertas esa cantidad.
>
> create view dbo.vw_o
> as
> select c1, c2, ..., cn, count(*) as cnt
> from dbo.origen
> group by c1, c2, ..., cn
> go
>
> create view dbo.vw_d
> as
> select c1, c2, ..., cn, count(*) as cnt
> from dbo.destino
> group by c1, c2, ..., cn
> go
>
> select
> o.c1, o.c2, ..., o.cn, (o.cnt - d.cnt) as cnt
> into
> #t
> from
> dbo.vw_o as o, dbo.vw_d as d
> where
> (o.c1 = d.c1 or (o.c1 is null and d.c1 is null))
> and (o.c2 = d.c2 or (o.c2 is null and d.c2 is null))
> ...
> and (o.cn = d.cn or (o.cn is null and d.cn is null))
> and o.cnt > d.cnt
>
> insert into dbo.destino(c1, c2, ..., cn)
> select t.c1, t.c2, ..., t.cn
> from #t as t, dbo.numero as n
> where n.numero <= t.cnt
>
> drop table #t
> go
>
> Si estas usando 2005, puedes crear la tabla auxiliar de #s en el aire.
> Hay
> un articulo muy interesante, de Itzik Ben-Gan, en la ultima edicion de
> la
> revista sql magazine o en su libro "Inside Microsoft SQL Server 2005:
> T-SQL
> Querying" sobre como hacerlo.
>
> Claro esta que esta solucion sera lenta, puesto que cada vez que
> ejecutes
> el
> script, se debera calcular el agregado para toda la tabla. Quizas
> puedas
> usar
> alguna de las columnas tipo fecha para calcular el agregado solo de la
> fecha
> en cuestion.
>
>
> AMB
>
> "Salvador Ramos" wrote:
>
>> Hola Carlos,
>>
>> Perdona que te ande liando, realmente te puse un ejemplo para
>> explicar la
>> situación, pero realmente son tablas más complejas, con más columnas
>> y
>> diversos tipos de datos. Las que envié en el primer post de este
>> hilo.
>>
>> Estoy trabajando con el amigo Miguel Egea en una solución basada en
>> una
>> tabla intermedia donde pueda generar una PK y ya a partir de ahí
>> pueda
>> importar correctamente. Al menos hemos visto algo de luz para
>> resolver el
>> problema.
>>
>> Ya cuento aquí la solución cuando consiga implementarla.
>> Muchas gracias por tu tiempo.
>>
>> Un saludo
>> Salvador Ramos
>> Murcia - España
>>
>> [Microsoft MVP SQL Server / MCTS: SQL Server 2005]
>> www.helpdna.net (información sobre SQL Server y .NET)
>>
>>
>> "Carlos Sacristán" <csacristanARROBAmvpsPUNTOorg> escribió en el
>> mensaje
>> news:
>> > Vaya, nunca dejaré de sorprenderme la cantidad de situaciones en
>> > las
>> > que podemos encontrarnos... parece increíble que necesites algo
>> > así.
>> >
>> > Mmmmm si tienes una tabla de numeración, prueba con lo
>> > siguiente. A
>> > mí me salen las filas que están en la tabla origen y no en la de
>> > destino
>> > el número de veces correcto:
>> >
>> > select o.c1, o.c2, o.c3
>> >
>> > from (select count(*) num, c1, c2, c3 from __origen group by c1,
>> > c2,
>> > c3) o
>> >
>> > left join (select count(*) num, c1, c2, c3 from __destino group by
>> > c1,
>> > c2,
>> > c3) d
>> >
>> > on o.c1=d.c1 and o.c2=d.c2 and o.c3=d.c3
>> >
>> > full outer join __numeros n on (o.num - isnull(d.num, 0)) > n.num
>> >
>> > where o.c1 is not null and o.num > isnull(d.num, 0)
>> >
>> >
>> >
>> > Un saludo
>> >
>> > -
>> > "Sólo sé que no sé nada. " (Sócrates)
>> >
>> > "Salvador Ramos" escribió en
>> > el
>> > mensaje news:%
>> >> Efectivamente, que en la tabla destino tiene que haber las mismas
>> >> filas
>> >> que en la tabla origen, y con lo que indicas no se incluyen las
>> >> filas
>> >> que
>> >> aparecen 2, 3 o más veces en la tabla origen (lo habitual es que
>> >> haya
>> >> filas que aparecen dos veces, pero yo lo tengo que plantear
>> >> independientemente del número de repeticiones que haya.
>> >>
>> >> Además imaginate que en la importación de ayer había sólo una fila
>> >> con
>> >> los valoeres 1 - 1 - 4 y en la de hoy aparece otra más, esa fila
>> >> tendría
>> >> que importarla.
>> >>
>> >> Muchas gracias
>> >>
>> >> Un saludo
>> >> Salvador Ramos
>> >> Murcia - España
>> >>
>> >> [Microsoft MVP SQL Server / MCTS: SQL Server 2005]
>> >> www.helpdna.net (información sobre SQL Server y .NET)
>> >>
>> >>
>> >> "Carlos Sacristán" <csacristanARROBAmvpsPUNTOorg> escribió en el
>> >> mensaje
>> >> news:
>> >>> Bueno, pues si efectivamente lo he entendido bien y no hay más
>> >>> detalles a tener en cuenta, lo siguiente te devuelve las filas
>> >>> que no
>> >>> están en la tabla destino:
>> >>>
>> >>> select distinct o.* from origen o left join destino d on
>> >>> o.c1=d.c1
>> >>> and
>> >>> o.c2=d.c2 and o.c3=d.c3 where d.c1 is null
>> >>>
>> >>> No sé. Me da a mí que hay algo más por ahí...
>> >>>
>> >>>
>> >>>
>> >>> Un saludo
>> >>>
>> >>> -
>> >>> "Sólo sé que no sé nada. " (Sócrates)
>> >>>
>> >>> "Salvador Ramos" escribió
>> >>> en el
>> >>> mensaje news:
>> >>>> Hola Carlos,
>> >>>>
>> >>>> Perdona si no me he explicado bien, es que he intentado resumir
>> >>>> un
>> >>>> poco
>> >>>> el problema para solucionar su núcleo y que me podáis entender,
>> >>>> pero
>> >>>> creo que no lo he conseguido.
>> >>>>
>> >>>> Tengo una tabla Origen (la del primer script) y necesito ir
>> >>>> pasando
>> >>>> datos procedentes de ella a una tabla destino (la del segundo
>> >>>> script).
>> >>>> Mi idea es pasar los movimientos que no estén en la tabla
>> >>>> Destino y
>> >>>> si
>> >>>> en la taba Origen. El problema es que la tabla origen no tiene
>> >>>> PK y
>> >>>> si
>> >>>> que tiene filas que son idénticas (tienen los mismos valores en
>> >>>> todas
>> >>>> sus columnas).
>> >>>>
>> >>>> Por ejemplo (con campos inventados) en tabla Origen:
>> >>>> C1 C2 C3
>> >>>> 1 1 2
>> >>>> 1 1 3
>> >>>> 1 1 4
>> >>>> 1 1 4
>> >>>> 1 1 5
>> >>>>
>> >>>> Y tabla destino (suponiendo que tenga los mismos campos):
>> >>>> C1 C2 C3
>> >>>> 1 1 2
>> >>>> 1 1 3
>> >>>>
>> >>>> Y ahora quiero importar las filas que me faltan en la tabla
>> >>>> Destino.
>> >>>>
>> >>>> Un saludo
>> >>>> Salvador Ramos
>> >>>> Murcia - España
>> >>>>
>> >>>> [Microsoft MVP SQL Server / MCTS: SQL Server 2005]
>> >>>> www.helpdna.net (información sobre SQL Server y .NET)
>> >>>>
>> >>>>
>> >>>> "Carlos Sacristán" <csacristanARROBAmvpsPUNTOorg> escribió en el
>> >>>> mensaje news:
>> >>>>> Pero cuál es el problema que te ocurre? No nos dices qué
>> >>>>> necesitas
>> >>>>> hacer exactamente...
>> >>>>>
>> >>>>>
>> >>>>> Un saludo
>> >>>>>
>> >>>>> -
>> >>>>> "Sólo sé que no sé nada. " (Sócrates)
>> >>>>>
>> >>>>> "Salvador Ramos" escribió
>> >>>>> en
>> >>>>> el
>> >>>>> mensaje news:
>> >>>>>> Hola a todos,
>> >>>>>>
>> >>>>>> Tengo una tabla origen en la cual no tengo PK, y cuento con
>> >>>>>> algunas
>> >>>>>> repetidas (filas totalmente iguales, con el mismo valor en
>> >>>>>> todas
>> >>>>>> sus
>> >>>>>> columnas:
>> >>>>>>
>> >>>>>> CREATE TABLE [dbo].[avlValec](
>> >>>>>> [Empresa] [int] NULL,
>> >>>>>> [cliente] [int] NULL,
>> >>>>>> [tipo_fact] [char](2) COLLATE Modern_Spanish_CI_AS NULL,
>> >>>>>> [num_tarjeta] [char](19) COLLATE Modern_Spanish_CI_AS NULL,
>> >>>>>> [fecha] [smalldatetime] NULL,
>> >>>>>> [num_mvto] [varchar](10) COLLATE Modern_Spanish_CI_AS NULL,
>> >>>>>> [cod_articulo] [varchar](8) COLLATE Modern_Spanish_CI_AS NULL,
>> >>>>>> [denominacion] [varchar](40) COLLATE Modern_Spanish_CI_AS
>> >>>>>> NULL,
>> >>>>>> [pvp_iva] [decimal](8, 3) NULL,
>> >>>>>> [tipo_dto] [char](1) COLLATE Modern_Spanish_CI_AS NULL,
>> >>>>>> [canti] [decimal](8, 2) NULL,
>> >>>>>> [importe_vale] [decimal](8, 2) NULL,
>> >>>>>> [impor_dto] [decimal](7, 2) NULL,
>> >>>>>> [dto] [decimal](6, 3) NULL,
>> >>>>>> [iva] [decimal](3, 1) NULL,
>> >>>>>> [codigo_esta] [int] NULL,
>> >>>>>> [hora] [varchar](4) COLLATE Modern_Spanish_CI_AS NULL,






email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una pregunta AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida