有沒有辦法參數化響應類型?
它比你想象的更簡單。只需返回VARCHAR並從VARCHAR轉換爲十進制(x,y)即可。你甚至都不需要投 - 你可以直接(只要其持有有效的十進制數據)分配一個VARCHAR到小數列/變量。
我將創建2個功能來代替。 StringToDecimal2執行實際轉換,但返回6個「錯誤代碼」之一。你可以用它來檢查why
一個字符串是否無效。或者使用包裝器dbo.StringToDecimal
,它只是將無效代碼變成NULL。
CREATE FUNCTION [dbo].[StringToDecimal2]
(
@conversionString VARCHAR(12),
@precision int, -- total digits
@scale int -- after decimal point
)
RETURNS VARCHAR(100)
AS
BEGIN
-- remove spaces, we'll allow this error. no need to trim
set @conversionString = REPLACE(@conversionString,' ','')
-- note: 1,234.56 (thousands separated) will be invalid, so will 1,234,56 (European decimals)
-- well, ok, let's clean up the thousands separators. BUT! It will incorrectly scale European decimals
set @conversionString = REPLACE(@conversionString,',','')
-- we don't support scientific notation either, so 1e4 (10,000) is out
if @conversionString like '%[^0-9.+-]%' return 'INVALID1' -- only digits and decimal are valid (plus +-)
if @conversionString like '%.%.%' return 'INVALID2' -- too many decimals
if @conversionString like '_%[+-]%' return 'INVALID3' -- +- symbol not in the first position
if @conversionString like '[.+-]' return 'INVALID4' -- a single character from "+-."
if @conversionString like '[+-].' return 'INVALID5' -- symbol and decimal only
-- add a decimal place so it is easier to work with below
if @conversionString not like '%.%'
set @conversionString = @conversionString + '.'
-- allow decimal places to go only as far as scale
set @conversionString = left(@conversionString, charindex('.', @conversionString)[email protected])
-- ensure the data is within precision number of digits in total
if charindex('.', @conversionString) > @precision - @scale + 1
return 'INVALID6' -- too many digits before decimal
RETURN @conversionString
END
GO
CREATE FUNCTION [dbo].[StringToDecimal]
(
@conversionString VARCHAR(12),
@precision int, -- total digits
@scale int -- after decimal point
)
RETURNS VARCHAR(100)
AS
BEGIN
RETURN case when [dbo].[StringToDecimal2](@conversionString, @precision, @scale) like 'INVALID%'
then null else [dbo].[StringToDecimal2](@conversionString, @precision, @scale) end
END
GO
一些測試:
select [dbo].[StringToDecimal2]('12342342', 9,2)
select convert(decimal(9,2),[dbo].[StringToDecimal]('1234234', 9,2))
select convert(decimal(9,2),[dbo].[StringToDecimal]('12342342', 9,2))
select convert(decimal(9,2),[dbo].[StringToDecimal]('123423.3333', 9,2))
select convert(decimal(20,10),[dbo].[StringToDecimal]('123423sd.3333', 20,10))
select convert(decimal(20,10),[dbo].[StringToDecimal]('123423sd..3333', 20,10))
select convert(decimal(20,10),[dbo].[StringToDecimal]('-123423.3333', 20,10))
select convert(decimal(20,10),[dbo].[StringToDecimal]('+123423..3333', 20,10))
什麼是髒數據實際上是什麼樣子?你是否必須在數據庫中執行此操作?外部的Perl/Python /無論腳本或.NET程序會更容易嗎?你能否通過參數化響應類型來闡明你的意思;你正在轉換_to_不同的數據類型? – Pondlife 2011-02-15 15:50:00