MS SQL REPLACE based on 1 character to the left of the $ - sql-server

I am not a SQL expert so please forgive me if this is SQL 101 :).
In a select statement there are 2 replace functions. They look for a Servername and it's admin share d$ by it's UNC path. Example '\SERVERNAME\d$'
It then replaces '\SERVERNAME\d$' with 'D:'.
Here is the query currently:
select Replace(p.Path,'\\SERVERNAME\d$','D:') as searchpath
,p.path as fullpath
,s.ShareName
,s.SharePath
,p.Member
,p.Access
From Paths As p
Left Outer Join Shares as s on
Replace(p.Path,'\\SERVERNAME\d$','D:') Like s.SharePath + '\%'
Up until now it has always been d$.
Today my needs have changed and I need the query to find ANY servername UNC path admin share regardless of share letter (c$, d$, e$, f$...etc) and replace it with it's respective drive letter (D:, E:, F:... etc).
My thought is replace function could find the $ and look one character to the left of it to get the proper share letter, then use that for the replace. The issue I have, not being a SQL professional, is that I know SQL can likley do what I need it to do...I just don't know how to get there. I've googled and found some examples, but haven't had any luck in getting them to work.
Any help would be greatly appreciated.

You can use a combination of STUFF, PATINDEX, LEN to get what you want.
Sample Query
DECLARE #ReplaceChar VARCHAR(100) = '[prefixcharacters]\\SERVERNAME\d$[postcharacter]'
DECLARE #SearchString VARCHAR(100) = '\\SERVERNAME\_$'
SELECT
STUFF(#ReplaceChar,PATINDEX('%' + #SearchString + '%',#ReplaceChar),LEN(#SearchString),
UPPER(SUBSTRING(#ReplaceChar,PATINDEX('%' + #SearchString + '%',#ReplaceChar) + LEN(#SearchString) - 2,1)) + ':') as searchpath
WHERE PATINDEX('%' + #SearchString + '%',#ReplaceChar) > 0
Output
[prefixcharacters]D:[postcharacter]
Alternate Query
You can shorten the query if you want to get the previous character before $ as per your title. Something like this
DECLARE #ReplaceChar VARCHAR(100) = '[prefixcharacters]\\SERVERNAME\d$[postcharacter]'
DECLARE #SearchString VARCHAR(100) = '\\SERVERNAME\_$'
SELECT
STUFF(#ReplaceChar,
PATINDEX('%'+#SearchString+'%',#ReplaceChar),
LEN(#SearchString),
UPPER(SUBSTRING(#ReplaceChar,CHARINDEX('$',#ReplaceChar) -1,1)) + ':')
WHERE PATINDEX('%'+#SearchString+'%',#ReplaceChar) > 0
In this query
STUFF replaces your pattern with with the character before $ + ':'
Start of pattern is identified by PATINDEX('%'+#SearchString+'%',#ReplaceChar)
D is identified by getting the charindex of '$' and then getting the previous character using SUBSTRING

What about ¸
select Replace(SUBSTRING(p.path, 14, Len(#spath)-14),'$',':') as searchpath
,p.path as fullpath
,s.ShareName
,s.SharePath
,p.Member
,p.Access
From Paths As p
Left Outer Join Shares as s on
Replace(SUBSTRING(p.path, 14, Len(#spath)-14),'$',':') Like s.SharePath + '\%
select as searchpath

DECLARE #str nvarchar (100)
SET #str = '\\SERVERNAME\d$'
IF #str LIKE '\\SERVERNAME\_$'
SET #str = UPPER(SUBSTRING(#str, 14, 1)) + ':'
SELECT #str
Starting from previous, something like
select UPPER(SUBSTRING(p.path, 14, 1)) + ':' as searchpath
,p.path as fullpath
,s.ShareName
,s.SharePath
,p.Member
,p.Access
From Paths As p
Left Outer Join Shares as s on
SUBSTRING(p.path, 14, 1) + ':' Like s.SharePath + '\%'

I am no mysql expert either :)
Based on the logic you mentioned in the last part of the question, I have used concat and substring to get to the drive letter in the column.
Hope this helps
select replace(path, concat(substring(path, 1, locate('$', path) - 2), substring(path, locate('$', path) - 1, 1) , '$'), concat(substring(path, locate('$', path) - 1, 1) , ':')) as searchpath ...
The remaining part of the query would be the same.

Related

Using SQL WHERE LIKE to filter when have consecutive numbers

Trying to convert a PostgreSQL view to SQL Server (2016) view.
I have a table with a column named filename, with the following data:
R24bMP1.png
MP3.png
R28.jpg
I002.jpg
App_1472669569054.jpg
Test_1575753047890.png
So, I like to filter all rows the filename must contains 13 consecutives numbers, in the example, only App_1472669569054.jpg and Test_1575753047890.png.
In PostgreSQL, I can use regex to do this:
SELECT * FROM table WHERE filename ~ '\d{13}'.
Tried in SQL Server with:
SELECT * FROM table WHERE filename LIKE '%[0-9]{13}%', but got no results. The only way that worked is:
SELECT * FROM table WHERE filename LIKE '%[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%'
After that, I need to get only the number part of filename, in the example, the returned value must be:
1472669569054
1575753047890
I know I can use CLR with SQL Server, but I like to known if is possible to filter without CLR in this case.
As Martin Smith pointed out:
'%[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%'
can be reduced to:
'%' + replicate('[0-9]',13) + '%'
You were most of the way there:
declare #filename varchar(128) = 'Test_1575753047890.png'
select test=substring(#filename
,patindex('%' + replicate('[0-9]',13) + '%',#filename)
,13
)
returns: 1575753047890
So for your table it would look like:
select test=substring([filename]
,patindex('%' + replicate('[0-9]',13) + '%',[filename])
,13
)
from t
where patindex('%' + replicate('[0-9]',13) + '%',[filename]) > 0

Extract everything in between & -- & from a column in a table

I have the value for the column in a table and i need to exact some part of the string
baf93b64-c255-4dda-b9dc-3f7438b49335-mkttrg&utm_source=bing&utm_medium=cpc&utm_campaign=MO+-+Payday&utm_term=payday+loan&utm_content=Payday+Loans+(Phrase)
now I have to extract from the first & i.e.,
utm-source = bing
utm-medium = cpc
utc_campaign = MO+Payday
utm_term = 'payday+loan'
utm_content = Payday+loans+(Phrase).
can you please help me with the sub string function to extract these parts from the column mentioned value.
Thanks in advance.
Use substring with the start at the charindex, and number of character extract is the length of the string subtract the length of the two pieces from the beginning and the end. You will need to do some data validation so that the col is of the form you want.
substring(col, charindex('&', col) + 1, len(col) - charindex('&', reverse(col)) - charindex('&', col))
Test code:
DECLARE #col nvarchar(100) = '12&12545643&euwpo';
SELECT substring(#col, charindex('&', #col) + 1, len(#col) - charindex('&', reverse(#col)) - charindex('&', #col))
The main approach of solving this issue via using SplitString function.
Then depends on your comment:
in the string what i have mentioned in my question, it is not picking
the last part "utm_content=Payday+Loans+(Phrase)" as it doesnt have
the & at the end i guess!!
Use the following Code:-
SELECT top ((select count (*) FROM dbo.SplitString('baf93b64-c255-4dda-b9dc-3f7438b49335-mkttrg&utm_source=bing&utm_medium=cpc&utm_campaign=MO+-+Payday&utm_term=payday+loan&utm_content=Payday+Loans+(Phrase)', '&')
where item like '%=%' ) -1) item
FROM dbo.SplitString('baf93b64-c255-4dda-b9dc-3f7438b49335-mkttrg&utm_source=bing&utm_medium=cpc&utm_campaign=MO+-+Payday&utm_term=payday+loan&utm_content=Payday+Loans+(Phrase)', '&')
where item like '%=%'
Result:-

Get a Substring in SQL between two characters and remove all white spaces

I've a strings such as:
Games/Maps/MapsLevel1/Level 1.swf
Games/AnimalWorld/Animal1.1/Level 1.1.swf
Games/patterns and spatial understanding/Level 13.5/Level 13.5.swf
I want to get only file name without its extension(String After last Slash and before Last dot), i.e Level 1 and Level 1.1 and Level 13.5, Even I want to remove all the white spaces and the final string should be in lower case i.e the final output should be
level1
level1.1
level13.5 and so on..
I tried following query but i got Level 1.swf, How do i change this Query?
SELECT SUBSTRING(vchServerPath, LEN(vchServerPath) - CHARINDEX('/', REVERSE(vchServerPath)) + 2, LEN(vchServerPath)) FROM Games
SELECT (left((Path), LEN(Path) - charindex('.', reverse(Path))))
FROM
(
SELECT SUBSTRING(vchServerPath,
LEN(vchServerPath) - CHARINDEX('/', REVERSE(vchServerPath)) + 2,
LEN(vchServerPath)) Path
FROM Games
) A
This would work, I kept your inner substring which got you part way and I added the stripping of the dot.
I have included a sql fiddle link for you to see it in action sql fiddle
Edited:
Following will remove the white space and returns lower case...
SELECT REPLACE(LOWER((left((Path), LEN(Path) - charindex('.', reverse(Path))))), ' ', '')
FROM
(
SELECT SUBSTRING(vchServerPath,
LEN(vchServerPath) - CHARINDEX('/', REVERSE(vchServerPath)) + 2,
LEN(vchServerPath)) Path
FROM Games
) A
Try this:
select
case
when vchServerPath is not null
then reverse(replace(substring(reverse(vchServerPath),charindex('.',reverse(vchServerPath))+1, charindex('/',reverse(vchServerPath))-(charindex('.',reverse(vchServerPath))+1)),' ',''))
else ''
end
This should work fine; with extension removed.
select
REVERSE(
SUBSTRING(
reverse('Games/patterns and spatial understanding/Level 13.5/Level 13.5.swf'),
5,
(charindex('/',
reverse('Games/patterns and spatial understanding/Level 13.5/Level 13.5.swf')) - 5)
))

Toad and SQL Server 2005

where a.system_nr =''''5300'''' and
a.external_status_cd = '''''''' and
a.cust_acct_id = b.rel_cust_acct_id and
b.cust_acct_id = c.cust_acct_id and
c.cust_acct_id = d.cust_acct_id and
d.acct_status_cd = ''''OPEN'''' and
d.time_mnth_gen_id =''''' + #BegDate + ''''' and
a.cust_acct_id = e.cust_acct_id and
e.tran_dt >=''''' + #BegDate + ''''' and
e.tran_dt<=''''' + #EndDate + ''''' and
d.portfolio_cd = ''''HEQ'''' and
a.time_mnth_gen_id =''''' + #BegDate + ''''' '')'
Here is the where condition which is already written and I need to make changes.
Can you please tell me why they are using '''''+#begdate'''''? Can i use '+Bedate'?
I mean why they are using ''''' each side?
Try this in SQL Server:
select '''''someval'''''
You notice that item gives:
''someval''
In SQL Server '' will equate to a single quote character, so the above line is
select [open string][single quote][single quote]someval[single quote][single quote][close string]
Without seeing the rest of the SQL, my guesses would be:
for use in dynamic SQL as #BegDate is a variable and you have the statement ending with a single quote
the data contains a bunch of single quotes
You should not be able to just '+BegDate' because it's a variable and stripping the # would cause it to be evaluated as a field.
If you meant to just reduce the number of single quotes, I would imagine the original author put them there for a reason. You can run the query with the original single quotes and again with the reduced single quotes and see if you get the same result set.

How to do hit-highlighting of results from a SQL Server full-text query

We have a web application that uses SQL Server 2008 as the database. Our users are able to do full-text searches on particular columns in the database. SQL Server's full-text functionality does not seem to provide support for hit highlighting. Do we need to build this ourselves or is there perhaps some library or knowledge around on how to do this?
BTW the application is written in C# so a .Net solution would be ideal but not necessary as we could translate.
Expanding on Ishmael's idea, it's not the final solution, but I think it's a good way to start.
Firstly we need to get the list of words that have been retrieved with the full-text engine:
declare #SearchPattern nvarchar(1000) = 'FORMSOF (INFLECTIONAL, " ' + #SearchString + ' ")'
declare #SearchWords table (Word varchar(100), Expansion_type int)
insert into #SearchWords
select distinct display_term, expansion_type
from sys.dm_fts_parser(#SearchPattern, 1033, 0, 0)
where special_term = 'Exact Match'
There is already quite a lot one can expand on, for example the search pattern is quite basic; also there are probably better ways to filter out the words you don't need, but it least it gives you a list of stem words etc. that would be matched by full-text search.
After you get the results you need, you can use RegEx to parse through the result set (or preferably only a subset to speed it up, although I haven't yet figured out a good way to do so). For this I simply use two while loops and a bunch of temporary table and variables:
declare #FinalResults table
while (select COUNT(*) from #PrelimResults) > 0
begin
select top 1 #CurrID = [UID], #Text = Text from #PrelimResults
declare #TextLength int = LEN(#Text )
declare #IndexOfDot int = CHARINDEX('.', REVERSE(#Text ), #TextLength - dbo.RegExIndexOf(#Text, '\b' + #FirstSearchWord + '\b') + 1)
set #Text = SUBSTRING(#Text, case #IndexOfDot when 0 then 0 else #TextLength - #IndexOfDot + 3 end, 300)
while (select COUNT(*) from #TempSearchWords) > 0
begin
select top 1 #CurrWord = Word from #TempSearchWords
set #Text = dbo.RegExReplace(#Text, '\b' + #CurrWord + '\b', '<b>' + SUBSTRING(#Text, dbo.RegExIndexOf(#Text, '\b' + #CurrWord + '\b'), LEN(#CurrWord) + 1) + '</b>')
delete from #TempSearchWords where Word = #CurrWord
end
insert into #FinalResults
select * from #PrelimResults where [UID] = #CurrID
delete from #PrelimResults where [UID] = #CurrID
end
Several notes:
1. Nested while loops probably aren't the most efficient way of doing it, however nothing else comes to mind. If I were to use cursors, it would essentially be the same thing?
2. #FirstSearchWord here to refers to the first instance in the text of one of the original search words, so essentially the text you are replacing is only going to be in the summary. Again, it's quite a basic method, some sort of text cluster finding algorithm would probably be handy.
3. To get RegEx in the first place, you need CLR user-defined functions.
It looks like you could parse the output of the new SQL Server 2008 stored procedure sys.dm_fts_parser and use regex, but I haven't looked at it too closely.
You might be missing the point of the database in this instance. Its job is to return the data to you that satisfies the conditions you gave it. I think you will want to implement the highlighting probably using regex in your web control.
Here is something a quick search would reveal.
http://www.dotnetjunkies.com/PrintContent.aspx?type=article&id=195E323C-78F3-4884-A5AA-3A1081AC3B35
Some details:
search_kiemeles=replace(lcase(search),"""","")
do while not rs.eof 'The search result loop
hirdetes=rs("hirdetes")
data=RegExpValueA("([A-Za-zöüóőúéáűíÖÜÓŐÚÉÁŰÍ0-9]+)",search_kiemeles) 'Give back all the search words in an array, I need non-english characters also
For i=0 to Ubound(data,1)
hirdetes = RegExpReplace(hirdetes,"("&NoAccentRE(data(i))&")","<em>$1</em>")
Next
response.write hirdetes
rs.movenext
Loop
...
Functions
'All Match to Array
Function RegExpValueA(patrn, strng)
Dim regEx
Set regEx = New RegExp ' Create a regular expression.
regEx.IgnoreCase = True ' Set case insensitivity.
regEx.Global = True
Dim Match, Matches, RetStr
Dim data()
Dim count
count = 0
Redim data(-1) 'VBSCript Ubound array bug workaround
if isnull(strng) or strng="" then
RegExpValueA = data
exit function
end if
regEx.Pattern = patrn ' Set pattern.
Set Matches = regEx.Execute(strng) ' Execute search.
For Each Match in Matches ' Iterate Matches collection.
count = count + 1
Redim Preserve data(count-1)
data(count-1) = Match.Value
Next
set regEx = nothing
RegExpValueA = data
End Function
'Replace non-english chars
Function NoAccentRE(accent_string)
NoAccentRE=accent_string
NoAccentRE=Replace(NoAccentRE,"a","§")
NoAccentRE=Replace(NoAccentRE,"á","§")
NoAccentRE=Replace(NoAccentRE,"§","[aá]")
NoAccentRE=Replace(NoAccentRE,"e","§")
NoAccentRE=Replace(NoAccentRE,"é","§")
NoAccentRE=Replace(NoAccentRE,"§","[eé]")
NoAccentRE=Replace(NoAccentRE,"i","§")
NoAccentRE=Replace(NoAccentRE,"í","§")
NoAccentRE=Replace(NoAccentRE,"§","[ií]")
NoAccentRE=Replace(NoAccentRE,"o","§")
NoAccentRE=Replace(NoAccentRE,"ó","§")
NoAccentRE=Replace(NoAccentRE,"ö","§")
NoAccentRE=Replace(NoAccentRE,"ő","§")
NoAccentRE=Replace(NoAccentRE,"§","[oóöő]")
NoAccentRE=Replace(NoAccentRE,"u","§")
NoAccentRE=Replace(NoAccentRE,"ú","§")
NoAccentRE=Replace(NoAccentRE,"ü","§")
NoAccentRE=Replace(NoAccentRE,"ű","§")
NoAccentRE=Replace(NoAccentRE,"§","[uúüű]")
end function

Resources