Skip to content

9. Utilização do SGBD MySQL

9.1. Instalação do módulo MySQLdb

Vamos escrever scripts utilizando uma base de dados MySQL:

As funções Python para gerir uma base de dados MySQL estão encapsuladas num módulo MySQLdb que não está incluído na distribuição inicial do Python. Por isso, terá de descarregar e instalar o módulo. Aqui está uma forma de o fazer:

  • No menu Programas, selecione [1] o gestor de pacotes do Python. A janela de comandos [2] irá então aparecer.

Procure a palavra-chave mysql nos pacotes:


C:\Documents and Settings\st>pypm search mysql
Get: [pypm-be.activestate.com] :repository-index:
Get: [pypm-free.activestate.com] :repository-index:
autosync: synced 2 repositories
  chartio                    Setup wizard and connection client for connecting
  chartio-setup              Setup wizard and connection client for connecting
  cns.recipe.zmysqlda        Recipe for installing ZMySQLDA
  collective.recipe.zmysqlda Recipe for installing ZMySQLDA
  django-mysql-manager       DESCRIPTION_DESCRIPTION_DESCRIPTION
  jaraco.mysql               MySQLDB-compatible MySQL wrapper by Jason R. Coomb
  lovely.testlayers          mysql, postgres nginx, memcached cassandra test la
  mtstat-mysql               MySQL Plugins for mtstat
  mysql-autodoc              Generate HTML documentation from a mysql database
  mysql-python               Python interface to MySQL
  mysqldbda                  MySQL Database adapter
  products.zmysqlda          MySQL Zope2 adapter.
  pymysql                    Pure Python MySQL Driver
  pymysql-sa                 PyMySQL dialect for SQLAlchemy.
  pymysql3                   Pure Python MySQL Driver
  sa-mysql-dt                Alternative implementation of DateTime column for
  schemaobject               Iterate over a MySQL database schema as a Python o
  schemasync                 A MySQL Schema Synchronization Utility
  simplestore                A datastore layer built on top of MySQL in Python.
  sqlbean                    A auto maping ORM for MYSQL and can bind with memc
  sqlwitch                   sqlwitch offers idiomatic SQL generation on top of
  tiddlywebplugins.mysql     MySQL-based store for tiddlyweb
  tiddlywebplugins.mysql2    MySQL-based store for tiddlyweb
zest.recipe.mysql          A Buildout recipe to setup a MySQL database.

Todos os módulos cujo nome ou descrição contém a palavra-chave "mysql" foram listados. O que nos interessa é o [mysql-python], linha 14. Vamos instalá-lo:


C:\Documents and Settings\st>pypm install mysql-python
The following packages will be installed into "%APPDATA%\Python" (2.7):
 mysql-python-1.2.3
Hit: [pypm-free.activestate.com] mysql-python 1.2.3
Installing mysql-python-1.2.3
 
C:\Documents and Settings\st>echo %APPDATA%
C:\Documents and Settings\st\Application Data
  • Linha 5: O pacote mysql-python-1.2.3 foi instalado na pasta "%APPDATA%\Python", onde APPDATA é a pasta especificada na linha 8.

Esta operação pode falhar se:

  • o interpretador Python utilizado for uma versão de 64 bits;
  • o caminho %APPDATA% contiver caracteres acentuados.

9.2. Instalação do MySQL

Existem várias formas de instalar o SGBD MySQL. Aqui, utilizámos o WampServer, um pacote que combina vários componentes de software:

  • um servidor web Apache. Iremos utilizá-lo para escrever scripts web em Python;
  • o sistema de gestão de bases de dados MySQL;
  • a linguagem de script PHP;
  • uma ferramenta de administração de bases de dados MySQL escrita em PHP: o phpMyAdmin.

O WampServer pode ser descarregado (junho de 2011) no seguinte endereço:

http://www.wampserver.com/download.php
  • Em [1], descarregue a versão adequada do WampServer;
  • em [2], uma vez instalado, inicie-o. Isto irá iniciar o servidor web Apache e o sistema de gestão de bases de dados MySQL;
  • em [3], uma vez iniciado, o WampServer pode ser gerido através de um ícone [3] localizado no canto inferior direito da barra de tarefas;
  • Em [4], inicie a ferramenta de administração do MySQL.

Crie uma base de dados [dbpersonnes]:

