Cómo hacer una variable con una lista nvarchar

02/10/2009 - 14:21 por DT | Informe spam
Hola a todos

Tengo el siguiente sql.
Select *
from tabla
Where nombre IN ('Carlos', 'Maria')

Ahora intento hacer esto:
Declare @nombres nvarchar(100)
Set @nombres = 'Carlos, Maria'


Select *
from tabla
Where nombre IN @nombre

Ningún resuldato cuál es el problema???
Gracias por sus consejos!
(sql Server 2005)

Preguntas similare

Leer las respuestas

#11 Alejandro Mesa
04/10/2009 - 20:24 | Informe spam
Carlos,

Hombre, te levantastes con ganas de profundizar en este tema, cosa que me
parece muy bien, o sera que te acostastes pensando en esto.

Yo no tengo acceso al codigo interno usado por sql server, solo se que esta
hecho con en C++, y de verdad necesito tiempo para dijerir tu planteamiento,
que en un principio me parece logico.

Recuerda que las CTEs pueden ser mas complejas, pues podemos usar varios
meimbros ancla (anchor) y varios meimbros recursivos. Tambien que en cada
pasada solo podemos accesar a los resultados de la ultima pasada, lo cual
como que se me asemeja al acceso de la pila cuando usamos recursividad o
llamada de una funcion a si misma.

Provare tu funcion en cuando tenga tiempo y te dejare saber como me fue y
como se compara con otros metodos. en este momento estoy terminando los
slided para una presentacion sobre los planes de ejecucion y su re-uso.

Tu actitud me parece muy positiva.

Saludos,
Alejandro Mesa


"Carlos M. Calvelo" wrote:

Hola Alejandro,

A raíz de lo que hablamos ayer en este hilo quisiera compartir lo
siguiente.

La forma general de CTE´s recursivas es algo así:

WITH <NombreTabla>
(
<consulta base>
UNION ALL
<consulta2> OPERATOR <consulta sobre NombreTabla>
)
<consulta-resultado> (a base de <NombreTabla>)

La recursividad es obvia en la definición de la CTE. Es decir que se
hace referencia a <NombreTabla> dentro de su propia definición. Como
todos sabemos y como ya hemos visto en el hilo, la ejecución de una
CTE está restringida por un máximo de llamadas recursivas. Por
defecto 100 y como máximo 32767 (´por casualidad´ el valor máximo que
puede obtener un entero representado en two´s complement en 16 bits).

Ahora hay que diferenciar entre la definición o especificación de una
función en general o una CTE en particular (el códico que escribe el
programador) y el proceso que esa definición genera en la memoria de
una computadora para calcular el resultado deseado. En concreto, la
definición puede ser recursiva (algo deseable para poder expresar de
forma sencilla la solución a ciertos problemas) y el proceso que se
lleva a cabo para realizar el cálculo puede ser iterativo. Esto
último es deseable porque un proceso iterativo puede usar una
cantidad de memoria constante independientemente del input y un
proceso recursivo no.

Bien. Pues los diseñadores y programadores de estas CTE's parecen
no ser conscientes de esto, porque el proceso que generan estas
CTE's es recursivo y no tiene por que serlo.

Para la consulta definida recursivamente arriba el método iterativo
para su ejecución, en líneas generales, es el siguiente:
(No estoy tratando de ser preciso aquí, solo de comunicar la idea.)

<resultado> := <consulta-base>;

<resultado-intermedio> := <resultado> OP <consulta-recursiva>;

WHILE NOT (<resultado-intermedio> = {})
BEGIN

<resultado> :> <resultado> UNION <resultado-intermedio>;

<resultado-intermedio> :> <resultado-intermedio> OP <consulta-recursiva>;

END

Aclaraciones:
Los valores que se asignan con :=, son tablas (resultados de
consultas).
OP es la operación que define la recursión (por ejemplo un join)
{} representa una tabla sin registros.

Obviamente esta estrategia es iterativa y de paso una explicación
sencilla de que son las CTE's recursivas en general. Pero visto lo
visto con la restricción de MAXRECURSION, no es algo así lo que
hace SQL Server.

Para un ejemplo de como la recursión en el proceso representa un
problema véase este mismo hilo. Y aquí abajo pongo una solución que
yo mismo tengo que programar como iterativa, pero que en realidad
es la estrategia que deberían seguir automáticamente las CTE´s sin
restricciones como el MAXRECURSION.

En comentarios he tratado de señalar los puntos clave que concuerdan
con la estrategia general descrita arriba. Esta función hace lo
mismo que la versión con CTE pero sin tal restricción. Naturalmente
no es tan eficiente, pero no se trata de eso aquí.
De lo que se trata es de que el trabajo con SQL Server es una lucha
constante con restricciones sin ninguna base en la lógica. Eso nos
obliga a tener que solucinar rompecabezas que no tienen ninguna razón
de ser y eso es a coste del problema que realmente tenemos entre
manos. Muchos BLOGs y publicaciones en internet se basan precisamente
en esos rompecabezas, pero por lo general sin crítica alguna hacia
el producto.

