Foros del Web » Programando para Internet » PHP » Zend »

Consultas con Zend_Db

Estas en el tema de Consultas con Zend_Db en el foro de Zend en Foros del Web. Hola tengo un problema, y es que tengo una consulta a una base de datos, pero quiero poder realizar la misma consulta a otras bases ...
  #1 (permalink)  
Antiguo 27/01/2010, 02:31
 
Fecha de Ingreso: enero-2010
Mensajes: 14
Antigüedad: 12 años, 3 meses
Puntos: 0
Consultas con Zend_Db

Hola tengo un problema, y es que tengo una consulta a una base de datos, pero quiero poder realizar la misma consulta a otras bases de datos, ese tema ya lo tengo medio controlado.

El problema es que las estructuras de las bases de datos son las mismas pero el nombre de las tablas que quiero consultar no (de echo es solo una tabla de cada base de datos).

Quiero poder modificar esa tabla (solo el nombre de la tabla) y que realize exactamente lo mismo (realmente es una modificacion de la pagina web para añadirle funcionalidaes).

Creo que podria hacer algo asi para seleccionar un nombre de tabla o otro dependiendo de la url que se ingrese.

Código:
protected function _setupTableName()
    {
        //dependiendo de la url elegimos 
		if url= *.com
			$this->_name = 'table1';
			parent::_setupTableName();
		elseif url = *.fr
			$this->_name = 'table2';
			parent::_setupTableName();		
    }
Como podria hacer el select? yo lo tengo asi actualmente:

public function getLastQueryErrorsByHour($date,$date_next,$hour){

Código:
$select = " select EXTRACT(HOUR from temp.fecha) as hora, count(*) as total
		from (
			select *
			from table1
			where fecha between '".$date."' AND ".$date_next."'
			and root_cause like 'coldfusion.runtime.RequestTimedOutException%'
		) as temp
		group by hora
		order by 1;";

		$stmt =$this->_db->query($select);
		$result = $stmt->fetchAll();

		return $result;
}
Me podrias dar la alternativa con los select() ->from()->where() ??
donde la tabla es la anterior seleccionada con el if? Porque no se hacerlo.

Gracias.
  #2 (permalink)  
Antiguo 27/01/2010, 09:34
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 16 años
Puntos: 2135
Respuesta: Consultas con Zend_Db

No es 100% necesario que lo hagas con un Zend_Db_Select, si tu query es tan compleja la puedes dejar así y solamente hacer:
Código PHP:
Ver original
  1. $select = " select EXTRACT(HOUR from temp.fecha) as hora, count(*) as total
  2.         from (
  3.             select *
  4.             from ".$this->_name."
  5.             where fecha between '".$date."' AND ".$date_next."'
  6.             and root_cause like 'coldfusion.runtime.RequestTimedOutException%'
  7.         ) as temp
  8.         group by hora
  9.         order by 1;";
  10.  
  11.         $stmt =$this->_db->query($select);
  12.         $result = $stmt->fetchAll();
  13.  
  14.         return $result;

Saludos.
  #3 (permalink)  
Antiguo 29/01/2010, 06:41
 
Fecha de Ingreso: enero-2010
Mensajes: 14
Antigüedad: 12 años, 3 meses
Puntos: 0
Respuesta: Consultas con Zend_Db

Muchas gracias. La verdad que era bastante obvio la solucion jejeje. Poner una variable en lugar de un nombre de tabla, pero no sabia como se debia de poner.

Tengo otra duda a ver si me podeis ayudar:

Quiero hacer una query a diferentes bases de datos (cada query la guardo en un array con sus resultados), quiero guardar el resultado de cada una de las consultas en un array para asi poder crear una grafica de todas las consultas.

Lo detallo: Yo hago una consulta a una base de datos 1 que me retorna un array de dos posicions (la hora) y (los datos de esa hora) y esto quiero guardarlo en un array que tenga 11 campos (uno por cada consulta que quiero hacer de las 11 bases de datos), asi finalmente tener:

