Saya memiliki skenario ini, sepertinya MySQL mengambil nilai desimal terbesar dan mencoba untuk memberikan nilai-nilai lainnya.
Masalahnya adalah bahwa kueri ini dihasilkan oleh perpustakaan eksternal, jadi saya tidak memiliki kendali atas kode ini, setidaknya pada tingkat ini. Apakah Anda punya ide bagaimana cara memperbaikinya?
SELECT 20 AS x
UNION SELECT null
UNION SELECT 2.2;
+------+
| x |
+------+
| 9.9 | -- why from 20 to 9.9
| NULL |
| 2.2 |
+------+
Hasil yang diharapkan
+------+
| x |
+------+
| 20 | -- or 20.0, doesn't matter really in my case
| NULL |
| 2.2 |
+------+
Menambahkan lebih banyak konteks, saya menggunakan Entity Framework 6 dengan perpustakaan ekstensi http://entityframework-extensions.net/ untuk menyimpan perubahan dalam batch, khususnya konteks metode.BulkSaveChanges () ;, perpustakaan ini membuat kueri menggunakan "pilih serikat" .
SELECT 20 UNION SELECT null UNION SELECT 40 UNION SELECT 4.3;
berfungsi dengan baikJawaban:
Sepertinya bug bagi saya dan saya dapat mengonfirmasi perilaku membingungkan ini di:
Jika memungkinkan, Anda dapat melemparkan nilai integer ke ganda:
atau pastikan Anda memiliki nilai ganda terlebih dahulu:
Pengamatan selanjutnya setelah membaca komentar di jawaban @Evan Carroll
Ok, menggunakan nilai int sepertinya tidak menghasilkan kesalahan.
GALAT: Sepertinya output adalah desimal (2,1)
Kesalahan tidak terisolasi ke antarmuka baris perintah, itu ada untuk python2-mysql-1.3.12-1.fc27.x86_64 juga:
Anehnya kesalahan ini hilang jika nol dipindahkan pertama atau terakhir:
Jika nol ditempatkan terlebih dahulu, tipe yang dihasilkan adalah desimal (20,1). Jika null ditempatkan, jenis yang dihasilkan terakhir adalah desimal (3,1)
Kesalahan juga hilang jika kaki lain ditambahkan ke serikat:
jenis desimal yang dihasilkan (20,1)
menambahkan nol lain di tengah mempertahankan kesalahan:
Tetapi menambahkan nol di awal memperbaikinya:
Seperti yang diharapkan, casting nilai pertama ke desimal (3,1) berfungsi.
Akhirnya, secara eksplisit casting ke desimal (2,1) menghasilkan kesalahan yang sama tetapi dengan peringatan:
sumber
SELECT CAST(20 AS DECIMAL) AS x UNION SELECT NULL UNION SELECT 2.2;
20
sebagai020
. Perilaku ini sama di MariaDB 10.2 dan di MySQL 8.0 . Terlihat sangat mirip dengan panjang literal yang mempengaruhi tipe kolom gabungan. Bagaimanapun, ini pasti bug di buku saya.Bug MDEV-15999
Bug MDEV-15999 yang diajukan oleh dbdemon melaporkan ini. Sejak diperbaiki di 10.3.1.
Sifat MySQL / MariaDB yang aneh
Dari dokumen,
Dalam hal ini, mereka melakukan rekonsiliasi
decimal
daninteger
dengan mempromosikan integer kedecimal
yang tidak dapat menampungnya. Saya tahu itu mengerikan, tetapi sama mengerikannya adalah ini diam-diam berperilaku seperti itu.Yang sepertinya membuka jalan untuk masalah ini.
sumber
SELECT cast(20 as signed) UNION SELECT null UNION SELECT 2.2 ;
menghasilkan hasil yang salah (9,9) yang sama. Tetapi jika kita menggunakan "unisgned" di sana semuanya berjalan dengan baik. Go figure ...SELECT -20 UNION SELECT null UNION SELECT 2.2 ;
bekerja dengan benar juga, seperti halnyaSELECT 20. UNION SELECT null UNION SELECT 2.2 ;
2.2
tetapi terlalu sempit untuk dipegang20
. Anda dapat melihat ini dengan mengubah klausa pilih terakhir menjadiCAST(2.2 AS DECIMAL(10,2))
, yang memberikan20.0
sebagai baris pertama (berjalan secara implisitCAST(20 AS DECIMAL(10,2))
).2.2
. Jika Anda mencoba ,select 20000 union select null union select 2.22
dapatkan9999.99
didecimal(6,2)
. Selalu satu digit terlalu pendek untuk menampung nilainyaNULL
nilai di tengah, ia menghitung pendek presisi 1.