Communauté Eggdrop

Version complète : moderation SQL
Vous consultez actuellement la version basse qualité d’un document. Voir la version complète avec le bon formatage.
Pages : 1 2
Bonjour,

Je viens demander un renseignement sur un soucis de code en SQL.
Voilà lorsque je tape .moderation sur un salon, il m'affiche les tables sur le salon "mais pas dans le bon ordre".

Exemple en premier sur ma base SQL j'ai : .+badword Permet d'ajouter un mot interdit

Et je ses pas comment faire pour sa mette dans l'ordre

Voici le code TCL

tcl
##########################
# moderation.tcl en SQL. #
#                        #
# By alias_angelius.     #
##########################

# Information relative à Mysql.
set modera(sql:login) "moderator"
set modera(sql:pass) "multipass"
set modera(sql:db) "moderator"
set modera(sql:host) "127.0.0.1"
set modera(sql:sock) "/tmp/mysql.sock"
 
catch {package require mysqltcl}

# Proc - Connexion mySQL #
proc service:connect {} {
set ::mysqlink [mysqlconnect -host $::modera(sql:host) -user $::modera(sql:login) -password $::modera(sql:pass) -sock $::modera(sql:sock)]
mysqluse $::mysqlink $::modera(sql:db)
}
# Proc - Deconnexion mySQL #
proc service:deconnect {} {
mysqlclose $::mysqlink; unset -nocomplain ::mysqlink
}
 
bind pub o|o .moderation modo
proc modo { nick host hand chan arg } {
service:connect
mysqlsel $::mysqlink "SELECT * FROM `help` ORDER BY cmd"
if {[mysqlresult $::mysqlink rows] ne 0} {
while {[set row [mysqlnext $::mysqlink]] != ""} {
set colone(cmd) [lindex $row 0]
set colone(msg) [lindex $row 1]
putserv "privmsg $chan :\00314Liste des Commandes \002\0034Moderation\002\0034"
puthelp "privmsg $chan :\00314$colone(cmd) \0031: \0034$colone(msg)\0034"
}
puthelp "privmsg $chan :\00314Fin de la Liste des Commandes \002\0034Moderation\002\0034"
}
service:deconnect
}



Si quelqu'un aurais une idée/piste sa serait sympa !

Merci d'avance
Tu fais un order by cmd, donc le tri est fait sur la colonne cmd.
Il faut que tu ajoutes une colonne pour l'ordre si tu ne veux pas utiliser l'ordre alphabétique de ce champ.
Rajouter une colonne pour l'ordre ?
Du genre "cmd,msg,num"

Puis num sera remplis avec le nombre 1 pour la première etc ?
Résolus.

tcl
mysqlsel $::mysqlink "SELECT * FROM `help`"



Voilà comme ça je l'ai dans l'ordre
Dans l'ordre de l'index par défaut (ordre d'entrée en base). Que se passera-t-il quand tu voudras intercaler une commande ?
Je débute dans le SQL, donc je ne c'est pas ce qui se passera..

Mais si tu as un exemple "disons une explication" Je serais ravis !
Après j'ai regarder sur le wiki, mais je n'es pas trouver d'endroit permettant de chercher (l'ordre d'entrée de base).

Mais comme citer au dessus, je veux bien avoir un exemple sur quel type condition utilisé
Dans une base de données, si tu ne mets pas un index, une requête sans "order by" te ressortira les enregistrements dans l'ordre où tu les as entrés dans la base.
Donc oui, la solution est de rajouter un champ "ordre" et de faire ta requête avec un "order by ordre asc".
Oui pour l'ordre je l'utilise souvent.
Mais la dans l'exemple sa faisait dans le désordre en mettant un "order by cmd", chose que je ne comprenez pas pourquoi.

Exemple dans ce code TCL j'ai utilisé le "order by mots", ce qui donne l'ordre du champ (mots) à chercher.

Et si je comprend bien le système je regarde la colonne "mots" dans la base SQL, si j'ai un retour donc je n'exécute rien.
Si j'ai aucun retour, alors ont enregistre.

Voici l'exemple :

tcl
bind pub o|o .+badword +badword
proc +badword { nick host hand chan arg } {
	set colonne(mots) [string tolower [lindex $arg 0]]
	set colonne(salon) [lindex $arg 1]
	if ![onchan $nick $::back(chan)] {
		putserv "notice $nick :\00314Erreur vous devez être sur\003 \0034$::back(chan)\0034"
		return
	}
	if {$colonne(mots)==""} {
		putserv "notice $nick :\00314Incorrect veuillez mettre un mot\003. Exemple : .+badword \0034connard #salon\0034"
		return 0
	}
	if {![string match #* $colonne(salon)]} {
		putserv "notice $nick :\00314Incorrect veuillez mettre un salon\003. Exemple : \0034#SQL\0034"
		return 0
	}
	service:connect
	mysqlsel $::mysqlink "SELECT * FROM `badword` ORDER BY mots"
	if {[mysqlresult $::mysqlink rows] ne 0} {
		while {[set row [mysqlnext $::mysqlink]] != ""} {
			set checkmots [lindex $row 0]
			if {[string match [string tolower $colonne(mots)] [string tolower $checkmots]]} {
				putserv "notice $nick :\00314Mot invalide ! le mot\003 (\0034$colonne(mots)\0031) et déjà enregistré !"
				return 0
			}
		}
		service:deconnect
	}
	service:connect
	mysqlsel $::mysqlink "INSERT INTO badword (mots, salon) VALUES ('$colonne(mots)', '$colonne(salon)')"
	service:deconnect
	puthelp "privmsg $::back(chan) :$::chanlog(+badword) \00314Sur\003 \0034$chan\0034 \0031\002$hand@$nick\002\0031 (\0037$colonne(mots)\0031)"
}



Bien évidament, j'utilise le "order by mots", uniquement pour ma recherche si "mots" et existant.
Sinon je "insert into" le mot

Je ne c'est pas si je m'exprime bien, et si c'est ce que tu veut me faire comprendre
Ton tri ne te sert à rien si c'est pour vérifier la présence ou l'absence d'une entrée dans la base.
Si tu veux quelque chose de propre, ta requête doit être:
Code :
select count(*) as nb from badword where mots='$colonne(mots)'
Avec ça, tu auras toujours un retour de ta requête qui sera le nombre de lignes dont mots est égal à celui que tu recherches, donc 0 ou 1.
Donc si je comprend bien..

Sa devrais donner ainsi :

tcl
# Proc - Badword #
bind pub o|o .+badword +badword
proc +badword { nick host hand chan arg } {
	set colonne(mots) [string tolower [lindex $arg 0]]
	set colonne(salon) [lindex $arg 1]
	if ![onchan $nick $::back(chan)] {
		putserv "notice $nick :\00314Erreur vous devez être sur\003 \0034$::back(chan)\0034"
		return
	}
	if {$colonne(mots)==""} {
		putserv "notice $nick :\00314Incorrect veuillez mettre un mot\003. Exemple : .+badword \0034connard #salon\0034"
		return 0
	}
	if {![string match #* $colonne(salon)]} {
		putserv "notice $nick :\00314Incorrect veuillez mettre un salon\003. Exemple : \0034#SQL\0034"
		return 0
	}
	service:connect
	mysqlsel $::mysqlink "SELECT * FROM `badword` WHERE mots='$colonne(mots)' and salon='$colonne(salon)'"
	if {[mysqlresult $::mysqlink rows] ne 0} {
		while {[set row [mysqlnext $::mysqlink]] != ""} {
			set checkmots [lindex $row 0]
			set checksalon [lindex $row 1]
			if {[string match [string tolower $colonne(mots)] [string tolower $checkmots]] && [string match $colonne(salon) $checksalon]} {
				putserv "notice $nick :\00314Mot invalide ! le mot\003 (\0034$colonne(mots)\0031) et déjà enregistré sur le salon !"
				return 0
			}
		}
		service:deconnect
	}
	service:connect
	mysqlsel $::mysqlink "INSERT INTO badword (mots, salon) VALUES ('$colonne(mots)', '$colonne(salon)')"
	service:deconnect
	puthelp "privmsg $::back(chan) :$::chanlog(+badword) \00314Sur\003 \0034$chan\0034 \0031\002$hand@$nick\002\0031 (\0037$colonne(mots)\0031)"
}


Non.
Ou oui, selon ce que tu veux faire sans lire ce que je te dis.

J'abandonne.
Heu.. J'ai modifié en fonction de ce que tu as dit..

tcl
mysqlsel $::mysqlink "SELECT * FROM `badword` WHERE mots='$colonne(mots)' and salon='$colonne(salon)'"



J'ai rajouté la condition pour le salon seulement

(08/03/2017, 18:37)CrazyCat a écrit : [ -> ]Ton tri ne te sert à rien si c'est pour vérifier la présence ou l'absence d'une entrée dans la base.
Si tu veux quelque chose de propre, ta requête doit être:
Code :
select count(*) as nb from badword where mots='$colonne(mots)'
Avec ça, tu auras toujours un retour de ta requête qui sera le nombre de lignes dont mots est égal à celui que tu recherches, donc 0 ou 1.
Oui, tu as ajouté un truc et pas revu ton TCL.

Je te dis d'ajouter un count(), qui te permet d'avoir toujours un résultat et donc de ne pas avoir à faire ta boucle: soit nb = 0 et le mot n'est pas présent soit nb > 0 et le mot est présent.

Voici à quoi devrait ressembler ton script si tu avais tout lu / suivi:
tcl
#Proc - Badword #
bind pub o|o .+badword +badword
proc +badword { nick host hand chan arg } {
	set colonne(mots) [string tolower [lindex $arg 0]]
	set colonne(salon) [lindex $arg 1]
	if ![onchan $nick $::back(chan)] {
		putserv "notice $nick :\00314Erreur vous devez être sur\003 \0034$::back(chan)\0034"
		return
	}
	if {$colonne(mots)==""} {
		putserv "notice $nick :\00314Incorrect veuillez mettre un mot\003. Exemple : .+badword \0034connard #salon\0034"
		return 0
	}
	if {![string match #* $colonne(salon)]} {
		putserv "notice $nick :\00314Incorrect veuillez mettre un salon\003. Exemple : \0034#SQL\0034"
		return 0
	}
	service:connect
	set res [mysqlsel $::mysqlink "SELECT count(*) FROM `badword` WHERE mots='$colonne(mots)' and salon='$colonne(salon)'" -list]
	set nb [lindex $res 0]
	service:deconnect
	if {$nb >= 1} {
		putserv "notice $nick :\00314Mot invalide ! le mot\003 (\0034$colonne(mots)\0031) et déjà enregistré sur le salon !"
		return 0
	}
	service:connect
	mysqlsel $::mysqlink "INSERT INTO badword (mots, salon) VALUES ('$colonne(mots)', '$colonne(salon)')"
	service:deconnect
	puthelp "privmsg $::back(chan) :$::chanlog(+badword) \00314Sur\003 \0034$chan\0034 \0031\002$hand@$nick\002\0031 (\0037$colonne(mots)\0031)"
}


Oui excuse moi, j'ai mal lu et suivi ton raisonnement..

En effet en faisant ainsi, la recherche et meilleur !

Par contre petite question

tcl
if {$nb >= 1} {



La le mot et présent, si mot non présent sa deviendrais "<=0" Si je comprend bien ton explication
Non, "=0", ça ne peut pas être inférieur à 0, il s'agit d'un comptage.
Pages : 1 2