[Solved] Consulta para borrar datos de la BD

Hola todos, estoy intentando realizar una consulta para eliminar los datos de algunas tablas de mi base de datos, pero al ejecutar la accion me aparece el siguiente error:




CDbCommand falló al ejecutar la sentencia SQL: SQLSTATE[HY000]: General error. 



mi consulta es:




delete cpmercancias, detallesrecepcion, datosrecepcion, facturas, detallesfact, datossal, detallesfactc, datossalc, detallesorden, datosorden, detallestrans, datostrans, invdetallemov, invdocumentomov, invdetallemovs, invdocumentomovs

  FROM (   (   (   detallesfact

            	JOIN

       			datossal

            	ON (detallesfact.Id_sal = datossal.nfactura))

        	JOIN

   			facturas

        	ON (facturas.nfactura = datossal.nfactura))

    	JOIN

   		datossalc

    	ON (facturas.nfactura = datossalc.nfactura))

   	JOIN detallesfactc

      	ON (detallesfactc.Id_sal = datossalc.nfactura)

   	CROSS JOIN detallestrans

   	JOIN datostrans

      	ON (detallestrans.Id_sal = datostrans.nfactura)

   	CROSS JOIN invdetallemovs

   	JOIN invdocumentomovs

      	ON (invdetallemovs.Id_con = invdocumentomovs.Id)

   	CROSS JOIN invdetallemov

   	JOIN invdocumentomov

      	ON (invdetallemov.Id_con = invdocumentomov.Id)

   	CROSS JOIN (   cpmercancias

       			JOIN

                  	datosrecepcion

       			ON (cpmercancias.nvale = datosrecepcion.nfactura))

   	JOIN detallesrecepcion

      	ON (detallesrecepcion.Id_cons = datosrecepcion.nfactura)

   	CROSS JOIN detallescom

   	JOIN datoscom

      	ON (detallescom.Id_sal = datoscom.nfactura)

   	CROSS JOIN detallesorden

   	JOIN datosorden

      	ON (detallesorden.Id_sal = datosorden.norden)



y mi codigo en yii es:




public function actionHacerCierreanual() {


    	$almacen = $_POST['entidad'];


    	$query = "DELETE cpmercancias, detallesrecepcion, datosrecepcion, facturas, detallesfact, datossal, detallesfactc, datossalc, detallesorden, datosorden, detallestrans, datostrans, invdetallemov, invdocumentomov, invdetallemovs, invdocumentomovs

  FROM (   (   (   detallesfact

            	JOIN

       			datossal

            	ON (detallesfact.Id_sal = datossal.nfactura))

        	JOIN

   			facturas

        	ON (facturas.nfactura = datossal.nfactura))

    	JOIN

   		datossalc

    	ON (facturas.nfactura = datossalc.nfactura))

   	JOIN detallesfactc

      	ON (detallesfactc.Id_sal = datossalc.nfactura)

   	CROSS JOIN detallestrans

   	JOIN datostrans

      	ON (detallestrans.Id_sal = datostrans.nfactura)

   	CROSS JOIN invdetallemovs

   	JOIN invdocumentomovs

      	ON (invdetallemovs.Id_con = invdocumentomovs.Id)

   	CROSS JOIN invdetallemov

   	JOIN invdocumentomov

      	ON (invdetallemov.Id_con = invdocumentomov.Id)

   	CROSS JOIN (   cpmercancias

       			JOIN

                  	datosrecepcion

       			ON (cpmercancias.nvale = datosrecepcion.nfactura))

   	JOIN detallesrecepcion

      	ON (detallesrecepcion.Id_cons = datosrecepcion.nfactura)

   	CROSS JOIN detallescom

   	JOIN datoscom

      	ON (detallescom.Id_sal = datoscom.nfactura)

   	CROSS JOIN detallesorden

   	JOIN datosorden

      	ON (detallesorden.Id_sal = datosorden.norden) ";

    	

    	Yii::app()->db->createCommand($query)->execute();


   	$dataReader = Yii::app()->db->createCommand($query)->queryAll();


   	// Yii::app()->end();

	}



agradeciendo a todos me echen una mano con esto, saludos

Hola a todos de nuevo, les informo que resolvi provisionalmente, haciendo las consulta nuevamente, de todas formas pienso que esa nos es la solucion para el error que me origino el post, les dejo como me quedo ahora la accion, ademas tuve que eliminar la sentencia:




 $dataReader = Yii::app()->db->createCommand($query)->queryAll();



que era donde daba el error, asi que si alguien me puede ayudar con la solucion correcta para esto me gustaria como siempre sean amables y me la hagan llegar, para darle el correcto funcionamiento a la accion.

