Tengo el siguiente sql.
Select *
from tabla
Where nombre IN ('Carlos', 'Maria')
Ahora intento hacer esto:
Declare @nombres nvarchar(100)
Set @nombres = 'Carlos, Maria'
-- Tambi�n he intentado:
-- 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)
Declare @tabla varchar(50)Declare
@condicion varchar(50)Declare
@Sql varchar(350)set @tabla = 'Nombre_Tabla'
set @condicion = 'nombre in (''Carlos'', ''Maria'')'
select @Sql = 'select * From ' + @tabla + ' Where ' + @condicion
select @Sql
-- select * from nombre_tabla where nombre in ('Carlos', 'Maria')
exec (@Sql)
Saludos,
Julio.
"DT" <digi...@switch.com> escribi� en el mensaje de
noticias:7912270E-F0F2-47AD...@microsoft.com...
No existe la macro-sustitucion en T-SQL. La sentencia que tratas de armar,
esta preguntando lo sgte:
select *
from T
where nombre in ('Carlos, Maria');
Te das cuenta que la cadena 'Carlos, Maria' es el unico elemento contenido
en la lista?
Si expandimos el operador "ïn", entonces tendriamos:
select *
from T
where nombre = 'Carlos, Maria';
Lo mismo si usas:
select *
from T
where nombre = '''Carlos'', ''Maria''';
La cadena '''Carlos'', ''Maria''' sigue siendo un unico elemnto y no una
lista.
Existen varias formas de hacerlo. Yo no recomiendo el uso de sql dinamico
solo para concatenar la lista, pues eso puede causar que el cache de
procedimientos crezca demasiado con planes que no seran re-utlizados.
1 - Usar el operador "like".
set @nombres = 'Carlos,Maria';
select *
from T
where ',' + nombre + ',' like '%,' + @nombres + ',%'
A pesar de que funciona, cuando se manipula una columna en un predicado, SQL
Server no puede usar el histograma (en caso de existir un indice que se pueda
usar) para estimar la selectividad de ese predicado. Esto puede provocar que
SQL Server decida usar un scan de el indice en vez de usar seek.
2 - Usar XML para desmantelar la lista.
declare @nombres varchar(100);
declare @x xml;
set @nombres = 'Carlos,Maria';
set @x = '<e>' + REPLACE(@nombres, ',', '</e><e>') + '</e>';
select *
from T
where nombre in (
select N.c.value('.', 'varchar(50)')
from @x.nodes('/e') as N(c)
) as A;
GO
Esta solucion tambien tiene inconvenientes. Si la cadena contiene algun
caracter no valido para xml, entonces puede causar error.
declare @nombres varchar(1000);
declare @x xml;
set @nombres = 'SQL&Server,2008';
set @x = '<e>' + REPLACE(@nombres, ',', '</e><e>') + '</e>';
select N.c.value('.', 'nvarchar(40)')
from @x.nodes('/e') as N(c);
GO
Resultado:
Msg 9411, Level 16, State 1, Line 6
XML parsing: line 1, character 14, semicolon expected
3 - Puedes crear una funcion tipo tabla que devuelva cada elemento de la
lista como una fila. Puedes crear la funcion usando SQLCLR o T-SQL.
CREATE TABLE Numbers (Number int NOT NULL PRIMARY KEY);
go
CREATE FUNCTION dbo.fn_nums(@n AS bigint) RETURNS TABLE AS
RETURN
WITH
L0 AS(SELECT 1 AS c UNION ALL SELECT 1),
L1 AS(SELECT 1 AS c FROM L0 AS A, L0 AS B),
L2 AS(SELECT 1 AS c FROM L1 AS A, L1 AS B),
L3 AS(SELECT 1 AS c FROM L2 AS A, L2 AS B),
L4 AS(SELECT 1 AS c FROM L3 AS A, L3 AS B),
L5 AS(SELECT 1 AS c FROM L4 AS A, L4 AS B),
Nums AS(SELECT ROW_NUMBER() OVER(ORDER BY c) AS n FROM L5)
SELECT n FROM Nums WHERE n <= @n;
GO
INSERT Numbers(Number) SELECT n FROM fn_nums(1000);
go
CREATE FUNCTION inline_split_me(@param nvarchar(MAX))
RETURNS TABLE AS
RETURN(SELECT ltrim(rtrim(convert(nvarchar(4000),
substring(@param, Number,
charindex(N',' COLLATE Slovenian_BIN2,
@param + N',', Number) -
Number)
))) AS Value
FROM Numbers
WHERE Number <= convert(int, len(@param))
AND substring(N',' + @param, Number, 1) =
N',' COLLATE Slovenian_BIN2)
go
declare @nombres varchar(100);
set @nombres = 'Carlos,Maria';
select Value from dbo.inline_split_me(@nombres) as T;
select *
from T
where nombre in (select Value from dbo.inline_split_me(@nombres) as T);
go
drop function dbo.fn_nums,dbo.inline_split_me;
drop table Numbers;
go
No tienes porque eliminar la tabla auxiliar de numeros, pues hay muchos
problemas que se pueden resolver usando esta tabla.
Aca te paso un articulo muy interesante que toca todos estos metodos a fondo.
Arrays and Lists in SQL Server
http://www.sommarskog.se/arrays-in-sql.html
AMB
"DT" wrote:
> 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'
>
> -- Tambin he intentado:
> -- Set @nombres = '''Carlos','Maria'''
>
> Select *
> from tabla
> Where nombre IN @nombre
>
> Ningn resuldato.... cul es el problema???
On 3 okt, 03:18, Alejandro Mesa
<AlejandroM...@discussions.microsoft.com> wrote:
<...>
>
> 1 - Usar el operador "like".
>
> set @nombres = 'Carlos,Maria';
>
> select *
> from T
> where ',' + nombre + ',' like '%,' + @nombres + ',%'
>
> A pesar de que funciona, ...
Pues no va a funcionar.
Por ejemplo, para el registro con nombre='Carlos':
',Carlos,' like '%,Carlos,Maria,%' es false
Que forma de complicarse la vida Alejandro. En lo que es fuerte SQL
es en trabajar con tablas. No con listas, arrays o documentos XML.
Parece entonces que estructurar @nombres en una tabla sería lo
mas sensato.
declare @nombres table(nombre varchar(50))
insert @nombres (nombre) values ('Carlos')
insert @nombres (nombre) values ('Maria')
Dada esta estructura (una tabla) se simplifica la cosa:
select * from T
where nombre in (select nombre from @nombres)
o bien:
select * from T
where exists(select * from @nombres where nombre=T.nombre)
o tal vez:
select T.* from T join @nombres N on T.nombre=N.nombre
o ...?
Saludos,
Carlos
> > select *
> > from T
> > where ',' + nombre + ',' like '%,' + @nombres + ',%'
> >
> > A pesar de que funciona, ...
>
> Pues no va a funcionar.
Gracías por la corrección. Eso me pasa por contestar de carretilla.
use Northwind;
go
declare @customers nvarchar(100);
set @customers = N'BLONP,BOLID';
select *
from dbo.customers
where N',' + @customers + ',' like N'%,' + customerid + N',%';
go
> Que forma de complicarse la vida Alejandro. En lo que es fuerte SQL
> es en trabajar con tablas. No con listas, arrays o documentos XML.
> Parece entonces que estructurar @nombres en una tabla sería lo
> mas sensato.
Claro que si, que usando una tabla es lo logico, pero hasta la version 2005,
no contavamos con esa facilidad. Como bien sabes, no teniamos un parametro
tipo tabla para ser usado en un procedimiento almacenado, el cual ya tenemos
en la version 2008.
Si trabajas con versiones anteriores a la 2008, entonces como defines esa
variable tipo tabla desde una aplicacion cliente?
Claro esta que puedes enviar tantas sentencias "insert" como elementos en la
lista, pero eso es mas lento que enviar la lista y desmantelarla en el
servidor.
AMB
On 3 okt, 19:56, Alejandro Mesa
<AlejandroM...@discussions.microsoft.com> wrote:
>
> > Que forma de complicarse la vida Alejandro. En lo que es fuerte SQL
> > es en trabajar con tablas. No con listas, arrays o documentos XML.
> > Parece entonces que estructurar @nombres en una tabla sería lo
> > mas sensato.
>
> Claro que si, que usando una tabla es lo logico, pero hasta la version 2005,
> no contavamos con esa facilidad. Como bien sabes, no teniamos un parametro
> tipo tabla para ser usado en un procedimiento almacenado, el cual ya tenemos
> en la version 2008.
>
> Si trabajas con versiones anteriores a la 2008, entonces como defines esa
> variable tipo tabla desde una aplicacion cliente?
>
OK!
Claro que para solucionarlo de forma genérica se complica la cosa.
El OP empezó con que hace esto:
Declare @nombres nvarchar(100)
Set @nombres = 'Carlos, Maria'
y me has pillado pensando:
"Pues que haga esto:
declare @nombres table(nombre varchar(50))
insert @nombres (nombre) values ('Carlos')
insert @nombres (nombre) values ('Maria')
... y ya está."
Puede usted considerar mis comentarios anteriores al respecto
como 'no enviados'. :-)
Saludos,
Carlos
Me alegro que lo comentates, porque yo olvide hablar sobre la nueva
facilidad que tenemos en la version 2008 (table-valued parameters).
Tus comentarios son siempre bienvenidos, asi que no dejes de hacerlos.
AMB
On 4 okt, 01:41, Alejandro Mesa
<AlejandroM...@discussions.microsoft.com> wrote:
> Carlos,
>
> Me alegro que lo comentates, porque yo olvide hablar sobre la nueva
> facilidad que tenemos en la version 2008 (table-valued parameters).
>
> Tus comentarios son siempre bienvenidos, asi que no dejes de hacerlos.
>
Pues ahí va: :)
Me he puesto a hacer uno de mis pinitos :) y a ver que te parece.
Con una CTE he conseguido algo que parece bastante eficiente. Pero
tiene el problema de que no puedo meterlo en una función porque
no se puede especificar un option(maxrecursion ...) en funciones.
A ver, que pongo lo que tengo por ahora:
-- creamos una cadena @nombres:
declare @nombres varchar(max), @i int, @dt datetime
set @nombres=''
set @i=0
while @i<32767
begin
set @nombres=@nombres+'N'+cast(@i as varchar)+','
set @i=@i+1
end
-- aqui viene el test para el famoso inline_split_me():
set @dt=getdate()
select Value from dbo.inline_split_me(@nombres) as T;
print datediff(ms,@dt,getdate())
-- y aqui viene mi pinito que me gustaría meter en una
-- función
set @dt=getdate()
-- estos serían los parámetros de la función:
declare @string varchar(max), @delim char(1)
set @string=@nombres
set @delim=',';
begin
declare @lenstr int;
set @lenstr =len(@string);
with A as
(
select
case
when p=0 then @string
when p=1 then ''
else left(@string,p-1)
end as delimvalue,
case when p=0 then @lenstr+1 else p end as m,
charindex(@delim,@string,
case
when p=0 then @lenstr
else p
end+1) as n
from (select charindex(@delim,@string) as p) b
union all
select
case
when n=m+1 or @lenstr=m then ''
when n=0 then right(@string,@lenstr-m)
else substring(@string,m+1,n-m-1)
end as delimvalue,
case when n=0 then @lenstr+1 else n end as m,
charindex(@delim,@string,n+1) as n
from A
where m<=@lenstr
)
select delimvalue from A option(maxrecursion 32767)
end
print datediff(ms,@dt,getdate())
----
Para cada registro en la CTE, las columnas m y n son las
posiciones de las las dos siguientes comas. Un poco
críptico, pero espero se entienda.
Pero no veo forma de meter esto en una función con el
dichoso option(maxrecursion...)
Fíjate además que los resutados de la función inline_split_me() y
de la CTE son distintos. @nombres termina con "N32766," o sea
que hay una cadena vacía al final. Ese registro se ve en el
resultado de la CTE, pero no en el de la función.
Un problema? del CTE es también que solo puede generar hasta
32767 registros, por lo de la 'maxrecursion'. Una ventaja es
que es independiente de la tabla Numbers.
Buen pasatiempos este! :-)
Bueno... a ver que te parece.
Saludos,
Carlos
Fantastico, no hay mejor forma de aprender que tratando de hacerlo por uno
mismo.
> Con una CTE he conseguido algo que parece bastante eficiente. Pero
> tiene el problema de que no puedo meterlo en una función porque
> no se puede especificar un option(maxrecursion ...) en funciones.
Asi es. Seria responsabilidad de quien use la funcion de usar la "opcion" en
el query la use.
select *
from tu_funcion('Carlos,Maria') as T
option (maxrecursion 0);
go
Pero si el programador no lo hace entonces pudiera recivir el error cuando
la CTE recursiva se pase de el valor por defecto de maxrecursion (100).
Si lees el articulo de Erland, el cual es muy refrescante, te daras cuenta
que uno de los metodos es usar una CTE recursiva como la que has usado.
AMB
On 4 okt, 02:25, Alejandro Mesa
<AlejandroM...@discussions.microsoft.com> wrote:
> Carlos,
>
> Fantastico, no hay mejor forma de aprender que tratando de hacerlo por uno
> mismo.
>
> > Con una CTE he conseguido algo que parece bastante eficiente. Pero
> > tiene el problema de que no puedo meterlo en una función porque
> > no se puede especificar un option(maxrecursion ...) en funciones.
>
> Asi es. Seria responsabilidad de quien use la funcion de usar la "opcion" en
> el query la use.
>
> select *
> from tu_funcion('Carlos,Maria') as T
> option (maxrecursion 0);
> go
>
> Pero si el programador no lo hace entonces pudiera recivir el error cuando
> la CTE recursiva se pase de el valor por defecto de maxrecursion (100).
>
Pues no me gusta tener dejar la opcion fuera de la función.., y
si nos ponemos a eso no me gusta ni que exista tal opción.
Pero... es lo que hay.
Saludos,
Carlos
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
-- resultado <consulta-base> (solo una columna de @t1)
insert into @res (delimvalue) select delimvalue from @t1
-- primer resultado intermedio
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)
-- tenemos un resultado intermedio en @t2?
while exists(select * from @t2)
begin
delete @t1
insert into @t1 (delimvalue, m, n)
select delimvalue, m, n from @t2
-- resultado = resultado UNION resultado intermedio
insert into @res (delimvalue) select delimvalue from @t1
delete @t2
-- nuevo resultado intemedio
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
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
On 4 okt, 20:24, Alejandro Mesa
<AlejandroM...@discussions.microsoft.com> 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
Muchas gracias :)
"Carlos M. Calvelo" <c_ja...@hotmail.com> wrote in message
news:64fa03ff-e032-43f0...@g1g2000vbr.googlegroups.com...
Hola Alejandro,
On 4 okt, 20:24, Alejandro Mesa
<AlejandroM...@discussions.microsoft.com> 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.
On 5 okt, 13:45, "DT" <digit...@switch.com> 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
> 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
On 6 okt, 14:58, Alejandro Mesa
<AlejandroM...@discussions.microsoft.com> wrote:
> 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.
Siempre se aprende algo. Yo creo que mas tratando de ayudar
que al revés. Yo ya había concluído que 32767 era el máximo
'maxrecursion' y hoy me me acabo de enterar de que con
option(maxrecursion 0) ya no hay máximo. Parece raro que
nadie me haya corregido.
>
> Menos mal que el intercambio contigo siempre es ameno y productivo. :)
>
Me alegro de que pienses así. Seguro que se debe a tu
actitud :) Para que sea como dices hacen falta mas de uno.
Saludos,
Carlos