Image

Crie um utilizador [admpersonnes] com a palavra-passe [nobody]:

  • em [1], o nome de utilizador;
  • em [2], o servidor DBMS no qual lhes concede permissões;
  • em [3], a sua palavra-passe [nobody];
  • em [4], o mesmo que acima;
  • em [5], não concedemos privilégios a este utilizador;
  • em [6], crie o utilizador.
  • em [7], volte à página inicial do phpMyAdmin;
  • em [8], utilize o link [Privilégios] nesta página para modificar os privilégios do utilizador [admpersonnes] [9].
  • em [10], especifique que pretende conceder ao utilizador [admpersonnes] direitos sobre a base de dados [dbpersonnes];
  • Em [11], confirme a seleção.
  • Utilizando o link [12] [Selecionar tudo], conceda ao utilizador [admpersonnes] todos os direitos sobre a base de dados [dbpersonnes] [13];
  • Confirmamos em [14].

Agora temos:

  • uma base de dados MySQL [dbpersonnes];
  • um utilizador [admpersonnes / nobody] que tem acesso total a esta base de dados.

Vamos escrever scripts em Python para trabalhar com a base de dados.

9.3. Ligar-se a uma base de dados MySQL - 1


Programa (mysqldb_01)


# import du module MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
 
# connexion à une base MySQL
....

Notas:

  • Linhas 2–4: Os scripts que contêm operações com o SGBD MySQL devem importar o módulo MySQLdb. Recorde-se que instalámos este módulo na pasta [%APPDATA%\Python]. A pasta [%APPDATA%\Python] é pesquisada automaticamente quando um script Python solicita um módulo. Na verdade, todas as pastas listadas em sys.path são pesquisadas. Aqui está um exemplo que exibe essas pastas:
1
2
3
4
5
6
7
#    -*- coding=utf-8 -*-

import sys

#    display of sys.path files
for dossier in sys.path:
    print dossier

A saída no ecrã é a seguinte:

D:\data\istia-1112\python\tutoriel
C:\Windows\system32\python27.zip
D:\Programs\ActivePython\Python2.7.2\DLLs
D:\Programs\ActivePython\Python2.7.2\lib
D:\Programs\ActivePython\Python2.7.2\lib\plat-win
D:\Programs\ActivePython\Python2.7.2\lib\lib-tk
D:\Programs\ActivePython\Python2.7.2
C:\Users\Serge TahÚ\AppData\Roaming\Python\Python27\site-packages
D:\Programs\ActivePython\Python2.7.2\lib\site-packages
D:\Programs\ActivePython\Python2.7.2\lib\site-packages\win32
D:\Programs\ActivePython\Python2.7.2\lib\site-packages\win32\lib
D:\Programs\ActivePython\Python2.7.2\lib\site-packages\Pythonwin
D:\Programs\ActivePython\Python2.7.2\lib\site-packages\setuptools-0.6c11-py2.7.egg-info

Linha 8, a pasta [site-packages] onde o MySQLdb foi originalmente instalado. Estamos a mover a pasta [site-packages], que é onde o utilitário pypm instala os módulos Python. Para adicionar uma nova pasta na qual o Python irá procurar módulos, adicionamo-la à lista sys.path:


# import du module MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
 
# connexion à une base MySQL
....

Na linha 3, adicionamos a pasta para onde o módulo MySQLdb foi movido.

O código completo do exemplo é o seguinte:


# import du module MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
 
# connexion à une base MySQL
# l'identité de l'utilisateur est (admpersonnes,nobody)
user="admpersonnes"
pwd="nobody"
host="localhost"
connexion=None
try:
    print "connexion..."
    # connexion
    connexion=MySQLdb.connect(host=host,user=user,passwd=pwd)
    # suivi
    print "Connexion a MySQL reussie sous l'identite host={0},user={1},passwd={2}".format(host,user,pwd)
except MySQLdb.OperationalError,message:
    print "Erreur : {0}".format(message)
