2012-09-04 20 views
5

Tengo dos preguntas sobre Compound-Statement y Transactions en MySQL.COMIENZO DE LA TRANSACCIÓN dentro de COMIENZO ... contexto END o fuera y sintaxis LOOP

PRIMERO:

Hay dos notas en el Manual de MySQL:

Nota

Dentro de todos los programas almacenados, las golosinas analizador de empezar [TRABAJO] como el comienzo de una EMPEZAR .. . FIN bloque. Para comenzar una transacción en este contexto , use START TRANSACTION en su lugar.

Nota

Dentro de todos los programas almacenados (procedimientos almacenados y funciones, disparadores, y eventos), las golosinas analizador de empezar [TRABAJO] como el comienzo de un bloque BEGIN ... END . Comience una transacción en este contexto con START TRANSACCIÓN en su lugar.

No entiendo exactamente lo que significa. ¿Quiere decir que tengo que poner START TRANSACTION en lugar de BEGIN o justo después de BEGIN?

// 1st variant: 

BEGIN 
    START TRANSACTION 
    COMMIT 
END 


// 2nd variant: 

START TRANSACTION 
COMMIT 
END 

¿Cuál es la forma correcta, primera variante o segunda variante?

SEGUNDO:

no quiero crear un procedimiento almacenado o función. Sólo quiero crear un bloque compuesto-Declaración con un bucle interior en el flujo general, así:

USE 'someDb'; 
START TRANSACTION 
    ... create table statement 
    ... insert statement 

// now I want to implement some insert/select statements using loop, I do as follows: 

DELIMITER $ 
BEGIN 
    SET @n = 1, @m = 2; 
    lab1: LOOP 

    ... some insert, select statements here 

    END LOOP lab1; 
END $ 
DELIMITER ; 

END 

COMMIT 

¿Es posible este tipo de estructura? Debido a que he tirado un error:

Query: BEGIN SET @n = 1, @m = 2; lab1: LOOP SELECT ... 
Error Code: 1064 
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SET @n = 1, @m = 2; 
lab1: LOOP SELECT ... 

Mis preguntas son:

  1. ¿Está permitido el uso de BEGIN...END simplemente en el flujo general sin utilizar procedimientos almacenados o funciones?
  2. ¿Está permitido usar BEGIN...END dentro de START TRANSACTION...COMMIT o tengo que poner START TRANSACTION...COMMIT dentro de BEGIN...END?

    BEGIN 
        START TRANSACTION 
        COMMIT 
    END 
    
    // vs. 
    
    START TRANSACTION 
        BEGIN 
        END 
    COMMIT 
    
  3. Do I por todos los medios tienen que utilizar BEGIN...END si quiero usar sólo LOOP? ¿Puedo simplemente usar la sintaxis LOOP sin iniciar BEGIN...END? El único ejemplo en el manual de LOOP es la siguiente:

    CREATE PROCEDURE doiterate(p1 INT) 
        BEGIN 
         label1: LOOP 
         ... 
    

Respuesta

10
  1. ¿Está permitido el uso de BEGIN ... END simplemente en el flujo general sin utilizar procedimientos almacenados o funciones?

    No: las instrucciones compuestas solo se pueden utilizar en el cuerpo de los programas almacenados.

  2. Está permitido el uso de BEGIN...END interior de START TRANSACTION...COMMIT o tengo que poner START TRANSACTION...COMMIT interior de BEGIN...END?

    START TRANSACTION; y COMMIT; son declaraciones separadas. Si desea que el cuerpo de un programa almacenado contenga varias instrucciones, deberá incluir esas instrucciones en algún tipo de bloque de instrucciones compuesto como BEGIN ... END (que es similar a encerrar un bloque de instrucciones entre llaves { ... } dentro de un lenguaje tipo C))

    Dicho esto, usted podría tener un programa almacenado que contiene sólo la sola declaración o START TRANSACTION;COMMIT; — un programa de este tipo no requiere ningún bloque de sentencias compuestas y no haría más que iniciar un nuevo/confirmar la transacción actual, respectivamente.

    Fuera de un programa almacenado, donde no se permiten bloques de instrucciones compuestas, que puede emitir y START TRANSACTION;COMMIT; declaraciones como & cuando sea necesario.

  3. Do I por todos los medios tienen que utilizar BEGIN...END si quiero usar sólo LOOP? ¿Puedo simplemente usar la sintaxis LOOP sin iniciar BEGIN...END?

    LOOP es también un bloque de instrucciones compuesto, que sólo es válida dentro de un procedimiento almacenado. No es necesario para encerrar un bloque LOOP dentro de un bloque BEGIN ... END, aunque es habitual (de lo contrario, es difícil realizar cualquier inicialización de bucle requerida).

En su caso, en el que al parecer quiere insertar datos en una tabla de una estructura iterativa, que o bien necesitar:

  • definir un programa almacenado en el que se utiliza LOOP;

  • iterar un bucle en un programa externo que ejecuta consultas de base de datos en cada iteración; o

  • redefinir su lógica en términos de conjuntos en los que SQL puede operar directamente.

+0

¿Por qué los bucles solo existen dentro de un proceso almacenado? Parece retrasado para tener que crear un proceso almacenado temporal solo para hacer una inserción de bucle simple ..... – Pacerier

+0

@Pacerier: porque esa es la lógica de negocio que pertenece al código de la aplicación, no a la capa de la base de datos. – eggyal

+0

@eggyal, aunque estoy totalmente de acuerdo contigo Pacerier tiene un punto muy válido, ¿por qué mysql se comporta diferente para programas almacenados vs consultas estándar? –

Cuestiones relacionadas