2009-02-25 21 views
6

OK, sé que se puede hacer, lo hago con bastante frecuencia, pero ¿por qué es tan difícil hacer un ciclo en T-SQL? Puedo pensar en una tonelada de razones que me gustaría analizar a través de un conjunto de resultados de la consulta y hacer algo que simplemente no se puede hacer sin un bucle, sin embargo, el código para configurar y ejecutar mi ciclo es> 20 líneas.¿Por qué es tan difícil hacer un ciclo en T-SQL

Estoy seguro de que otros tienen opiniones similares, ¿por qué seguimos sin una forma sencilla de realizar un ciclo?

Un lado: finalmente conseguimos un UPSERT (también conocido como MERGE) en SQL2008 así que tal vez toda la esperanza no se pierde.

Respuesta

22

SQL está basado en un conjunto, declarative language; no es un procedimiento o imperative language. T-SQL trata de montarlos a ambos, pero aún está basado en un paradigma fundamentalmente basado en conjuntos.

+0

¿Tienes estos en el camino correcto? – AnthonyWJones

+0

¡Vaya! tienes razón, pegué mis enlaces en el orden incorrecto :) gracias –

1

Porque SQL es un lenguaje basado en Conjunto. El poder de sql es encontrar un grupo más pequeño dentro de un grupo más grande de datos basados ​​en características específicas. Para manejar esta tarea, el bucle es en gran medida innecesario. Obviamente se ha agregado para la conveniencia de manejar algunas situaciones, pero el uso previsto del lenguaje hace que esta característica sea irrelevante.

2

T-SQL no está diseñado para ser un lenguaje imperativo. Está diseñado para ser declarativo. Su naturaleza declarativa le permite al optomizador dividir las diferentes tareas y ejecutarlas en paralelo y de otras maneras hacer las cosas en un orden que sea más eficiente.

-2

No soy un experto en DB, pero creo que la naturaleza atómica de las transacciones de bases de datos dificultaría la realización de bucles porque la transacción está completa o no debería realizarse. ¡Mantener el estado puede ser molesto!

Wikipedia Article on Atomicity

0

SQL es un sistema basado SET, no un procedimiento (circular) uno. En general, se considera una mala práctica utilizar bucles en SQL porque tienen un rendimiento bajo en comparación con sus equivalentes basados ​​en conjuntos.

estará la estructura de bucle más común, los cursores se pueden utilizar también, pero tienen sus propios problemas (olvidando desasignar/cerrar)

... un ejemplo de WHILE (puede que no lo necesita, pero otros pueden)

DECLARE @iterator INT 
SET @iterator = 0 

WHILE @iterator < 20 
BEGIN 
    SELECT * FROM table WHERE rowKey = @iterator 
/*do stuff*/ 
    @iterator = @iterator + 1 
END 

La verdadera pregunta es "¿Qué es lo que usted está tratando de hacer que simplemente no se puede hacer de una manera basada en el set?"

10

puedo pensar en un montón de razones que me gustaría analizar a través de un conjunto de resultados de consulta y hacer algo que simplemente no se puede hacer sin un bucle

Y para la gran mayoría de En cambio, puedo mostrarle cómo hacerlo en una operación basada en conjuntos o explicar por qué debería hacerse en su código de cliente en lugar de en la base de datos. Necesitar hacer un ciclo en sql es muy raro.

+1

Acepto que deberían hacerse en el código del cliente; sin embargo, cuando procesamos millones de registros, es 100 veces más rápido hacerlo todo en la base de datos, incluso si ese no es el "lugar" apropiado para hacerlo. –

+1

Un ejemplo: realice un bucle a través de cada "accesorio" en la base de datos y realice un procedimiento almacenado que se inserta en una tabla y actualiza otra en función de los valores del accesorio. Tenemos que ejecutar esto regularmente, porque las tablas en las que se calculan los valores cambian regularmente. Código de cliente = 1 día, SQL = 1hr. –

+1

> "Estoy de acuerdo en que deberían hacerse en código de cliente; sin embargo," ... Eso es solo una parte. El otro está refactorizando para ser establecido en base. Para su ejemplo de "instalación", debería poder volver a escribir su procedimiento almacenado para operar en toda la mesa. –

1

casi todo se puede hacer establecen sobre la base, pruebe a utilizar una tabla de números

por qué 20 líneas? Esto es todo lo que necesita

select *,identity(int, 1,1) as Someid into #temp 
from sysobjects 

declare @id int, @MaxId int 
select @id = 1,@MaxId = max(Someid) from #temp 

while @id < @MaxId 
begin 
-- do your stuff here 
print @id 
set @id [email protected] + 1 
end 
1

depende de lo que desea hacer en un bucle.usando un bucle while no es difícil en absoluto:

declare @i int 
set @i = 20 
while @i>0 begin 
... do some stuff 
set @i = @i-1 
end 

sólo se vuelve engorroso cuando se utilizan cursores, que se deben evitar de todos modos.

1

Puede intentar usar funciones definidas por el usuario para hacer la mayor parte del trabajo en lugar de tomar un enfoque basado en bucles. Esto preservaría la intención del lenguaje SQL que se establece en función.

+0

me gusta esto. Voy a investigar. –

Cuestiones relacionadas