finally:
    try:
        connexion.close()
    except:
        pass
 
  • linhas 8–11: o script irá ligar (linha 15) o utilizador [admpersonnes / nobody] à base de dados MySQL na máquina [localhost]. Não se liga a uma base de dados específica;
  • linhas 12–24: a ligação pode falhar. Por isso, está envolvida num bloco try/except/finally;
  • linha 15: o método connect do módulo MySQLdb aceita vários parâmetros nomeados:
    • user: o utilizador proprietário da ligação [admpersonnes];
    • pwd: a palavra-passe do utilizador [nobody];
    • host: a máquina que executa o SGBD MySQL [localhost];
    • db: a base de dados à qual se deve ligar. Opcional.
  • linha 18: se for lançada uma exceção, esta é do tipo [MySQLdb.OperationalError] e a mensagem de erro associada será encontrada na variável [message];
  • linhas 20–23: na cláusula [finally], a ligação é encerrada. Se ocorrer uma exceção, esta é capturada (linha 23), mas não é tomada nenhuma ação (linha 24).

Resultados

connexion...
Connexion a MySQL reussie sous l'identite host=localhost,user=admpersonnes,passwd=nobody

9.4. Ligar a uma base de dados MySQL - 2


Programa (mysqldb_02)

#    import module MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb

# ---------------------------------------------------------------------------------
def testeConnexion(hote,login,pwd):
    #  connect then disconnect (login,pwd) mysql sgbd from host server
    #    launches eception MySQLdb.operationalError
    #    connection
    connexion=MySQLdb.connect(host=hote,user=login,passwd=pwd)
    print "Connexion a MySQL reussie sous l'identite (%s,%s,%s)" % (hote,login,passwd)
    #  close the connection
    connexion.close()
    print "Fermeture connexion MySQL reussie\n"


#    ---------------------------------------------- main
#  connection to the MySQL database
#    user identity
user="admpersonnes"
passwd="nobody"
host="localhost"
#    test connection
try:
    testeConnexion(host,user,passwd)
except MySQLdb.OperationalError,message:
    print message
#  with a non-existent user
try:
    testeConnexion(host,"xx","xx")
except MySQLdb.OperationalError,message:
    print message

Notas:

  • linhas 7–15: uma função que tenta ligar e, em seguida, desligar um utilizador de um SGBD MySQL. Apresenta o resultado;
  • linhas 18–34: programa principal – chama o método testConnection duas vezes e exibe quaisquer exceções.

Resultados

1
2
3
4
Connexion a MySQL reussie sous l'identite (localhost,admpersonnes,nobody)
Fermeture connexion MySQL reussie

Echec de la connexion a MySQL : (1045, "Access denied for user 'xx'@'localhost'(using password: YES)")

9.5. Criação de uma tabela MySQL

Agora que sabemos como estabelecer uma ligação com um SGBD MySQL, vamos começar a emitir comandos SQL através desta ligação. Para tal, vamos ligar-nos à base de dados criada [dbpersonnes] e utilizar a ligação para criar uma tabela na base de dados.


Programa (mysqldb_03)


# import du module MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
 
# ---------------------------------------------------------------------------------
def executeSQL(connexion,update):
    # exécute une requête update de mise à jour sur la connexion
    # on demande un curseur
    curseur=connexion.cursor()
    # exécute la requête sql sur la connexion
    try:
        curseur.execute(update)
        connexion.commit()
    except Exception, erreur:
        connexion.rollback()
        raise
    finally:
        curseur.close()
 
# ---------------------------------------------- main
# connexion à la base MySQL
# l'identité de l'utilisateur
ID="admpersonnes"
PWD="nobody"
# la machine hôte du sgbd
HOTE="localhost"
# identité de la base
BASE="dbpersonnes"
# connexion
try:
    connexion=MySQLdb.connect(host=HOTE,user=ID,passwd=PWD,db=BASE)
except MySQLdb.OperationalError,message:
    print message
    sys.exit()
 
# suppression de la table personnes si elle existe
# si elle n'existe pas une erreur se produira
# on l'ignore
requete="drop table personnes"
try:
    executeSQL(connexion,requete)
except:
    pass
# création de la table personnes
requete="create table personnes (prenom varchar(30) NOT NULL, nom varchar(30) NOT NULL, age integer NOT NULL, primary key(nom,prenom))"
try:
    executeSQL(connexion,requete)
except MySQLdb.OperationalError,message:
    print message
    sys.exit()
# on se deconnecte et on quitte
try:
    connexion.close()
except MySQLdb.OperationalError,message:
    print message
sys.exit()

