在varchar字段上执行过程函数

时间:2017-03-30 13:41:40

标签: sql sql-server function tsql

我有一个从两个数据库合并的数据集,一个是美国(英制单位),一个是欧洲(公制单位)。我清理了两个数据集之间重复的记录,并将数据转换为英寸,但单个数据库同时提供美国网上商店和欧洲网上商店。

欧洲网上商店需要以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(),但循环会更加灵活。

1 个答案:

答案 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

<强>返回

enter image description here

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