All posts in Databases

Oracle te un component força interessant per a la gestió de comptadors. És l’objecte SEQUENCE.

Per obtenir el següent valor de la seqüència executarem
SELECT nom_sequencia.nextval FROM DUAL;

A MySQL podem muntar un workarround per a emular aquesta característica d’Oracle creant una taula i dues funcions pròpies.

Creem una taula anomenada ubqSequencia on el nom de la seqüencia és clau primaria:
CREATE TABLE `ubqSequencia` (
`sqId` varchar(64) NOT NULL COMMENT 'Nom de la seqüència',
`sqCnt` bigint(20) UNSIGNED NOT NULL COMMENT 'Comptador de la seqüència',
`sqInc` int(11) NOT NULL default '1' COMMENT 'Increment per omissió de la seqüència',
`sqObs` longtext COMMENT 'Observacions',
PRIMARY KEY (`sqId`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Comptadors emulem create sequence a Oracle'

Creem una funció anomenada ubqSequenciaNextVal que li passem el nom de la seqüència i ens retorna el comptador un cop incrementat. És l’equivalent a la pseudo columna NEXTVAL d’Oracle per a objectes SEQUENCE.
DELIMITER $$

DROP FUNCTION IF EXISTS `ubqSequenciaNextVal`$$
CREATE FUNCTION `ubqSequenciaNextVal`(psqId CHAR(64)) RETURNS bigint(20)
BEGIN

insert into ubqSequencia (sqId, sqCnt, sqInc) values(psqId,1,1)
on duplicate key update sqCnt = sqCnt + sqInc;

RETURN (select sqCnt from ubqSequencia where sqId = psqId);

END$$

DELIMITER ;

Aquesta funció inicialitza sempre la seqüència que em passat com a paràmetre. En cas de que salti la clau duplicada, augmenta el comptador amb l’increment establert a la mateixa taula pel mateix comptador, per omissió +1.

I la funció ubqSequenciaCurrVal que retorna el valor actual del comptador. L’equivalent a la pseudo columna CURRVAL d’Oracle pels objectes SEQUENCE.
DELIMITER $$

DROP FUNCTION IF EXISTS `ubqSequenciaCurrVal`$$
CREATE FUNCTION `ubqSequenciaCurrVal`(psqId CHAR(64)) RETURNS bigint(20)
BEGIN

RETURN (select sqCnt from ubqSequencia where sqId = psqId);

END$$

DELIMITER ;

Un dels aspectes positius de tenir els comptadors a nivell de base de dades i no per lògica de programes, és que podem actualitzar els comptadors en MySQL des d’instruccions massives. Per exemple:


update PROVA set nouComptador = ubqSequenciaNextVal('XXYYZZ');

Actualitzant el camp nouComptador de tots els registres de la taula PROVA amb la seqüència XXYYZZ. Les proves realitzades han consumit 0.0946 segons en fer la seqüència de 414 registres en un update massiu.

Certifiquem que el comptador ha quedat actualitzat

mysql> select ubqSequenciaCurrVal('XXYYZZ');
+-------------------------------+
| ubqSequenciaCurrVal('XXYYZZ') |
+-------------------------------+
| 414 |
+-------------------------------+
1 row in set (0.00 sec)

I mostrem com afegim un

mysql> select ubqSequenciaNextVal('XXYYZZ');
+-------------------------------+
| ubqSequenciaNextVal('XXYYZZ') |
+-------------------------------+
| 415 |
+-------------------------------+

Save MySQL!

Categories: MySQL
Comments: No
FBGrpLgo

Michael Widenius, fundador i primerenc desenvolupador de MySQL ens informa de que s’ha creat una campanya per a salvar la llicència GPL del MySQL.

La compra de SUN per Oracle, pot fer perillar el desenvolupament del MySQL, pedra angular de la InterNet que coneixem avui en dia.
La majoria d’aplicacions a InterNet còrren en un clàssic LAMP: Linux, Apache, MySQL i PHP, i un canvi en el model de llicència de MySQL seria catastròfic per al desenvolupament de la xarxa, doncs el fet de poder tenir un entorn de programació totalment OpenSource aporta un munt d’aplicacions al consum de la xarxa de xarxes.
És important donar suport a aquesta petició abans del 4 de gener del 2010:

Per a importar un arxiu de dades separades per comes (CSV) a una taula MySQL, emprarem la instrucció LOAD DATA INFILE:

load data local infile 'categories.csv'
into table categories
fields terminated by ','
enclosed by '"'
lines terminated by "n"
(catCodi, catDesc);

Tots els fulls de càlcul permeten la exportació a CSV, pel que amb aquesta senzilla instrucció podrem importar ràpidament dades a MySQL.

Amb aquesta funció de quatre línies de codi, aconseguirem girar una data Timestamp, data + hora, tant si ens arriba en format MySQL yyyy-mm-dd hh:ii:ss com si ens arriba de pantalla en format europeu dd/mm/yyyy hh:ii:ss


/**
* Girem una data/hora en format MySQL a *EUR i viceversa
*
* @param string $timestamp
* @return string
*/
function giraTimestamp($data)
{
/**
* Mirem que la cadena compleixi amb els requisits de :
* entre 1 i 4 posicions decimals
* seguit d'un separador vàlid
* seguit d'entre 1 i 2 posicions decimals
* seguit d'un separador vàlid
* seguit d'entre 1 i 4 posicions decimals
* seguit d'un espai
* seguit d'entre 1 i 2 posicions decimals
* seguit d'un separador :
* seguit d'entre 1 i 2 posicions decimals
* seguit d'un separador : o no, doncs els segons no són obligatoris
* seguit d'entre 0 i 2 posicions decimals
*
* guardant-nos les xifres d'any, mes i dia i la data complerta
*/
if (preg_match('/(d{1,4})[-/.](d{1,2})[-/.](d{1,4})s(d{1,2}:d{1,2}:?d{0,2})/', $data, $jData))
{
/**
* Esborrem la primera possició de l'array resultant que és la cadena
* que s'ha parsejat.
*/
array_shift($jData);

/**
* Extraiem de l'array l'hora:minut:segon
*/
$jHora = array_splice($jData, 3);

/**
* Si la primera xifra te 4 posicions, vol dir que venim de
* MySQL, i representarem la data girada amb / com a separador
* En cas contrari, vol dir que venim de pantalla, i el
* separador serà l'standard de MySQL.
*/
if (strlen($jData[0]) == 4)
{
$separador = '/';
}
else
{
$separador = '-';
}

/**
* Retornem la data
*
* girem l'array que conté any,mes,dia o dia,mes,any
* la convertim a una cadena separant cada element pel separador calculat
* afegim espai blanc i l'hora complerta
*/
$ret = implode($separador, array_reverse($jData)) . ' ' . $jHora[0];

return $ret;
}
}

Per als camps de tipus date, que no tenen l’hora, la cadena de parseig serà:


/(d{1,4})[-/.](d{1,2})[-/.](d{1,4})/

logo_large

A Corretgé.com hem decidit implementar el gestor de projectes dotProject 2.1.2 i adaptar-lo a les nostres necessitats.
El primer que farem serà que el llistat de companyies del dotProject es correspongui amb la relació de clients de l’AbanQ i així evitar haver d’entrar les fitxes a les dues aplicacions:
Prèvia còpia de seguretat de les dades, arrenquem el MySQL i emprem la base de dades on tenim el dotProject i esborrem la taula companies:
drop table companies

I procedim a la creació de la vista basada en les dades de client de l’AbanQ que tenim en aquest cas a la base de dades crtfaclux. A la relació de clients d’AbanQ també ha d’existir la nostra pròpia empresa, que identificarem com de tipus 6, Interna, que la detectem pel NIF:
create view companies as
select c.codcliente as company_id,
0 as company_module,
convert(c.nombre USING utf8) as company_name,
c.telefono1 as company_phone1,
c.telefono2 as company_phone2,
c.fax as company_fax,
convert(d.direccion USING utf8) as company_address1,
convert(d.provincia USING utf8) as company_address2,
convert(d.ciudad USING utf8) as company_city,
d.codpais as company_state,
d.codpostal as company_zip,
substring_index(c.email, '@', -1) as company_primary_url,
1 as company_owner,
convert(c.nombrecomercial USING utf8) as company_description,
CASE c.cifnif
when 'B17803586' then 6
else 1
end as company_type,
c.email as company_email,
convert(c.contacto USING utf8) as company_custom
from crtfaclux.clientes c
left join crtfaclux.dirclientes d on c.codcliente = d.codcliente and d.domfacturacion = 1

Si accedim al llistat de companyies de dotProject trobarem integrades tots els nostres clients, assigants com a owner de la companyia l’administrador del dotProject. Aquest camp no es pot canviar. Si es necessita canviar dades, el que haurem de fer és integrar-les de manera periòdica i no pas crear una vista.

oracle-compra-sun

En Toni Hermoso informa d’una notícia Bomba: Oracle comprarà SUN per 7.400 milions de dollars, uns 5.700 milions d’Euros (els USA empren el que s’anomena Short Scale per a quantificiar un bil·lió).

Pagaran 9,5 USD per acció, preu de cotització de SUN a l’agost del 2008, molt per sobre dels 6,5 actuals i el doble dels 4,75 que cotitzaven abans del 17 de març, data en que es van fer públics els rumors de que IBM volia comprar SUN per 7.000 milions d’USD. SUN va trobar insuficient l’oferta d’IBM i van trencar unes converses molt avançades el 6 d’abril.L’aposta d’IBM era força interessant per al món Open Source: Assegurava la seva aposta per Java com a llenguatge inter-plataforma de propòsit general i mantenia desenvolupament de MySQL, com demostra la creació de l’IBMSB2i Storage Engine per a MySQL de l’AS/400.

L’aposta d’Oracle potser va més enrutada en assegurar-se poder servir als seus clients sol·lucions integrades amb maquinari, de fet històricament Oracle i SUN havien anat del braçet.

Possiblement també controlar els gestors de bases de dades que suporten SAP i potser incorporar a Oracle algunes de les funcionalitats de MySQL i viceversa. Seria fantàstic la creació d’un Oci Storage Engine per a MySQL ;-)

El Zend framework ens ho posa certament fàcil per a connectar amb una base de dades ORACLE.

La classe necessària i que hem d’incloure és la de les connexions OCI

require_once ('Zend/Db/Adapter/Pdo/Oci.php');

Creem un array on posarem totes les dades habituals de connnexió amb una base de dades

$arrayConnexio = array(
'host' => 'xx.xx.xx.xx',
'port' => 'xxxx',
'dbname' => 'SID_DE_LA_BBDD',
'username' =>'usuari',
'password' => 'password'
);

El host pot ser la seva adreça IP o bé el seu nom.
El port és el port de comunicació amb la BBDD (habitualment el 1521)

Ara només ens quedarà crear la instància de la classe i …

$laConnexioBBDD = new Zend_Db_Adapter_Pdo_Oci($arrayConnexio);

ja ho tindrem !

A partir d’aquí la manera de treballar és l’habitual amb les connexions a base de dades:

$rowset = $laConnexioBBDD->fetchAll($laQuery);

Pot ser d’interès especificar amb quina codificació de caràcters volem treballar. Així no depenem de la instal·lada per defecte al servidor.

$arrayConnexio = array(
...
'charset' => 'utf8'
);

Una bona manera d’esborrar registres per clau duplicada en MySQL és creant un índex UNIQUE amb la instrucció IGNORE.
ALTER IGNORE TABLE `taula` ADD UNIQUE KEY (`campClau`);
Si s’especifica IGNORE, només la primera fila és manté. Les altres files en conflicte són esborrades. Valors incorrectes seran truncats al valor més proper que esdevingui un valor acceptable.

Més informació al manual ALTER TABLE de MySQL