Tabla con dos Índices

08/06/2009 - 12:24 por Ajataru | Informe spam
Hola a todos,

me he encontrado casualmente con un problema, que me resulta un tanto
extraño:

- tengo una tabla en la que he definido un índice basado en dos campos.
- tengo otra tabla, en la que incluyo dos campos relacionados con el
índice de la primera tabla.
- para meter valores en la segunda tabla, tengo quue meter pares de
valores que existan en la primera.

hasta aquí, todo bien y normal, pero casualmente, metí unos valores en la
tabla, insertando solo el valor del primero de los índices, y no el segundo,
dejando en el un NULL. Por lo que tengo en la 2ª tabla un par de valores
(XXX, NULL), que obviamente, no existe como tal en la tabla primaria. Pues
SQL traga, y no da ningún error. Mientras uno de los dos valores sea un
NULL, no hace ninguna evaluación...

He comprobado los índices, y en ppio. está todo OK. Hay alguna opcion de la
BBDD que activa / desactiva este comportamiento?. Es esto normal?.

Muchas gracias.

Preguntas similare

Leer las respuestas

#11 Ajataru
09/06/2009 - 16:23 | Informe spam
Te expongo el caso:

es una tabla de registro de movimientos de stock en un sistema de
gestión. Los movimientos de stock, pueden ser de diversos tipos: órdenes de
compra, fabricación, venta, etc. Uno de estos tipos, es un movimiento de
stock entre proyectos, por lo que en la tabla, tengo un par de valores,
IdArticulo e IdProyecto, que me indentifican el articulo del cual he hecho
el movimiento, y otro par mas, que solo usaré cuando el tipo de movimiento
sea entre proyectos, que es IdArticuloOrigen, IDProyectoOrigen. Ambos pares
de valores están relacionados con la tabla de articulos, que es la que tiene
como clave primaria, los campos IdArticulo e IdProyecto. El primer par de
valores de la tabla de movimiento de stocks, si que lo puedo forzar a que no
sea Null, ya que nunca lo puede ser, pero en el segundo caso, si que es
opcional el rellenar o no este campo, por lo que si que tengo que permitir
valores Null.

Como apunto Carlos Sacristán, probablemente haya que irse a un trigger, que
verifique que o los dos valores son NULL, o ninguno de ellos.

Un saludo.


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

Creo que esa es una responsabilidad de el diseniador de la db, o de quien
la
implementa en SQL Server.

Por que tus columnas aceptan NULL?

Si un valor no es conocido, entonces como buscarlo en otra tabla.

Pudieras evitar este problema si continuas el proceso de normalizacion,
hasta obtener una relacion donde las columnas no acepten NULL y que la
restriccion de clave foranea sea quien dicte su dominio.


AMB


"Ajataru" wrote:

Carlos, gracias por tus respuestas.

A modo de ejemplo, un script para crear las tablas y poder probar esto.
Si tras crear estas tablas, metes registros en la tabla1, por ejemplo

a a
b b
c c

y ahora te vas a la tabla 2

puedes meter

a NULL
kk NULL
zzzz NULL

etc...

obviamente, lo que si que no puedes es meter

a xx

ahí si que se realiza la comprobación del FK.


/*****************************/
create table "Tabla1" (
"Id1" char(10) not null,
"Id2" char(10) not null)
go

alter table "Tabla1"
add constraint "Tabla1_PK" primary key ("Id1", "Id2")
go

create table "Tabla2" (
"IdTabla2" int identity not null,
"Id1" char(10) null,
"Id2" char(10) null)
go

alter table "Tabla2"
add constraint "Tabla2_PK" primary key ("IdTabla2")


go

alter table "Tabla2"
add constraint "Tabla1_Tabla2_FK1" foreign key (
"Id1",
"Id2")
references "Tabla1" (
"Id1",
"Id2") on update no action on delete no action

go

/************************************/

