it-swarm.asia

Data Terpotong untuk Kolom

DECLARE float_one, float_two, my_result NUMERIC(7,2)    
my_result = CONVERT(float_one/float_two, DECIMAL(7,2));

Dalam permintaan mysql ini, saya melakukan jenis operasi ini dalam prosedur tersimpan, tetapi lingkungan Linux phpmyadmin melempar peringatan berikut:

Catatan: # 1265 Data terpotong untuk kolom 'float_one' di baris 5

Adakah yang tahu bagaimana saya bisa menyelesaikan masalah ini?

CREATE TABLE IF NOT EXISTS `float_sample` (
      `id` int(11) NOT NULL auto_increment,
      `first_number` float(10,3) default NULL,
      `second_number` float(10,3) default NULL,
      PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;

INSERT INTO `float_sample` (`id`, `first_number`, `second_number`) 
VALUES    (1, 2.900, 1.900),    (2, 3.100, 22.100);

dan prosedurnya

DELIMITER $$
DROP PROCEDURE IF EXISTS float_test$$
CREATE PROCEDURE float_test(IN my_ID INT)  

BEGIN
DECLARE first_float, second_float DECIMAL(10,3);

DECLARE done INT DEFAULT 0;

DECLARE myCursor CURSOR FOR 
        SELECT `first_number`, `second_number`
        FROM `float_sample`
        WHERE `id` = my_ID;

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

OPEN myCursor;
my_loop:LOOP
    FETCH myCursor INTO first_float, second_float;

    IF done = 1 THEN
        LEAVE my_loop;
    END IF;

END LOOP my_loop;
CLOSE myCursor;

-- SELECT first_float, second_float;
END;$$
DELIMITER ;

dan hasilnya

1 70 10:41:36    CALL mytests.float_test(1) 0 row(s) affected, 2 warning(s):
1265 Data truncated for column 'first_float' at row 2
1265 Data truncated for column 'second_float' at row 2  0.032 sec
6
dole doug

Berapa nilai float_one pada saat konversi ???

Perhatikan contoh ini dari MySQL 5.5.12 di Windows

mysql> select convert(20000,decimal(7,2));
+-----------------------------+
| convert(20000,decimal(7,2)) |
+-----------------------------+
|                    20000.00 |
+-----------------------------+
1 row in set (0.00 sec)

mysql> select convert(200000,decimal(7,2));
+------------------------------+
| convert(200000,decimal(7,2)) |
+------------------------------+
|                     99999.99 |
+------------------------------+
1 row in set, 1 warning (0.00 sec)

mysql> show warnings;
+---------+------+-----------------------------------------------------------------------+
| Level   | Code | Message                                                               |
+---------+------+-----------------------------------------------------------------------+
| Warning | 1264 | Out of range value for column 'convert(200000,decimal(7,2))' at row 1 |
+---------+------+-----------------------------------------------------------------------+

1 row in set (0.00 sec)

Mungkin saja data terpotong jika angka yang lebih besar dari 99999,99 ada di float_one. Mungkin, mysql mengonversi float_one dan float_two ke DECIMAL (7,2) secara terpisah sebelum melakukan pembagian. Coba gunakan DECIMAL (10,2) atau lebih besar untuk mengakomodasi nilai besar.

UPDATE 2011-07-25 15:05 EDT

Ada masalah pemotongan yang pasti terjadi di sini

Menurut Manual Referensi MySQL Halaman 442 Ayat 2,

Nilai DECIMAL dan NUMERIC disimpan sebagai string, bukan sebagai angka titik mengambang biner, untuk menjaga ketepatan desimal angka-angka tersebut. Satu karakter digunakan untuk setiap digit nilai, titik deciaml (jika skala> 0) dan tanda - (untuk angka negatif). Jika skalanya adalah 0, nilai DECIMAL dan NUMERIC tidak mengandung titik desimal atau pecahan.

Kisaran maksimum DECIMAL dan NUMERIC sama dengan untuk GANDA, tetapi kisaran aktual untuk kolom DECIMAL atau NUMERIC yang diberikan dapat dibatasi oleh ketepatan dan skala untuk kolom pemberian, Ketika kolom tersebut diberi nilai dengan lebih banyak digit berikut titik desimal daripada yang diizinkan oleh skala yang ditentukan, nilainya dibulatkan ke skala itu. Ketika kolom DECIMAL atau NUMERIC diberikan nilai yang besarnya melebihi kisaran yang tersirat oleh presisi dan skala yang ditentukan (atau default), MySQL menyimpan nilai yang mewakili titik akhir yang sesuai dari rentang tersebut.

Anda perlu mengakomodasi presisi dan/atau skala yang lebih besar.

Berikut ini adalah contoh mengapa

Saya menulis prosedur tersimpan ini menggunakan spesifikasi Anda untuk DECMIAL dan NUMERIC.

DELIMITER $$

DROP PROCEDURE IF EXISTS `test`.`NumTest` $$
CREATE PROCEDURE `test`.`NumTest` (num1 NUMERIC(7,2), num2 NUMERIC(7,2))
BEGIN

  DECLARE float_one,float_two,my_result NUMERIC(7,2);
  DECLARE f1,f2 DOUBLE(7,2);

  SET f1 = num1;
  SET f2 = num2;

  SET float_one = num1;
  SET float_two = num2;

  SELECT f1 / f2;
  SELECT float_one / float_two;
  SELECT CONVERT(float_one / float_two,DECIMAL(7,2));
  SET my_result = CONVERT(float_one / float_two,DECIMAL(7,2));
  SELECT my_result;

END $$

DELIMITER ;

Saya menggunakan dua nilai: 290.0 dan 14.5 untuk tes ini.

Sebelum memanggil prosedur tersimpan NumTest, saya secara manual menghitung 290.0/14.5

mysql> select 290.0 / 14.5;
+--------------+
| 290.0 / 14.5 |
+--------------+
|     20.00000 |
+--------------+
1 row in set (0.00 sec)

Saya membagi setiap angka dengan 100, 10.000, dan 1000000 dan mencoba lagi

mysql> select 2.9 / .145;
+------------+
| 2.9 / .145 |
+------------+
|   20.00000 |
+------------+
1 row in set (0.00 sec)

mysql> select .029 / .00145;
+---------------+
| .029 / .00145 |
+---------------+
|    20.0000000 |
+---------------+
1 row in set (0.00 sec)

mysql> select .00029 / .0000145;
+-------------------+
| .00029 / .0000145 |
+-------------------+
|      20.000000000 |
+-------------------+
1 row in set (0.00 sec)

Sejauh ini bagus !!! Sekarang untuk prosedur tersimpan.

mysql> call numtest(290.0,14.5);
+-----------+
| f1 / f2   |
+-----------+
| 20.000000 |
+-----------+
1 row in set (0.00 sec)

+-----------------------+
| float_one / float_two |
+-----------------------+
|             20.000000 |
+-----------------------+
1 row in set (0.00 sec)

+---------------------------------------------+
| CONVERT(float_one / float_two,DECIMAL(7,2)) |
+---------------------------------------------+
|                                       20.00 |
+---------------------------------------------+
1 row in set (0.00 sec)

+-----------+
| my_result |
+-----------+
|     20.00 |
+-----------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Jadi dua nomor orignal saya berfungsi dengan baik. Mari kita bagi dengan 100 dan coba lagi.

mysql> call numtest(2.9,0.145);
+-----------+
| f1 / f2   |
+-----------+
| 19.333333 |
+-----------+
1 row in set (0.00 sec)

+-----------------------+
| float_one / float_two |
+-----------------------+
|             19.333333 |
+-----------------------+
1 row in set (0.00 sec)

+---------------------------------------------+
| CONVERT(float_one / float_two,DECIMAL(7,2)) |
+---------------------------------------------+
|                                       19.33 |
+---------------------------------------------+
1 row in set (0.00 sec)

+-----------+
| my_result |
+-----------+
|     19.33 |
+-----------+
1 row in set (0.00 sec)

Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> show warnings;
+-------+------+-------------------------------------------+
| Level | Code | Message                                   |
+-------+------+-------------------------------------------+
| Note  | 1265 | Data truncated for column 'num2' at row 2 |
+-------+------+-------------------------------------------+
1 row in set (0.00 sec)

Tunggu, kami kehilangan beberapa presisi. Apa yang terjadi ??? Bagaimana ini bisa terjadi ??? Anda perlu mengakomodasi lebih banyak digit decmial (> 2)

UPDATE 2011-07-25 17:37 EDT

Saya mengganti (7,2) dengan (10,7) dalam prosedur tersimpan dan mendapatkan kembali presisi yang tepat

mysql> call numtest(2.9,0.145);
+----------------+
| f1 / f2        |
+----------------+
| 20.00000000000 |
+----------------+
1 row in set (0.00 sec)

+-----------------------+
| float_one / float_two |
+-----------------------+
|        20.00000000000 |
+-----------------------+
1 row in set (0.01 sec)

+----------------------------------------------+
| CONVERT(float_one / float_two,DECIMAL(10,7)) |
+----------------------------------------------+
|                                   20.0000000 |
+----------------------------------------------+
1 row in set (0.03 sec)

+------------+
| my_result  |
+------------+
| 20.0000000 |
+------------+
1 row in set (0.05 sec)

Query OK, 0 rows affected (0.06 sec)

mysql>
3
RolandoMySQLDBA

Dari apa yang saya lihat prosedur tersimpan Anda hanya loop melalui baris - itu tidak 'menyimpan data' di mana saja dan Anda telah berkomentar keluar select:

- SELECT first_float, second_float;

Ya, Anda mendapatkan peringatan saat bidang float(10,3) dikonversi ke decimal(10,3). Apakah masalah atau tidak tergantung pada apa yang ingin Anda lakukan dengan bidang tersebut.

Apakah ini hanya contoh kode asli? Anda mungkin perlu memposting lagi ...