2016-08-18 40 views
0

我需要做一個過程,並作爲它的核心點我必須得到一個雙字節字符串的字節長度。但是,當我在我的MySQL v5.5.50實例的過程中使用LENGHT()函數時,出現非常奇怪的原因,我得到了字符總數......不是字符串的字節數。在Prodedure中的MySQL函數LENGTH()不返回字符串長度作爲字節

這是在 「測試」 功能(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)'返回'225'而不是'50081'。 – Barmar

回答

1
  • 請看SHOW CREATE PROCEDURE我想你會發現假設爲CHARACTER SET latin1,而不是utf8。
  • latin1中,à只有1個字節(十六進制E0)。 utf8將是2個字節(十六進制C3A0)。
  • 將數值返回爲LONGTEXT似乎很奇怪。 (這與問題無關)
+0

我發現了一個workarround,但我正在尋找一個優雅的解決方案。我的事情是在函數的聲明。 'DROP FUNCTION IF EXISTS prueba; DELIMITER // CREATE FUNCTION prueba(cadena VARCHAR(256))RETURN LONGTEXT BEGIN RETURN LENGTH(CONVERT(cadena USING utf8)); END // DELIMITER;' – ViktorWest77

相關問題