我有一个从两个数据库合并的数据集,一个是美国(英制单位),一个是欧洲(公制单位)。我清理了两个数据集之间重复的记录,并将数据转换为英寸,但单个数据库同时提供美国网上商店和欧洲网上商店。
欧洲网上商店需要以CM为单位显示单位,而不是英寸。这对于大多数字段来说不是问题,因为测量值存储为整数并且可以在视图中转换。我想将文本字段中基于英寸的测量实例转换为厘米,但我见过的唯一自定义函数是基于集合的函数,而不是我需要的传统的基于过程的操作,这将涉及循环遍历文本字段。
table productData
id | height | width | detail
00001 | 12 | 18 | Up to 12" of steel
00002 | 24 | 18 | Up to 24" of steel
00003 | 8 | 8 | Brace with multiple 2" x 3" brackets
... | .. | .. | ...
view productData_EU
SELECT
id,
CEILING(height * 5 / 2) height,
CEILING(width * 5 / 2) width,
detail
FROM productData
id | height | width | detail
00001 | 30 | 45 | Up to 12" of steel
00002 | 60 | 45 | Up to 24" of steel
00003 | 20 | 20 | Brace with multiple 2" x 3" brackets
... | .. | .. | ...
view productData_EU
SELECT
id,
CEILING(height * 5 / 2) height,
CEILING(width * 5 / 2) width,
CUSTOMFUNCTION(detail) detail
FROM productData
id | height | width | detail
00001 | 30 | 45 | Up to 30 cm of steel
00002 | 60 | 45 | Up to 60 cm of steel
00003 | 20 | 20 | Brace with multiple 5 cm x 8 cm brackets
... | .. | .. | ...
在制作此视图时,如何在每条记录上执行传统功能(CUSTOMFUNCTION
)?我可以选择标量UDF,它嵌套了很多CHARINDEX()
和REPLACE()
,但循环会更加灵活。
答案 0 :(得分:1)
我修改了我的EXTRACT表值函数来执行全局搜索并替换和转换为CM。假设这是唯一需要的转换。
现在,我不喜欢将TVF转换为标量,但性能应该仍然可观。
这将转换任何以空格开头并以双引号结尾的值。例如,一些值为12“的钢
这可以进一步参数化,但我不想过度设计它
示例强>
Declare @productData table (id varchar(25),height int,width int ,detail varchar(100))
Insert Into @productData values
('00001', 12, 18,'Up to 12" of steel'),
('00002', 24, 18,'Up to 24" of steel'),
('00003', 8, 8,'Brace with multiple 2" x 3" brackets')
Select id
,height = ceiling(height * 5 / 2.0)
,width = ceiling(width * 5 / 2.0)
,detail = [dbo].[CUSTOMFUNCTION1](A.detail)
From @productData A
<强>返回强>
UDF
CREATE FUNCTION [dbo].[CUSTOMFUNCTION1](@String varchar(max))
Returns varchar(max) as
Begin
with cte1(N) As (Select Top (IsNull(DataLength(@String),0)) N=Row_Number() Over (Order By (Select null)) From master..spt_values N1,master..spt_values N2 ),
cte2(N) As (Select 1 Union All Select t.N+DataLength(' ') From cte1 t Where Substring(@String,t.N,DataLength(' ')) = ' '),
cte3(N,L) As (Select S.N,IsNull(NullIf(CharIndex(' ',@String,s.N),0)-S.N,8000) From cte2 S)
Select @String = Replace(@String,' '+RetVal+'"',concat(' ',ceiling(RetVal * 5 / 2.0),' cm'))
From (
Select RetVal = left(RetVal,charindex('"',RetVal)-1)
From (Select *,RetVal = Substring(@String, N, L) From cte3) A
Where charindex('"',RetVal)>1
) R1
Return @String
End