Alejandro, quizás quieras probar la función que he puesto abajo. No
he tratado de ninguna manera de optimizar. Solo he peleado con ella
para hacerla funcionar y solo es un ejemplo de una estrategia mas
general que deberían seguir las CTE's para calcular sus resultados
sin recursión. Comentarios son bienvenidos.

Los que quieran profundizar mas en los conceptos mencionados arriba
sobre recursividad e iteración (diferencia entre especificación de
una función y el poceso que esta genera en memoria) pueden darse un
paseo por el mundo de lenguajes funcionales. Por ejemplo algo de la
famila LISP (Scheme) y ver lo que significan conceptos como 'tail
recursion' y demás. Pero es también un 'truco' de optimización
utilizado por compiladores de lenguajes mas 'convencionales'.

Me parece que voy a tener que empezar un BLOG :) para publicar este
tipo de cosas. Pero mucho mejor elaborado y no así a correr y a
medias como en esta aportación. Además ya no me parece un tema
para este foro.

Saludos,
Carlos

create function [dbo].[delimstr2table3](@string varchar(max), @delim
char(1))
returns @res table(delimvalue varchar(100))
as
begin
declare @t1 table(delimvalue varchar(100), m int, n int)
declare @t2 table(delimvalue varchar(100), m int, n int)

insert into @t1 (delimvalue, m, n)
select
case
when p=0 then @string
when p=1 then ''
else left(@string,p-1)
end as delimvalue,
case when p=0 then len(@string)+1 else p end as m,
charindex(@delim,@string,
case
when p=0 then len(@string)
else p
end+1) as n
from (select charindex(@delim,@string) as p) b

insert into @res (delimvalue) select delimvalue from @t1

insert into @t2 (delimvalue, m, n)
select
case
when n=m+1 or len(@string)=m then ''
when n=0 then right(@string,len(@string)-m)
else substring(@string,m+1,n-m-1)
end as delimvalue,
case when n=0 then len(@string)+1 else n end as m,
charindex(@delim,@string,n+1) as n
from @t1
where m<=len(@string)

while exists(select * from @t2)
begin
delete @t1

insert into @t1 (delimvalue, m, n)
select delimvalue, m, n from @t2

insert into @res (delimvalue) select delimvalue from @t1

delete @t2

insert into @t2 (delimvalue, m, n)
select
case
when n=m+1 or len(@string)=m then ''
when n=0 then right(@string,len(@string)-m)
else substring(@string,m+1,n-m-1)
end as delimvalue,
case when n=0 then len(@string)+1 else n end as m,
charindex(@delim,@string,n+1) as n
from @t1
where m<=len(@string)
end
return
end

Respuesta Responder a este mensaje
#12 Carlos M. Calvelo
04/10/2009 - 22:29 | Informe spam
Hola Alejandro,

On 4 okt, 20:24, Alejandro Mesa
wrote:
Carlos,

Hombre, te levantastes con ganas de profundizar en este tema, cosa que me
parece muy bien, o sera que te acostastes pensando en esto.

Yo no tengo acceso al codigo interno usado por sql server, solo se que esta
hecho con en C++, y de verdad necesito tiempo para dijerir tu planteamiento,
que en un principio me parece logico.

Recuerda que las CTEs pueden ser mas complejas, pues podemos usar varios
meimbros ancla (anchor) y varios meimbros recursivos. Tambien que en cada
pasada solo podemos accesar a los resultados de la ultima pasada, lo cual
como que se me asemeja al acceso de la pila cuando usamos recursividad o
llamada de una funcion a si misma.



Soy consciente de ello. Claro que lo que he explicado, con lo de
los resultados intermedios, es solo el principio. Lo he hecho solo
a un nivel. Es solo la base de la estrategia que se puede ampliar
para varios niveles, cada uno con sus resultados intermedios.


Provare tu funcion en cuando tenga tiempo y te dejare saber como me fue y
como se compara con otros metodos.



Hombre, tampoco es que yo te quiera poner a trabajar! Simplemente
he compartido la idea. Que no es nada nuevo, ni mio.

En cuanto a eficiencia no te molestes. Puedes controlar que sí
funciona y ya está. Solo he tratado de dejar ver que la
especificación recursiva de un CTE es traducible a un proceso
iterativo, sin preocuparme para nada de la eficiencia. Pero bien
implementado puede ser igual de eficiente en cuanto a tiempo y más
eficiente en cuanto a espacio (memoria).
La esencia es que con un input lo suficientemente grande un proceso
recursivo no tendrá suficiente memoria para terminar debido al
crecimiento de la pila (stack). Ese problema desaparece con un
proceso iterativo.

