Substring with conditional statement - sql

tl;dr
I don't understand how to conditionally change the length parameter of SUBSTRING(..)
Short enough, did read
I've got a text field in a sql table that I want to retrieve a substring from
There is a specific part of text I am having trouble retrieving a substring from, because I cannot guarantee the next string.
For example, I have:
... Tracking Code : /a/delimited/string AttributeW : ValueW ...
And
... Tracking Code : /a/different/delimited/string A random string ...
From both of those i want /a/delimited/string and /a/different/delimited/string respectively
My current sql looks something like:
DECLARE #TrackingStartStr VARCHAR(50), #TrackingEndStr VARCHAR(50)
SET #TrackingStartStr = 'Tracking Code :'
SET #TrackingEndStr = 'Some string that indicates the text is about to end'
SELECT
AField
,RTRIM(LTRIM(Substring(CAST([Body] AS VARCHAR(MAX))
,Charindex(#TrackingStartStr,CAST([Body] AS VARCHAR(MAX))) + LEN(#TrackingStartStr)
,charindex(#TrackingEndStr,CAST([Body] AS VARCHAR(MAX))) - (Charindex(#TrackingStartStr,CAST([Body] AS VARCHAR(MAX))) + LEN(#TrackingStartStr))
))) AS TrackingCode
From tbl_stupidTextTable
I don't know how to conditionally change what #TrackingEndStr is for each row.

Try:
select substring(stringfield,
charindex('/', stringfield, 1),
charindex(' ',
stringfield,
charindex('/', stringfield, 1)) -
charindex('/', stringfield, 1)) as val
from tbl
SQL Fiddle demo: http://sqlfiddle.com/#!6/cebab/16/0

Related

Get part of the string between 2 different strings

I'm using SQL-Server 2008 R2.
First of all, I want to tell you that's I know that store strings like this is super bad practice, but as I'm SQL developer I don't have an ability to change it, the software of third-party generating output and inserting to the database like this.
Explanation
Sample value looks like:
Name: 'Document No. 996'
Unique No: 'A 54 x. 488sCHU'
No 2: 'RF123456789'
String 'This is dynamic text' value 'test' wrong data
Values 'ETC1 ETC2'.
Note: this is 1 value (1 column, 1 row)
As you see above, the structure is like: After word Name is added : then in single quotes, then some document no, after it line break and so on.
What I need (desired results)
I need to extract from that string this part: String 'This is dynamic text'.
This part always starts with word String, after it will be 1 space and in single quotes will be some text.
So it looks like I have look between 2 chars, first would be String ' and second '.
I have to use maybe SUBSTRING and CHARINDEX, but in anyway I can't achieve it.
What I've tried
There is sample data and what I've tried, just without success:
DECLARE #c varchar(100)
SET #c = 'Name: ''Document No. 996''
Unique No: ''A 54 x. 488sCHU''
No 2: ''RF123456789''
String ''This is dynamic text'' value ''test'' wrong data
Values ''ETC1 ETC2''.'
SELECT SUBSTRING(STUFF(#c, 1, CHARINDEX('String ''',#c), ''), 0, CHARINDEX('''', STUFF(#c, 1, CHARINDEX('String ''',#c), '')))
You can use it
DECLARE #c varchar(1000)
SET #c = 'Name: ''Document No. 996''
Unique No: ''A 54 x. 488sCHU''
No 2: ''RF123456789''
String ''This is dynamic text'' value ''test'' wrong data
Values ''ETC1 ETC2''.'
SELECT SUBSTRING( #c, CHARINDEX('String ''',#c) , CHARINDEX('''', #c, CHARINDEX('String ''',#c)+8 ) - CHARINDEX('String ''',#c)+1)
Result:
String 'This is dynamic text'
DECLARE #c varchar(255) --100 will truncate your string
SET #c = 'Name: ''Document No. 996''
Unique No: ''A 54 x. 488sCHU''
No 2: ''RF123456789''
String ''This is dynamic text'' value ''test'' wrong data
Values ''ETC1 ETC2''.'
Here is solution split in two parts for better understanding. First part is to find substring that starts with String keyword and goes until the end of the original string. We store it #c1, to reuse it twice. Second part is finding next ' but only in #c1 and cutting everything right from it.
DECLARE #c1 Varchar(255)
SELECT #c1 = SUBSTRING(#c, CHARINDEX('String ''',#c) + 8, 255)
--This is dynamic text' value 'test' wrong data Values 'ETC1 ETC2'.
SELECT LEFT(#c1, CHARINDEX('''',#c1) - 1)
--This is dynamic text
All put together - in single query:
SELECT LEFT(SUBSTRING(#c, CHARINDEX('String ''',#c) + 8, 255), CHARINDEX('''',SUBSTRING(#c, CHARINDEX('String ''',#c) + 8, 255)) - 1)
Not Sure but you are looking something as below :
DECLARE #DATA NVARCHAR(MAX);
SET #DATA = 'Name: ''Document No. 996''
Unique No: ''A 54 x. 488sCHU''
No 2: ''RF123456789''
String ''This is dynamic text'' value ''test'' wrong data
Values ''ETC1 ETC2''.';
SELECT SUBSTRING(SUBSTRING(#DATA, CHARINDEX('String', #DATA), CHARINDEX('Values', #DATA)-CHARINDEX('String', #DATA)), 1, CHARINDEX('''', SUBSTRING(SUBSTRING(#DATA, CHARINDEX('String', #DATA), CHARINDEX('Values', #DATA)-CHARINDEX('String', #DATA)), CHARINDEX('''', SUBSTRING(#DATA, CHARINDEX('String', #DATA), CHARINDEX('Values', #DATA)-CHARINDEX('String', #DATA)))+1, LEN(SUBSTRING(#DATA, CHARINDEX('String', #DATA), CHARINDEX('Values', #DATA)-CHARINDEX('String', #DATA)))))+CHARINDEX('''', SUBSTRING(#DATA, CHARINDEX('String', #DATA), CHARINDEX('Values', #DATA)-CHARINDEX('String', #DATA))));
Result :
String 'This is dynamic text'

SQL functions (String Selection)

I/P : P-2120-001-A10 I need O/p As P-2120 using SQL Server Functions.
this is the given string 'P-2120-001-A10' and i need to select data from given string left of the second '-' symbol i.e 'P-2120' its should select dynamically
Whilst it isn't clear what you are asking for this will transform I/P : P-2120-001-A10 into O/p As P-2120
with sample as (
select 'I/P : P-2120-001-A10' as astring
)
select
substring(astring,7,6) AS guess1
, 'O/p As ' + substring(astring,7,6) AS guess2
from sample
After your Question edit, you could use SUBSTRING & CHARINDEX Function to read the data from string left of the second '-' symbol Dynamically.
SELECT SUBSTRING(<I/P>, 1, CHARINDEX('-', <I/P>)-1)+'-'+SUBSTRING(SUBSTRING(<I/P>, CHARINDEX('-', <I/P>)+1, LEN(<I/P>)), 1, CHARINDEX('-', SUBSTRING(<I/P>, CHARINDEX('-', <I/P>)+1, LEN(<I/P>)))-1);
Output :
P-2120

SQL Server Query Output with sql scenario replace values with 'x' [duplicate]

This question already has answers here:
Replacing certain character in email addresses with '*' in an SQL query
(3 answers)
Closed 6 years ago.
I have one col in my table like:
COL
Kiyara#ymail.com
Akira#zmail.com
I want my output something like this:
COL
Kxxxxx#ymail.com
Axxxx#zmail.com
iyara replaced with 5x's(xxxxx) and 'kira' with 4x's(xxxx)
There's probably a better way to do it that this, but this achieves what you're after:
DECLARE #email NVARCHAR(50) = 'Kiyara#ymail.com';
SELECT LEFT(#email, 1) + REPLICATE('X',
LEN(SUBSTRING(#email, 2,
CHARINDEX('#', #email) - 1)))
+ SUBSTRING(#email, CHARINDEX('#', #email), LEN(#email));
-- Result: KXXXXXX#ymail.com
This uses the REPLICATE() method, which according to the docs online starts with SQL Server 2008.
REPLICATE (Transact-SQL)
Repeats a string value a specified number of times.
REPLICATE ( string_expression ,integer_expression )
SELECT LEFT(col, 1) + RIGHT('xxxxxxxxxxxxxxxx', CHARINDEX('#', col) - 2) +
SUBSTRING(col, CHARINDEX('#', col), LEN(col) - CHARINDEX('#', col) + 1);
Explanation:
Take Kiyara#ymail.com as an example, and each piece of my query is shown here.
K LEFT(col, 1)
xxxxx RIGHT('xxxxxxxxxxxxxxxx', CHARINDEX('#', col) - 2)
#ymail.com SUBSTRING(col, CHARINDEX('#', col), LEN(col) - CHARINDEX('#', col) + 1)
Note that you can replace the call to RIGHT() with a string of x's long enough to match your longest expected email name.
Try it's
select substring('Akira#zmail.com',1,1) + REPLICATE('x',charindex('#','Akira#zmail.com')) + SUBSTRING('Akira#zmail.com',charindex('#','Akira#zmail.com'),200)
Change the email by column or whatever you want
declare #n nvarchar(max)
set #n='Kiyara#ymail.com'
select concat(substring(#n,1,1),replicate('X',len( substring(#n,2,charindex('#',#n,1)-2))),SUBSTRING(#n,charindex('#',#n),200))
In this with the help o substring you have found first letter ans then rest of he letter til # i.e iyara is searched using charindex ans substring,which will be converted into 'x' using replicate function and then rest id printed.

SQL Server query to delete text from text column

I have a SQL Server database with a table feedback that contains a text column comment. In that column I have tag data, for example
This is my record <tag>Random characters are here</tag> with information.
How do I write a query to update all of these records to remove the <tag></tag> and all of the text in between?
I'd like to write this to a different 'temporary' table to first verify the changes and then update the original table.
I am running SQL Server 2014 Express.
Thank you
Here is a function to remove tags..
CREATE FUNCTION [dbo].[RemoveTag](#text NVARCHAR(MAX), #tag as nvarchar(max))
RETURNS NVARCHAR(MAX)
AS
BEGIN
declare #startTagIndex as int
declare #endTagIndex as int
set #startTagIndex = CHARINDEX('<' + #tag + '>', #text)
if(#startTagIndex > 0) BEGIN
set #endTagIndex = CHARINDEX('</' + #tag + '>', #text, #startTagIndex)
if(#endTagIndex > 0) BEGIN
return LEFT(#text, #startTagIndex - 1) + RIGHT(#text, len(#text) - len(#tag) - #endTagIndex - 2)
END
END
return #text
END
Later you can use it like:
Update table set field = dbo.RemoveTag(field, 'tag')
If you want to write fields to other table then:
CREATE TABLE dbo.OtherTable (
OtherField nvarchar(MAX) NOT NULL
)
GO
INSERT INTO OtherTable (OtherField)
SELECT dbo.RemoveTag(field, 'tag') from table
Making a lot assumptions about the format of your string. But if they're valid then this is very simple:
left(s, charindex('<tag>', s - 1)) +
substring(s, charindex('</tag>', s) + 6, len(s))
Obviously we're basically assuming that the search strings appear only once and in the correct order. There's also an assumption that there will be matches. Also, I used len(s) as an easy upper bound on the number of characters to take from the right. You could just hard-code something appropriate if you felt like it since SQL Server doesn't error for going past the end. s is just a stand in for your char column.
http://sqlfiddle.com/#!3/771a3/8
Not sure if extra whitespace is going to be an issue so you might want to trim and add a space character in the middle.
rtrim(left(s, charindex('<tag>', s) - 1)) + ' ' +
ltrim(substring(s, charindex('</tag>', s) + 6, len(s)))
You can use CHARINDEX to find where your tags start and stop, SUBSTRING to get all text between < and >, and REPLACE to swap out the substring for ''.
Select Field,
Substring(FIELD, charindex('<', Field), CHARINDEX('>', Field,
(CHARINDEX('>', FIELD)) + 1) - charindex('<', Field)+1) as ToRemove,
replace (Field, Substring(FIELD, charindex('<', Field), CHARINDEX('>',
Field, (CHARINDEX('>', FIELD)) + 1) - charindex('<', Field)+1), '')
as FinalResult
from TableName
The output will be three columns, Field, ToRemove and FinalResult, but nothing will actually be updated.
I think the only way this will fail is if you have nested tags. <b><i>sometext</i></b>
To actually make the change:
Update #TableName set Field = replace (Field, Substring(FIELD, charindex('<', Field), CHARINDEX('>', Field, (CHARINDEX('>', FIELD)) + 1) - charindex('<', Field)+1), '')
Tested on SQL Server 2012.

Extracting text between two characters in SQL

I am trying to extract the text between two characters using t-sql. I have been able to write it where it pulls the information close to what I want, but for some reason I am not getting what i am expecting(suprise, suprise). Could really use alittle help refining it. I am trying to extract part of the table name that is located between two [ ]. An example of the column data is as follows(this is a table that records all changes made to the database so the column text is basically SQL statements):
ALTER TABLE [TABLENAME].[MYTABLE] ADD
[VIP_CUSTOMER] [int] NULL
I am trying to extract part of the table name, in this example I just want 'MYTABLE'
Right now I am using:
select SUBSTRING(db.Event_Text, CHARINDEX('.', db.Event_Text) + 2, (CHARINDEX(']', db.Event_Text)) - CHARINDEX('', db.Event_Text) + Len(']')) as OBJName
FROM DBA_AUDIT_EVENT DB
WHERE DATABASE_NAME = 'XYZ'
But when I use this, I don't always get the results needed. Sometimes I get 'MYTABLE] ADD' and sometimes I get the part of the name I want, and sometimes depending on the length of the tablename I only get part the first part of the name with part of the name cut off at the end. Is there anyway to get this right, or is there a better way of writing it? Any help would be greatly appreciated. Thanks in advance.
Long, but here's a formula using the brackets:
Declare #text varchar(200);
Select #text='ALTER TABLE [TABLENAME].[MYTABLE] ADD [VIP_CUSTOMER] [int] NULL';
Select SUBSTRING(#text,
CHARINDEX('[', #text, CHARINDEX('[', #text) + 1 ) +1,
CHARINDEX(']', #text, CHARINDEX('[', #text, CHARINDEX('[', #text) + 1 ) ) -
CHARINDEX('[', #text, CHARINDEX('[', #text) + 1 ) - 1 );
Replace #text with your column name.
Give this a shot:
select SUBSTRING(db.Event_Text, CHARINDEX('.', db.Event_Text) + 2
, CHARINDEX(']', db.Event_Text) - 2) as OBJName
FROM DBA_AUDIT_EVENT DB
WHERE DATABASE_NAME = 'XYZ'
this is a pretty ugly way to get the length, but I've used something like this before:
select SUBSTRING(db.Event_Text,
CHARINDEX('.', db.Event_Text) + 2,
charindex('] ADD',db.Event_Text) - CHARINDEX('.',db.Event_Text)-2))
Give it a try, it may work for you.