ArraySuperior [11] = [arrayConsulta1[hora][datos]],[arrayConsulta2[hora][datos],[arrayConsulta3[hora][datos],...,[arrayConsulta11[hora11][datos11] ]

Luego este ArraySuperiro ya lo tratare para mostrarlo en una grafica y tal de forma que me salga en una misma grafica de lineas (11 lineas) los datos de las 11 bases de datos.

La hora es comun en todas.

Os dejo el codigo que uso para la consulta individual que hago actualmente:

Código:
public function getLastErrorsByHour($date,$date_next,$hour){		
				
		$select = " 
		select EXTRACT(HOUR from temp.fecha) as hora, count(*) as total
		from (
			select *
			from ".$this->name." 
			where fecha between '".$date."' AND '".$date_next."'
		) as temp
		group by hora
		order by 1;";

		$stmt =$this->_db->query($select);
		$result = $stmt->fetchAll();
					
		return $result;
Ya se que es un poco complicado, seguro que hay una forma mejor y mas facil.

La base de datos la escojo en el Bootstrap.php segun la url ingresada y alli le defino el nombre de la base de datos (referenciadolo al Application.ini) y el nombre de la tabla (que es diferente en cada una de la bade de datos)

Código:
protected function _initDatabaseRegistry()
{        	
//Obtenemos el nombre de la url 
$direc = $_SERVER['SERVER_NAME'];
		
//definimos el nombre de la bd y la tabla
if ($direc == "www.pag.com"){$table_name = 'em_t1';	$db_selection = 'db_es';}
elseif ($direc == "ar.pag.com"){$table_name = 'em_t2'; $db_selection = db_ar';}
elseif ($direc == 'cl.pag.com'){$table_name = 'em_t3'; $db_selection = 'db_cl';}
elseif ($direc == 'co.pag.com'){$table_name = 'em_t4';	$db_selection = 'db_co';}
elseif ($direc == 'mx.pag.com'){$table_name = 'em_t5_mx';	$db_selection = 'db_mx';}
elseif ($direc == 'it.pag.com'){$table_name = 'em_t6_it'; $db_selection = 'db_it';}
elseif ($direc == 'fr.pag.com'){$table_name = 'em_t7_fr'; $db_selection = 'db_fr';}
	elseif ($direc == 'uk.pag.com'){$table_name = 'em_t8_uk'; $db_selection = 'db_uk';}
	elseif ($direc == 'de.pag.com'){$table_name = 'em_t8_de'; $db_selection = 'db_de';}
	elseif ($direc == 'us.pag.com'){$table_name = 'em_t9_us'; $db_selection = 'db_us';}
	elseif ($direc == 'in.pag.com'){$table_name = 'em_t10_in'; $db_selection = 'db_in';}
	elseif ($direc == 'ij.pag.com'){$table_name = 'em_t11';	$db_selection = 'db_ij';}
		
// carga de configuracion
$dbconf = $this->getOption($db_selection);
//definimos la tabla de la base de datos
define($table_name, $dbconf->db->table->prefix);
// cargar conexion
$db = new Zend_Db_Adapter_Pdo_Mysql ($dbconf);
// guardar en registro
Zend_Registry::set ( "database", $db );
		
return $db;
}
Con esto consigo que segun la url que ingrese pueda acceder a una base de datos y su tabla correspondiente.

$db_selection = 'db_es' hacen referencia a las definiciones del application.ini de las bbdd.

$table_name = 'em_t1' lo uso en el modulo unico que tengo para hacer las consultas y que las consultas que uiero hacer son las mismas para todas las bbdd y las estructuras de las tablas son iguales.



Gracias.

Última edición por Aragorn_miki; 29/01/2010 a las 06:55 Razón: Ampliación
  #4 (permalink)  
Antiguo 29/01/2010, 10:15
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 16 años
Puntos: 2135
Respuesta: Consultas con Zend_Db

Pues puedes hacer dos cosas, ya que cada consulta se ejecuta en una base de datos y tabla diferentes, puedes ir almacenando en una variable los resultados, o guardarlos en un archivo temporal.

Saludos.
  #5 (permalink)  
Antiguo 01/02/2010, 02:04
 
Fecha de Ingreso: enero-2010
Mensajes: 14
Antigüedad: 12 años, 3 meses
Puntos: 0
Respuesta: Consultas con Zend_Db

eso es lo que tenia pensado, pero no se donde hacerlo, es decir, dentro de la query no puedo hacerlo porque he de cambiar la bbdd y la tabla.

Deberia hacerlo en el Controller cuando llamo a la funciones que tiene la query?? Deberia hacerlo en el modelo, cuando defino la query?
  #6 (permalink)  
Antiguo 01/02/2010, 09:40
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 16 años
Puntos: 2135
Respuesta: Consultas con Zend_Db

La idea es que sea en el modelo, el controller solo le pide los datos al modelo, y el modelo se debe de encargar internamente de donde almacenar toda la información, y de enviar las querys y hacer lo necesario, ya que es la tarea del modelo.

Saludos.
  #7 (permalink)  
Antiguo 02/02/2010, 02:00
 
Fecha de Ingreso: enero-2010
Mensajes: 14
Antigüedad: 12 años, 3 meses
Puntos: 0
Respuesta: Consultas con Zend_Db

Ok, muchas gracias pro la respuesta.

COmo veras yo accedo a las diferentes bbdd segun la url que ingrese en el navegador. Para poder hacer un buscqueda en todas las bbdd en una sola query, como deberia hacerlo? porque he provado con un for para todas pero no me cambia de bbdd (supongo que el cambio lo hace en el bootstrap.php y desde el modelo no se como acceder.)
  #8 (permalink)  
Antiguo 02/02/2010, 08:39
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 16 años
Puntos: 2135
Respuesta: Consultas con Zend_Db

Lo mejor es que toda esa información la tengas en un archivo de configuración, y así lo puedes leer desde el modelo. Vas a tener que cargar un adaptador Zend_Db_Adapter_Mysql por cada query que quieras correr.

Saludos.
  #9 (permalink)  
Antiguo 03/02/2010, 02:37
 
Fecha de Ingreso: enero-2010
Mensajes: 14
Antigüedad: 12 años, 3 meses
Puntos: 0
Respuesta: Consultas con Zend_Db

Pero eso lo hago en el bootstrap.php no? con el codigo:
Código:
protected function _initDatabaseRegistry()
{        	
//Obtenemos el nombre de la url 
$direc = $_SERVER['SERVER_NAME'];
		
//definimos el nombre de la bd y la tabla
if ($direc == "www.pag.com"){$table_name = 'em_t1';	$db_selection = 'db_es';}
elseif ($direc == "ar.pag.com"){$table_name = 'em_t2'; $db_selection = db_ar';}
elseif ($direc == 'cl.pag.com'){$table_name = 'em_t3'; $db_selection = 'db_cl';}
elseif ($direc == 'co.pag.com'){$table_name = 'em_t4';	$db_selection = 'db_co';}
elseif ($direc == 'mx.pag.com'){$table_name = 'em_t5_mx';	$db_selection = 'db_mx';}
elseif ($direc == 'it.pag.com'){$table_name = 'em_t6_it'; $db_selection = 'db_it';}
elseif ($direc == 'fr.pag.com'){$table_name = 'em_t7_fr'; $db_selection = 'db_fr';}
	elseif ($direc == 'uk.pag.com'){$table_name = 'em_t8_uk'; $db_selection = 'db_uk';}
	elseif ($direc == 'de.pag.com'){$table_name = 'em_t8_de'; $db_selection = 'db_de';}
	elseif ($direc == 'us.pag.com'){$table_name = 'em_t9_us'; $db_selection = 'db_us';}
	elseif ($direc == 'in.pag.com'){$table_name = 'em_t10_in'; $db_selection = 'db_in';}
	elseif ($direc == 'ij.pag.com'){$table_name = 'em_t11';	$db_selection = 'db_ij';}
		
// carga de configuracion
$dbconf = $this->getOption($db_selection);
//definimos la tabla de la base de datos
define($table_name, $dbconf->db->table->prefix);
// cargar conexion
$db = new Zend_Db_Adapter_Pdo_Mysql ($dbconf);
// guardar en registro
Zend_Registry::set ( "database", $db );
		
return $db;
}
Selecciono una bbdd en uncion de la url.

Habia probado de poner una tabla fija en el controller con las configuraciones de cada bbdd y crear un for que por cada entrada de la tabla realizara la query y lo guardase en un array, pero no lo hacia, no hacia el bucle porque no se como hacer la llamada:

Código:
// cargar conexion
$db = new Zend_Db_Adapter_Pdo_Mysql ($dbconf);
desde el controller.

///////////////////////////////////////////////////////////////////////////////////////////////

OTRA DUDA: (ya se que tengo muchas, lo siento)

He creado un sistema de pestañas para mi pagina principal, en el archivo layout tengo esto en el body:

Código:
<?php /* CONTENT */ ?>
	
	<div class="tabber" id="tab1">
	
	<h2><a name="tab1">Principal</a></h2>
		<h2><a name="tab1"></a></h2>
		<p><?php echo $this->layout()->content?></p>
      </div>
	
	
  <div class="tabbertab">
    <h2><a name="tab1">General</a></h2>
    <p><?php echo $this->action(index,index,errorevents); ?></p>
  </div>
  
  <div class="tabbertab">
    <h2>Pestaña2</h2>
    <p><?php echo $this->action(index,errorweb,errorevents); 
	//echo $this->layout()->content?></p>
  </div>
  
  <div class="tabbertab">
    <h2>Pestaña3</h2>
    <p><?php echo $this->action(index,errormdc,errrorevents);?></p>
  </div>
  <div class="tabbertab">
    <h2>Pestaña4</h2>
    <p><?php echo $this->action(index,queryp,querypaises); ?></p>   
  </div>

  
</div>
Con este codigo, respaldado por tabber.js que es el que crea las pestañas, tengo una serie de pestañas que cargan en cada una un controller y un action diferente pero el mismo model para asi hacerlo mas rapido que si utilizaba un model para cada controller (ya se que asi puede ser que rompa el MVC).

Funciona a la perfeccion, pero la question es que en cada pestaña me muestra una grafica, que es del dia actual y tengo unos enlaces que me crean una grafica de la fecha que seleccione. El problema es que para que pueda funcionar el sistema de pestañas bien ,he de poner la llamada
Código:
$this->action('action','controller','model');
porque si pongo
Código:
$this->layout()->content
en todas las pestañas me carga lo mismo, pues al hacer click en los enlaces me carga el resultado en la pestaña que he llamado PRINCIPAL que es donde tengo el
Código:
$this->layout()->content
.

Hay alguna manera de hacer un
Código:
$this->action('action','controller','model');
con parametros o algo para asi poder llamarla en cada pestaña??

Gracias!

Última edición por Aragorn_miki; 03/02/2010 a las 02:47 Razón: Ampliacion de dudas...
  #10 (permalink)  
Antiguo 03/02/2010, 08:24
 
Fecha de Ingreso: octubre-2009
Mensajes: 240
Antigüedad: 12 años, 7 meses
Puntos: 6
Respuesta: Consultas con Zend_Db

Yo en ese caso haría un view helper, ademas de tener mejor rendimiento, le puedes pasar los parametros como a cualquier metodo de una clase.
Código PHP:
Ver original
  1. class App_Helper_Menu extends Zend_View_Helper_Abstract{
  2.    
  3.     public function menu(){
  4.        
  5.         $dives="<div id=\"menuhelper\">";
  6.         $dives.="<ol>";
  7.         $dives.="<li><a href=\"hola\" title=\"hola que tal\">hola</a></li>";
  8.         $dives.="<li><a href=\"quetal\" title=\"que tal hola\">quetal</a></li>";
  9.         $dives.="<li><a href=\"quetal\" title=\"que tal hola\">quetal</a></li>";
  10.         $dives.="</ol>";
  11.         $dives.="</div>";
  12.         return $dives;
  13.        
  14.     }
  #11 (permalink)  
Antiguo 03/02/2010, 08:30
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 16 años
Puntos: 2135
Respuesta: Consultas con Zend_Db

Aunque lo hagas en el Bootstrap es bueno que tengas esa información en algún otro lado para que precisamente lo puedas leer en tu modelo o en otro lado.

De tu otra duda, si ves el Manual: http://framework.zend.com/manual/en/...w.helpers.html el 4to parámetro del action View Helper es un array con parámetros para recibirlos. Aunque ten en cuenta que lo mejor es crear view helpers que lean modelos ya que es probable que el action view helper lo quiten.

Saludos.
  #12 (permalink)  
Antiguo 04/02/2010, 02:08
 
Fecha de Ingreso: enero-2010
Mensajes: 14
Antigüedad: 12 años, 3 meses
Puntos: 0
Respuesta: Consultas con Zend_Db

Bueno ya lo he solucionado con el codigo:
Código:
<?php /* CONTENT */ ?>
	

	<div id="tab2" class="tabberlive">
		<ul class="tabbernav">
			
			<li class="">
				<a id="tab2nav1" class="" href="<?php echo $this->url(array('controller'=>'index','action'=>'index'));?>"" title="Tab 1">Principal</a>
			</li>
			<li class="">
				<a id="tab2nav2" class="" href="<?php echo $this->url(array('controller'=>'index','action'=>'web'));?>"" title="Tab 1">Web</a>
			</li>
			<li class="">
				<a id="tab2nav3" class="" href="<?php echo $this->url(array('controller'=>'index','action'=>'mdc'));?>"" title="Tab 1">MdC</a>
			</li>
			<li class="">
				<a id="tab2nav4" class="" href="<?php echo $this->url(array('controller'=>'index', 'action'=>'timeoutsdia','day'=>date("d",$date_next),'month'=>date("m",$date_next),'year'=>date("Y",$date_next)));?>"" title="Tab 1">Timeouts/Dia</a>
			</li>
			<li class="">
				<a id="tab2nav5" class="" href="<?php echo $this->url(array('controller'=>'index','action'=>'cfruntime'));?>"" title="Tab 1">CFRuntime</a>
			</li>
		</ul>
	</div>	
	
	<?php echo $this->layout()->content?>
en el layout.phtml

Lo que hago es llamar a una clase tabber (javascript taberline) que se encarga de lo de las pestañas y en cada pestaña construyo la url directamente, asi me aseguro de llamar al controlador y el modelo.

Volviendo al tema de la llamada a las diferentes conexiones de las bbdd, he creado una action donde declar lo mismo que en el bootsrap.php, es decir los nombres de las tablas y las definiciones del application.ini donde tengo definidas las bbddd (los users, passwords, conexiones, etc...), lo hago con dos tablas y luego uso lo mismo que uso en el bootstrap.php para cambiar de url:

Código:
//tabla1[11] tiene los nombres de las tablas
//tabla3[11] tiene los hosts
//tabla4[11] tiene los users
//tabla5[11] tiene los nombres de las bbdd

for($i=0;$i<=4;$i++){ 
				// carga de configuracion
				Zend_Debug::dump($i);
				$db = new Zend_Db_Adapter_Pdo_Mysql(array(
					'host'     => $tabla3[$i],
					'username' => $tabla4[$i],
					'password' => 'lakers00',
					'dbname'   => $tabla5[$i]));

                        $table_name = $tabla[$i];

                 /*QUERY en la clausura from uso el $table_name*/ 

                        $stmt =$this->_db->query($select);
			$result = $stmt->fetchAll();
}
		return $result;
Pero no me funciona es como si no me hiciese el bucle for, alguna ayuda?

Última edición por Aragorn_miki; 05/02/2010 a las 05:25 Razón: Ampliación
  #13 (permalink)  
Antiguo 10/02/2010, 04:29
 
Fecha de Ingreso: enero-2010
Mensajes: 14
Antigüedad: 12 años, 3 meses
Puntos: 0
Respuesta: Consultas con Zend_Db

Alguien me puede echar una mano?

No consigo hacer que mire en todas las bases de datos, como en el bootstrap.php tengo que escoja una bbdd o otra en funcion de la url, cualquier cambio que hago en el Modelo no me lo selecciona, porque cada vez machaca con el bootstrap.php

Necesito ayuda urgente porfavor!

Etiquetas: multiples, zend_db, zend-framework
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 21:10.