Campos calculados

11/03/2009 - 19:24 por José Antonio Muñoz | Informe spam
Hola al grupo,

En la ayuda de SQL Server 2008 he leido que un campo calculado no puede ser
una subconsulta pero si puede ser una función escalar, entonces mi pregunta
es ¿puedo crear un campo calculado en una tabla "X" que obtiene, a través de
una función escalar creada previamente y que incluye una consulta, un valor
de otra tabla "Y"?

Es decir, me explico a través de un sencillo ejemplo; tengo una tabla X:

CREATE TABLE x
(
Codigo Int,
Fecha As Dbo.ObtieneFecha(Codigo)
)

Y tengo una función:

CREATE FUNCTION Dbo.ObtieneFecha ( @Codigo Int ) RETURNS Date
AS
BEGIN
DECLARE @Fecha Date
SELECT @Fecha=Fecha FROM Y WHERE Codigo=@Codigo
RETURN @Fecha
END

¿Hasta que punto se pueden incluir este tipo de campos calculados en una
tabla? ¿Qué inconvenientes tendría? ¿Donde está el límite si la consulta se
complica aún más con otras consultas? ¿Sería aconsejable hacerlo en vez de
tener un campo normal que a través de una aplicación voy calculando a partir
de esas consultas?

Gracias por vuestra atención y saludos,
José Antonio Muñoz.

Preguntas similare

Leer las respuestas

#1 Alejandro Mesa
11/03/2009 - 21:00 | Informe spam
José Antonio Muñoz,

De poder hacerlo, claro que se puede, pero cual es el proposito de tener
este campo calculado.

1 - Cada vez que selecciones de la tabla e incluyas este campo en la lista
de columnas en la select, la funcion se tendra que ejecutar por cada fila
seleccionada. Esto puede traerte serios problemas de desempanio de una query.

Esto se puede evitar si haces una union de ambas tabla para traer el valor
de la otra columna.

2 - Para evitar lo anterior, tendrias que crear esa columna calculada con
opcion PERSISTED. Pero entonces que pasa si ese valor cambia en la otra
tabla, es eso importante para lo que tratas de hacer?

La mala noticia es que si tu funcion accesa alguna otra tabla, entonces esta
no puede ser usada para crear una columna calculada como persisted.

Si nos comentas con mas detalle el proposito de lo que deseas hacer, quizas
alguien pueda darte alguna otra alternativa. Por ejemplo, pudieras llenar esa
columna usando un trigger.


AMB


"José Antonio Muñoz" wrote:

Hola al grupo,

En la ayuda de SQL Server 2008 he leido que un campo calculado no puede ser
una subconsulta pero si puede ser una función escalar, entonces mi pregunta
es ¿puedo crear un campo calculado en una tabla "X" que obtiene, a través de
una función escalar creada previamente y que incluye una consulta, un valor
de otra tabla "Y"?

Es decir, me explico a través de un sencillo ejemplo; tengo una tabla X:

CREATE TABLE x
(
Codigo Int,
Fecha As Dbo.ObtieneFecha(Codigo)
)

Y tengo una función:

CREATE FUNCTION Dbo.ObtieneFecha ( @Codigo Int ) RETURNS Date
AS
BEGIN
DECLARE @Fecha Date
SELECT @Fecha=Fecha FROM Y WHERE Codigo=@Codigo
RETURN @Fecha
END

¿Hasta que punto se pueden incluir este tipo de campos calculados en una
tabla? ¿Qué inconvenientes tendría? ¿Donde está el límite si la consulta se
complica aún más con otras consultas? ¿Sería aconsejable hacerlo en vez de
tener un campo normal que a través de una aplicación voy calculando a partir
de esas consultas?

Gracias por vuestra atención y saludos,
José Antonio Muñoz.


Respuesta Responder a este mensaje
#2 José Antonio Muñoz
12/03/2009 - 09:09 | Informe spam
En principio pensé hacerlo con un trigger pero se me ocrrió la idea de
hacerlo como he explicado anteriormente. El problema del trigger es que el
campo en cuestión se actualiza con mucha frecuencia a partir de otra tabla
por lo que también relentiza la ejecución de consultas.

De todas formas la consulta "SELECT TOP 1 Fecha FROM Y WHERE Codigo=@Codigo"
es de ejecución rápida ¿no? tan solo devuelve un valor, aunque se ejecute
por cada recuperación de fila de la tabla principal. Yo necesito obtener el
valor de la fecha siempre que acceso a esa tabla.

