在 SQL Server 中,如何选择位于 SQL 字符串中某个字符之间的所有单词?

huangapple go评论66阅读模式
英文:

How to select all the words between a char in sql string in sql server?

问题

Sure, here's the translated content:

我有一个包含以下示例值的表格

Commands
SELECT - #TRAPAY# Cell 2
SELECT - #OSTLIA#
SELECT ISNULL(CONVERT(VARCHAR(50), #OPCASH# + #ACCREC# + #INVENT# + #OCASS# + #TRAPAY_N# + #OSTLIA_N#), ''-')
SELECT #GTFA#
SELECT #ACCDEP#

我需要提取所有位于#之间的单词。这是否可能?

我尝试使用SUBSTRING,但不是所有单词的长度都完全相同。

英文:

I have a table with a column with these example values

Commands
SELECT - #TRAPAY# Cell 2
SELECT - #OSTLIA#
SELECT ISNULL(CONVERT(VARCHAR(50), #OPCASH# + #ACCREC# + #INVENT# + #OCASS# + #TRAPAY_N# + #OSTLIA_N#), '-')
SELECT #GTFA#
SELECT #ACCDEP#

And I need to extract all the words between the #. Is it possible?

I have tried using SUBSTRING but not all the words have the exact same length.

答案1

得分: 1

你可以创建一个类似这样的函数:

-- 创建一个函数
create function dbo.ufn_extract_words (
  @input nvarchar(2000), @str nvarchar(15)
) returns nvarchar(2000) as begin

  if(@input is null)
    return null;

  if(@str is null)
    return null;

  declare
    @result nvarchar(2000), @len int,
    @start int, @end int;

  select
    @result = '', -- 初始化返回值,不要设置为 null 值*
    @start = charindex(@str, @input), -- 查找第一个匹配项
    @len = len(@str);

  while @start > 0 begin

    -- 查找下一个匹配项
    select @end = charindex(@str, @input, @start + @len);
    if @end = 0 break;

    -- 在前一个单词之后添加逗号,如果不是开头
    if len(@result) > 0 set @result = @result + ',';

    -- 提取单词
    set @result = @result + substring(@input, @start + @len, @end - @start - @len);

    -- 查找下一个起始匹配项
    set @start = charindex(@str, @input, @end + @len);

  end

  return @result;

end;

go

declare @table table (
  Commands nvarchar(2000)
)

insert into @table (Commands) values
  ('SELECT - #TRAPAY#'),
  ('SELECT - #OSTLIA#'),
  ('SELECT ISNULL(CONVERT(VARCHAR(50), #OPCASH# + #ACCREC# + #INVENT# + #OCASS# + #TRAPAY_N# + #OSTLIA_N#), ''''-'''')'),
  ('SELECT #GTFA#'),
  ('SELECT #ACCDEP#');

select Commands, Words = dbo.ufn_extract_words(Commands, '#') from @table;

-- 删除函数
drop function dbo.ufn_extract_words;
go
英文:

You may create a function like this:

-- create a function
create function dbo.ufn_extract_words (
  @input nvarchar(2000), @str nvarchar(15)
) returns nvarchar(2000) as begin

  if(@input is null)
    return null;

  if(@str is null)
    return null;

  declare
    @result nvarchar(2000), @len int,
    @start int, @end int;

  select
    @result = '', -- initialize the return value, don't set to null value*
    @start = charindex(@str, @input), -- find the first match
    @len = len(@str);

  while @start > 0 begin

    -- find the next match
    select @end = charindex(@str, @input, @start + @len);
    if @end = 0 break;

    -- add a comma after the previous word, if not the beginning
    if len(@result) > 0 set @result = @result + ',';

    -- extract word
    set @result = @result + substring(@input, @start + @len, @end - @start - @len);

    -- find the next start match
    set @start = charindex(@str, @input, @end + @len);

  end

  return @result;

end;

go

declare @table table (
  Commands nvarchar(2000)
)

insert into @table (Commands) values
  ('SELECT - #TRAPAY#'),
  ('SELECT - #OSTLIA#'),
  ('SELECT ISNULL(CONVERT(VARCHAR(50), #OPCASH# + #ACCREC# + #INVENT# + #OCASS# + #TRAPAY_N# + #OSTLIA_N#), ''''-'''')'),
  ('SELECT #GTFA#'),
  ('SELECT #ACCDEP#');

select Commands, Words = dbo.ufn_extract_words(Commands, '#') from @table;

-- drop function
drop function dbo.ufn_extract_words;
go

答案2

得分: 0

以下是翻译好的部分:

使用Replace函数来填充#之间的文本
SELECT REPLACE('#TRAPAY#', '#', '')
SELECT REPLACE('#OSTLIA#', '#', '')
SELECT REPLACE('ISNULL(CONVERT(VARCHAR(50), #OPCASH# + #ACCREC# + #INVENT# + #OCASS# + #TRAPAY_N# + #OSTLIA_N#)''''-'''''')', '#', '')
SELECT REPLACE('#GTFA#', '#', '')
SELECT REPLACE('#ACCDEP#', '#', '')

如果您想将单个字符串中的#之间的单词放在不同的行中,请使用STRING_SPLIT
SELECT * FROM STRING_SPLIT('ISNULL(CONVERT(VARCHAR(50), #OPCASH# + #ACCREC# + #INVENT# + #OCASS# + #TRAPAY_N# + #OSTLIA_N#)''''-'''''')', '#') WHERE RTRIM(value) <> ''

下面粘贴了两个输出
SELECT REPLACE('#TRAPAY#', '#', '')
SELECT REPLACE('#OSTLIA#', '#', '')
SELECT REPLACE('ISNULL(CONVERT(VARCHAR(50), #OPCASH# + #ACCREC# + #INVENT# + #OCASS# + #TRAPAY_N# + #OSTLIA_N#)''''-'''''')', '#', '')
SELECT REPLACE('#GTFA#', '#', '')
SELECT REPLACE('#ACCDEP#', '#', '')

| (无列名) |
| :--------|
| TRAPAY   |

| (无列名) |
| :--------|
| OSTLIA   |

| (无列名) |
| :--------|
| ISNULL(CONVERT(VARCHAR(50), OPCASH + ACCREC + INVENT + OCASS + TRAPAY_N + OSTLIA_N)''''-'''''') |

| (无列名) |
| :--------|
| GTFA     |

| (无列名) |
| :--------|
| ACCDEP   |

SELECT * FROM STRING_SPLIT('#TRAPAY#', '#') WHERE RTRIM(value) <> ''
SELECT * FROM STRING_SPLIT('#OSTLIA#', '#') WHERE RTRIM(value) <> ''
SELECT * FROM STRING_SPLIT('ISNULL(CONVERT(VARCHAR(50), #OPCASH# + #ACCREC# + #INVENT# + #OCASS# + #TRAPAY_N# + #OSTLIA_N#)''''-'''''')', '#') WHERE RTRIM(value) <> ''
SELECT * FROM STRING_SPLIT('#GTFA#', '#') WHERE RTRIM(value) <> ''
SELECT * FROM STRING_SPLIT('#ACCDEP#', '#') WHERE RTRIM(value) <> ''
value
TRAPAY
value
OSTLIA
value
ISNULL(CONVERT(VARCHAR(50), OPCASH + ACCREC + INVENT + OCASS + TRAPAY_N + OSTLIA_N)''''-'''''')
value
GTFA
value
ACCDEP

fiddle

英文:

Use Replace Function to populate only text in between the #

SELECT REPLACE(&#39;#TRAPAY#&#39; ,&#39;#&#39;,&#39;&#39;)
SELECT REPLACE(&#39;#OSTLIA#&#39;,&#39;#&#39;,&#39;&#39;)
SELECT REPLACE(&#39;ISNULL(CONVERT(VARCHAR(50), #OPCASH# + #ACCREC# + #INVENT# + #OCASS# + #TRAPAY_N# + #OSTLIA_N#)&#39;&#39;&#39;&#39;, &#39;&#39;&#39;&#39;-&#39;&#39;&#39;&#39;)&#39;,&#39;#&#39;,&#39;&#39;)
SELECT REPLACE(&#39;#GTFA#&#39;,&#39;#&#39;,&#39;&#39;)
SELECT REPLACE(&#39;#ACCDEP#&#39;,&#39;#&#39;,&#39;&#39;)

You one String which contains multiple #. If you want in between words in separate rows, then Use STRING_SPLIT

SELECT * FROM STRING_SPLIT(&#39;ISNULL(CONVERT(VARCHAR(50), #OPCASH# + #ACCREC# + #INVENT# + #OCASS# + #TRAPAY_N# + #OSTLIA_N#)&#39;&#39;&#39;&#39;, &#39;&#39;&#39;&#39;-&#39;&#39;&#39;&#39;)&#39;,&#39;#&#39;) WHERE RTRIM(value) &lt;&gt; &#39;&#39;

Below pasted both outputs

SELECT REPLACE(&#39;#TRAPAY#&#39; ,&#39;#&#39;,&#39;&#39;)
SELECT REPLACE(&#39;#OSTLIA#&#39;,&#39;#&#39;,&#39;&#39;)
SELECT REPLACE(&#39;ISNULL(CONVERT(VARCHAR(50), #OPCASH# + #ACCREC# + #INVENT# + #OCASS# + #TRAPAY_N# + #OSTLIA_N#)&#39;&#39;&#39;&#39;, &#39;&#39;&#39;&#39;-&#39;&#39;&#39;&#39;)&#39;,&#39;#&#39;,&#39;&#39;)
SELECT REPLACE(&#39;#GTFA#&#39;,&#39;#&#39;,&#39;&#39;)
SELECT REPLACE(&#39;#ACCDEP#&#39;,&#39;#&#39;,&#39;&#39;)
(No column name)
TRAPAY
(No column name)
OSTLIA
(No column name)
ISNULL(CONVERT(VARCHAR(50), OPCASH + ACCREC + INVENT + OCASS + TRAPAY_N + OSTLIA_N)'', ''-'')
(No column name)
GTFA
(No column name)
ACCDEP
SELECT * FROM STRING_SPLIT(&#39;#TRAPAY#&#39; ,&#39;#&#39;) WHERE RTRIM(value) &lt;&gt; &#39;&#39;
SELECT * FROM STRING_SPLIT(&#39;#OSTLIA#&#39;,&#39;#&#39;) WHERE RTRIM(value) &lt;&gt; &#39;&#39;
SELECT * FROM STRING_SPLIT(&#39;ISNULL(CONVERT(VARCHAR(50), #OPCASH# + #ACCREC# + #INVENT# + #OCASS# + #TRAPAY_N# + #OSTLIA_N#)&#39;&#39;&#39;&#39;, &#39;&#39;&#39;&#39;-&#39;&#39;&#39;&#39;)&#39;,&#39;#&#39;) WHERE RTRIM(value) &lt;&gt; &#39;&#39;
SELECT * FROM STRING_SPLIT(&#39;#GTFA#&#39;,&#39;#&#39;) WHERE RTRIM(value) &lt;&gt; &#39;&#39;
SELECT * FROM STRING_SPLIT(&#39;#ACCDEP#&#39;,&#39;#&#39;) WHERE RTRIM(value) &lt;&gt; &#39;&#39;
value
TRAPAY
value
OSTLIA
value
ISNULL(CONVERT(VARCHAR(50),
OPCASH
 +
ACCREC
 +
INVENT
 +
OCASS
 +
TRAPAY_N
 +
OSTLIA_N
)'', ''-'')
value
GTFA
value
ACCDEP

fiddle

huangapple
  • 本文由 发表于 2023年6月6日 09:21:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76410881.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定