【问题标题】:Selecting Multiple Substrings from a Field从字段中选择多个子字符串
【发布时间】:2013-05-20 00:22:48
【问题描述】:

我正在尝试创建一个从字段中选择记录片段的 SQL 查询。以下是一个未编辑字段中内容的简短示例:

<Name>Example1</Name>
<Type>String</Type>
<Nullable>False</Nullable>
<AllowBlank>False</AllowBlank>
<Prompt>Start Date (DD-MMM-YYYY)</Prompt> 
<PromptUser>True</PromptUser>    </Parameter>    
<Parameter> 
<Name>Example2</Name>      
<Type>String</Type>      
<Nullable>False</Nullable>      
<AllowBlank>False</AllowBlank>
<Prompt>Case (Enter Case Number, % for all, OR %AL% for Alberta)</Prompt>      
<PromptUser>True</PromptUser>      
<DefaultValues>        
<Value>%al%</Value>      
</DefaultValues>      
<Values>        
<Value>%al%</Value>      
</Values>    </Parameter>    
<Parameter>

完全一团糟,好吧,我正在尝试提取所有名称、提示,如果它有一个值,那么它的值并将所有这些放入一个格式化的字段中。例如上面的字段应该是这样的

Name: Example1
Prompt: Start Date (DD-MMM-YYYY)
Name: Example2
Prompt: Case (Enter Case Number, % for all, OR %AL% for Alberta)
Value: %al%

我尝试过使用 STUFF,但在单个字段中可以有任意数量的带有提示和值的名称。我的下一个想法是使用替换来替换所有 但这会让我留下像这样的东西

Name: Example1
String
False
False
Prompt: Start Date (DD-MMM-YYYY)
Name: Example2     
String      
False     
False
Prompt: Case (Enter Case Number, % for all, OR %AL% for Alberta)    
True  
Value: %al% 
%al%

编辑:另一个可能解决问题的想法是,如果我可以使用 REPLACE 替换两个已知字符/字符串之间或连同两个已知字符/字符串一起替换的未知长度字符串,例如替换 &lt;Type&gt;###&lt;/Type&gt; 其中 ### 表示中间的任意数量的字符两个已知字符串 和 。问题是我不知道这是否可能,或者如果可能的话,该怎么做。

欢迎提出任何建议。

【问题讨论】:

  • 您使用的是哪个 RDBMS?
  • 我正在使用 Microsoft SQL Server Management Studio,SQL server 2008 r2
  • 显示您尝试过的代码。
  • 我正在尝试上传一些代码,但它不允许我,而是在我尝试保存编辑时出错
  • 我现在尝试的代码是一个巨大的嵌套 REPLACE 语句,与此类似,只是有更多替换“REPLACE(REPLACE(CONVERT(varchar(8000), cc.[Parameter]), ' ', 'Parameter: '),'', 'Prompt: ')" 它给出的输出类似于上面最后一个示例输出中的输出。我仍然无法保存我的问题的代码。

标签: sql replace sql-server-2008-r2 substring case


【解决方案1】:

这就是我想出的。我希望它有所帮助。基本上它会查找标签,如果它是一个结束标签,它会删除它,如果它是一个开放标签,它会被标签变体替换。

declare @var nvarchar(max)
declare @tag nvarchar(max)
declare @label nvarchar(max)
declare @start int
declare @stop int
declare @len int

set @var = '<Name>Example1</Name>
<Type>String</Type>
<Nullable>False</Nullable>
<AllowBlank>False</AllowBlank>
<Prompt>Start Date (DD-MMM-YYYY)</Prompt> 
<PromptUser>True</PromptUser>        
<Parameter> </Parameter>
<Name>Example2</Name>      
<Type>String</Type>      
<Nullable>False</Nullable>      
<AllowBlank>False</AllowBlank>
<Prompt>Case (Enter Case Number, % for all, OR %AL% for Alberta)</Prompt>      
<PromptUser>True</PromptUser>      
<DefaultValues>        
<Value>%al%</Value>      
</DefaultValues>      
<Values>        
    <Value>%al%</Value>      
</Values>        
<Parameter></Parameter>'

set @start = charindex('<',@var)
set @stop = charindex('>',@var)
set @len = @stop - @start +1
set @tag = substring(@var,@start,@len)
set @label = substring(@var,@start+1,@len-2)
set @var =  replace(@var,@tag,@label + ' : ')

while(@start <> 0)
begin
set @start = charindex('<',@var)
set @stop = charindex('>',@var)
set @len = @stop - @start +1
    if(@start <> 0)
    begin
        set @tag = substring(@var,@start,@len)      
        if(charindex('/',@tag) = 0)
        begin
            set @label = substring(@var,@start+1,@len-2)+ ' : '
        end
        else
        begin
            set @label = ''
        end
        set @var = replace(@var,@tag,@label)
    end
end

print @var

这会导致: 名称:Example1 类型:字符串 可空:假 允许空白:假 提示:开始日期 (DD-MMM-YYYY) 提示用户:真
参数:
名称:Example2
类型:字符串
可空:假
允许空白:假 提示:案例(输入案例编号,全部输入 %,或阿尔伯塔省 %AL%)
提示用户:真
默认值:
值:%al%

价值观:
值:%al%

参数:

【讨论】:

  • 感谢您的代码,您的输出与我正在寻找的内容相似,尽管我只寻找字段中的名称、提示和值。在该列中还有多条具有这些值的记录,我需要提取出来,所以我不能 100% 确定如何为此设置 @var,但我会继续尝试。感谢您到目前为止的帮助,如果您或其他任何人能想到一种方法或其他帮助,请发布。
【解决方案2】:

我更改了代码,以便只保存名称、提示和值部分。

虽然我更改了 notepad++ 中的代码,但有一点警告,所以它可能有错误。 这个想法是你把这段代码放在一个函数中,并将@var部分作为参数传递。

declare @var nvarchar(max)
declare @tag nvarchar(max)
declare @label nvarchar(max)
declare @start int
declare @stop int
declare @len int
declare @needed int

set @var = '<Name>Example1</Name>
<Type>String</Type>
<Nullable>False</Nullable>
<AllowBlank>False</AllowBlank>
<Prompt>Start Date (DD-MMM-YYYY)</Prompt> 
<PromptUser>True</PromptUser>        
<Parameter> </Parameter>
<Name>Example2</Name>      
<Type>String</Type>      
<Nullable>False</Nullable>      
<AllowBlank>False</AllowBlank>
<Prompt>Case (Enter Case Number, % for all, OR %AL% for Alberta)</Prompt>      
<PromptUser>True</PromptUser>      
<DefaultValues>        
<Value>%al%</Value>      
</DefaultValues>      
<Values>        
    <Value>%al%</Value>      
</Values>        
<Parameter></Parameter>'

set @start = charindex('<',@var)
set @stop = charindex('>',@var)
set @len = @stop - @start +1
set @tag = substring(@var,@start,@len)
set @label = substring(@var,@start+1,@len-2)
set @var =  replace(@var,@tag,@label + ' : ')

while(@start <> 0)
begin
    set @start = charindex('<',@var)
    set @stop = charindex('>',@var)
    set @len = @stop - @start +1
    if(@start <> 0)
    begin
        set @tag = substring(@var,@start,@len)      
        if(charindex('/',@tag) = 0)
        begin
            set @label = substring(@var,@start+1,@len-2)+ ' : '
            if(lower(@label) = 'name' or lower(@label) = 'value' or         lower(@label) = 'prompt')
            begin
                set @needed = 1
            end
            else
            begin
                set @needed = 0
            end
        end
        else
        begin
            set @label = ''
        end

        if(@needed = 1)
        begin
            set @var = replace(@var,@tag,@label)
            end
                else
                begin
                    set @var = replace(@var,@tag,'')
                    set @start = @stop
                    set @stop = charindex('<',@var)
                    set @tag = substring(@var,@start,@stop)
                set @var = replace(@var,@tag,'')
            end
        end
    end

    print @var

【讨论】:

  • 抱歉回复晚了。试过了,但它给出的错误是传递给子字符串函数的参数长度无效,在玩弄它之后我发现 if 语句 if(lower(label) = 'name' 或 lower(label) = 'value ' 或 lower(label) = 'prompt') 不起作用,因为它只设置为 1 时,由于某些未知原因,它不是其他名称的名称,此外 len 正在获得负值,这可能是由if 语句。我尝试应用类似的解决方案,但 if 语句再次不起作用。到目前为止,谢谢。
  • 在玩了一些之后,我发现 if 语句根本不起作用, name: 出现在我的版本上的唯一原因是因为我确实在循环之外命名
【解决方案3】:

所以我用 management studio 检查了代码,发现了一些错误。

declare @var nvarchar(max)
declare @tag nvarchar(max)
declare @label nvarchar(max)
declare @start int
declare @stop int
declare @len int
declare @needed int

set @var = '<Name>Example1</Name>
<Type>String</Type>
<Nullable>False</Nullable>
<AllowBlank>False</AllowBlank>
<Prompt>Start Date (DD-MMM-YYYY)</Prompt> 
<PromptUser>True</PromptUser>        
<Parameter> </Parameter>
<Name>Example2</Name>      
<Type>String</Type>      
<Nullable>False</Nullable>      
<AllowBlank>False</AllowBlank>
<Prompt>Case (Enter Case Number, % for all, OR %AL% for Alberta)</Prompt>      
<PromptUser>True</PromptUser>      
<DefaultValues>        
<Value>%al%</Value>      
</DefaultValues>      
<Values>        
    <Value>%al%</Value>      
</Values>        
<Parameter></Parameter>'

set @needed = 0
set @start = charindex('<',@var)
set @stop = charindex('>',@var)
set @len = @stop - @start +1
set @tag = substring(@var,@start,@len)
set @label = substring(@var,@start+1,@len-2)
set @var =  replace(@var,@tag,@label + ' : ')

while(@start <> 0)
begin
    set @start = charindex('<',@var)
    set @stop = charindex('>',@var)
    set @len = @stop - @start +1
    if(@start <> 0)
    begin   
        set @tag = substring(@var,@start,@len)      
        if(charindex('/',@tag) = 0)
            begin
                set @label = substring(@var,@start+1,@len-2)+ ' : '     
                if(lower(@label) <> 'name : ' and lower(@label) <> 'value : ' and lower(@label) <> 'prompt : ')
                begin
                    set @needed = 0
                    set @var = replace(@var,@tag,'')
                    set @start = @stop - len(@tag)              
                    set @stop = charindex('<',@var)
                    set @len = @stop - @start
                    set @tag = substring(@var,@start,@len)                                      
                    set @var = replace(@var,@tag,'')
                end             
            end
        else
            begin
                set @label = ''
            end
        set @var = replace(@var,@tag,@label)
    end
end
print replace(@var,'
','')

这会导致: 名称:Example1 提示:开始日期 (DD-MMM-YYYY)
名称:Example2
提示:案例(输入案例编号,全部输入 %,或阿尔伯塔省 %AL%)值:
%al%

【讨论】:

  • 使用此代码的略微修改版本解决了问题。自从我做任何与 SQL 相关的事情以来已经有一年了,所以被扔进这个问题就像被扔进了鲨鱼缸一样。非常感谢您帮助解决这个问题,如果没有您的帮助,我几乎不会以同样快的速度解决它。
  • 不客气。很高兴我能帮助你。如果问题得到解决,请标记答案或提交您的最终代码作为答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-12
  • 2018-05-25
  • 1970-01-01
  • 2014-10-24
  • 2014-11-25
  • 1970-01-01
  • 2014-12-07
相关资源
最近更新 更多