Ademas el ejemplo de convertir una cadena a una tabla no me parece
bueno para analizar esto. Mejor algo con estructura de árbol, que es
recursiva por naturaleza. Habría que preparar un ejemplo mejor.


en este momento estoy terminando los
slided para una presentacion sobre los planes de ejecucion y su re-uso.




Pues suerte con ello!

Tu actitud me parece muy positiva.




Mi actitud es siempre positiva. :)

Saludos,
Carlos
Respuesta Responder a este mensaje
#13 DT
05/10/2009 - 13:45 | Informe spam
Gracias a todos por su ayuda.
Lo he resulto utilizado las tablas temporales

Muchas gracias :)

"Carlos M. Calvelo" wrote in message
news:
Hola Alejandro,

On 4 okt, 20:24, Alejandro Mesa
wrote:
Carlos,

Hombre, te levantastes con ganas de profundizar en este tema, cosa que me
parece muy bien, o sera que te acostastes pensando en esto.

Yo no tengo acceso al codigo interno usado por sql server, solo se que
esta
hecho con en C++, y de verdad necesito tiempo para dijerir tu
planteamiento,
que en un principio me parece logico.

Recuerda que las CTEs pueden ser mas complejas, pues podemos usar varios
meimbros ancla (anchor) y varios meimbros recursivos. Tambien que en cada
pasada solo podemos accesar a los resultados de la ultima pasada, lo cual
como que se me asemeja al acceso de la pila cuando usamos recursividad o
llamada de una funcion a si misma.



Soy consciente de ello. Claro que lo que he explicado, con lo de
los resultados intermedios, es solo el principio. Lo he hecho solo
a un nivel. Es solo la base de la estrategia que se puede ampliar
para varios niveles, cada uno con sus resultados intermedios.


Provare tu funcion en cuando tenga tiempo y te dejare saber como me fue y
como se compara con otros metodos.



Hombre, tampoco es que yo te quiera poner a trabajar! Simplemente
he compartido la idea. Que no es nada nuevo, ni mio.

En cuanto a eficiencia no te molestes. Puedes controlar que sí
funciona y ya está. Solo he tratado de dejar ver que la
especificación recursiva de un CTE es traducible a un proceso
iterativo, sin preocuparme para nada de la eficiencia. Pero bien
implementado puede ser igual de eficiente en cuanto a tiempo y más
eficiente en cuanto a espacio (memoria).
La esencia es que con un input lo suficientemente grande un proceso
recursivo no tendrá suficiente memoria para terminar debido al
crecimiento de la pila (stack). Ese problema desaparece con un
proceso iterativo.

Ademas el ejemplo de convertir una cadena a una tabla no me parece
bueno para analizar esto. Mejor algo con estructura de árbol, que es
recursiva por naturaleza. Habría que preparar un ejemplo mejor.


en este momento estoy terminando los
slided para una presentacion sobre los planes de ejecucion y su re-uso.




Pues suerte con ello!

Tu actitud me parece muy positiva.




Mi actitud es siempre positiva. :)

Saludos,
Carlos
Respuesta Responder a este mensaje
#14 Carlos M. Calvelo
05/10/2009 - 23:04 | Informe spam
Hola DT,

On 5 okt, 13:45, "DT" wrote:
Gracias a todos por su ayuda.
Lo he resulto utilizado las tablas temporales



Y todo lo que te hemos hecho leer para eso! :-)


Muchas gracias :)



De nada hombre! (supongo que también en nombre de Alejandro y Julio)

Carlos
Respuesta Responder a este mensaje
#15 Alejandro Mesa
06/10/2009 - 14:58 | Informe spam
Carlos,

De nada hombre! (supongo que también en nombre de Alejandro y Julio)



Me alegra que el OP pueda dar solucion a su problema, pero en este caso
vemos el tiempo que se hubiese podido ahorrar si su especificacion hubiese
sido mas clara desde un principio.

Casi siempre este tipo de problema se presenta con aplicaciones clientes,
por ejemplo cuando usamos parametros multi-valores en Reporting Services. Yo
no hubiese gastado mi tiempo en tocar el tema si desde un principio el OP
hubiese aclarado que la lista es creada manualmente en el lado del servidor.

Menos mal que el intercambio contigo siempre es ameno y productivo. :)

AMB



"Carlos M. Calvelo" wrote:

Hola DT,

On 5 okt, 13:45, "DT" wrote:
> Gracias a todos por su ayuda.
> Lo he resulto utilizado las tablas temporales

Y todo lo que te hemos hecho leer para eso! :-)

>
> Muchas gracias :)

De nada hombre! (supongo que también en nombre de Alejandro y Julio)

Carlos


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