Aqui les dejo como quedo ahora la accion:





  public function actionHacerCierreanual() {


    	$almacen = $_POST['entidad'];


    	$query = "DELETE detallesorden, datosorden, detallesrecepcion, datosrecepcion,detallesfactc, datossalc, detallesfact, datossal, detallescom, datoscom,  detallestrans, datostrans, invdetallemov, invdocumentomov, invdetallemovs, invdocumentomovs 

               	FROM detallesorden, datosorden, detallesrecepcion, datosrecepcion, detallesfactc, datossalc, detallesfact, datossal, detallescom, datoscom,  detallestrans, datostrans, invdetallemov, invdocumentomov, invdetallemovs, invdocumentomovs

               	where detallesfactc.Id_sal = datossalc.nfactura and 

                  	datossal.nfactura= detallesfact.Id_sal and

                  	detallescom.Id_sal = datoscom.nfactura and

                  	invdetallemov.Id_con = invdocumentomov.Id and

                  	invdetallemovs.Id_con = invdocumentomovs.Id and

                  	detallestrans.Id_sal = datostrans.nfactura and

                  	detallesrecepcion.Id_cons = datosrecepcion.nfactura and

                  	detallesorden.Id_sal = datosorden.norden";

    	Yii::app()->db->createCommand($query)->execute();


    	//$dataReader = Yii::app()->db->createCommand($query)->queryAll();

    	// Yii::app()->end();

    	Yii::app()->user->setFlash('success', 'Cierre realizado satisfactoriamente');

    	$model = new Cierreanual; // para colocar la fecha en la BD

    	$model->fecha = date('Y-m-d');

    	$this->render('cierreanual');

	}



Ademas quiero que al hacer la operacion de cierre, me guarde en la BD la fecha en que se hace, para ello cree una parte en mi codigo pero no hace esa parte, lo de la consulta si la ejecuta ahora.

Hola Rafael,

No estoy seguro al 100% pero el error de la 1ª consulta creo que es por falta de memoria al hacer los calculos mysql, y la verdad que parece una query compleja.

intenta separarla en varias sentencias y pon explain delante para que te detalle un poco las claves que utiliza y las filas que afectan a la query. Esto lo puedes hacer directamente con phpmyadmin o cualquier otro programa.

explain delete from tabla1 where condition1 --> esta es muy simple pero según va siendo más compleja los problemas crecen.

Y bueno, estudia si prefieres una query compleja o varias más sencillas. No solo importa la eficiencia, importa que si dentro de 1 año tienes que crear un campo nuevo y afecta al sistema de borrado suele ser más sencillo implementarlo en varias querys sencillas frente a una compleja.

La 2ª parte parece sencilla te falta $model->save(); para guardar la fecha.

saludos y feliz navidad

Gracias rahaif por responder, en realidad lo resolví separando en varias consultas y trabaja bien, lo que yo necesito saber es porque el error en la linea:




$dataReader = Yii::app()->db->createCommand($query)->queryAll();



Me quedo así al separar las consultas, pero si te fijas la sentencia tambien la cambie:





public function actionHacerCierreanual() {


        $almacen = $_POST['entidad'];


        $query = "DELETE datoscom

        FROM 

	datoscom";

        Yii::app()->db->createCommand($query)->execute();


        $query = "DELETE datosorden 

        FROM 

	datosorden";

        Yii::app()->db->createCommand($query)->execute(); //UPDATE productos SET lg=2 WHERE Codde=1


        $query = "DELETE datosrecepcion 

        FROM 

	datosrecepcion";

        Yii::app()->db->createCommand($query)->execute();


        $query = "DELETE datossal 

        FROM 

	datossal";

        Yii::app()->db->createCommand($query)->execute();


        $query = "DELETE datossalc

        FROM 

	datossalc";

        Yii::app()->db->createCommand($query)->execute();


        $query = "DELETE datostrans

        FROM 

	datostrans";

        Yii::app()->db->createCommand($query)->execute();


        $query = "DELETE invdocumentomov 

        FROM 

	invdocumentomov";

        Yii::app()->db->createCommand($query)->execute();


        $query = "DELETE invdocumentomovs

        FROM 

	invdocumentomovs";

        Yii::app()->db->createCommand($query)->execute();


        $query = "UPDATE productos SET lg = 2 WHERE Codde <> 4";

        Yii::app()->db->createCommand($query)->execute();


        //$dataReader = Yii::app()->db->createCommand($query)->queryAll();

        // Yii::app()->end();

        Yii::app()->user->setFlash('success', 'Cierre realizado satisfactoriamente');

        $cerrar = Cierreanual::model()->findAll();

        if (!$cerrar) {

            $model = new Cierreanual;

            $model->fecha = date('Y-m-d');

            $model->save();

            $this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));

        }

        $this->render('cierreanual');

    }