Entonces, que sería más aconsejable ¿tener un campo calculado en una tabla X
que accede a una función y ésta a su vez obtiene un valor de otra tabla Y? o
¿Crear un trigger a partir de la tabla Y que cada vez que se actualiza un
determinado campo, guarda el valor de dicho campo en la tabla X? Teniendo en
cuenta que la tabla Y se actualiza con frecuencia.

Saludos,
José Antonio Muñoz

"Alejandro Mesa" escribió en el
mensaje de noticias
news:
José Antonio Muñoz,

De poder hacerlo, claro que se puede, pero cual es el proposito de tener
este campo calculado.

1 - Cada vez que selecciones de la tabla e incluyas este campo en la lista
de columnas en la select, la funcion se tendra que ejecutar por cada fila
seleccionada. Esto puede traerte serios problemas de desempanio de una
query.

Esto se puede evitar si haces una union de ambas tabla para traer el valor
de la otra columna.

2 - Para evitar lo anterior, tendrias que crear esa columna calculada con
opcion PERSISTED. Pero entonces que pasa si ese valor cambia en la otra
tabla, es eso importante para lo que tratas de hacer?

La mala noticia es que si tu funcion accesa alguna otra tabla, entonces
esta
no puede ser usada para crear una columna calculada como persisted.

Si nos comentas con mas detalle el proposito de lo que deseas hacer,
quizas
alguien pueda darte alguna otra alternativa. Por ejemplo, pudieras llenar
esa
columna usando un trigger.


AMB


"José Antonio Muñoz" wrote:

Hola al grupo,

En la ayuda de SQL Server 2008 he leido que un campo calculado no puede
ser
una subconsulta pero si puede ser una función escalar, entonces mi
pregunta
es ¿puedo crear un campo calculado en una tabla "X" que obtiene, a través
de
una función escalar creada previamente y que incluye una consulta, un
valor
de otra tabla "Y"?

Es decir, me explico a través de un sencillo ejemplo; tengo una tabla X:

CREATE TABLE x
(
Codigo Int,
Fecha As Dbo.ObtieneFecha(Codigo)
)

Y tengo una función:

CREATE FUNCTION Dbo.ObtieneFecha ( @Codigo Int ) RETURNS Date
AS
BEGIN
DECLARE @Fecha Date
SELECT @Fecha=Fecha FROM Y WHERE Codigo=@Codigo
RETURN @Fecha
END

¿Hasta que punto se pueden incluir este tipo de campos calculados en una
tabla? ¿Qué inconvenientes tendría? ¿Donde está el límite si la consulta
se
complica aún más con otras consultas? ¿Sería aconsejable hacerlo en vez
de
tener un campo normal que a través de una aplicación voy calculando a
partir
de esas consultas?

Gracias por vuestra atención y saludos,
José Antonio Muñoz.


Respuesta Responder a este mensaje
#3 Carlos Sacristan
12/03/2009 - 09:41 | Informe spam
Jose Antonio, aunque esa consulta, tomada individualmente, sea rápida, ten
en cuenta que se va a ejecutar por cada una de las filas del conjunto de
resultados principal (en este caso tu tabla), con lo que los recursos que
impliquen resolverla se multiplican por cada uno de los registros devueltos.
Esto es muy ineficiente, y empeora cuantas más filas se devuelven.

Una columna calculada podría servir, pero si cambia el valor de la tabla a
la que accedes no te va a funcionar. El trigger parece ser la única solución,
pero si dices que ambas tablas se modifican mucho y que por lo tanto el
rendimiento podría verse afectado, habrá que desecharlo también.

Por tanto, la única opción que veo es que devuelvas ese valor en la
consulta, únicamente cuando lo necesites, por ejemplo en una vista o en el
código de un procedimiento almacenado. Haciéndolo así tienes más
posibilidades de recodificar la sintaxis para hacerla más eficiente
(trabajando por conjuntos en vez de fila a fila, que es la solución que
estabas pensando)


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


"José Antonio Muñoz" wrote:

En principio pensé hacerlo con un trigger pero se me ocrrió la idea de
hacerlo como he explicado anteriormente. El problema del trigger es que el
campo en cuestión se actualiza con mucha frecuencia a partir de otra tabla
por lo que también relentiza la ejecución de consultas.

