Para entenderle sí van a tener que saber de PHP.

En varias ocasiones me he visto forzado a guardar en un campo de la base de datos un string así “1,2,3,4,5″, generalmente cada número representa un ID que concierne a una llave foránea. Precisamente porque soy holgazán, me di a la tarea de idear una función que me permitiera crear una cadena SQL válida con tantos OR como números (incluso palabras) separados por comas tenga el campo.

Esta función nace del siguiente caso práctico… tengo una tabla llamada campaña, la cual almacena cierta información, a cada campaña se le pueden asignar “N” cantidad de agentes, ergo hice un listado de agentes que (mediante ajax) se asignan a la campaña en dicho campo con el formato “1,2,3,4,5,6″, cada número significa el id del registro del agente. Para continuar, al consultar la campaña debía extraer el nombre de cada uno de los agentes para listarlos como “asignados” a “x” campaña…

La finalidad es escribir menos y hacer más.

 


	//Este convierte un '1,2,3' en un (campo = {1} OR campo = {2} OR campo = {3})
	function or_sql_cadena ( $parametros = null )
	{
		//el resultado siempre lo declaro al principio y como vacío para que si se cuelan... se lleven un '';
		$result = '';
		//Haciendo que el que llama esta funcíón sepa que debe mandar una rreglo como parámetro.
		if( is_array($parametros) )
		{
			//Variables para todo el flujo de la función.
			$campo_comparacion = '';
			$arr_temporal = array();
			$result_and = '';
			$result_or = '';

			if(array_key_exists('campo_comparacion', $parametros)) // que sí venga el parámetro
			{
				if(!empty($parametros['campo_comparacion'])) //Que el parámetro no sea vacío
				{
					$campo_comparacion = $parametros['campo_comparacion'];
				}
			}

			if(array_key_exists('cadena_texto', $parametros)) // que el parámetro sí venga
			{
				if( !empty($parametros['cadena_texto']) ) //que el paraámetro no sea vacío
				{
					$arr_temporal = explode(',', $parametros['cadena_texto']);
				}
			}
			//Si trae datos el arreglo, etonces continua
			if(count($arr_temporal)>=1)
			{
				//Armando la cadena SQL empezando con el AND
				$result_and .=  ' AND (';
				//por cada posición del arreglo temporal haz:
				foreach($arr_temporal as $idx => $campo_id)
				{
					//si ya trae algo la cadena, entonces métele un OR
					if ($result_or != '') { $result_or .= ' OR '; }
					//aquí hago que el query haga la comparación entre datos con el campo (casi siempre llave foránea) que se va a comparar
					$result_or .= " {$campo_comparacion} = {$campo_id}";
				}
				//concateno lo que armó el for
				$result_and .= $result_or;
				//cierro la condición
				$result_and .= ')';
			}
			//Si hubo incidencias en el for, entonces haz:
			if ($result_or != '')
			{
				//Si el query tiene AND
				if ($result_and != '')
				{
					//regresas la cadena al resultado
					$result = $result_and;
				}
			}

		}
		//regresa la cadena al resultado
		return $result;
	}

La manera en que se invoca dicha función es ésta:


//obtener todos los datos de la campaña
$sql_get_campana = "SELECT * FROM campana cmp WHERE cmp.cmp_id = {$db_indial->escape($campana_id)} AND cmp.cmp_estatus =  {$db_indial->escape(CAMPANA_ACTIVO)}  LIMIT 1; ';
$registro_campana = $db_indial->query($sql_get_campana)->num_rows() == 1 ? $db_indial->query($sql_get_campana)->row() : false;

//obtener todos los datos de los agentes
$agentes_asignados_cadena = (count($registro_campana)>=1) ? $registro_campana->cmp_agentes : ''; // asigno el valor del campo

//por si no trae ningún agente:
$registros_agentes = '';
$sql_get_agentes_or = '';
if(!empty($agentes_asignados_cadena)) // Cuando traigo un dato, entonces preparo la consulta SQL para que haga el OR
{
	$param_or_sql['cadena_texto'] = $agentes_asignados_cadena;
	$param_or_sql['campo_comparacion'] = 'agn.agn_id';
	$sql_get_agentes_or = $this->indial_utilerias->or_sql_cadena($param_or_sql);
	$sql_get_lista_agentes = "SELECT * FROM agente agn WHERE agn.agn_estatus = {AGENTE_ACTIVO}  {$sql_get_agentes_or}  AND agn.agn_enllamada = 0 ";
	$sql_get_lista_agentes .= " AND agn.agn_estatusoperativo IN (SELECT cat_id FROM catalogo WHERE sec_id = {$db_indial->escape(ESTATUS_PANEL_AGENTE)} AND cat_valor0 = UPPER('SI')) ";
	$sql_get_lista_agentes .= "ORDER BY agn_id ASC; ";
	$registros_agentes = $db_indial->query($sql_get_lista_agentes)->num_rows() >= 1 ? $db_indial->query($sql_get_lista_agentes)->result() : false;
} 

//Happy coding.
SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
 

Primero, un poco de contexto… En el jale tengo que hacer un query para un mini-reporte que servirá de guía para “X” area, así que hice un query usando la siguiente instrucción:
*El SGBDR es PostgreSQL

	SELECT pi.anio,pi.proyecto,pp.area,m.meta,c.promesa	,c.avance,c.comentarios,((c.avance / c.cantidad ) * 100) as porcentaje

	FROM piezas pi FULL JOIN participantes_proyecto pp
	ON pi.proins_clave_anio = pp.proins_clave_anio
	AND pi.id = pp.id 

	FULL JOIN metas m
	ON m.id = pp.id
	AND m.area = pp.area
	AND m.anio = pp.anio

	FULL JOIN calendarizacion c
	ON c.anio = m.anio
	AND c.area = m.area

	WHERE pi.anio = 2010
	AND pp.area = 'Informatica'; Continue reading »
SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
© 2012 Geekeandome Suffusion theme by Sayontan Sinha