"Carlos Sacristan" escribió en el mensaje
news:
> En el momento en que aceptas que exista el "valor" NULL, la lógica es
> trivalente. Es decir, que contempla tres valores de verdad: verdadero,
> falso e indeterminado.
>
> Da igual que la tabla contenga un campo o cientos de ellos: en el
> momento
> en que uno sólo almacene un valor NULL, el resultado de la comparación
> es
> indeterminado. No es un problema del diseño de las validaciones que
> hace
> SQL Server, está simplemente aplicando las reglas de la lógica.
>
> El verdadero problema es que tú necesitas aplicar un criterio muy
> particular. La solución pasa por crearte un trigger que realice esa
> validación extra que necesitas
>
> Un saludo
> -
> www.navento.com
> Servicios de Localización GPS
>
> http://blogs.solidq.com/ES/ElRincon...fault.aspx
>
> "Ajataru" escribió en el mensaje
> news:h0lc8i$
>> Carlos,
>>
>> creo que has dado en el clavo con cómo hace SQL server el chequeo
>> de
>> los FK habiendo un valor NULL por el medio, devuelve indeterminado,
>> que
>> no es false, y lo da como OK. Esto explicaría el comportamiento,
>> aunque
>> yo no lo veo muy lógico, ya que una condición se cumple, o no.
>> Entiendo
>> que cuando el índice está formado por un único campo no evalue los
>> NULLS,
>> pero si hay mas de un campo, creo que si que debería de hacerlo
>> siempre
>> que alguno de los valores no sea NULL... pero bueno, habrá que asumir
>> que
>> trabaja así.
>>
>>
>>
>> "Carlos Sacristan" escribió en el mensaje
>> news:
>>> Ajataru, es que sólo tienes tres opciones:
>>>
>>> 1.- que en la tabla 2 se inserten valores que existan en tabla1->
>>> crear FK de tabla2 a tabla1
>>> 2.- que en la tabla 2 se inserten valores que no tienen
>>> necesariamente que existir en tabla1 -> no crear FK
>>> 3.- que en la tabla 2 se inserten valores que existan en tabla1
>>> pero
>>> que puedas insertar NULL -> crear FK de tabla2 a tabla1 con los
>>> campos
>>> de tabla2 aceptando NULL.
>>>
>>> NULL es un "valor" especial (lo entrecomillo porque en realidad no es
>>> ningún valor). Comparar NULL con NULL no devuelve verdadero, sino
>>> NULL.
>>> En el caso de insertar un NULL en un campo (o campos) que compone una
>>> FK, SQL Server tiene que chequear la respuesta de la pregunta
>>> ¿el(los)
>>> valor(es) insertado(s) en tabla2 existe(n) en tabla1?, ante la que
>>> hay 3
>>> posibles respuestas:
>>>
>>> 1.- SI. Entonces la restricción se valida correctamente
>>> 2.- NO. El motor devuelve una excepción indicando que se ha
>>> intentado
>>> violar esa restricción
>>> 3.- NULL. Al comparar un valor con NULL, devuelve indeterminado.
>>> En
>>> el caso concreto de la FK, no la está incumpliendo (aunque tampoco la
>>> está cumpliendo), sino "todo lo contrario".
>>>
>>> Por tu último comentario, realmente no sé qué es lo que necesitas. Si
>>> en
>>> ciertos casos necesitas validar la FK y en otros no, entonces no te
>>> sirve una FK. Probablemente necesites validar esa regla por medio de
>>> un
>>> trigger, que te permite crear una lógica más compleja.
>>>
>>> Espero haberme explicado.
>>>
>>> Un saludo
>>> -
>>> www.navento.com
>>> Servicios de Localización GPS
>>>
>>> http://blogs.solidq.com/ES/ElRincon...fault.aspx
>>>
>>> "Ajataru" escribió en el mensaje
>>> news:h0j61r$
>>>> Es una buena idea, siempre que por narices en la segunda tabla
>>>> tengas
>>>> que referenciar siempre un registro de la primera: puede darse el
>>>> caso,
>>>> de que no siempre lo tengas que hacer...
>>>>
>>>> No se si este es un problema de fondo de SQL, de mi instalación, o
>>>> de
>>>> como he creado los índices... le ocurre esto a alguien mas?.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> "Carlos Sacristan" escribió en el mensaje
>>>> news:%
>>>>> Cambia la definición de esa segunda tabla para que esos campos no
>>>>> acepten NULL
>>>>>
>>>>> Un saludo
>>>>> -
>>>>> www.navento.com
>>>>> Servicios de Localización GPS
>>>>>
>>>>> http://blogs.solidq.com/ES/ElRincon...fault.aspx
>>>>>
>>>>> "Ajataru" escribió en el mensaje
>>>>> news:h0iot5$
>>>>>> Hola a todos,
>>>>>>
>>>>>> me he encontrado casualmente con un problema, que me resulta un
>>>>>> tanto extraño:
>>>>>>
>>>>>> - tengo una tabla en la que he definido un índice basado en dos
>>>>>> campos.
>>>>>> - tengo otra tabla, en la que incluyo dos campos relacionados
>>>>>> con
>>>>>> el índice de la primera tabla.
>>>>>> - para meter valores en la segunda tabla, tengo quue meter
>>>>>> pares
>>>>>> de valores que existan en la primera.
>>>>>>
>>>>>> hasta aquí, todo bien y normal, pero casualmente, metí unos
>>>>>> valores
>>>>>> en la tabla, insertando solo el valor del primero de los índices,
>>>>>> y
>>>>>> no el segundo, dejando en el un NULL. Por lo que tengo en la 2ª
>>>>>> tabla
>>>>>> un par de valores (XXX, NULL), que obviamente, no existe como tal
>>>>>> en
>>>>>> la tabla primaria. Pues SQL traga, y no da ningún error. Mientras
>>>>>> uno
>>>>>> de los dos valores sea un NULL, no hace ninguna evaluación...
>>>>>>
>>>>>> He comprobado los índices, y en ppio. está todo OK. Hay alguna
>>>>>> opcion
>>>>>> de la BBDD que activa / desactiva este comportamiento?. Es esto
>>>>>> normal?.
>>>>>>
>>>>>> Muchas gracias.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>
>



Respuesta Responder a este mensaje
#12 Carlos Sacristan
09/06/2009 - 16:52 | Informe spam
Yo haría dos tablas de registro de movimientos de stock: una para los
movimientos que no sean entre proyectos, y otra para movimientos entre
proyectos.

La primera tendría la FK que contiene ahora, pero no tendría los campos
IdArticuloOrigen ni IdProyectoOrigen. Probablemente crearía también una
restricción check para validar que no se hace referencia a movimientos entre
proyectos.

La segunda tendría como FK esos cuatro campos, validando de ese modo que el
movimiento al que hace referencia es entre proyectos.

Luego, si necesitas saber los identificadores de movimientos, crearía una
vista con la unión de esas dos tablas.

