Apakah ada cara di T-SQL untuk mentransmisikan nvarchar ke int dan mengembalikan nilai default atau NULL jika konversi gagal?
116
Gunakan fungsi TRY_CONVERT .
Buat fungsi yang ditentukan pengguna. Ini akan menghindari masalah yang disebutkan Fedor Hajdu berkaitan dengan mata uang, angka pecahan, dll:
CREATE FUNCTION dbo.TryConvertInt(@Value varchar(18))
RETURNS int
AS
BEGIN
SET @Value = REPLACE(@Value, ',', '')
IF ISNUMERIC(@Value + 'e0') = 0 RETURN NULL
IF ( CHARINDEX('.', @Value) > 0 AND CONVERT(bigint, PARSENAME(@Value, 1)) <> 0 ) RETURN NULL
DECLARE @I bigint =
CASE
WHEN CHARINDEX('.', @Value) > 0 THEN CONVERT(bigint, PARSENAME(@Value, 2))
ELSE CONVERT(bigint, @Value)
END
IF ABS(@I) > 2147483647 RETURN NULL
RETURN @I
END
GO
-- Testing
DECLARE @Test TABLE(Value nvarchar(50)) -- Result
INSERT INTO @Test SELECT '1234' -- 1234
INSERT INTO @Test SELECT '1,234' -- 1234
INSERT INTO @Test SELECT '1234.0' -- 1234
INSERT INTO @Test SELECT '-1234' -- -1234
INSERT INTO @Test SELECT '$1234' -- NULL
INSERT INTO @Test SELECT '1234e10' -- NULL
INSERT INTO @Test SELECT '1234 5678' -- NULL
INSERT INTO @Test SELECT '123-456' -- NULL
INSERT INTO @Test SELECT '1234.5' -- NULL
INSERT INTO @Test SELECT '123456789000000' -- NULL
INSERT INTO @Test SELECT 'N/A' -- NULL
SELECT Value, dbo.TryConvertInt(Value) FROM @Test
Referensi: Saya menggunakan halaman ini secara ekstensif saat membuat solusi saya.
Iya :). Coba ini:
ISNUMERIC()
memiliki beberapa masalah yang ditunjukkan oleh Fedor Hajdu .Ini mengembalikan nilai true untuk string seperti
$
(adalah mata uang),,
atau.
(keduanya adalah pemisah),+
dan-
.sumber
ISNUMERIC
jawaban ini untuk digunakan pada data yang tidak divalidasi (dan Anda tidak perluISNUMERIC
memeriksa terlebih dahulu untuk data yang divalidasi dengan benar). Penulis mengakui adanya masalah ini tetapi tidak menanganinya.TRY_CONVERT
/TRY_CAST
, yang secara eksplisit dimaksudkan untuk menyelesaikan pertanyaan OP. Jawaban ini ditulis sebelum SQL 2012 dirilis.Saya lebih suka membuat fungsi seperti TryParse atau menggunakan
TRY-CATCH
blok T-SQL untuk mendapatkan apa yang Anda inginkan.ISNUMERIK tidak selalu berfungsi sebagaimana mestinya. Kode yang diberikan sebelumnya akan gagal jika Anda melakukan:
SET @text = '$'
$ sign dapat dikonversi ke tipe data uang, jadi
ISNUMERIC()
mengembalikan true dalam kasus itu. Ini akan melakukan hal yang sama untuk '-' (minus), ',' (koma) dan '.' karakter.sumber
ISNUMERIC()
kembali1
juga untuk,
dan.
.Seperti yang telah disebutkan, Anda mungkin mengalami beberapa masalah jika Anda menggunakan
ISNUMERIC
:Jika Anda menginginkan konversi yang andal, Anda harus membuat kode sendiri.
Pembaruan : Rekomendasi baru saya akan menggunakan konversi uji perantara
FLOAT
untuk memvalidasi nomor. Pendekatan ini berdasarkan komentar adrianm . Logikanya dapat didefinisikan sebagai fungsi nilai tabel sebaris:Beberapa tes:
Hasilnya mirip dengan jawaban Joseph Sturtevant , dengan perbedaan utama berikut:
.
atau,
untuk meniru perilaku pemelukINT
agama asli .'1,234'
dan'1234.0'
kembaliNULL
.'00000000000000001234'
mengevaluasi ke12
. Menambah panjang parameter akan mengakibatkan kesalahan pada angka yang melimpahBIGINT
, seperti BBAN (nomor rekening bank dasar) seperti'212110090000000235698741'
.Ditarik : Pendekatan di bawah ini tidak lagi direkomendasikan, karena ditinggalkan hanya sebagai referensi.
Cuplikan di bawah ini berfungsi pada bilangan bulat non-negatif. Ia memeriksa bahwa string Anda tidak berisi karakter non-digit, tidak kosong, dan tidak meluap (dengan melebihi nilai maksimum untuk
int
tipe tersebut). Namun, ini juga memberikanNULL
bilangan bulat valid yang panjangnya melebihi 10 karakter karena angka nol di depannya.Jika Anda ingin mendukung sejumlah nol di depan, gunakan di bawah ini.
CASE
Pernyataan bertingkat , meskipun berat, diperlukan untuk mempromosikan evaluasi hubung singkat dan mengurangi kemungkinan kesalahan (timbul, misalnya, dari meneruskan panjang negatif keLEFT
).Jika Anda ingin mendukung bilangan bulat positif dan negatif dengan sejumlah nol di depan:
sumber
Salam.
Saya menulis fungsi skalar yang berguna untuk mensimulasikan fungsi TRY_CAST dari SQL SERVER 2012 di SQL Server 2008.
Anda dapat melihatnya di tautan berikutnya di bawah dan kami saling membantu untuk memperbaikinya. Fungsi TRY_CAST untuk SQL Server 2008 https://gist.github.com/jotapardo/800881eba8c5072eb8d99ce6eb74c8bb
Contoh:
Untuk saat ini hanya mendukung tipe data INT, DATE, NUMERIC, BIT dan FLOAT
Saya harap Anda merasa berguna.
KODE:
sumber
Jawaban Joseph menunjukkan ISNUMERIC juga menangani notasi ilmiah seperti '1.3e + 3' tetapi jawabannya tidak menangani format angka ini.
Mentransmisikan uang atau float terlebih dahulu menangani masalah mata uang dan ilmiah:
Fungsi akan gagal jika angkanya lebih besar dari bigint.
Jika Anda ingin mengembalikan nilai default yang berbeda, biarkan fungsi ini jadi generik dan ganti null setelahnya:
sumber
Saya tahu ini tidak cantik tapi sederhana. Coba ini:
sumber
Solusi saya untuk masalah ini adalah membuat fungsi yang ditunjukkan di bawah ini. Persyaratan saya termasuk bahwa nomor tersebut harus berupa bilangan bulat standar, bukan BIGINT, dan saya harus mengizinkan bilangan negatif dan bilangan positif. Saya belum menemukan keadaan di mana ini gagal.
sumber