Si se fijan separe las consultas, con consultas sencillas para cada tabla de la BD, de todas formas si hubiera una forma donde ejecutar en una sola query al menos las de delete y en otra query la de update lo agradecería, pero digo esta no es la solución optima que necesito.

Feliz navidad y prospero año nuevo a todos.

Buenas, Rafael.

Perdona por tardar tanto en contestar pero estamos en fiestas por aquí y no toco el pc desde hace 2 semanas.

Efectivamente la primera consulta es muy complicada, no sé si tanto como para que te pete.

De todas formas, todas esas tablas no están relacionadas entre sí? Es decir, si tienes la base de datos bien relacionada, eliminando en las tablas adecuadas se eliminarían automáticamente los datos del resto de tablas.

Podrías indicarnos la relación entre eas tablas?

Un saludo.

Ok gracias lagogz por responder y felicidades por este nuevo año 2017, que te traiga muchas cosas buenas, al igual aqui estabamnos tambien de fiesta:

Efectivamente las relaciones son unos a muchos entre las siguientes tablas, o sea, las primeras tablas de cada relacion son los detalles de las facturas y la segunda los datos de las facturas:

detallesrecepcion con datosrecepcion

detallesfactc con datossalc

detallesfact con datossal

detallescom con datoscom

detallestrans con datostrans

invdetallemov con invdocumentomov

invdetallemovs con invdocumentomovs

detallesorden con datosorden.

Ejemplo en datosrecepcion estan los datos de las recepcienes de productos y en detalles estan los productos que corresponden a cada recepcion, con codigos de productos, precios, importes, etc.

El problema es con esta linea de codigo que tuve que sustituirla:




$dataReader = Yii::app()->db->createCommand($query)->queryAll();



Como explique mas arriba, ya resolvi el problema provicional, dividiendo las consultas, o sea, si hago esta consulta para borrar la tabla datosrecepcion, tambien se eliman los detalles de las recepciones, la tabla detallesrecepcion:

con esta consulta y el comando de abajo




 $query = "DELETE datosrecepcion 

    	FROM 

	datosrecepcion";

        	Yii::app()->db->createCommand($query)->execute();



y asi con cada tabla, el problema es que queria hacerlo en una sola consulta.

Buenas Rafael.

Feliz año a tí y a tod@s también.

Rspecto a tu problema, por lo que entiendo no todas esas tablas entán relacionadas entre si. Es decir, TODAS! Sí estan relacionadas entre algunas de ellas, pero no todas.

Sabiendo esto creo que la mejor opción es hacer consultas individuales para cada grupo de tablas relacionadas, eso sí, ejecutándolas dentro de una transacción para evitar posibles pérdidas de integridad de los datos.

Yo lo que haría es:




Yii::app()->db->beginTransaction();


if(Yii::app()->db->createCommand($query)->execute() > 0)

{

    // Sigues ejecutando las siguientes consultas de eliminación.


    // Esto se pondría después de la última consulta de borrado.

    Yii::app()->db->getCurrentTransaction()->commit();

}

else

{

    // No ha eliminado nada, entonces la consulta ha fallado.


    // Cuidado con esto, pq podría ser que no hubiese ningún registro que eliminar en la tabla,

    // lo que también devolvería cero. En este caso podrías hacer una consulta de SELECT 

    // previamente para saber si se debe o no eliminar algún registro.

    Yii::app()->db->getCurrentTransaction()->rollback();

    break; // O exit; o lo que quieras.

}



De esta forma te aseguras que si alguna de tus consultas de borrado falla, las otras ya ejecutadas no tendrán efecto ya que se ejecutará un rollback, con lo que la base de datos quedará tal cuál a antes de iniciar el borrado.

Siempre que en un método (controlador o grupo de código) se pretenda ejecutar varias consutlas DML (en concreto INSERT, UPDATE y DELETE), es conveniente (en mi opinión obligatorio) hacerlo dentro de una transacción para tener el control de posibles fallos y no afectar a la integridad de tus datos (que es lo más preciado que tienes, jejejeje, si pierdes tus datos te echan a la P_ _ a calle :-[ ). Bueno…en un país civilizado, aquí en España igual te hacen presidente del gobierno. B)

Un saludo.

Gracias lagogz por responder, voy a resolver como me indicaste, para tener un poco mas de eficiencia en la salva

Para eso estamos.

Un saludo.