You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将SQL字符串解析函数内联至长查询以适配新系统?

问题:将SQL字符串解析函数内联到查询中

我们正在把一条包含复杂字符串解析函数的长SQL SELECT语句移植到新系统,但新平台不支持移植外部函数,需要把[dbo].fn_parseformattedstring函数内联到查询里。


原查询伪代码

SELECT 
    812_ACT_RM.R1_ACT,
    812_ACT_RM.R1_FIRST,
    -- ... 其他更多字段
JOIN 
    (SELECT 
         W_N9R.W_N9_IDSF, 
         dbo.fn_parseformattedstring(1, W_N9R.W_N9_IDSF) AS KOX
    )
    -- ... 其他更多关联逻辑

原函数定义

create function [dbo].fn_parseformattedstring(@format_id int,@str_in as varchar(max))
returns varchar(200)
as
begin
declare @str_out as varchar(max)
declare @idx integer
declare @idy integer

set @str_out = ''
If @format_id = 1 -- Date(s): {October 4, 5, 6 and December 8, 2010}  Time:
begin
        set @idx = CHARINDEX('Date(s):', @str_in)
        If @idx > 0 
        begin
           If len(@str_in) >  @idx + len('Date(s):')
           begin
              set @idx = @idx+ len('Date(s):')
              set @idy = CHARINDEX('Time',@str_in,@idx)  -- added @idx parameter
              If @idy > 0  
                set @str_out = RTRIM(LTRIM(SUBSTRING(@str_in, @idx, @idy-@idx)))
            end
        end
                
        set @idx = CHARINDEX('Date:', @str_in)
        If @idx > 0 
        begin
           If len(@str_in) >  @idx + len('Date:')
           begin
              set @idx = @idx+ len('Date:')
              set @idy = CHARINDEX('Time',@str_in,@idx)
              If @idy > 0  
                set @str_out = RTRIM(LTRIM(SUBSTRING(@str_in, @idx, @idy-@idx)))
            end
        end 
            
        set @idx = CHARINDEX('Dates:', @str_in)
        If @idx > 0 
        begin
           If len(@str_in) >  @idx + len('Dates:')
           begin
              set @idx = @idx+ len('Dates:')
              set @idy = CHARINDEX('Time',@str_in,@idx)
              If @idy > 0  
                set @str_out = RTRIM(LTRIM(SUBSTRING(@str_in, @idx, @idy-@idx)))
            end
        end 
            
end

If @format_id = 2 -- Time: {8:30 AM - 3:30 PM}  Location:
begin

  set @idx = CHARINDEX('Time(s):',@str_in)
  If @idx > 0
  begin
    If len(@str_in) >  @idx + len('Time(s):')
    begin
       set @idx = @idx+len('Time(s):')
       set @idy = CHARINDEX('Location:',@str_in,@idx)
       If @idy > 0  
        set @str_out = RTRIM(LTRIM(SUBSTRING(@str_in, @idx, @idy-@idx)))
     end
   end
   
  set @idx = CHARINDEX('Time:',@str_in)
  If @idx > 0 
  begin
    If len(@str_in) >  @idx + len('Time:')
    begin
       set @idx = @idx+len('Time:')
       set @idy = CHARINDEX('Location',@str_in,@idx)
       If @idy > 0  
        set @str_out = RTRIM(LTRIM(SUBSTRING(@str_in, @idx, @idy-@idx)))
     end
   end
   
  set @idx = CHARINDEX('Times:',@str_in)
  If @idx > 0 
  begin
    If len(@str_in) >  @idx + len('Times:')
    begin
     set @idx = @idx+len('Times:')
     set @idy = CHARINDEX('Location',@str_in,@idx)
     If @idy > 0  
     set @str_out = RTRIM(LTRIM(SUBSTRING(@str_in, @idx, @idy-@idx)))
     end
   end
   
   
end
   return  cast(@str_out as varchar(200))
end

内联后的查询(针对format_id=1的情况)

直接替换原查询中调用函数的部分,复刻原函数逻辑:

SELECT 
    812_ACT_RM.R1_ACT,
    812_ACT_RM.R1_FIRST,
    -- ... 其他更多字段
JOIN 
    (SELECT 
         W_N9R.W_N9_IDSF,
         -- 内联format_id=1的解析逻辑
         CAST(
             CASE
                 -- 先匹配'Date(s):'的情况
                 WHEN CHARINDEX('Date(s):', W_N9R.W_N9_IDSF) > 0 
                      AND LEN(W_N9R.W_N9_IDSF) > CHARINDEX('Date(s):', W_N9R.W_N9_IDSF) + LEN('Date(s):')
                      AND CHARINDEX('Time', W_N9R.W_N9_IDSF, CHARINDEX('Date(s):', W_N9R.W_N9_IDSF) + LEN('Date(s):')) > 0
                 THEN RTRIM(LTRIM(SUBSTRING(W_N9R.W_N9_IDSF, 
                                           CHARINDEX('Date(s):', W_N9R.W_N9_IDSF) + LEN('Date(s):'),
                                           CHARINDEX('Time', W_N9R.W_N9_IDSF, CHARINDEX('Date(s):', W_N9R.W_N9_IDSF) + LEN('Date(s):')) 
                                           - (CHARINDEX('Date(s):', W_N9R.W_N9_IDSF) + LEN('Date(s):'))
                                          )))
                 -- 再匹配'Date:'的情况
                 WHEN CHARINDEX('Date:', W_N9R.W_N9_IDSF) > 0 
                      AND LEN(W_N9R.W_N9_IDSF) > CHARINDEX('Date:', W_N9R.W_N9_IDSF) + LEN('Date:')
                      AND CHARINDEX('Time', W_N9R.W_N9_IDSF, CHARINDEX('Date:', W_N9R.W_N9_IDSF) + LEN('Date:')) > 0
                 THEN RTRIM(LTRIM(SUBSTRING(W_N9R.W_N9_IDSF, 
                                           CHARINDEX('Date:', W_N9R.W_N9_IDSF) + LEN('Date:'),
                                           CHARINDEX('Time', W_N9R.W_N9_IDSF, CHARINDEX('Date:', W_N9R.W_N9_IDSF) + LEN('Date:')) 
                                           - (CHARINDEX('Date:', W_N9R.W_N9_IDSF) + LEN('Date:'))
                                          )))
                 -- 最后匹配'Dates:'的情况
                 WHEN CHARINDEX('Dates:', W_N9R.W_N9_IDSF) > 0 
                      AND LEN(W_N9R.W_N9_IDSF) > CHARINDEX('Dates:', W_N9R.W_N9_IDSF) + LEN('Dates:')
                      AND CHARINDEX('Time', W_N9R.W_N9_IDSF, CHARINDEX('Dates:', W_N9R.W_N9_IDSF) + LEN('Dates:')) > 0
                 THEN RTRIM(LTRIM(SUBSTRING(W_N9R.W_N9_IDSF, 
                                           CHARINDEX('Dates:', W_N9R.W_N9_IDSF) + LEN('Dates:'),
                                           CHARINDEX('Time', W_N9R.W_N9_IDSF, CHARINDEX('Dates:', W_N9R.W_N9_IDSF) + LEN('Dates:')) 
                                           - (CHARINDEX('Dates:', W_N9R.W_N9_IDSF) + LEN('Dates:'))
                                          )))
                 -- 无匹配返回空字符串
                 ELSE ''
             END AS VARCHAR(200)
         ) AS KOX
    ) AS SubQueryAlias -- 替换为原查询中子查询的实际别名
    -- ... 其他更多关联逻辑

说明

  • 代码完全复刻原函数@format_id=1时的执行顺序和逻辑,保证输出结果和原函数一致
  • 若后续需要使用@format_id=2的逻辑,只需将CASE块替换为原函数中对应Time相关的匹配规则即可
  • 保持原查询其他部分不变,直接替换函数调用区域即可正常运行

内容的提问来源于stack exchange,提问作者dgo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 18:34:56