2016-08-18 7 views
0

プロシージャを作成する必要があり、その中核として、2バイト文字の文字列のバイト長を取得する必要があります。しかし、私のMySQL v5.5.50インスタンス上のプロシージャ内でLENGHT()関数を使用すると非常に奇妙な理由で、私は文字数の合計を取得します....文字列のバイト数ではありません。MySQL関数LENGTH()内のProdedureは文字列の長さをバイトとして返しません

これは、 "テスト" 機能(phpMyAdminのエクスポート)である:

CREATE DEFINER=`root`@`localhost` FUNCTION `prueba`(`cadena` VARCHAR(256)) RETURNS longtext CHARSET latin1 
    NO SQL 
BEGIN 

RETURN LENGTH(cadena); 

END 

この関数は返します

SELECT prueba ("à"); 

prueba ("à") 
============= 
1 

私が間違って何をしているのか?

DROP FUNCTION IF EXISTS TRACKLIST; 
DELIMITER // 
CREATE FUNCTION TRACKLIST(v_codAlbum INT) RETURNS LONGTEXT 

BEGIN 

DECLARE v_finished INTEGER DEFAULT 0; 
DECLARE v_salida LONGTEXT DEFAULT ""; 
DECLARE v_track LONGTEXT DEFAULT ""; 
DECLARE v_artist LONGTEXT DEFAULT ""; 

DECLARE v_total_tracks INTEGER DEFAULT 0; 
DECLARE v_tracknum INTEGER DEFAULT 0; 
DECLARE v_titlelen INTEGER DEFAULT 0; 
DECLARE v_artistlen INTEGER DEFAULT 0; 

DECLARE curs CURSOR FOR 
    SELECT Titulo 
    FROM tracks t1 INNER JOIN artistas t2 
    where t1.IdContenido = t2.IdContenido 
    and idAlbum = v_codAlbum 
    and NumeroTrack > 0 
    order by numerotrack asc; 

DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_finished = 1; 

-- Recupero el numero de Canciones (tracks) 
SELECT count(*) INTO v_total_tracks 
FROM tracks t1 INNER JOIN artistas t2 
where t1.IdContenido = t2.IdContenido 
and idAlbum = v_codAlbum 
and NumeroTrack > 0; 

-- Recupero el nombre del Artista 
SELECT t2.Descripcion INTO v_artist 
FROM albumes t1 INNER JOIN interpretes t2 
WHERE t1.idInterprete = t2.idInterprete 
and t1.idAlbum = v_codAlbum; 

-- Inicializo la estructura de datos de tracklist 
SET v_salida = CONCAT('a:', v_total_tracks, ':{'); 
SET v_tracknum = 0; 

OPEN curs; 

-- Comienzo LOOP para agregar las canciones (tracks) 
get_tracks: LOOP 
    FETCH curs INTO v_track; 
    IF v_finished = 1 THEN 
    LEAVE get_tracks; 
    END IF; 

    -- Calculo el tamaño del string de nombre de cancion y nombre de Artista, necesario para agregar a la estructura de datos 
    SET v_titlelen = LENGTH(v_track); 
    SET v_artistlen = LENGTH(v_artist); 


    -- Estructura de datos con Nombre de Cancion y Nombre de Artista, solo estos datos 
    SET v_salida = CONCAT(v_salida,'i:',v_tracknum,';a:5:{'); 
    SET v_salida = CONCAT(v_salida,'s:24:"releasetrack_track_title";s:',v_titlelen,':"',v_track,'";'); 
    SET v_salida = CONCAT(v_salida,'s:24:"releasetrack_artist_name";s:',v_artistlen,':"',v_artist,'";'); 

    -- Este puto campo es requerido para que todo funcione. 
    SET v_salida = CONCAT(v_salida,'s:21:"releasetrack_mp3_demo";s:0:"";'); 

    -- Estos campos solo son requeridos para que funcione la aplicacion. 
    -- SOLO SE INCLUYEN EN LA CANCION "0" 

    IF v_tracknum = 0 THEN 
    SET v_salida = CONCAT(v_salida,'s:18:"releasetrack_scurl";'); 
    SET v_salida = CONCAT(v_salida,'s:0:"";'); 
    SET v_salida = CONCAT(v_salida,'s:19:"releasetrack_buyurl";'); 
    SET v_salida = CONCAT(v_salida,'s:0:"";'); 
    END IF; 

    -- Cierro Estructura para datos de una cancion 
    SET v_salida = CONCAT(v_salida,'}'); 

    SET v_tracknum = v_tracknum + 1; 
END LOOP get_tracks; 
CLOSE curs; 

-- Cierro Estructura de toda la lista de Canciones 
SET v_salida = CONCAT(v_salida,'}'); 

-- 
RETURN v_salida; 

END// 
DELIMITER ; 

ここ

DETAILS

DETAILS

+1

本当に 'LENGTH()'のスペルミスはありましたか? – Barmar

+0

これは、MySQLで関数を作成するための正しい構文はありません。コマンドは 'CREATE FUNCTION'で、' RETURNS INT'節で戻り値の型を指定する必要があります。構文エラーを報告しない実際の関数定義を表示してください。 – Barmar

+0

問題は、 'cadena'が関数内でマルチバイト文字列として見えていないようです。 'RETURN ORD(cadena)'は '50081'ではなく' 225'を返します。 – Barmar

答えて

1
  • SHOW CREATE PROCEDUREをご覧ください機能文字セットとエンコーディングについての詳細は、次のとおりです。:(

    はこれが本当の仕事関数であります私はあなたがそれを見つけると思う。cadenaはutf8ではなくCHARACTER SET latin1とします。

  • latin1では、àは1バイト(Hex E0)です。 utf8は2バイト(16進数C3A0)になります。
  • 数字をLONGTEXTとして返すのは奇妙に思えます。 (これは質問には関係ありません)
+0

私はworkarroundを見つけましたが、私は洗練されたソリューションを探しています。私はそれが関数の宣言にあることです。 '存在する場合は機能を停止するprueba; DELIMITER // CREATE FUNCTION prueba(cadena VARCHAR(256))RETURN LONGTEXT BEGIN 戻り値(CONVERT(cadena USING utf8)); END // DELIMITER; ' – ViktorWest77

関連する問題