Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在varchar字段上执行过程函数_Sql_Sql Server_Function_Tsql - Fatal编程技术网

Sql 在varchar字段上执行过程函数

Sql 在varchar字段上执行过程函数,sql,sql-server,function,tsql,Sql,Sql Server,Function,Tsql,我有一个由两个数据库合并而成的数据集,一个是美国(英制单位),一个是欧洲(公制单位)。我已经清理了两个数据集之间的重复记录,并将数据转换为英寸,但单个数据库同时为美国和欧洲的网络商店提供数据 欧洲网络商店需要以厘米而不是英寸显示单位。对于大多数字段来说,这不是问题,因为测量值存储为整数,并且可以在视图中转换。我想将文本字段中基于英寸的度量值的实例转换为厘米,但我所见过的SQL的唯一自定义函数是基于集合的函数,而不是我需要的传统基于过程的操作,它需要在文本字段中循环 现在的 渴望的 制作此视图时,

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

欧洲网络商店需要以厘米而不是英寸显示单位。对于大多数字段来说,这不是问题,因为测量值存储为整数,并且可以在视图中转换。我想将文本字段中基于英寸的度量值的实例转换为厘米,但我所见过的SQL的唯一自定义函数是基于集合的函数,而不是我需要的传统基于过程的操作,它需要在文本字段中循环

现在的 渴望的
制作此视图时,如何对每条记录执行传统功能(
CUSTOMFUNCTION
)?我有一个标量UDF选项,它嵌套了大量的
CHARINDEX()
REPLACE()
,但是循环会更加灵活。

我修改了提取表值函数,以执行全局搜索、替换和到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

在UI层做这件事可能会更容易些吗?实际上DB不应该关心这样的表示细节——数据显然是文本,不用于计算,因此由UI来国际化内容。我个人希望在界面级别做这件事。不幸的是,我没有参与这方面的工作,目前也没有无法推动它。我个人会将这两组数据存储在单独的列中,因为这是作为Detail和Detail_CM的文本数据。这样,您只需转换一次,而不是每次查询,因为就性能而言,这将是转换的一个主要问题,在任何情况下您都不想逐行执行。One注意:如果你的字符串不超过2500,你可以删除>>>>,master..spt_值N2这绝对是太棒了。我仍在尝试按照某些步骤操作,但这正是我想要的。@Fritz很高兴这很有帮助。如果你有问题,请点击我:)@Fritz确保你使用的是上面列出的版本。我做了一些f进行小的编辑以确保正确replacements@Fritz干得好。2005年?是时候让那个人退休了
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
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