Notas:

  • linha 7: a função executeSQL executa uma consulta SQL numa ligação aberta;
  • linha 10: As operações SQL na ligação são realizadas através de um objeto especial denominado cursor;
  • Linha 10: Obter um cursor;
  • linha 13: execute a consulta SQL;
  • linha 14: a transação atual é confirmada;
  • linha 15: se ocorrer uma exceção, a mensagem de erro é armazenada na variável de erro;
  • linha 16: a transação atual é revertida;
  • linha 17: a exceção é re-lançada;
  • linha 19: quer haja um erro ou não, o cursor é fechado. Isto liberta os recursos a ele associados.

Resultados

create table personnes (prenom varchar(30) NOT NULL, nom varchar(30) NOT NULL, age integer NOT NULL, primary key(nom,prenom)) : requete reussie

Verificação com o phpMyAdmin:

  • A base de dados [dbpersonnes] [1] possui uma tabela [personnes] [2] com a estrutura [3] e a chave primária [4].

9.6. Preenchimento da tabela [people]

Depois de criar a tabela [people], vamos agora preenchê-la.


Programa (mysqldb_04)

#    import module MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
#    other modules
import re

# ---------------------------------------------------------------------------------
def executerCommandes(HOTE,ID,PWD,BASE,SQL,suivi=False,arret=True):
    #    uses connection (HOTE,ID,PWD,BASE)
    #  executes the SQL commands contained in the SQL text file on this connection
    #  this is a file of SQL commands to be executed one per line
    #  if followed=True then each execution of a SQL order is displayed, indicating success or failure
    #  if arret=True, the function stops on the 1st error encountered, otherwise it executes all sql commands
    #  the function returns a list (no. of errors, error1, error2, ...)

    #  check for the presence of the SQL file
    data=None
    try:
        data=open(SQL,"r")
    except:
        return [1,"Le fichier %s n'existe pas" % (SQL)]

    #    connection
    try:
        connexion=MySQLdb.connect(host=HOTE,user=ID,passwd=PWD,db=BASE)
    except MySQLdb.OperationalError,erreur:
        return [1,"Erreur lors de la connexion a MySQL sous l'identite (%s,%s,%s,%s) : %s" % (HOTE, ID, PWD, BASE, erreur)]

    #  a cursor is requested
    curseur=connexion.cursor()
    #  execution of SQL queries contained in the SQL file
    #  we put them in a table
    requetes=data.readlines()
    #    run them one by one - initially no errors
    erreurs=[0]
    for i in range(len(requetes)):
        #  store the current query
        requete=requetes[i]
        #  do we have an empty query? If so, move on to the next query
        if re.match(r"^\s*$",requete):
            continue
        #    query execution i
        erreur=""
        try:
            curseur.execute(requete)
        except Exception, erreur:
            pass
        #   was there a mistake?
        if erreur:
            #    one more mistake
            erreurs[0]+=1
            #  error msg
            msg="%s : Erreur (%s)" % (requete,erreur)
            erreurs.append(msg)
            #  screen tracking or not?
            if suivi:
                print msg
            #    shall we stop?
            if arret:
                return erreurs
        else:
            if suivi: 
                print "%s : Execution reussie" % (requete)
    #  close connection and release resources
    curseur.close()
    connexion.commit()
    #    we disconnect
    try:
        connexion.close()
    except MySQLdb.OperationalError,erreur:
        #    one more mistake
        erreurs[0]+=1
        #  error msg
        msg="%s : Erreur (%s)" % (requete,erreur)
        erreurs.append(msg)

    #    return
    return erreurs


#    ---------------------------------------------- main
#  connection to the MySQL database
#    user identity
ID="admpersonnes"
PWD="nobody"
#  the sgbd host machine
HOTE="localhost"
#    base identity
BASE="dbpersonnes"
#  identity of the SQL command text file to be executed
TEXTE="sql.txt";

#  table creation and filling
erreurs=executerCommandes(HOTE,ID,PWD,BASE,TEXTE,True,False)
# display number of errors
print "il y a eu %s erreur(s)" % (erreurs[0])
for i in range(1,len(erreurs)):
    print erreurs[i]

Resultados

O ficheiro sql.txt:

1
2
3
4
5
6
7
8
9
drop table personnes
create table personnes (prenom varchar(30) not null, nom varchar(30) not null, age integer not null, primary key (nom,prenom))
insert into personnes values('Paul','Langevin',48)
insert into personnes values ('Sylvie','Lefur',70)
xx

insert into personnes values ('Pierre','Nicazou',35)
insert into personnes values ('Geraldine','Colou',26)
insert into personnes values ('Paulette','Girond',56)

Foi inserido intencionalmente um erro na linha 5.

Resultados no ecrã:

drop table personnes : Execution reussie
create table personnes (prenom varchar(30) not null, nom varchar(30) not null, age integer not null, primary key (nom,prenom)) : Execution reussie
insert into personnes values('Paul','Langevin',48) : Execution reussie
insert into personnes values ('Sylvie','Lefur',70) : Execution reussie
xx : Erreur ((1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xx' at
 line 1"))
insert into personnes values ('Pierre','Nicazou',35) : Execution reussie
insert into personnes values ('Geraldine','Colou',26) : Execution reussie
insert into personnes values ('Paulette','Girond',56) : Execution reussie
il y a eu 1 erreur(s)
xx : Erreur ((1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xx' at line 1"))

Verificação com o phpMyAdmin:

Image

  • Em [1], o link [Ver] permite-lhe ver o conteúdo da tabela [people] [2].

9.7. Execução de consultas SQL arbitrárias

O script a seguir permite executar um ficheiro de comandos SQL e exibir o resultado de cada um:

  • o resultado do SELECT, se o comando for um SELECT;
  • o número de linhas modificadas se o comando for INSERT, UPDATE ou DELETE.

Programa (mysqldb_05)

#    import module MySQLdb
import sys
sys.path.append("D:\Programs\ActivePython\site-packages")
import MySQLdb
#    other modules
import re

def cutNewLineChar(ligne):
    #  delete the [line] end-of-line mark if it exists
    l=len(ligne)
    while(ligne[l-1]=="\n" or ligne[l-1]=="\r"):
        l-=1
    return(ligne[0:l])

# ---------------------------------------------------------------------------------
def afficherInfos(curseur):
    #  displays the result of an sql query
    #    was it a select?
    if curseur.description:
        #    there's a description - so it's a select
        #  description[i] is the description of column no. i in the select
        #  description[i][0] is the name of column no. i in the select
        #  displays field names
        titre=""
        for i in range(len(curseur.description)):
            titre+=curseur.description[i][0]+","
        #  displays the list of fields without the trailing comma
        print titre[0:len(titre)-1]
        #  dividing line
        print "-"*(len(titre)-1)
        #  current select line
        ligne=curseur.fetchone()
        while ligne:
            print ligne
            #  next line of the select
            ligne=curseur.fetchone()
    else:
        #  there are no fields - it wasn't a select
        print "%s lignes(s) a (ont) ete modifiee(s)" % (curseur.rowcount)


# ---------------------------------------------------------------------------------
def executerCommandes(HOTE,ID,PWD,BASE,SQL,suivi=False,arret=True):
    #    uses connection (HOTE,ID,PWD,BASE)
    #  executes the SQL commands contained in the SQL text file on this connection
    #  this is a file of SQL commands to be executed one per line
    #  if followed=1 then each execution of a SQL order is displayed, indicating success or failure
    #  if arret=1, the function stops on the 1st error encountered, otherwise it executes all sql commands
    #  the function returns an array (nb of errors, error1, error2, ...)

    #  check for the presence of the SQL file
    data=None
    try:
        data=open(SQL,"r")
    except:
        return [1,"Le fichier %s n'existe pas" % (SQL)]

    #    connection
    try:
        connexion=MySQLdb.connect(host=HOTE,user=ID,passwd=PWD,db=BASE)
    except MySQLdb.OperationalError,erreur:
        return [1,"Erreur lors de la connexion a MySQL sous l'identite (%s,%s,%s,%s) : %s" % (HOTE, ID, PWD, BASE, erreur)]

    #  a cursor is requested
    curseur=connexion.cursor()
    #  execution of SQL queries contained in the SQL file
    #  we put them in a table
    requetes=data.readlines()
    #    run them one by one - initially no errors
    erreurs=[0]
    for i in range(len(requetes)):
        #  store the current query
        requete=requetes[i]
        #  do we have an empty query? If so, move on to the next query
        if re.match(r"^\s*$",requete):
            continue
        #    query execution i
        erreur=""
        try:
            curseur.execute(requete)
        except Exception, erreur:
            pass
        #   was there a mistake?
        if erreur:
            #    one more mistake
            erreurs[0]+=1
            #  error msg
            msg="%s : Erreur (%s)" % (requete,erreur)
            erreurs.append(msg)
            #  screen tracking or not?
            if suivi:
                print msg
            #    shall we stop?
            if arret:
                return erreurs
        else:
            if suivi: 
                print "%s : Execution reussie" % (requete)
                #  information on the result of the query
                afficherInfos(curseur)

    #  close connection and release resources
    curseur.close()
    connexion.commit()
    #    we disconnect
    try:
        connexion.close()
    except MySQLdb.OperationalError,erreur:
        #    one more mistake
        erreurs[0]+=1
        #  error msg
        msg="%s : Erreur (%s)" % (requete,erreur)
        erreurs.append(msg)

    #    return
    return erreurs


#    ---------------------------------------------- main
#  connection to the MySQL database
#    user identity
ID="admpersonnes"
PWD="nobody"
#  the sgbd host machine
HOTE="localhost"
#    base identity
BASE="dbpersonnes"
#  identity of the SQL command text file to be executed
TEXTE="sql2.txt"


#  table creation and filling
erreurs=executerCommandes(HOTE,ID,PWD,BASE,TEXTE,True,False)
# display number of errors
print "il y a eu %s erreur(s)" % (erreurs[0])
for i in range(1,len(erreurs)):
    print erreurs[i]

Notas:

  • A nova funcionalidade encontra-se na linha 100 do script: após a execução de uma instrução SQL, solicitamos informações sobre o cursor utilizado por essa consulta. Estas informações são fornecidas pela função displayInfo nas linhas 16–40;
  • Linhas 19 e 39: Se a consulta SQL executada for um SELECT, o atributo [cursor.description] é uma matriz em que o elemento i descreve o campo i do resultado do SELECT. Caso contrário, o atributo [cursor.rowcount] (linha 39) é o número de linhas modificadas pela consulta INSERT, UPDATE ou DELETE;
  • Linhas 32 e 36: o método [cursor.fetchone] recupera a linha atual do SELECT. Existe um método [cursor.fetchall] que recupera todas as linhas de uma só vez.

Resultados

O ficheiro das consultas executadas:

1
2
3
4
5
6
7
8
9
select * from personnes
select nom,prenom from personnes order by nom asc, prenom desc
select * from personnes where age between 20 and 40 order by age desc, nom asc, prenom asc
insert into personnes values('Josette','Bruneau',46)
update personnes set age=47 where nom='Bruneau'
select * from personnes where nom='Bruneau'
delete from personnes where nom='Bruneau'
select * from personnes where nom='Bruneau'
xselect * from personnes where nom='Bruneau'

Resultados no ecrã:

select * from personnes : Execution reussie
prenom,nom,age
---------------
('Geraldine', 'Colou', 26L)
('Paulette', 'Girond', 56L)
('Paul', 'Langevin', 48L)
('Sylvie', 'Lefur', 70L)
('Pierre', 'Nicazou', 35L)
select nom,prenom from personnes order by nom asc, prenom desc : Execution reussie
nom,prenom
-----------
('Colou', 'Geraldine')
('Girond', 'Paulette')
('Langevin', 'Paul')
('Lefur', 'Sylvie')
('Nicazou', 'Pierre')
select * from personnes where age between 20 and 40 order by age desc, nom asc,prenom asc : Execution reussie
prenom,nom,age
---------------
('Pierre', 'Nicazou', 35L)
('Geraldine', 'Colou', 26L)
insert into personnes values('Josette','Bruneau',46) : Execution reussie
1 lignes(s) a (ont) ete modifiee(s)
update personnes set age=47 where nom='Bruneau' : Execution reussie
1 lignes(s) a (ont) ete modifiee(s)
select * from personnes where nom='Bruneau' : Execution reussie
prenom,nom,age
---------------
('Josette', 'Bruneau', 47L)
delete from personnes where nom='Bruneau' : Execution reussie
1 lignes(s) a (ont) ete modifiee(s)
select * from personnes where nom='Bruneau' : Execution reussie
prenom,nom,age
---------------
xselect * from personnes where nom='Bruneau' : Erreur ((1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xselect * from personnes where nom='Bruneau'' at line 1"))

Verificação no PhpMyAdmin: