mysql

Risultato query Mysql con campi uno sotto l'altro

mysql
Tags: mysqlpill

All'interno della consolle mysql quando si fa una query il risultato viene mostrato in forma tabellare. Se invece è utile mostrare ogni cella di un record su una riga nuova si può usare "\G" in fondo alla query (al posto di ";").

select * from tabella\G

Risultato:

*************************** 1. row ***************************
field1: 44386
field2: 12345
*************************** 1. row ***************************
max(plexid): 44386


Mysql: Table 'name' is specified twice, both as a target for 'UPDATE' and as a separate source for data

mysql
Tags: mysqlpill

Il problema in oggetto lo abbiamo se cerchiamo di fare una query di questo tipo:

update MYTABLE set COL=COL+1 where ID in (select ID from MYTABLE where OTHERCOL=0)

In pratica stiamo cercando di fare una query di update (o di delete), selezionando le righe tramite una query di select sulla stessa tabella. La cosa potrebbe essere perfettamente lecita (almeno se la query di select non si basa su colonne modificate dalla query di update), ma MYSQL ce la blocca comunque.

E' possibile aggirare il controllo di mysql cammuffando la query di select con una ulteriore subquery:

update MYTABLE set COL=COL+1 where ID in (select * from (select ID from MYTABLE where OTHERCOL=0) _alias)

Mysql: rinominare un database

mysql
Tags: mysql

Le versioni recenti di mysql (dalla 5.1.23) non permettono più di fare un semplice "RENAME DATABASE" per cambiare il nome dell'intero database.

E' però possibile effettuare una query del tipo "RENAME TABLE vecchio_db.tabella TO nuovo_db.tabella" per spostare una tabella da un database all'altro. Quindi un sistema efficace per fare il rename dell'intero database è quello di creare un database con il nuovo nome, spostare tutte le tabelle li dentro, quindi eliminare il vecchio database.

Da shell potete usare questo pattern (opportunamente parametrizzato per accedere al database):

[bash]

mysqladmin -u username -p create NUOVO_DB

Mysqldump senza bloccare il server

mysql

Se vogliamo fare un dump di un database che potrebbe essere particolarmente impegnativo per la macchina (e quindi che rischierebbe di bloccare/rallentare i servizi in uso e in particolare gli altri accessi al DB) è possibile usare queste opzioni:

mysqldump --single-transaction --quick --lock-tables=false

In questo modo il dump avverrà a bassa priorità, usando una sola transazione e senza fare locking di tabelle (ovviamente questo può comportare dei dump con problemi di consistenza).

Mysql: inserire in una colonna un contatore sequenziale di riga

mysql

A volte può servire inserire in una select un contatore sequenziale, in modo che ad ogni record venga generato il numero successivo. Ad esempio per generare degli ID incrementali per una "insert into table". Ecco come:

select @c := @c + 1, ... from ..., (select @c := 0) c

L'esempio effettua un conteggio da 1 a 10, variando i numeri è possibile ovviamente cambiarlo. Ad esempio, per inserire degli utenti drupal:

select @curRow := value from sequences;
insert into users (uid, ...) select @curRow := @curRow + 1 uid, ... from externale_table ...;
delete from sequences; insert into sequences (value) values(@curRow + 1);

Apparmor e come cambiare la datadir di Mysql

mysql

Problema: occorre cambiare il percorso dove Mysql salva i dati dei database (datadir), quindi editiamo il file /etc/mysql/my.cnf, impostiamo datadir di conseguenza, riavviamo mysql e... non funziona niente!

 

Il motivo è Apparmor un sistema di sicurezza usato da Ubuntu per evitare manipolazioni spiacevoli del sistema. Questa applicazione, tra le altre cose, definisce dei "range di disco" che i processi possono andare a lavorare, e nello specifico definisce dove mysql può salvare i suoi file.

Per questo motivo se si vuole cambiare la datadir occorre aggiornare di conseguenza anche i paramentri di Apparmor.

 

E' semplice:

sudo vi /etc/apparmor.d/usr.sbin.mysqld

PHP, Mysql e "The used command is not allowed with this MySQL version"

php
Tags: phpmysql

Problema: in uno script PHP cerchiamo di eseguire il comando mysql: "LOAD DATA LOCAL INFILE ..."

(Quindi in genere cerchiamo di importare un file csv in una tabella mysql dal file system locale).

Lo script si blocca con un errore:

The used command is not allowed with this MySQL version

Mentre se proviamo a fare lo stesso comando direttamente da una shell Mysql funziona tutto (se non è così il problema è da cercarsi nella configurazione generale mysql).

 

Il problema è dovuto al fatto che la connessione a Mysql non specifica l'abilitazione dei LOCAL_FILES.

Per abilitarla direttamente va usato il flag "128" al comando mysql_connect o mysql_pconnect.

Esempio

[php]