Archivos de Categoría: Base de datos - Paginas 6

Importar un CSV a MySQL tratando los campos

Estos días ando pegándome con una aplicación para importar datos directamente desde ficheros CSV sin importar la estructura que estos tengan. La verdad bastante divertido sobretodo porque toca pegarme con cosas que habitualmente no se hacen. Como por ejemplo usar la función fgetcsv de php que parsea el csv y te lo guarda en una estructura, muy útil la verdad. Por ejemplo la función que uso en la clase de importación para coger el fichero y cargarlo sería de la siguiente forma:

/* La función recoge dos parámetros, el nombre del fichero ya subido al servidor y el tipo de importación (en esta aplicación dependiendo del tipo de importación trata los datos de una forma o de otra) */
public function cargar($fichero, $tipo){
        $columnas = array();
        $this->tabla = "tmp_".$tipo."_".$fichero;
  // abrimos el fichero y lo recorremos para saber los nombres de las columnas
        $fpointer = fopen($this->path.'/archivos/importaciones/'.$fichero.'.csv', "r");
    
        if ($fpointer){
            $_separador = ';';
            $arr = fgetcsv($fpointer, 10*1024, $_separador);
            if(count($arr) == 1){
                fclose($fpointer);
                $fpointer = fopen($this->path.'/archivos/importaciones/'.$fichero.'.csv', "r");
                $_separador = ',';
                $arr = fgetcsv($fpointer, 10*1024, $_separador);
            }
            
            if(is_array($arr) && !empty($arr)){
                    foreach($arr as $val){
                        if(trim($val)!="") $columnas[] = $val;
                    }    
            }            
            unset($arr);
           // una vez tenemos los nombres de las columnas creamos una nueva table con todas las columnas del csv            
            $sql = "CREATE TABLE IF NOT EXISTS tmp_".$tipo."_".$fichero." (`id` int(11) NOT NULL AUTO_INCREMENT, `ib_tramitado` char(1) DEFAULT 'N',";
            if(!empty($columnas)){
              $arr = array();
              for($i=0; $i<sizeof($columnas); $i++){
                  $arr&#91;&#93; = "`".$columnas&#91;$i&#93;."` TEXT";
              }    
              $sql .= implode(",", $arr);
              $sql .= ", PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;";
              // ejecutamos la consulta con mi clase de base de datos, pero se podría usar cualquiera que ejecute la query almacenada en la variable $query
              db::query($sql);
              // recoremos de nuevo el fichero pero ya insertando los datos en la tabla que hemos creado
              while(! feof($fpointer)){
                  $_registro = array();
                  $_valores = fgetcsv($fpointer, 10*1024, $_separador);
                  foreach($columnas as $indice=>$columna){
                      if(isset($_valores[$indice])){
                          $_registro["`". $columna ."`"]=$_valores[$indice];
                      }
                  }
// lo mismo, estoy usando mi clase de acceso a base de datos pero se podría usar cluarquier otra
                  db::insert("tmp_".$tipo."_".$fichero, $_registro);                  
              }              
            }
      } 
      fclose($fpointer); 
      foreach($columnas as $columna){
          $this->columnas[] = "`". $columna ."`";
      }
// devolvemos la estructura con las columnas que tiene la tabla
      return $this->columnas;
    }

Todos los campos se han importado a la tabla temporal como tipo TEXT porque no sabemos el tipo de dato que van a tener. Si sabemos que alguno de los datos es un número, podemos “limpiarlo” de símbolos raros con un simple update. En mi caso era un campo de moneda que habían dejado con el símbolo del euro y los puntos como separadores de millares.

update $tabla set $campo = CONVERT(replace($campo, '.', ''),UNSIGNED INTEGER)

Y luego ya “solo” toca tratar los datos pero eso ya depende de la estructura de base de datos.

Listar campos de una tabla de MySQL

Estoy dándole vueltas a montar un CRUD sencillito para facilitarme los back office que hago. Viendo opciones de cómo hacerlo, me he encontrado con una cláusula de MySQL que permite devolver los campos de una tabla con sus propiedades, algo que me vendrá bastante bien para este proyecto.


-- Si queremos sacar la estructura de la tabla 
describe tabla;

-- Y si queremos sacar la información de un campo en concreto 
describe tabla campo;

En breve me iré de vacaciones y seguramente le eche unas horas a este proyecto, a ver qué tal queda. Ya iré informando

Listar los bloqueos de una base de datos

Últimamente ando bastante liado y no he podido postear nada pero después de tener que pegarme con un Navision que bloqueaba una tabla y tiraba mi aplicación, he tenido que volver para poner la consulta de marras que he tenido que usar para listar los bloqueos de la base de datos en cuestión:

SELECT OBJECT_NAME(P.object_id) AS TableName, 
       L.resource_type, 
       L.resource_description
FROM sys.dm_tran_locks AS L 
INNER JOIN sys.partitions AS P 
ON L.resource_associated_entity_id = P.hobt_id

PD: A ver si ahora que me estoy liberando un poco de trabajo, puedo volver a postear con algo más de regularidad