Jump to content

[Minicurso] MySQL en quest


ElRaulxX

Mensajes recomendados

He visto que muchos preguntáis como utilizar querys de sql en quest. Le dije a keko que haría este mini tutorial, y aquí lo tenéis.

Primero de todo decir que esta función no viene por defecto en el metin y es por eso que algunos usuarios la han hecho ellos mismos, pues la utilidad de esta función es muy grande.
Tengo contado tres personas que han publicado esta función: Hanashi, mijago y yuko. Quizá han sido publicadas más, pero solamente recuerdo estas.
A mi parecer, la más practica que he visto hasta ahora es la última versión de mijago y es la que utilizaremos en este Minicurso.


Primero de todo, debemos declarar estas dos funciones en nuestro questlib.lua

 

mysql_query = function(query)	if not pre then		local rt = io.open('CONFIG','r'):read('*all')		pre,_= string.gsub(rt,'.+PLAYER_SQL:%s(%S+)%s(%S+)%s(%S+)%s(%S+).+','-h%1 -u%2 -p%3 -D%4')	end	math.randomseed(os.time())	local fi,t,out = 'mysql_data_'..math.random(10^9)+math.random(2^4,2^10),{},{}	os.execute('mysql '..pre..' --e='..string.format('%q',query)..' > '..fi) -- für MySQL51	-- os.execute('mysql '..pre..' -e'..string.format('%q',query)..' > '..fi) -- für MySQL55	for av in io.open(fi,'r'):lines() do table.insert(t,split(av,'t')) end; os.remove(fi);	for i = 2, table.getn(t) do table.foreach(t[i],function(a,b)		out[i-1]			   = out[i-1] or {}		out[i-1][a]			= tonumber(b) or b or 'NULL'		out[t[1][a]]		   = out[t[1][a]] or {}		out[t[1][a]][i-1]	  = tonumber(b) or b or 'NULL'	end) end	return outendfunction split(str, delim, maxNb)	if str == nil then return str end	if string.find(str, delim) == nil then return { str } end	if maxNb == nil or maxNb < 1 then maxNb = 0 end	local result = {}	local pat = "(.-)" .. delim .. "()"	local nb = 0	local lastPos	for part, pos in string.gfind(str, pat) do		nb = nb + 1		result[nb] = part		lastPos = pos		if nb == maxNb then break end	end	if nb ~= maxNb then result[nb + 1] = string.sub(str, lastPos) end	return resultend

 



ATENCION! Si en nuestro servidor tenemos instalado la versión 5.5 de MySQL debemos borrar esto:

	os.execute('mysql '..pre..' --e='..string.format('%q',query)..' > '..fi) -- für MySQL51

y quitar las -- de aquí:

	--os.execute('mysql '..pre..' -e'..string.format('%q',query)..' > '..fi) -- für MySQL55

La razón es simple, la sintaxis de esta versión de MySQL es distinta.

Ahora tenemos que añadir en quest_functions la función:

mysql_query

La función split no hace falta añadirla en este archivo ya que se utiliza internamente en mysql_query.

Bien, ahora ya tenemos instalada la función de mysql.
Ahora lo más importante: ¿cómo se usa?

Tenemos esta tabla:
Imagen enviada
Como vemos, la tabla se llama 'tablatest' y se encuentra en la db 'test'. Esta tabla posee tres campos, que son 'campo1', 'campo2' y 'campo3'.
Con la función mysql_query llamaremos, añadiremos o modificaremos valores de esta tabla. La sintaxis de mysql_query es la misma que cualquier otra query de mysql que utilicemos (de navicat, php...). Sino sabéis la sintaxis os aconsejo que miréis cursos para aprender. La sintaxis es muy sencilla y no tiene complicación, solo se necesita mirar un poco y lo dominaréis perfectamente. Existen miles de cursos y tutoriales por internet de mysql, tan solo debéis buscarlos.

ATENCION: Para utilizar sentencias que retornen algún tipo de valor (select) debemos asignar la función a una variable. Las demás (update, insert into...) tan solo tenemos que utilizarla como cualquier otra función.

Bien, empecemos. Comenzaremos llamando toda la tabla.

local read = mysql_query("SELECT * FROM test.tablatest")

Esto almacenará en la variable la siguiente tabla:

local read = {[campo1] = {"texto1","texto2","texto3"},[campo2] = {"texto4","texto5","texto6"},[campo3] = {"texto7","texto8","texto9"}}

Teniendo esto en cuenta, y sabiendo un poco de tablas y arrays en lua está todo solucionado.
Queremos mostrar en pantalla 'texto5' que está almacenado en nuestra tabla. Lo llamaremos de esta manera.

local read = mysql_query("SELECT * FROM test.tablatest")say(read.campo2[2])--esto muestra texto5

Ahora queremos llamar 'texto9':

local read = mysql_query("SELECT * FROM test.tablatest")say(read.campo3[3])--esto muestra texto9

Ahora queremos llamar 'texto1':

local read = mysql_query("SELECT * FROM test.tablatest")say(read.campo1[1])--esto muestra texto1

Aquí no voy a ponerme a explicar arrays porqué no trata de eso el curso, pero creo que mirando los ejemplos y pensando un poco lo entenderéis.

Ahora también podemos añadir una condición:

local read = mysql_query("SELECT * FROM test.tablatest WHERE campo2 = 'texto5'")

Esto almacenará en la variable la siguiente tabla:

local read = {[campo2] = {"texto4","texto5","texto6"}}

Y ahora podemos llamarlo de la misma manera que en el ejemplo anterior.
Esto nos mostrará 'texto6' en pantalla.

local read = mysql_query("SELECT * FROM test.tablatest WHERE campo2 = 'texto5'")say(read.campo2[3])--esto muestra texto6

Y para hacerla verdaderamente útil podemos llamar a variables o funciones.

local var = "texto5"local read = mysql_query("SELECT * FROM test.tablatest WHERE campo2 = '"..var.."'")say(read.campo2[3])--esto muestra texto6

Algo importante que hay que decir es que esta función siempre crea tablas y por lo tanto siempre deberemos llamarlo de la misma manera, aunque haya seleccionado un solo valor.

local read = mysql_query("SELECT campo1 FROM test.tablatest WHERE campo1 = 'texto1'")say(read.campo1[1])--esto muestra texto1

Creo que con estos ejemplos ya podéis ver como funciona un select (la verdad es que es bastante difícil explicarlo teniendo en cuenta que no tenéis conocimientos de tablas, pero al menos lo he intentado xd). La mejor manera que veáis su uso es que vayáis haciendo pruebas en navicat y luego trasladarlo a una quest.

Y ahora la segunda parte.
Si queremos añadir nuevos valores lo hacemos de esta manera:

mysql_query("INSERT INTO test.tablatest VALUES ('texto10','texto11','texto12')")

o como hemos hecho antes:

local v1 = "texto10"local v2 = "texto11"local v3 = "texto12"mysql_query("INSERT INTO test.tablatest VALUES ('"..v1.."','"..v2.."','"..v3.."')")

Y nos quedará la tabla así:
Imagen enviada

Y si queremos modificar valores:

mysql_query("UPDATE test.tablatest SET campo1='prueba' WHERE campo1='texto10'")
local x = "prueba"local y = "texto10"mysql_query("UPDATE test.tablatest SET campo1='"..x.."' WHERE campo1='"..y.."'")

Y nos quedaría esto:
Imagen enviada

Sabiendo de mysql no debería ser ninguna complicación, el problema es que no sepáis :huh:
Cuando publiquemos el capítulo de arrays y tablas lo entenderéis todo mejor, no os preocupéis.

Y creo que eso es todo. Saludos!

Enlace para comentar
Compartir en otros sitios

Si por ejemplo, hiciese:

 

local a = select("Triton", "Baron", "Salir")

if a == 1 then

mysql_query("UPDATE player.item_proto SET refine_item='270' WHERE vnum='169'")

elseif a == 2 then

mysql_query("UPDATE player.item_proto SET refine_item='260' WHERE vnum='169'")

end

 

Entonces, haria como si el jugador escogiese la arma que quisiese obtener despues de transformar la primera, me equivoco?

Enlace para comentar
Compartir en otros sitios

Si por ejemplo, hiciese:

 

local a = select("Triton", "Baron", "Salir")

if a == 1 then

mysql_query("UPDATE player.item_proto SET refine_item='270' WHERE vnum='169'")

elseif a == 2 then

mysql_query("UPDATE player.item_proto SET refine_item='260' WHERE vnum='169'")

end

 

Entonces, haria como si el jugador escogiese la arma que quisiese obtener despues de transformar la primera, me equivoco?

 

No existe ningun refine_item si no refined_vnum en el item_proto (aunque imagino que seria solo un ejemplo) pero sí que cambiaría al arma a la que forjaria con esa query.

 

Sin embargo, no estoi seguro de que se pueda cambiar el campo refined_vnum sin tener que hacer un reboot despues en el servidor aunque sea via mysql_query, sería cosa de probarlo.

Enlace para comentar
Compartir en otros sitios

No existe ningun refine_item si no refined_vnum en el item_proto (aunque imagino que seria solo un ejemplo) pero sí que cambiaría al arma a la que forjaria con esa query.

 

Sin embargo, no estoi seguro de que se pueda cambiar el campo refined_vnum sin tener que hacer un reboot despues en el servidor aunque sea via mysql_query, sería cosa de probarlo.

 

Entonces no hay manera de hacer eso sin tener que dar reboot ?

O crear por ejemplo una 2ª columna de refined_vnum y por quest hacer ese tipo de seleccion ?

Enlace para comentar
Compartir en otros sitios

  • 8 months later...
Buenas tardes,
 
Tengo una dudita y es la siguiente, necesito saber la ip de x personaje, pero no se como iria la query para saber la ip dependiendo del nombre del pj, a ver si me echan una mano con eso.
 
Gracias de antemano.
 
EDIT: Ya la hice, esta es: local localip = mysql_query("SELECT ip FROM player.player WHERE name = '"..pc.get_name().."'")
Enlace para comentar
Compartir en otros sitios

  • Dilong locked this tema
Guest
Este tema está cerrado a otras respuestas.
  • Recientemente navegando por este tema   0 miembros

    • No hay usuarios registrados visitando esta página.
×
×
  • Crear nuevo...