En definitiva lo que te sugiero es lo que comentaba Alejandro: normalizar
hasta que las columnas no acepten NULL, y que las propias FK sean las que
validen los datos.

Un saludo
-
www.navento.com
Servicios de Localización GPS

http://blogs.solidq.com/ES/ElRincon...fault.aspx

"Ajataru" escribió en el mensaje
news:h0lr8j$
Te expongo el caso:

es una tabla de registro de movimientos de stock en un sistema de
gestión. Los movimientos de stock, pueden ser de diversos tipos: órdenes
de compra, fabricación, venta, etc. Uno de estos tipos, es un movimiento
de stock entre proyectos, por lo que en la tabla, tengo un par de valores,
IdArticulo e IdProyecto, que me indentifican el articulo del cual he hecho
el movimiento, y otro par mas, que solo usaré cuando el tipo de movimiento
sea entre proyectos, que es IdArticuloOrigen, IDProyectoOrigen. Ambos
pares de valores están relacionados con la tabla de articulos, que es la
que tiene como clave primaria, los campos IdArticulo e IdProyecto. El
primer par de valores de la tabla de movimiento de stocks, si que lo puedo
forzar a que no sea Null, ya que nunca lo puede ser, pero en el segundo
caso, si que es opcional el rellenar o no este campo, por lo que si que
tengo que permitir valores Null.

Como apunto Carlos Sacristán, probablemente haya que irse a un trigger,
que verifique que o los dos valores son NULL, o ninguno de ellos.

Un saludo.


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

Creo que esa es una responsabilidad de el diseniador de la db, o de quien
la
implementa en SQL Server.

Por que tus columnas aceptan NULL?

Si un valor no es conocido, entonces como buscarlo en otra tabla.

Pudieras evitar este problema si continuas el proceso de normalizacion,
hasta obtener una relacion donde las columnas no acepten NULL y que la
restriccion de clave foranea sea quien dicte su dominio.


AMB


"Ajataru" wrote:

Carlos, gracias por tus respuestas.

A modo de ejemplo, un script para crear las tablas y poder probar esto.
Si tras crear estas tablas, metes registros en la tabla1, por ejemplo

a a
b b
c c

y ahora te vas a la tabla 2

puedes meter

a NULL
kk NULL
zzzz NULL

etc...

obviamente, lo que si que no puedes es meter

a xx

ahí si que se realiza la comprobación del FK.


/*****************************/
create table "Tabla1" (
"Id1" char(10) not null,
"Id2" char(10) not null)
go

alter table "Tabla1"
add constraint "Tabla1_PK" primary key ("Id1", "Id2")
go

create table "Tabla2" (
"IdTabla2" int identity not null,
"Id1" char(10) null,
"Id2" char(10) null)
go

alter table "Tabla2"
add constraint "Tabla2_PK" primary key ("IdTabla2")


go

alter table "Tabla2"
add constraint "Tabla1_Tabla2_FK1" foreign key (
"Id1",
"Id2")
references "Tabla1" (
"Id1",
"Id2") on update no action on delete no action

go

/************************************/