De todas formas la consulta "SELECT TOP 1 Fecha FROM Y WHERE Codigo=@Codigo"
es de ejecución rápida ¿no? tan solo devuelve un valor, aunque se ejecute
por cada recuperación de fila de la tabla principal. Yo necesito obtener el
valor de la fecha siempre que acceso a esa tabla.

Entonces, que sería más aconsejable ¿tener un campo calculado en una tabla X
que accede a una función y ésta a su vez obtiene un valor de otra tabla Y? o
¿Crear un trigger a partir de la tabla Y que cada vez que se actualiza un
determinado campo, guarda el valor de dicho campo en la tabla X? Teniendo en
cuenta que la tabla Y se actualiza con frecuencia.

Saludos,
José Antonio Muñoz

"Alejandro Mesa" escribió en el
mensaje de noticias
news:
> José Antonio Muñoz,
>
> De poder hacerlo, claro que se puede, pero cual es el proposito de tener
> este campo calculado.
>
> 1 - Cada vez que selecciones de la tabla e incluyas este campo en la lista
> de columnas en la select, la funcion se tendra que ejecutar por cada fila
> seleccionada. Esto puede traerte serios problemas de desempanio de una
> query.
>
> Esto se puede evitar si haces una union de ambas tabla para traer el valor
> de la otra columna.
>
> 2 - Para evitar lo anterior, tendrias que crear esa columna calculada con
> opcion PERSISTED. Pero entonces que pasa si ese valor cambia en la otra
> tabla, es eso importante para lo que tratas de hacer?
>
> La mala noticia es que si tu funcion accesa alguna otra tabla, entonces
> esta
> no puede ser usada para crear una columna calculada como persisted.
>
> Si nos comentas con mas detalle el proposito de lo que deseas hacer,
> quizas
> alguien pueda darte alguna otra alternativa. Por ejemplo, pudieras llenar
> esa
> columna usando un trigger.
>
>
> AMB
>
>
> "José Antonio Muñoz" wrote:
>
>> Hola al grupo,
>>
>> En la ayuda de SQL Server 2008 he leido que un campo calculado no puede
>> ser
>> una subconsulta pero si puede ser una función escalar, entonces mi
>> pregunta
>> es ¿puedo crear un campo calculado en una tabla "X" que obtiene, a través
>> de
>> una función escalar creada previamente y que incluye una consulta, un
>> valor
>> de otra tabla "Y"?
>>
>> Es decir, me explico a través de un sencillo ejemplo; tengo una tabla X:
>>
>> CREATE TABLE x
>> (
>> Codigo Int,
>> Fecha As Dbo.ObtieneFecha(Codigo)
>> )
>>
>> Y tengo una función:
>>
>> CREATE FUNCTION Dbo.ObtieneFecha ( @Codigo Int ) RETURNS Date
>> AS
>> BEGIN
>> DECLARE @Fecha Date
>> SELECT @Fecha=Fecha FROM Y WHERE Codigo=@Codigo
>> RETURN @Fecha
>> END
>>
>> ¿Hasta que punto se pueden incluir este tipo de campos calculados en una
>> tabla? ¿Qué inconvenientes tendría? ¿Donde está el límite si la consulta
>> se
>> complica aún más con otras consultas? ¿Sería aconsejable hacerlo en vez
>> de
>> tener un campo normal que a través de una aplicación voy calculando a
>> partir
>> de esas consultas?
>>
>> Gracias por vuestra atención y saludos,
>> José Antonio Muñoz.
>>
>>


Respuesta Responder a este mensaje
#4 Alejandro Mesa
12/03/2009 - 14:39 | Informe spam
José Antonio Muñoz,

Creo que lo que Carlos recomienda seria una buena solucion. Accesa a esa
columna solo cuando sea necesario. Puedes usar una vista, una funcion en line
tipo tabla, o un procedimiento.


AMB

"Carlos Sacristan" wrote:


Jose Antonio, aunque esa consulta, tomada individualmente, sea rápida, ten
en cuenta que se va a ejecutar por cada una de las filas del conjunto de
resultados principal (en este caso tu tabla), con lo que los recursos que
impliquen resolverla se multiplican por cada uno de los registros devueltos.
Esto es muy ineficiente, y empeora cuantas más filas se devuelven.

Una columna calculada podría servir, pero si cambia el valor de la tabla a
la que accedes no te va a funcionar. El trigger parece ser la única solución,
pero si dices que ambas tablas se modifican mucho y que por lo tanto el
rendimiento podría verse afectado, habrá que desecharlo también.

