Remove non-numeric value from SQL Select statement along with ending decimal point - sql

I have an application version column in one of my tables. Most of the values are standard versions, such as 2020.2.0, but some have pre-release tags on them (2020.2.0.PR).
The following returns the latest entry in the table:
SELECT version
from dbo.server_log_entry
where server_log_entry_id = (SELECT MAX(server_log_entry_id) from dbo.server_log_entry)
In this case, it returns:
2020.2.0.PR
I'm working on a script that will compare the latest version in the DB table to a version in a file to make sure the two are compatible. The script takes the version in the file and converts it to a [version] object. I'd like to have powershell query against the database and pull the value to a version object, however I'm having some trouble removing the '.' before the PR tag. Currently I have:
DECLARE #databaseVersion NVARCHAR(30)
SET #databaseVersion = (SELECT version from dbo.server_log_entry where server_log_entry_id = (SELECT MAX(server_log_entry_id) from dbo.server_log_entry))
SELECT LEFT(SUBSTRING(#databaseVersion, PATINDEX('%[0-9.-]%', #databaseVersion), 8000),
PATINDEX('%[^0-9.-]%', SUBSTRING(#databaseVersion, PATINDEX('%[0-9.-]%', #databaseVersion), 8000) + 'X') -1)
This will give me a value of
2020.2.0.
I'd like to remove the ending period so the query returns
2020.2.0
however I'm not quite sure how to do that, or if I'm going about this the incorrect way.

After some trial/error, I found that the following works how I need it to
"SELECT DISTINCT SUBSTRING([version], 0, CASE WHEN PATINDEX('%.[^0-9.]%', [version]) <> 0 THEN PATINDEX('%.[^0-9.]%', [version]) ELSE 100 END) FROM dbo.server_log_entry

perhaps REPLACE( ver, '.PR','')
SELECT replace( version, '.PR','')
from dbo.server_log_entry
where server_log_entry_id = (SELECT MAX(server_log_entry_id) from dbo.server_log_entry)

You can use REVERSE with CHARINDEX to get the result.
declare #databaseVersion VARCHAR(100) = '2020.2.0.PR'
SELECT REVERSE(RIGHT(REVERSE(#databaseVersion),
LEN(#databaseVersion)-CHARINDEX('.',REVERSE(#databaseVersion))))
2020.2.0

Related

SQL Substring function usage

This the column Description
Entity=10||WorkdayReferenceID=9000100332||HCMCostCenterMgr=nicoleb#broadinstitute.org||FRP=||
I want to retrieve the emailid only in the above scenario the desired output would be
nicoleb#broadinstitute.org
I tried using this:
select RTRIM(NVL(SUBSTR(TL.DESCRIPTION,(INSTR(TL.DESCRIPTION, '=',1,3)+1),
(LENGTH(TL.DESCRIPTION)-1)),'TL.DESCRIPTION'), '|') AS CCM
But after that new value of FRP was added so it got wrong .
Assuming (and it is a big assumption) that there is only ever one # in the data, the approach would be find the #, and then you want the text that is after the preceding = and before the next |. I do not know if the email address is always after HCMCostCenterMgr= so I won't assume that (but if that is the case the solution is easier).
It looks like you might be using Oracle (I see a NVL function), but I did this as SQL Server (it is more familiar off the top of my head). Here is a small script that will return just the email address you want - you can easily change these functions to Oracle if you need a version for Oracle.
DECLARE #data VARCHAR(200);
SELECT #data = 'Entity=10||WorkdayReferenceID=9000100332||HCMCostCenterMgr=nicoleb#broadinstitute.org||FRP=||';
SELECT REVERSE(SUBSTRING(REVERSE(SUBSTRING(#data, 1, CHARINDEX('|', #data, CHARINDEX('#', #data)) - 1)), 1, CHARINDEX('=', REVERSE(SUBSTRING(#data, 1, CHARINDEX('|', #data, CHARINDEX('#', #data)) - 1)))-1));
It is ugly, but SQL often gets a bit convoluted. I had to reverse the string to find things before the '#' and then reverse it at the end to get the value in the correct direction.

SQL Case Decimal Between

In my database I have an entry like: 'V2.0.0.0 VersionData'
I need my case statement to look at this value, trim off from the space onwards and remove the V at the start leaving '2.0.0.0, the case statement should then return 'Pass' if its greater than 2.0.1.0 else 'Fail'
This is what I have so far but it doesnt work:
Select
CASE
When (Select
Convert(Decimal(4,4),
REPLACE(
LEFT(EntryValue,
CHARINDEX(' ', EntryValue) - 1),'v',''))
from table where entrytype = 'VERSION') BETWEEN 0 and 2.1 THEN 'Pass'
Else 'Fail'
END [V-Check]
Your problem is that
declare #EntryValue varchar(250)='V2.0.0.0 VersionData'
Select REPLACE(LEFT(#EntryValue,CHARINDEX(' ', #EntryValue) - 1),'v','')
--2.0.0.0
You do not have a string that can be intepreted like a decimal.
Without knowing how your version numbering Works, a solution can not be found,
For instance is V2.11.0.0 possible? If so, then is V2.5.0.0 a a lower or higher version?
If you convert 2.11.0.0 to the decimal 2.11 then it will be lower than 2.5
In what I think would be the default intepretation of the version number, you do not have a single number, but 4 numbers you have to compare consecutively to get a result.
One of many ways to parse out the numbers in the version would then be:
declare #EntryValue varchar(250)='V2.0.0.0 VersionData'
;with cte as
(
select charindex('.',#EntryValue) p1
,charindex('.',#EntryValue,charindex('.',#EntryValue)+1) p2
,charindex('.',#EntryValue,charindex('.',#EntryValue,charindex('.',#EntryValue)+1)+1) p3
,charindex(' ',#EntryValue) p4
)
select substring(#EntryValue,2,p1-2)+0 [MajorVersion]
,SUBSTRING(#EntryValue,p1+1,p2-p1-1)+0 [MinorVersion]
,SUBSTRING(#EntryValue,p2+1,p3-p2-1)+0 [BugFixRelease]
,SUBSTRING(#EntryValue,p3+1,p4-p3-1)+0 [Build]
from cte
If the numbers cannot be larger than 10, then you have an easy task, then you can just use a simple compare
select case when 'V2.1.0.0 VersionData'>= 'V2.0.1.0 VersionData' then 1 else 0 end
Since the lexicographical ordering of the characters would ensure that the result is correct.
-- Added in edit
If you have up to 4 numbers in your version, then you can abuse the internal function PARSENAME to get the numbers in an easier fashion:
declare #EntryValue varchar(250)='V2.0.0.0 VersionData'
select
parsename(stuff(left(#EntryValue,charindex(' ',#EntryValue)),1,1,''),4)+0 MajorVersion
, parsename(stuff(left(#EntryValue,charindex(' ',#EntryValue)),1,1,''),3)+0 MinorVersion
, parsename(stuff(left(#EntryValue,charindex(' ',#EntryValue)),1,1,''),2)+0 Release
, parsename(stuff(left(#EntryValue,charindex(' ',#EntryValue)),1,1,''),1)+0 Build
One problem is that converting a string '2.0.1.0', which contains several .-characters will not properly convert into 2010 (as you might intend).
However, if you can guarantee that you always have exactly 4 version parts and each version part is between 0..9, i.e. there is no version like, for example, 2.0.11.0' or2.0.1.0.9', then the following solution should work. It simply relies on the order of string values, which - above mentioned restriction concerning version parts guaranteed - is just as if you compared integral values:
with versions as
( select entryValue, Substring(LEFT(EntryValue,
CHARINDEX(' ', EntryValue)),2,100) as versionStr
from (values
('V2.0.0.0 some older version'),
('V2.0.1.0 sufficient version'),
('V2.0.1.9 newer version')
) as versionTable(entryValue)
)
select *, (case when versionStr >= '2.0.1.0' then 'Pass' else 'Fail' end) as "check"
from versions;

SQL Query Remove Part of Path/Null

So I am new the whole SQL Query business but I need some help with two issues. My goal is to have anything in the Column "EnvironmentName" that has the word "Database" in Column "NodeName" to be displayed in the query results. I did this with
FROM [Backbone_ASPIDER].[dbo].[vw_CFGsvr_Con]
WHERE NodeName = 'Database'
ORDER BY EnvironmentName asc
WHERE NodePath
Results of Query:
I am able to get my query results but would like to remove the rows with NULL. I have tried to use "IS NOT NULL" but SQL Server Management Studio labeles this as "incorrect syntax."
What I have tried:
FROM [Backbone_ASPIDER].[dbo].[vw_CFGsvr_Con]
WHERE NodeName = 'Database'
ORDER BY EnvironmentName asc IS NOT NULL
WHERE NodePath
Thank you in advance!
Your query is pretty close..
1: You have to specify a specific column to not be null while using IS NOT NULL.
So modify your query to:
FROM [Backbone_ASPIDER].[dbo].[vw_CFGsvr_Con]
WHERE NodeName = 'Database' AND EnvironmentName IS NOT NULL
ORDER BY EnvironmentName asc
WHERE NodePath
2: Check out this article about trimming parts of strings from query results
http://basitaalishan.com/2014/02/23/removing-part-of-string-before-and-after-specific-character-using-transact-sql-string-functions/
Where clause will come first and Then order by statement
Like following way
Select * FROM [Backbone_ASPIDER].[dbo].[vw_CFGsvr_Con]
WHERE [Backbone_ASPIDER].[dbo].[vw_CFGsvr_Con].[NodeName] = 'Database' AND [Backbone_ASPIDER].[dbo].[vw_CFGsvr_Con].[EnvironmentName] IS NOT NULL
ORDER BY [Backbone_ASPIDER].[dbo].[vw_CFGsvr_Con].[EnvironmentName] asc
EDIT: I just noticed you removed this from your OP, so feel free to disregard if you took care of that.
I don't think anyone addressed the substring problem yet. There's several ways you could get at this depending on how complex the strings are you have to slice up, but here's how I'd do it
-- Populating some fake data, representative of what you've got
if object_id('tempdb.dbo.#t') is not null drop table #t
create table #t
(
nPath varchar(1000)
)
insert into #t
select '/Database/Mappings/Silver/Birthday' union all
select '/Database/Connections/Blue/Happy'
-- First, get the character index of the first '/' after as many characters the word '/database/' takes up.
-- You could have hard coded this value too. Add 1 to it so that it moves PAST the slash.
;with a as
(
select
ixs = charindex('/', nPath, len('/Database/') + 1),
-- Get everything to the right of what you just determined with all the charindex() stuff
ss = right(nPath, len(nPath) - charindex('/', nPath, len('/Database/') + 1)),
nPath
from #t
)
-- Now just take the left of the now-cleaned-up string from start to the first pipe
select
ixs,
ss,
color = left(ss, charindex('/', ss) -1),
nPath
from a

Search and Replace Byte Order Mark In Sql Server

i have 10 table and more than 10000 record that contain 
how can search  and replace this in DB?
since the  equal 0xEF,0xBB,0xBF how can search this?
i use this code
WITH foo(myvarbincolumn) AS
(
SELECT text from BPM_Letters
)
SELECT *
FROM foo
WHERE CONVERT(VARCHAR(max), myvarbincolumn) COLLATE Arabic_CI_AS
LIKE '%' + CONVERT(NVARCHAR(max), CHAR(0xEF)+CHAR(0xBB)+CHAR(0xBF)) + '%'
I found this code in stackoverflow but it s incomplete.
script of BPM_Letters
this code not find any record!
please help me
I wrote a query to find that weird character via the query below:
SELECT cast(LEFT(text,1) AS VARBINARY(MAX)) from BPM_Letters
and the result was 0xFFFE. So I wrote this query and it worked perfectly:
UPDATE BPM_Letters Set text=REPLACE(text,0xFFFE,'');
What about this CTE:
StripBOM AS
(
SELECT CASE
WHEN LEFT(text,3) = 0xEFBBBF
THEN CONVERT(varbinary(max),SUBSTRING(text, 4, LEN(text)))
ELSE text
END AS text
FROM BPM_Letters
)
It should provide you with a new table where all BOM characters have been stripped off.
P.S. This code assumes 'text' field is of type varbinary.
Here's a simpler answer that builds on the other ones:
UPDATE BPM_Letters SET text=substr(text, 4) WHERE left(text, 3) = 0xEFBBBF;
I've tested this, and it works.

SQL strip text and convert to integer

In my database (SQL 2005) I have a field which holds a comment but in the comment I have an id and I would like to strip out just the id, and IF possible convert it to an int:
activation successful of id 1010101
The line above is the exact structure of the data in the db field.
And no I don't want to do this in the code of the application, I actually don't want to touch it, just in case you were wondering ;-)
This should do the trick:
SELECT SUBSTRING(column, PATINDEX('%[0-9]%', column), 999)
FROM table
Based on your sample data, this that there is only one occurence of an integer in the string and that it is at the end.
I don't have a means to test it at the moment, but:
select convert(int, substring(fieldName, len('activation successful of id '), len(fieldName) - len('activation successful of id '))) from tableName
Would you be open to writing a bit of code? One option, create a CLR User Defined function, then use Regex. You can find more details here. This will handle complex strings.
If your above line is always formatted as 'activation successful of id #######', with your number at the end of the field, then:
declare #myColumn varchar(100)
set #myColumn = 'activation successful of id 1010102'
SELECT
#myColumn as [OriginalColumn]
, CONVERT(int, REVERSE(LEFT(REVERSE(#myColumn), CHARINDEX(' ', REVERSE(#myColumn))))) as [DesiredColumn]
Will give you:
OriginalColumn DesiredColumn
---------------------------------------- -------------
activation successful of id 1010102 1010102
(1 row(s) affected)
select cast(right(column_name,charindex(' ',reverse(column_name))) as int)
CAST(REVERSE(LEFT(REVERSE(#Test),CHARINDEX(' ',REVERSE(#Test))-1)) AS INTEGER)
-- Test table, you will probably use some query
DECLARE #testTable TABLE(comment VARCHAR(255))
INSERT INTO #testTable(comment)
VALUES ('activation successful of id 1010101')
-- Use Charindex to find "id " then isolate the numeric part
-- Finally check to make sure the number is numeric before converting
SELECT CASE WHEN ISNUMERIC(JUSTNUMBER)=1 THEN CAST(JUSTNUMBER AS INTEGER) ELSE -1 END
FROM (
select right(comment, len(comment) - charindex('id ', comment)-2) as justnumber
from #testtable) TT
I would also add that this approach is more set based and hence more efficient for a bunch of data values. But it is super easy to do it just for one value as a variable. Instead of using the column comment you can use a variable like #chvComment.
If the comment string is EXACTLY like that you can use replace.
select replace(comment_col, 'activation successful of id ', '') as id from ....
It almost certainly won't be though - what about unsuccessful Activations?
You might end up with nested replace statements
select replace(replace(comment_col, 'activation not successful of id ', ''), 'activation successful of id ', '') as id from ....
[sorry can't tell from this edit screen if that's entirely valid sql]
That starts to get messy; you might consider creating a function and putting the replace statements in that.
If this is a one off job, it won't really matter. You could also use a regex, but that's quite slow (and in any case mean you now have 2 problems).