"Carlos Sacristan" escribió en el mensaje
news:
> En el momento en que aceptas que exista el "valor" NULL, la lógica es
> trivalente. Es decir, que contempla tres valores de verdad: verdadero,
> falso e indeterminado.
>
> Da igual que la tabla contenga un campo o cientos de ellos: en el
> momento
> en que uno sólo almacene un valor NULL, el resultado de la comparación
> es
> indeterminado. No es un problema del diseño de las validaciones que
> hace
> SQL Server, está simplemente aplicando las reglas de la lógica.
>
> El verdadero problema es que tú necesitas aplicar un criterio muy
> particular. La solución pasa por crearte un trigger que realice esa
> validación extra que necesitas
>
> Un saludo
> -
> www.navento.com
> Servicios de Localización GPS
>
> http://blogs.solidq.com/ES/ElRincon...fault.aspx
>
> "Ajataru" escribió en el mensaje
> news:h0lc8i$
>> Carlos,
>>
>> creo que has dado en el clavo con cómo hace SQL server el chequeo
>> de
>> los FK habiendo un valor NULL por el medio, devuelve indeterminado,
>> que
>> no es false, y lo da como OK. Esto explicaría el comportamiento,
>> aunque
>> yo no lo veo muy lógico, ya que una condición se cumple, o no.
>> Entiendo
>> que cuando el índice está formado por un único campo no evalue los
>> NULLS,
>> pero si hay mas de un campo, creo que si que debería de hacerlo
>> siempre
>> que alguno de los valores no sea NULL... pero bueno, habrá que asumir
>> que
>> trabaja así.
>>
>>
>>
>> "Carlos Sacristan" escribió en el mensaje
>> news:
>>> Ajataru, es que sólo tienes tres opciones:
>>>
>>> 1.- que en la tabla 2 se inserten valores que existan en tabla1->
>>> crear FK de tabla2 a tabla1
>>> 2.- que en la tabla 2 se inserten valores que no tienen
>>> necesariamente que existir en tabla1 -> no crear FK
>>> 3.- que en la tabla 2 se inserten valores que existan en tabla1
>>> pero
>>> que puedas insertar NULL -> crear FK de tabla2 a tabla1 con los
>>> campos
>>> de tabla2 aceptando NULL.
>>>
>>> NULL es un "valor" especial (lo entrecomillo porque en realidad no
>>> es
>>> ningún valor). Comparar NULL con NULL no devuelve verdadero, sino
>>> NULL.
>>> En el caso de insertar un NULL en un campo (o campos) que compone
>>> una
>>> FK, SQL Server tiene que chequear la respuesta de la pregunta
>>> ¿el(los)
>>> valor(es) insertado(s) en tabla2 existe(n) en tabla1?, ante la que
>>> hay 3
>>> posibles respuestas:
>>>
>>> 1.- SI. Entonces la restricción se valida correctamente
>>> 2.- NO. El motor devuelve una excepción indicando que se ha
>>> intentado
>>> violar esa restricción
>>> 3.- NULL. Al comparar un valor con NULL, devuelve indeterminado.
>>> En
>>> el caso concreto de la FK, no la está incumpliendo (aunque tampoco
>>> la
>>> está cumpliendo), sino "todo lo contrario".
>>>
>>> Por tu último comentario, realmente no sé qué es lo que necesitas.
>>> Si en
>>> ciertos casos necesitas validar la FK y en otros no, entonces no te
>>> sirve una FK. Probablemente necesites validar esa regla por medio de
>>> un
>>> trigger, que te permite crear una lógica más compleja.
>>>
>>> Espero haberme explicado.
>>>
>>> Un saludo
>>> -
>>> www.navento.com
>>> Servicios de Localización GPS
>>>
>>> http://blogs.solidq.com/ES/ElRincon...fault.aspx
>>>
>>> "Ajataru" escribió en el mensaje
>>> news:h0j61r$
>>>> Es una buena idea, siempre que por narices en la segunda tabla
>>>> tengas
>>>> que referenciar siempre un registro de la primera: puede darse el
>>>> caso,
>>>> de que no siempre lo tengas que hacer...
>>>>
>>>> No se si este es un problema de fondo de SQL, de mi instalación, o
>>>> de
>>>> como he creado los índices... le ocurre esto a alguien mas?.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> "Carlos Sacristan" escribió en el mensaje
>>>> news:%
>>>>> Cambia la definición de esa segunda tabla para que esos campos no
>>>>> acepten NULL
>>>>>
>>>>> Un saludo
>>>>> -
>>>>> www.navento.com
>>>>> Servicios de Localización GPS
>>>>>
>>>>> http://blogs.solidq.com/ES/ElRincon...fault.aspx
>>>>>
>>>>> "Ajataru" escribió en el mensaje
>>>>> news:h0iot5$
>>>>>> Hola a todos,
>>>>>>
>>>>>> me he encontrado casualmente con un problema, que me resulta
>>>>>> un
>>>>>> tanto extraño:
>>>>>>
>>>>>> - tengo una tabla en la que he definido un índice basado en
>>>>>> dos
>>>>>> campos.
>>>>>> - tengo otra tabla, en la que incluyo dos campos relacionados
>>>>>> con
>>>>>> el índice de la primera tabla.
>>>>>> - para meter valores en la segunda tabla, tengo quue meter
>>>>>> pares
>>>>>> de valores que existan en la primera.
>>>>>>
>>>>>> hasta aquí, todo bien y normal, pero casualmente, metí unos
>>>>>> valores
>>>>>> en la tabla, insertando solo el valor del primero de los índices,
>>>>>> y
>>>>>> no el segundo, dejando en el un NULL. Por lo que tengo en la 2ª
>>>>>> tabla
>>>>>> un par de valores (XXX, NULL), que obviamente, no existe como tal
>>>>>> en
>>>>>> la tabla primaria. Pues SQL traga, y no da ningún error. Mientras
>>>>>> uno
>>>>>> de los dos valores sea un NULL, no hace ninguna evaluación...
>>>>>>
>>>>>> He comprobado los índices, y en ppio. está todo OK. Hay alguna
>>>>>> opcion
>>>>>> de la BBDD que activa / desactiva este comportamiento?. Es esto
>>>>>> normal?.
>>>>>>
>>>>>> Muchas gracias.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>
>









Respuesta Responder a este mensaje
#13 Carlos M. Calvelo
09/06/2009 - 17:01 | Informe spam
Hola Ajataru,

On 9 jun, 16:23, "Ajataru" wrote:
Te expongo el caso:

es una tabla de registro de movimientos de stock en un sistema de
gestión. Los movimientos de stock, pueden ser de diversos tipos: órdenes de
compra, fabricación, venta, etc. Uno de estos tipos, es un movimiento de
stock entre proyectos, por lo que en la tabla, tengo un par de valores,
IdArticulo e IdProyecto, que me indentifican el articulo del cual he hecho
el movimiento,



Entiendo que siempre tienes un IdArticulo y un IdProyecto
independientemente del tipo de movimiento.

y otro par mas, que solo usaré cuando el tipo de movimiento
sea entre proyectos, que es IdArticuloOrigen, IDProyectoOrigen.



Ahí está el origen del problema. IdArticuloOrigen y IDProyectoOrigen
no dependen solo del la PK de la tabla movimientos, sino también
del tipo. La tabla no está normalizada y ahora estás peleando con
las consecuencias.



Ambos pares
de valores están relacionados con la tabla de articulos, que es la que tiene
como clave primaria, los campos IdArticulo e IdProyecto. El primer par de
valores de la tabla de movimiento de stocks, si que lo puedo forzar a que no
sea Null, ya que nunca lo puede ser, pero en el segundo caso, si que es
opcional el rellenar o no este campo, por lo que si que tengo que permitir
valores Null.



