0

I have a string of data

'["Dog",,,1,"Person","2020-03-17",,4,"Todd]'

I am trying to use the replace function to replace double commas with NULL values

Solution

'["Dog",NULL,NULL,1,"Person","2020-03-17",NULL,4,"Todd]'

But I keep ending up with

'"Dog",NULL,,1,"Person","2020-03-17",NULL,4,"Todd'

(The ,,, needs to become ,NULL,NULL, but only becomes ,NULL,,)

Here is my sample code I'm using

   REPLACE(FileData, ',,' , ',NULL,')
   WHERE FileData LIKE '%,,%'
4
  • Presumably, that code is part of an update or select, so it actually does something. Commented Mar 23, 2020 at 17:15
  • For the example you've given, the code works: DB<>Fiddle Commented Mar 23, 2020 at 17:16
  • @GordonLinoff yes it will be part of an update statement. Commented Mar 23, 2020 at 17:20
  • @Larnu the issue im facing is when there is three commas of missing data in a row. ',,,' I end up with ,NULL,, Commented Mar 23, 2020 at 17:21

3 Answers 3

3

If you do the same replacement twice, any number of sequential commas will get handled.

REPLACE(REPLACE(FileData, ',,' , ',NULL,'), ',,' , ',NULL,')

The first REPLACE deals with all the odd positions...

',,,,,,,,'` => ',NULL,,NULL,,NULL,,NULL,'

Doing it again will deal with all of the remaining positions.

=> ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,'


Note, by specifically handling a special case of three consecutive commas (as in an other answer here) you won't handle four or five or six, etc. The above solution generalises to Any length of consecutive commas.

To be fully robust, you may also need to consider when there is a missing NULL at the first or last place in the string.

[,ThatOneToMyLeft,and,ThatOneToMyRight,]

A laborious but robust approach could be to replace [, and ,] with [,, and ,,] respectively, then do the double-replacement, then undo the first steps...

REPLACE(
  REPLACE(
    REPLACE(
      REPLACE(
        REPLACE(
          REPLACE(
            FileData,
            '[,',
            '[,,'
          ),
          ',]',
          ',,]'
        ),
        ',,',
        ',NULL,'
      ),
      ',,',
      ',NULL,'
    ),
    ',]',
    ']',
  ),
  '[,',
  '['
)

There are ways to make even that less verbose, but I have to run right now :)

Sign up to request clarification or add additional context in comments.

3 Comments

DECLARE @text varchar(max) = '["Dog",,]' is probably an edge case, but it's good approach. +1
@Zhorov - I'm actually pretty bummed that I didn't deal with that. It's been a long time since I had to deal with comma delimited strings in SQL, but even without the encasing square brackets the solution would be the same...
This is awesome. What was your approach of understanding the odd positions for the first replace?? @MatBailie
1

You can try the following:

REPLACE(REPLACE(FileData, ',,,' , ',NULL,,'), ',,' , ',NULL,')
   Where FileData LIKE '%,,%'

2 Comments

The inner replacement need only be the same as the outer replacement. After all, the inner will then make ,,, into ,NULL,, and then the outer will finish the job. Nesting it as such would also mean that any length of ,,,,,,, will get handled. (',,,,,' => ,NULL,,NULL,,' => ',NULL,NULL,NULL,NULL,')
(Both replacements should be on ,, for maximum benefit. You don't need to handle special cases of three or more sequential commas. Doing it once as the OP has it will deal with all the odd numbered occurrences, 1st, 3rd, etc. Doing it again, in exactly the same way, will deal with All of the remaining occurrences.)
0

You can create a function for your problem solving that associates to string replacement function.

Check this:

update table1
set column1 = dbo.ReplaceEx(column1, ',', 'NULL')
where column1 like '%,,%'

create function dbo.ReplaceEx(@string varchar(2000), @separator varchar(4), @nullValue varchar(10))
returns varchar(4000)
with execute as caller
as
begin
    declare @result varchar(4000);
    set @result = '';

    select @result = concat_ws(@sep, @result,
        case when rtrim(value) = '' then @nullValue
        else case when ltrim(rtrim(value)) = '[' then '[' + @nullValue
        else case when ltrim(rtrim(value)) = ']' then @nullValue + ']'
        else value end end end
     )
    from string_split(@string, @separator);

    return (@result);
end;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.