[RESOLU] Créer une base de données, avec comme nom une variable

Eléphant du PHP | 76 Messages

15 nov. 2012, 03:52

Bonsoir,

J'ai beau chercher, mais honnêtement, je trouve rien du tout.

J'essai de créer dynamiquement une base de donnée, a l'envoie d'un formulaire...

Mais je dois nommer la table, avec le nom d'une variable!!

J'essai ceci :
$client_table = time();
							
							$sql = "CREATE TABLE if not exists CLIENT_'".$client_table."' ( 
									id tinyint(4) unsigned NOT NULL auto_increment, 
									email varchar(80) NOT NULL, 
									motdepasse varchar(32), 
									PRIMARY KEY (id) 
									)"; 
									$verifsql = mysql_query($sql);
									
									if (!$verifsql)
									{
									die(mysql_error());
									}
Et ceci :
$client_table = time();
							
							$sql = "CREATE TABLE if not exists CLIENT_'$client_table' ( 
									id tinyint(4) unsigned NOT NULL auto_increment, 
									email varchar(80) NOT NULL, 
									motdepasse varchar(32), 
									PRIMARY KEY (id) 
									)"; 
									$verifsql = mysql_query($sql);
									
									if (!$verifsql)
									{
									die(mysql_error());
									}
Mais ça ne fonctionne pas.

Quelqu'un a une idée?

Merci!

Eléphant du PHP | 229 Messages

15 nov. 2012, 08:58

Bonjour,

attention aux failles de sécurités dû aux insertions sql, si tu insères une variable dans ta base de données.

Test ta requête dans phpadmin (sans variable)et après, si c'est ok, rédige le PHP.

Test ta variable avec :
echo var_dump($variable)

Bon codage.

edit : avec le nom de la variable ou le contenu de la variable ?
Modifié en dernier par schim59 le 15 nov. 2012, 10:11, modifié 1 fois.

ViPHP
ViPHP | 2577 Messages

15 nov. 2012, 10:07

<?PHP
$client_table = "toto";
$sql = "CREATE TABLE if not exists CLIENT_'$client_table' (..."; 
?>
<?PHP
$sql = "CREATE TABLE if not exists CLIENT_'toto'(..."; 
?>
Il n'y a pas de différence entre l'utilisation d'une variable ou pas. Par contre, il faudrai vérifier que le code sql et surtout le mysql_error() pour voir l'erreur.
Un coup d'oeil rapide : les quotes autour de la variable (ou de toto) sont en trop.

ViPHP
ViPHP | 4039 Messages

15 nov. 2012, 10:58

Dites, il n'y aurait pas une monstrueuse erreur de conception ?

Créer une table par client, pour ne contenir qu'une rangée d'informations (id, email, mdp) ?

Une pratique plus rationnelle voudrait que tu ne crées qu'une table pour tes clients, qui occuperont alors chacun une rangée. N'hésite pas à te documenter concernant les bonnes pratiques concernant les bases de données.

De plus, j'ose espérer que le mot de passe ne sera pas stocké en clair ? :priere:

(je donne des indices, il faut bien passer un jour par la, mais autant ne pas rester trop longtemps à ce stade :wink: )
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

Eléphant du PHP | 267 Messages

15 nov. 2012, 11:16

salut,

le caractère ' n'est pas un caractère autorisé selon la norme SQL

essaie comme ceci, ça devrait fonctionner :
$sql = "CREATE TABLE if not exists CLIENT_".$client_table." ( 
@+
dix2

Eléphant du PHP | 267 Messages

15 nov. 2012, 11:22

MySQL accèpte le caractère ' à condition d'encadrer le nom par des côtes (Alt Gr + 7)
$sql = "CREATE TABLE if not exists `CLIENT_'".$client_table."'` ( 

Eléphant du PHP | 76 Messages

15 nov. 2012, 15:18

Merci pour vos réponses, je vais tester cela tentot :)

Pour répondre a ta question,

J'ai une table "user", qui contient tout mes clients.

Mais chaque "user", va avoir une table a lui, contenant ses propres clients ;)

J'aurais pu créer une seulement table client, et ajouter une colone "user_id", pour associer la ligne au bon user, mais je vais avoir besoin des # de client, incrémenté, sans en sauter.

ViPHP
ViPHP | 2577 Messages

15 nov. 2012, 17:00

Dans ce cas tu peux faire une table :
sous_client(id_client,id_sous_client,....)

Enfin ca dépend un peut de ce que tu gères. Tu peux également faire une table client, une table a_pour_sous_client qui relie 2 clients.

Eléphant du PHP | 76 Messages

15 nov. 2012, 17:04

Oui mais, prenons par exemple que je souhaite, que tout les user, est chacun leur table client, et facture. Si j'ai seulement une grande table, avec tout les factures et seulement un user_id qui relie la facture au bon client, les numéros de factures ne se suivrons pas. C'est pour cela que je souhaite pas cela de cette façon.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

15 nov. 2012, 22:12

Oui mais, prenons par exemple que je souhaite, que tout les user, est chacun leur table client, et facture. Si j'ai seulement une grande table, avec tout les factures et seulement un user_id qui relie la facture au bon client, les numéros de factures ne se suivrons pas. C'est pour cela que je souhaite pas cela de cette façon.
Tu peux très bien utiliser une table qui gère des séquences pour numéroter comme tu le souhaite (+ trigger pour ne pas devoir le gérer à la main).


Ceci dit est vraiment pertinent ?

Le tout c'est de garder la relation client facture, le numéro n'a pas besoin de se suivre.

En tous cas le faire avec une table me semble plus pertinent que d'avoir une table par client ;)


@+

@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 76 Messages

15 nov. 2012, 22:18

Il faut que les numéros de facture de suivre!

J'ai du mal a imaginer cela :

id, user_id, facture_id, ...
1, roger, 1
2, bob, 1
3, bob, 2
4, bob, 4
5, roger, 2
6, bob, 5
7, roger, 3
....

Mais le id_facture incrémenté automatiquement...

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

16 nov. 2012, 00:32

pas d'auto_increment sur autre chose qu'une clef primaire !

sur le principe je dirais quelque chose dans ce style
create table clients(
	idClient int not null auto_increment primary key, 
	nom VARCHAR(50) not null
)engine=innodb;

create table numeroFacture (
	idClient int not null UNIQUE,
	numero int not null DEFAULT 0, 
	FOREIGN Key (idClient) REFERENCES clients(idClient)
		on delete restrict
)engine=innodb;


CREATE table factures (
	idFacture int not NULL auto_increment PRIMARY KEY, 
	idClient int not null,
	numero int not null,
	-- etc etc
	-- fkc
	FOREIGN Key (idClient) REFERENCES clients(idClient)
		on delete restrict
)engine=innodb;

-- procédure pour la gestion des numéros de factures, par client

drop procedure genNum;
delimiter /
CREATE PROCEDURE genNum(in client INT, out num INT)
begin 
	UPDATE numeroFacture set numero = numero +1 where idClient = @client;
	select max(numero) INTO @num from numeroFacture where idClient = @client;
end

/
-- un TRIGGER pour gérer cela
create TRIGGER trg_facture_before_insert
BEFORE INSERT on factures
FOR EACH ROW
BEGIN
	set @nouveauNumero;
	if NEW.numero is NULL then 
		genNum(new.idClient, @nouveauNumero);
		set new.numero = @nouveauNumero;
	end if;

end /

delimiter ;
Lorsque tu ajoute une facture dans le système fait un simple insert et le trigger fait le boulot.
Tu peux très bien te passer de la procédure stockée, mais cela te permet de l'utiliser en dehors :)

par contre le trigger est obligatoire pour t'éviter de faire trop de requête entre php et le serveur mysql.

@+
Il en faut peu pour être heureux ......

Eléphant du PHP | 76 Messages

16 nov. 2012, 01:23

Ouff, je vais essayer de déchiffrer tout cela, ça ne fait pas trop longtemp que je travail avec mysql comme ça, et j'ai de la difficulté a comprend les relations entre les tables :)

Merci beaucoup, je vous tiens au courant.

Eléphant du PHP | 76 Messages

16 nov. 2012, 01:47

On me donne cette erreur :

#1005 - Can't create table 'cloud_data.numerofacture' (errno: 150) (Détails...)

Quand je tente d'insérer ceci :

CREATE TABLE numeroFacture (
        idClient int NOT NULL UNIQUE,
        numero int NOT NULL DEFAULT 0, 
        FOREIGN KEY (idClient) REFERENCES clients(idClient)
                ON DELETE restrict
)engine=innodb;

Eléphant du PHP | 76 Messages

16 nov. 2012, 02:08

Bref, j'ai réussis a faire ce que je souhaitais :)
$sql = "CREATE TABLE if not exists `zclient_$user_id` ( 
									id int(4) unsigned NOT NULL auto_increment, 
									email varchar(80) NOT NULL, 
									motdepasse varchar(32), 
									PRIMARY KEY (id) 
									)"; 
La bonne syntaxe est celle-ci ;)