Normalizando la tabla si prodrías forzar la referencia FK desde
una tercera tabla (resultado de la normalización), sin tener que
reñirte con los nulos (como ya he tratado de explicar).

Saludos,
Carlos
Respuesta Responder a este mensaje
#14 Ajataru
09/06/2009 - 17:20 | Informe spam
Muchas gracias a ambos Carlos,

haré lo que proponeís, de normalizar las tablas, creando una tercera
tabla, para las transacciones entre proyectos.

Un saludo.


"Ajataru" escribió en el mensaje
news:h0lr8j$
Te expongo el caso:

es una tabla de registro de movimientos de stock en un sistema de
gestión. Los movimientos de stock, pueden ser de diversos tipos: órdenes
de compra, fabricación, venta, etc. Uno de estos tipos, es un movimiento
de stock entre proyectos, por lo que en la tabla, tengo un par de valores,
IdArticulo e IdProyecto, que me indentifican el articulo del cual he hecho
el movimiento, y otro par mas, que solo usaré cuando el tipo de movimiento
sea entre proyectos, que es IdArticuloOrigen, IDProyectoOrigen. Ambos
pares de valores están relacionados con la tabla de articulos, que es la
que tiene como clave primaria, los campos IdArticulo e IdProyecto. El
primer par de valores de la tabla de movimiento de stocks, si que lo puedo
forzar a que no sea Null, ya que nunca lo puede ser, pero en el segundo
caso, si que es opcional el rellenar o no este campo, por lo que si que
tengo que permitir valores Null.

Como apunto Carlos Sacristán, probablemente haya que irse a un trigger,
que verifique que o los dos valores son NULL, o ninguno de ellos.

Un saludo.


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

Creo que esa es una responsabilidad de el diseniador de la db, o de quien
la
implementa en SQL Server.

Por que tus columnas aceptan NULL?

Si un valor no es conocido, entonces como buscarlo en otra tabla.

Pudieras evitar este problema si continuas el proceso de normalizacion,
hasta obtener una relacion donde las columnas no acepten NULL y que la
restriccion de clave foranea sea quien dicte su dominio.


AMB


"Ajataru" wrote:

Carlos, gracias por tus respuestas.

A modo de ejemplo, un script para crear las tablas y poder probar esto.
Si tras crear estas tablas, metes registros en la tabla1, por ejemplo

a a
b b
c c

y ahora te vas a la tabla 2

puedes meter

a NULL
kk NULL
zzzz NULL

etc...

obviamente, lo que si que no puedes es meter

a xx

ahí si que se realiza la comprobación del FK.


/*****************************/
create table "Tabla1" (
"Id1" char(10) not null,
"Id2" char(10) not null)
go

alter table "Tabla1"
add constraint "Tabla1_PK" primary key ("Id1", "Id2")
go

create table "Tabla2" (
"IdTabla2" int identity not null,
"Id1" char(10) null,
"Id2" char(10) null)
go

alter table "Tabla2"
add constraint "Tabla2_PK" primary key ("IdTabla2")


go

alter table "Tabla2"
add constraint "Tabla1_Tabla2_FK1" foreign key (
"Id1",
"Id2")
references "Tabla1" (
"Id1",
"Id2") on update no action on delete no action

go

/************************************/

"Carlos Sacristan" escribió en el mensaje
news:
> En el momento en que aceptas que exista el "valor" NULL, la lógica es
> trivalente. Es decir, que contempla tres valores de verdad: verdadero,
> falso e indeterminado.
>
> Da igual que la tabla contenga un campo o cientos de ellos: en el
> momento
> en que uno sólo almacene un valor NULL, el resultado de la comparación
> es
> indeterminado. No es un problema del diseño de las validaciones que
> hace
> SQL Server, está simplemente aplicando las reglas de la lógica.
>
> El verdadero problema es que tú necesitas aplicar un criterio muy
> particular. La solución pasa por crearte un trigger que realice esa
> validación extra que necesitas
>
> Un saludo
> -
> www.navento.com
> Servicios de Localización GPS
>
> http://blogs.solidq.com/ES/ElRincon...fault.aspx
>
> "Ajataru" escribió en el mensaje
> news:h0lc8i$
>> Carlos,
>>
>> creo que has dado en el clavo con cómo hace SQL server el chequeo
>> de
>> los FK habiendo un valor NULL por el medio, devuelve indeterminado,
>> que
>> no es false, y lo da como OK. Esto explicaría el comportamiento,
>> aunque
>> yo no lo veo muy lógico, ya que una condición se cumple, o no.
>> Entiendo
>> que cuando el índice está formado por un único campo no evalue los
>> NULLS,
>> pero si hay mas de un campo, creo que si que debería de hacerlo
>> siempre
>> que alguno de los valores no sea NULL... pero bueno, habrá que asumir
>> que
>> trabaja así.
>>
>>
>>
>> "Carlos Sacristan" escribió en el mensaje
>> news:
>>> Ajataru, es que sólo tienes tres opciones:
>>>
>>> 1.- que en la tabla 2 se inserten valores que existan en tabla1->
>>> crear FK de tabla2 a tabla1
>>> 2.- que en la tabla 2 se inserten valores que no tienen
>>> necesariamente que existir en tabla1 -> no crear FK
>>> 3.- que en la tabla 2 se inserten valores que existan en tabla1
>>> pero
>>> que puedas insertar NULL -> crear FK de tabla2 a tabla1 con los
>>> campos
>>> de tabla2 aceptando NULL.
>>>
>>> NULL es un "valor" especial (lo entrecomillo porque en realidad no
>>> es
>>> ningún valor). Comparar NULL con NULL no devuelve verdadero, sino
>>> NULL.
>>> En el caso de insertar un NULL en un campo (o campos) que compone
>>> una
>>> FK, SQL Server tiene que chequear la respuesta de la pregunta
>>> ¿el(los)
>>> valor(es) insertado(s) en tabla2 existe(n) en tabla1?, ante la que
>>> hay 3
>>> posibles respuestas:
>>>
>>> 1.- SI. Entonces la restricción se valida correctamente
>>> 2.- NO. El motor devuelve una excepción indicando que se ha
>>> intentado
>>> violar esa restricción
>>> 3.- NULL. Al comparar un valor con NULL, devuelve indeterminado.
>>> En
>>> el caso concreto de la FK, no la está incumpliendo (aunque tampoco
>>> la
>>> está cumpliendo), sino "todo lo contrario".
>>>
>>> Por tu último comentario, realmente no sé qué es lo que necesitas.
>>> Si en
>>> ciertos casos necesitas validar la FK y en otros no, entonces no te
>>> sirve una FK. Probablemente necesites validar esa regla por medio de
>>> un
>>> trigger, que te permite crear una lógica más compleja.
>>>
>>> Espero haberme explicado.
>>>
>>> Un saludo
>>> -
>>> www.navento.com
>>> Servicios de Localización GPS
>>>
>>> http://blogs.solidq.com/ES/ElRincon...fault.aspx
>>>
>>> "Ajataru" escribió en el mensaje
>>> news:h0j61r$
>>>> Es una buena idea, siempre que por narices en la segunda tabla
>>>> tengas
>>>> que referenciar siempre un registro de la primera: puede darse el
>>>> caso,
>>>> de que no siempre lo tengas que hacer...
>>>>
>>>> No se si este es un problema de fondo de SQL, de mi instalación, o
>>>> de
>>>> como he creado los índices... le ocurre esto a alguien mas?.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> "Carlos Sacristan" escribió en el mensaje
>>>> news:%
>>>>> Cambia la definición de esa segunda tabla para que esos campos no
>>>>> acepten NULL
>>>>>
>>>>> Un saludo
>>>>> -
>>>>> www.navento.com
>>>>> Servicios de Localización GPS
>>>>>
>>>>> http://blogs.solidq.com/ES/ElRincon...fault.aspx
>>>>>
>>>>> "Ajataru" escribió en el mensaje
>>>>> news:h0iot5$
>>>>>> Hola a todos,
>>>>>>
>>>>>> me he encontrado casualmente con un problema, que me resulta
>>>>>> un
>>>>>> tanto extraño:
>>>>>>
>>>>>> - tengo una tabla en la que he definido un índice basado en
>>>>>> dos
>>>>>> campos.
>>>>>> - tengo otra tabla, en la que incluyo dos campos relacionados
>>>>>> con
>>>>>> el índice de la primera tabla.
>>>>>> - para meter valores en la segunda tabla, tengo quue meter
>>>>>> pares
>>>>>> de valores que existan en la primera.
>>>>>>
>>>>>> hasta aquí, todo bien y normal, pero casualmente, metí unos
>>>>>> valores
>>>>>> en la tabla, insertando solo el valor del primero de los índices,
>>>>>> y
>>>>>> no el segundo, dejando en el un NULL. Por lo que tengo en la 2ª
>>>>>> tabla
>>>>>> un par de valores (XXX, NULL), que obviamente, no existe como tal
>>>>>> en
>>>>>> la tabla primaria. Pues SQL traga, y no da ningún error. Mientras
>>>>>> uno
>>>>>> de los dos valores sea un NULL, no hace ninguna evaluación...
>>>>>>
>>>>>> He comprobado los índices, y en ppio. está todo OK. Hay alguna
>>>>>> opcion
>>>>>> de la BBDD que activa / desactiva este comportamiento?. Es esto
>>>>>> normal?.
>>>>>>
>>>>>> Muchas gracias.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>
>









Respuesta Responder a este mensaje
#15 Alejandro Mesa
09/06/2009 - 19:45 | Informe spam
Ajataru,

Te suguero busques un poco de informacion sobr el topico "SuperTipos y
Subtipos", o "Generalizacion y Especializacion". Esto te ayudara a resolver
tu problema.


AMB


"Ajataru" wrote:

Muchas gracias a ambos Carlos,

haré lo que proponeís, de normalizar las tablas, creando una tercera
tabla, para las transacciones entre proyectos.

Un saludo.


"Ajataru" escribió en el mensaje
news:h0lr8j$
> Te expongo el caso:
>
> es una tabla de registro de movimientos de stock en un sistema de
> gestión. Los movimientos de stock, pueden ser de diversos tipos: órdenes
> de compra, fabricación, venta, etc. Uno de estos tipos, es un movimiento
> de stock entre proyectos, por lo que en la tabla, tengo un par de valores,
> IdArticulo e IdProyecto, que me indentifican el articulo del cual he hecho
> el movimiento, y otro par mas, que solo usaré cuando el tipo de movimiento
> sea entre proyectos, que es IdArticuloOrigen, IDProyectoOrigen. Ambos
> pares de valores están relacionados con la tabla de articulos, que es la
> que tiene como clave primaria, los campos IdArticulo e IdProyecto. El
> primer par de valores de la tabla de movimiento de stocks, si que lo puedo
> forzar a que no sea Null, ya que nunca lo puede ser, pero en el segundo
> caso, si que es opcional el rellenar o no este campo, por lo que si que
> tengo que permitir valores Null.
>
> Como apunto Carlos Sacristán, probablemente haya que irse a un trigger,
> que verifique que o los dos valores son NULL, o ninguno de ellos.
>
> Un saludo.
>
>
> "Alejandro Mesa" escribió en el
> mensaje news:
>> Ajataru,
>>
>> Creo que esa es una responsabilidad de el diseniador de la db, o de quien
>> la
>> implementa en SQL Server.
>>
>> Por que tus columnas aceptan NULL?
>>
>> Si un valor no es conocido, entonces como buscarlo en otra tabla.
>>
>> Pudieras evitar este problema si continuas el proceso de normalizacion,
>> hasta obtener una relacion donde las columnas no acepten NULL y que la
>> restriccion de clave foranea sea quien dicte su dominio.
>>
>>
>> AMB
>>
>>
>> "Ajataru" wrote:
>>
>>> Carlos, gracias por tus respuestas.
>>>
>>> A modo de ejemplo, un script para crear las tablas y poder probar esto.
>>> Si tras crear estas tablas, metes registros en la tabla1, por ejemplo
>>>
>>> a a
>>> b b
>>> c c
>>>
>>> y ahora te vas a la tabla 2
>>>
>>> puedes meter
>>>
>>> a NULL
>>> kk NULL
>>> zzzz NULL
>>>
>>> etc...
>>>
>>> obviamente, lo que si que no puedes es meter
>>>
>>> a xx
>>>
>>> ahí si que se realiza la comprobación del FK.
>>>
>>>
>>> /*****************************/
>>> create table "Tabla1" (
>>> "Id1" char(10) not null,
>>> "Id2" char(10) not null)
>>> go
>>>
>>> alter table "Tabla1"
>>> add constraint "Tabla1_PK" primary key ("Id1", "Id2")
>>> go
>>>
>>> create table "Tabla2" (
>>> "IdTabla2" int identity not null,
>>> "Id1" char(10) null,
>>> "Id2" char(10) null)
>>> go
>>>
>>> alter table "Tabla2"
>>> add constraint "Tabla2_PK" primary key ("IdTabla2")
>>>
>>>
>>> go
>>>
>>> alter table "Tabla2"
>>> add constraint "Tabla1_Tabla2_FK1" foreign key (
>>> "Id1",
>>> "Id2")
>>> references "Tabla1" (
>>> "Id1",
>>> "Id2") on update no action on delete no action
>>>
>>> go
>>>
>>> /************************************/
>>>
>>> "Carlos Sacristan" escribió en el mensaje
>>> news:
>>> > En el momento en que aceptas que exista el "valor" NULL, la lógica es
>>> > trivalente. Es decir, que contempla tres valores de verdad: verdadero,
>>> > falso e indeterminado.
>>> >
>>> > Da igual que la tabla contenga un campo o cientos de ellos: en el
>>> > momento
>>> > en que uno sólo almacene un valor NULL, el resultado de la comparación
>>> > es
>>> > indeterminado. No es un problema del diseño de las validaciones que
>>> > hace
>>> > SQL Server, está simplemente aplicando las reglas de la lógica.
>>> >
>>> > El verdadero problema es que tú necesitas aplicar un criterio muy
>>> > particular. La solución pasa por crearte un trigger que realice esa
>>> > validación extra que necesitas
>>> >
>>> > Un saludo
>>> > -
>>> > www.navento.com
>>> > Servicios de Localización GPS
>>> >
>>> > http://blogs.solidq.com/ES/ElRincon...fault.aspx
>>> >
>>> > "Ajataru" escribió en el mensaje
>>> > news:h0lc8i$
>>> >> Carlos,
>>> >>
>>> >> creo que has dado en el clavo con cómo hace SQL server el chequeo
>>> >> de
>>> >> los FK habiendo un valor NULL por el medio, devuelve indeterminado,
>>> >> que
>>> >> no es false, y lo da como OK. Esto explicaría el comportamiento,
>>> >> aunque
>>> >> yo no lo veo muy lógico, ya que una condición se cumple, o no.
>>> >> Entiendo
>>> >> que cuando el índice está formado por un único campo no evalue los
>>> >> NULLS,
>>> >> pero si hay mas de un campo, creo que si que debería de hacerlo
>>> >> siempre
>>> >> que alguno de los valores no sea NULL... pero bueno, habrá que asumir
>>> >> que
>>> >> trabaja así.
>>> >>
>>> >>
>>> >>
>>> >> "Carlos Sacristan" escribió en el mensaje
>>> >> news:
>>> >>> Ajataru, es que sólo tienes tres opciones:
>>> >>>
>>> >>> 1.- que en la tabla 2 se inserten valores que existan en tabla1->
>>> >>> crear FK de tabla2 a tabla1
>>> >>> 2.- que en la tabla 2 se inserten valores que no tienen
>>> >>> necesariamente que existir en tabla1 -> no crear FK
>>> >>> 3.- que en la tabla 2 se inserten valores que existan en tabla1
>>> >>> pero
>>> >>> que puedas insertar NULL -> crear FK de tabla2 a tabla1 con los
>>> >>> campos
>>> >>> de tabla2 aceptando NULL.
>>> >>>
>>> >>> NULL es un "valor" especial (lo entrecomillo porque en realidad no
>>> >>> es
>>> >>> ningún valor). Comparar NULL con NULL no devuelve verdadero, sino
>>> >>> NULL.
>>> >>> En el caso de insertar un NULL en un campo (o campos) que compone
>>> >>> una
>>> >>> FK, SQL Server tiene que chequear la respuesta de la pregunta
>>> >>> ¿el(los)
>>> >>> valor(es) insertado(s) en tabla2 existe(n) en tabla1?, ante la que
>>> >>> hay 3
>>> >>> posibles respuestas:
>>> >>>
>>> >>> 1.- SI. Entonces la restricción se valida correctamente
>>> >>> 2.- NO. El motor devuelve una excepción indicando que se ha
>>> >>> intentado
>>> >>> violar esa restricción
>>> >>> 3.- NULL. Al comparar un valor con NULL, devuelve indeterminado.
>>> >>> En
>>> >>> el caso concreto de la FK, no la está incumpliendo (aunque tampoco
>>> >>> la
>>> >>> está cumpliendo), sino "todo lo contrario".
>>> >>>
>>> >>> Por tu último comentario, realmente no sé qué es lo que necesitas.
>>> >>> Si en
>>> >>> ciertos casos necesitas validar la FK y en otros no, entonces no te
>>> >>> sirve una FK. Probablemente necesites validar esa regla por medio de
>>> >>> un
>>> >>> trigger, que te permite crear una lógica más compleja.
>>> >>>
>>> >>> Espero haberme explicado.
>>> >>>
>>> >>> Un saludo
>>> >>> -
>>> >>> www.navento.com
>>> >>> Servicios de Localización GPS
>>> >>>
>>> >>> http://blogs.solidq.com/ES/ElRincon...fault.aspx
>>> >>>
>>> >>> "Ajataru" escribió en el mensaje
>>> >>> news:h0j61r$
>>> >>>> Es una buena idea, siempre que por narices en la segunda tabla
>>> >>>> tengas
>>> >>>> que referenciar siempre un registro de la primera: puede darse el
>>> >>>> caso,
>>> >>>> de que no siempre lo tengas que hacer...
>>> >>>>
>>> >>>> No se si este es un problema de fondo de SQL, de mi instalación, o
>>> >>>> de
>>> >>>> como he creado los índices... le ocurre esto a alguien mas?.
>>> >>>>
>>> >>>>
>>> >>>>
>>> >>>>
>>> >>>>
>>> >>>> "Carlos Sacristan" escribió en el mensaje
>>> >>>> news:%
>>> >>>>> Cambia la definición de esa segunda tabla para que esos campos no
>>> >>>>> acepten NULL
>>> >>>>>
>>> >>>>> Un saludo
>>> >>>>> -
>>> >>>>> www.navento.com
>>> >>>>> Servicios de Localización GPS
>>> >>>>>
>>> >>>>> http://blogs.solidq.com/ES/ElRincon...fault.aspx
>>> >>>>>
>>> >>>>> "Ajataru" escribió en el mensaje
>>> >>>>> news:h0iot5$
>>> >>>>>> Hola a todos,
>>> >>>>>>
>>> >>>>>> me he encontrado casualmente con un problema, que me resulta
>>> >>>>>> un
>>> >>>>>> tanto extraño:
>>> >>>>>>
>>> >>>>>> - tengo una tabla en la que he definido un índice basado en
>>> >>>>>> dos
>>> >>>>>> campos.
>>> >>>>>> - tengo otra tabla, en la que incluyo dos campos relacionados
>>> >>>>>> con
>>> >>>>>> el índice de la primera tabla.
>>> >>>>>> - para meter valores en la segunda tabla, tengo quue meter
>>> >>>>>> pares
>>> >>>>>> de valores que existan en la primera.
>>> >>>>>>
>>> >>>>>> hasta aquí, todo bien y normal, pero casualmente, metí unos
>>> >>>>>> valores
>>> >>>>>> en la tabla, insertando solo el valor del primero de los índices,
>>> >>>>>> y
>>> >>>>>> no el segundo, dejando en el un NULL. Por lo que tengo en la 2ª
>>> >>>>>> tabla
>>> >>>>>> un par de valores (XXX, NULL), que obviamente, no existe como tal
>>> >>>>>> en
>>> >>>>>> la tabla primaria. Pues SQL traga, y no da ningún error. Mientras
>>> >>>>>> uno
>>> >>>>>> de los dos valores sea un NULL, no hace ninguna evaluación...
>>> >>>>>>
>>> >>>>>> He comprobado los índices, y en ppio. está todo OK. Hay alguna
>>> >>>>>> opcion
>>> >>>>>> de la BBDD que activa / desactiva este comportamiento?. Es esto
>>> >>>>>> normal?.
>>> >>>>>>
>>> >>>>>> Muchas gracias.
>>> >>>>>>
>>> >>>>>>
>>> >>>>>>
>>> >>>>>>
>>> >>>>>
>>> >>>>>
>>> >>>>
>>> >>>>
>>> >>>
>>> >>>
>>> >>
>>> >>
>>> >
>>> >
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida