Cómo llamar a la función mysql udf
2) ¿Cómo sabes que UDF es literalmente útil, especialmente cuando necesitas ampliar la funcionalidad del servidor MYSQL? La siguiente tabla ofrece una comparación de las mejores soluciones:
Métodos para acelerar el desarrollo del lenguaje
Métodos para acelerar el desarrollo del lenguaje
Los procedimientos almacenados ralentizan SQL en ~ minutos (para funciones pequeñas)
Los procedimientos almacenados son SQL lentos ~ minutos (para funciones pequeñas)
UDF es rápido C ~ horas
UDF es aproximadamente 10 horas más rápido.
El principal problema de la función nativa fast C es ***
La función nativa fast c es desconocida
En comparación con otras, lento significa lento. En comparación con las declaraciones SQL ordinarias, los procedimientos almacenados siguen siendo muy rápidos.
Una pequeña explicación de la función local: no es esencialmente diferente de UDF. Pero debe escribirse en código de recursos MYSQL y luego volver a compilarse. Esto supondría mucho trabajo y tendría que hacerse con la última versión de MYSQL.
3) Esta parte es fácil. Cuando una UDF esté completa, úsela. Por ejemplo, "Seleccione mi función de la tabla (datos1, datos2)".
4) Escribir UDF
Ahora desarrolle y escriba una UDF:
Cree un nuevo proyecto de biblioteca compartida (en este ejemplo, use VC 6.0 para crear un estándar DLL).
Primero necesitas algunos archivos de encabezado. Estos archivos de encabezado son archivos de encabezado estándar y archivos en el directorio de inclusión del servidor MYSQL.
#ifdef estándar
/*El estándar ha sido definido y no utiliza ninguna función de mysql*/
#includes
# incluye
p>
#Include
#ifdef __WIN__
typedef unsigned _ _ int 64 ulonglong /*Microsoft tipo de 64 bits*/
typedef _ _ int64 longlong
#otherwise
typedef unsigned long long ulonglong
typedef long long longlong
#endif /*__WIN__*/
#De lo contrario
#includes
#includes
#endif
#includes
#includes
static pthread_mutex_t LOCK_hostname
Ahora tienes que decidir qué funcionalidad necesitas. Básicamente hay dos opciones:
¿Es esta función una función agregada? (Aprenderá mucho sobre las funciones agregadas más adelante).
¿Cuál es el tipo de retorno? Hay cuatro opciones:
Descripción del tipo
STRING cadena legal, convertida a tipo char*.
INTEGER es una variable entera ordinaria convertida a un entero de 64 bits.
El Real capta algunos puntos y los convierte al doble.
Tipo DECIAML Esto realmente no termina, MYSQL lo tratará como una cadena.
Ahora hablemos de funciones no agregadas.
Algunas funciones utilizadas por MYSQL cuando se usa UDF deben declararse y ejecutarse, pero primero se deben confirmar algunas estructuras necesarias:
UDF_Initialization:
Descripción del nombre del tipo
My_boolmabe_NULL es 1 si la función puede devolver NULL.
La fracción entera sin signo de una función real.
La longitud máxima larga sin firmar de la función de cadena.
El puntero libre char * ptr hace referencia a los datos de la función.
My_bool const_item 0 si el resultado es independiente,
ARGS UDF:
Descripción del nombre del tipo
Entero sin signo arg_count número de miembros
Una matriz de tipos de miembros de enumeración Item_result * arg_type.
Char ** args es una matriz de punteros a miembros.
Matriz de longitud de miembro *lengths larga sin firmar (para cadenas)
Matriz marcada con char *maybe_null "maybe_null"
Los atributos Char ** son una matriz de punteros apuntando a los atributos del miembro.
Matriz de longitud de atributo de longitud * larga sin firmar
Ahora mire esta función:
Cancelar/inicializar:
contraer extern " C "my_bool MyTest_INIT(UDF_INIT *initid, UDF_ARGS *args,
char *message)
{
//Muy importante El punto es construir recuerdos.
//Requerido
//Se necesita una variable larga para almacenar el número de detección.
//Aunque no hay ningún requisito en este ejemplo
龙龙* i = new 龙龙; //Crear variable
* I = 0; / Establecer valor inicial
//El puntero almacenado como un carácter en la variable del puntero.
//Confirme que no se encontrarán problemas de tipo.
initid- gt;ptr =(char *)I;
//Detecta el formato del miembro.
if(args- gt; arg_count != 1)
{
strcpy(message, "MyTest() requiere un argumento");
Devuelve 1;
}
if(args- gt; arg_type[0]!= INT_RESULT
{
strcpy(mensaje, "MiPrueba() requiere un número entero");
Devuelve 1;
}
Devuelve 0;
extern " C " void MyTest _ deinit(UDF _ INIT * initd)
{
//La memoria asignada debe borrarse aquí
//Introducir una función
Eliminar (longlong *)initid-gt;ptr
}
Función real:
extern " C " long long MyTest(UDF_INIT *initid, UDF_ARGS *args,
char *is_null, char *error)
{
/ *Finalmente , esta es la parte del trabajo real.
Esta función se llama para cada registro y el valor de retorno o un puntero al valor actual se guarda en la variable UDF_ARGS. Tienes que obtener el valor, completar el cálculo y devolver el valor. Tenga en cuenta que se puede acceder a la memoria asignada en MyTest_init a través de la variable UDF_INIT. En este ejemplo, cada valor de esta variable se establece en 5.
*/
return *(longlong *)args- gt; args[0]) 5;
}
Todo completado ! Ahora debes compilar la biblioteca de enlaces y copiarla a un directorio donde el sistema operativo pueda cargarla. Generalmente en WINDOWS, es la ruta de definición de las variables del sistema. Yo personalmente uso el directorio bin del servidor MYSQL. Debe confirmar que otros MySQL no puedan acceder al directorio. Luego confirme todas las funciones requeridas por MYSQL.
Se debe informar MYSQL, y esto debe ser sencillo: ejecute la siguiente instrucción SQL:
Crear función [agregada] MyTest
Devolver [INTEGER | REAL | DECIMAL]SONAME _ bibliotecas _ nombre exacto
Ahora puedes usarlo como cualquier otra característica.
5) Funciones miembro:
Ahora hablemos de funciones miembro. Cuando la UDF es una función miembro, se deben agregar algunas funciones y algunas funciones se usan de diferentes maneras. La secuencia de llamada es:
Llame a yTest_init para asignar memoria (como una UDF normal)
MYSQL clasifica la tabla a través de GROUP BY.
La primera fila de cada grupo llama MyTest_clear.
MyTest_add se llama para la primera columna de cada grupo.
Después de que el grupo cambie o la última columna cambie, llame a MyTest para obtener los resultados.
Repita de 3 a 5 hasta que se hayan procesado todas las columnas.
Llame a MyTest_deinit para borrar la memoria.
Ahora veamos las funciones requeridas por la nueva función agregada. En este ejemplo, simplemente se sumarán todos los valores. (Al igual que la función de suma local)
void MyTest_clear(Inicialización UDF *initid, char *is_null, char *error)
{
/*Will The El total se restablece a 0 para cada nuevo grupo. Por supuesto, debes asignar una variable de tipo longlong en la función de inicio y asignarla al puntero.
*/
*((longlong *)initid- gt;ptr)= 0;
}
void MyTest_add (UDF_initial *initialid, UDF_ARGS*parameters, char *is_null, char *error)
{
//Agrega el valor actual al total de cada columna.
*((longlong *)initid- gt;ptr)= *(longlong *)initid- gt;ptr)
*((longlong *)args- gt;args[ 0]);
}
longlong MyTest(UDF_initial*initialid, UDF_ARGS*parameters, char *is_null, char *error)
{
//Finalmente devuelve el valor total
return *(longlong *)initid- gt;ptr);
}
6 )Otros problemas:
Al escribir algunas UDF complejas, debemos prestar atención a varios problemas:
La función de cadena debe devolver un puntero al resultado, y *resultado y *longitud Establecer la longitud valor del directorio y valor de retorno. Por ejemplo:
memcpy(resultado, "cadena de resultado", 13);
*length = 13
El búfer de resultados creado por MyTest es de 255 palabras; Festival. Si el resultado se guarda dentro. No se preocupe por la asignación de memoria del resultado.
Si la función de cadena necesita devolver una cadena de más de 255 bytes. Debe asignarse con malloc o la nueva función MyTest_init o MyTest y luego liberarse con MyTest_deinit. Puede guardar la dirección de memoria asignada con un puntero a UDF_INIT y reutilizarla en MyTest.
Especifique un retorno de error en la función principal y establezca *error en 1: si MyTest() es cualquier columna y *error se establece en 1, para la columna actual y para la columna actual pasada por MyTest () El valor de esta función es NULL para cualquier solicitud de columna simultánea en la declaración llamada.
Para obtener más información, lea la ayuda en línea de MYSQL.
7) Algunas pautas:
Si realmente desea que la UDF funcione bien, aquí tiene algunas sugerencias :)
No llame a ningún otro programa en el UDF o proceso.
No guardar ninguna información local. (Estos * * * ya se disfrutan en la biblioteca normal)
No asigne ninguna variable global o estática.
Comprueba siempre el tipo de integrantes. Al igual que MYSQL convierte todos los tipos en tipos de caracteres. Si convierte un tipo de carácter en un puntero de número entero, puede producirse un error.
Presta especial atención a la asignación de memoria. Si hay una pérdida de memoria, ¡el servidor colapsará por completo!
8) Modo UDF
La depuración de UDF requiere coraje, porque si hay un problema con UDF, todo el servidor MYSQL fallará cada vez. Entonces escribí una herramienta de línea de comando para resolver este problema. Simplemente ejecútelo e imitará la instrucción de llamada "SELECT" para guardar los resultados en el archivo de la biblioteca, y todas las líneas de resultados se podrán imprimir. Entonces, cuando ocurre algún error con UDF, solo falla el programa, no todo el servidor.