Por tanto, la única opción que veo es que devuelvas ese valor en la
consulta, únicamente cuando lo necesites, por ejemplo en una vista o en el
código de un procedimiento almacenado. Haciéndolo así tienes más
posibilidades de recodificar la sintaxis para hacerla más eficiente
(trabajando por conjuntos en vez de fila a fila, que es la solución que
estabas pensando)


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


"José Antonio Muñoz" wrote:

> En principio pensé hacerlo con un trigger pero se me ocrrió la idea de
> hacerlo como he explicado anteriormente. El problema del trigger es que el
> campo en cuestión se actualiza con mucha frecuencia a partir de otra tabla
> por lo que también relentiza la ejecución de consultas.
>
> De todas formas la consulta "SELECT TOP 1 Fecha FROM Y WHERE Codigo=@Codigo"
> es de ejecución rápida ¿no? tan solo devuelve un valor, aunque se ejecute
> por cada recuperación de fila de la tabla principal. Yo necesito obtener el
> valor de la fecha siempre que acceso a esa tabla.
>
> Entonces, que sería más aconsejable ¿tener un campo calculado en una tabla X
> que accede a una función y ésta a su vez obtiene un valor de otra tabla Y? o
> ¿Crear un trigger a partir de la tabla Y que cada vez que se actualiza un
> determinado campo, guarda el valor de dicho campo en la tabla X? Teniendo en
> cuenta que la tabla Y se actualiza con frecuencia.
>
> Saludos,
> José Antonio Muñoz
>
> "Alejandro Mesa" escribió en el
> mensaje de noticias
> news:
> > José Antonio Muñoz,
> >
> > De poder hacerlo, claro que se puede, pero cual es el proposito de tener
> > este campo calculado.
> >
> > 1 - Cada vez que selecciones de la tabla e incluyas este campo en la lista
> > de columnas en la select, la funcion se tendra que ejecutar por cada fila
> > seleccionada. Esto puede traerte serios problemas de desempanio de una
> > query.
> >
> > Esto se puede evitar si haces una union de ambas tabla para traer el valor
> > de la otra columna.
> >
> > 2 - Para evitar lo anterior, tendrias que crear esa columna calculada con
> > opcion PERSISTED. Pero entonces que pasa si ese valor cambia en la otra
> > tabla, es eso importante para lo que tratas de hacer?
> >
> > La mala noticia es que si tu funcion accesa alguna otra tabla, entonces
> > esta
> > no puede ser usada para crear una columna calculada como persisted.
> >
> > Si nos comentas con mas detalle el proposito de lo que deseas hacer,
> > quizas
> > alguien pueda darte alguna otra alternativa. Por ejemplo, pudieras llenar
> > esa
> > columna usando un trigger.
> >
> >
> > AMB
> >
> >
> > "José Antonio Muñoz" wrote:
> >
> >> Hola al grupo,
> >>
> >> En la ayuda de SQL Server 2008 he leido que un campo calculado no puede
> >> ser
> >> una subconsulta pero si puede ser una función escalar, entonces mi
> >> pregunta
> >> es ¿puedo crear un campo calculado en una tabla "X" que obtiene, a través
> >> de
> >> una función escalar creada previamente y que incluye una consulta, un
> >> valor
> >> de otra tabla "Y"?
> >>
> >> Es decir, me explico a través de un sencillo ejemplo; tengo una tabla X:
> >>
> >> CREATE TABLE x
> >> (
> >> Codigo Int,
> >> Fecha As Dbo.ObtieneFecha(Codigo)
> >> )
> >>
> >> Y tengo una función:
> >>
> >> CREATE FUNCTION Dbo.ObtieneFecha ( @Codigo Int ) RETURNS Date
> >> AS
> >> BEGIN
> >> DECLARE @Fecha Date
> >> SELECT @Fecha=Fecha FROM Y WHERE Codigo=@Codigo
> >> RETURN @Fecha
> >> END
> >>
> >> ¿Hasta que punto se pueden incluir este tipo de campos calculados en una
> >> tabla? ¿Qué inconvenientes tendría? ¿Donde está el límite si la consulta
> >> se
> >> complica aún más con otras consultas? ¿Sería aconsejable hacerlo en vez
> >> de
> >> tener un campo normal que a través de una aplicación voy calculando a
> >> partir
> >> de esas consultas?
> >>
> >> Gracias por vuestra atención y saludos,
> >> José Antonio Muñoz.
> >>
> >>
>
>
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida