IP address pattern in SQL like command - sql-server

I want to select rows which contains an IP address in a nvarchar column. What's the correct where statement?
SELECT * FROM tblUrl WHERE ... (Url contains an IP address)

The "usual way" to encode IP address in Database is either:
192.168.001.010 (note the padding "0"s)
or
as a integer being (((192 * 256)+ 168 )* 256 + 1 )*256 +10
Both formats allow you to quickly match for an ip in an interval:
SELECT * FROM tblURL where URL > "192.168.010.000" and URL < "192.168.011.255"
or
SELECT * FROM tblURL where URL > 3232238080 and URL < 3232239080
If you table tblUrl contains URLs as suggested by your question, then you should perform a DNS lookup first to resolve the name into an IP Address.

You could simply do this
SELECT * FROM tblUrl WHERE URL like '192.168.1.%'
which will select all ip addresses from 192.168.1.1 to .254
Or you can be more creative such as
SELECT * FROM tblUrl WHERE URL like '192.168.1.[0-9][0-9]'
this will select all IP addresses 192.168.1.10 to .99

Related

multiple matches in regex in hive

When I run
select regexp_extract("hosts: 192.168.1.1 192.168.1.2 host",'((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)',0);
I got 192.168.1.1.
But what i want is 192.168.1.1,192.168.1.2 or ["192.168.1.1","192.168.1.2"]
What should I do, change reg or create a UDF?
Split string, explode, check each part for regexp matching, collect array of matching parts, if necessary to get string from array, use concat_ws() to concatenate array:
with your_data as(
select stack(1, 'hosts: 192.168.1.1 192.168.1.2 host' ) as hosts
)
select collect_set(case when part rlike '((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)'
then part
else null end )
from your_data d
lateral view explode(split(hosts, ' +')) s as part;
Result:
["192.168.1.1","192.168.1.2"]

Adding multiple records from a string

I have a string of email addresses. For example, "a#a.com; b#a.com; c#a.com"
My database is:
record | flag1 | flag2 | emailaddresss
--------------------------------------------------------
1 | 0 | 0 | a#a.com
2 | 0 | 0 | b#a.com
3 | 0 | 0 | c#a.com
What I need to do is parse the string, and if the address is not in the database, add it.
Then, return a string of just the record numbers that correspond to the email addresses.
So, if the call is made with "A#a.com; c#a.com; d#a.com", the rountine would add "d#a.com", then return "1, 3,4" corresponding to the records that match the email addresses.
What I am doing now is calling the database once per email address to look it up and confirm it exists (adding if it doesn't exist), then looping thru them again to get the addresses 1 by 1 from my powershell app to collect the record numbers.
There has to be a way to just pass all of the addresses to SQL at the same time, right?
I have it working in powershell.. but slowly..
I'd love a response from SQL as shown above of just the record number for each email address in a single response. That is, "1,2,4" etc.
My powershell code is:
$EmailList2 = $EmailList.split(";")
# lets get the ID # for each eamil address.
foreach($x in $EmailList2)
{
$data = exec-query "select Record from emailaddresses where emailAddress = #email" -parameter #{email=$x.trim()} -conn $connection
if ($($data.Tables.record) -gt 0)
{
$ResponseNumbers = $ResponseNumbers + "$($data.Tables.record), "
}
}
$ResponseNumbers = $($ResponseNumbers+"XX").replace(", XX","")
return $ResponseNumbers
You'd have to do this in 2 steps. Firstly INSERT the new values and then use a SELECT to get the values back. This answer uses delimitedsplit8k (not delimitedsplit8k_LEAD) as you're still using SQL Server 2008. On the note of 2008 I strongly suggest looking at upgrade paths soon as you have about 6 weeks of support left.
You can use the function to split the values and then INSERT/SELECT appropriately:
DECLARE #Emails varchar(8000) = 'a#a.com;b#a.com;c#a.com';
WITH Emails AS(
SELECT DS.Item AS Email
FROM dbo.DelimitedSplit8K(#Emails,';') DS)
INSERT INTO YT (emailaddress) --I don't know what the other columns value should be, so have excluded
SELECT E.Email
FROM dbo.YourTable YT
LEFT JOIN Emails E ON YT.emailaddress = E.Email
WHERE E.Email IS NULL;
SELECT YT.record
FROM dbo.YourTable YT
JOIN dbo.DelimitedSplit8K(#Emails,';') DS ON DS.Item = YT.emailaddress;

Search for row where email contains only the X character

I want to search for rows whose column email has only the X character.
For example, if the email is XXXX, it should fetch the row but if the email is XXX#XXX.COM it should not be fetched.
I have tried something like this, but it is returning me all emails having the character X in it:
select *
from STUDENTS
where EMAIL like '%[X+]%';
Any idea what is wrong with my query?
Thanks
Try below query:
select *
from STUDENTS
where LEN(EMAIL) > 0 AND LEN(REPLACE(EMAIL,'X','')) = 0;
I would use PATINDEX:
SELECT * FROM STUDENTS WHERE PATINDEX('%[^X]%', Email)=0
Only X means no other characters than X.
To handle NULLs and empty strings you should consider additional conditions. See demo below:
WITH STUDENTS AS
(
SELECT * FROM (VALUES ('XXXX'),('XXX#XXX.COM'),(NULL),('')) T(Email)
)
SELECT *
FROM STUDENTS
WHERE PATINDEX('%[^X]%', Email)=0 AND LEN(Email)>0
This will find all rows where email only contain 1 or more X and no other characters.
SELECT *
FROM STUDENTS
WHERE Email not like '%[^X]%' and Email <> ''

Sql Server wildcard Like Statement : How to use for data having undefined Length

I have URL data in a table like this(Showing only one row i have many more in table)
abc/portfolio/12/strategy
abc/portfolio/15/strategy
abc/portfolio/1/strategy
The data is in four part separated with '/'.
i got a string to match with this data, either i got a same string to match or if i can get "*" at any part of data if i don't need to match the particular part Like
abc/portfolio/*/strategy
if i get this string to match i don't have to match the '*' part,rest i need to match with the data. i need to match abc/portfolio/% with i need to Match %/strategy in a single column data.
i don't know how to do it with wildcards also as in data its not define that what is the length of a particular part.
As well as if i got two '**' then i need to match only intial Part of Data
Like if i get data to match abc/**/12/strategythen i only need to match abc\% in data.
Example:
Select Url_data from schema1.table1
where
url_data Like 'abc/portfolio/*/strategy'
here i need the "*" to work like, ignore the data in that particular Part.
outcome expected is :
abc/portfolio/12/strategy
abc/portfolio/15/strategy
abc/portfolio/1/strategy
Instead of "*" you can use '%' as follows
Select Url_data from schema1.table1
where
url_data Like 'abc/portfolio/%/strategy'
declare #v varchar(100) = 'abc/portfolio/*/strategy'
Select Url_data from schema1.table1 where url_data Like
replace(
case
when charindex('**',#v) > 0 then left(#v, charindex('**',#v))
else #v
end
,'*','%')
This will replace the * by % if only one * is in the variable #v or truncate the text after ** and replace ** it by %.
declare #v varchar(100) = 'abc/portfolio/*/strategy' -> abc/portfolio/%/strategy
declare #v varchar(100) = 'abc/portfolio/**/strategy' --> abc/portfolio/%

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

Resources