Regex parse sql string - c#

I have sql string like
select * from dbo.Person where Person = ? AND Name = ? OR (Country = ? OR City = 1)
If it's possible to get string array like below with Regex in C#
result[0] = Person = ?
result[1] = Name = ?
result[2] = (Country = ? OR City = 1)
thanks.

First try looks like this
var s = #"select* from dbo.Person where Person = ? AND Name = ? OR (Country = ? OR City = 1)";
var reg = new Regex("[A-Za-z]+ = [A-Za-z0-9?]+");
var result = reg.Matches(s);
Something like that but is no Regex
var s = #"select* from dbo.Person where Person = ? AND Name = ? OR(Country = ? OR City = 1)";
var s1 = s.Split(new[] { "where" }, StringSplitOptions.None)[1];
var s2 = s1.Split(new[] { "OR", "AND" }, StringSplitOptions.None);

If you need anything more complicated than this, it's going to quickly go beyond what you can easily solve with regex. I have released a free parser on GitHub that will parse out TSQL in a stable way into the pieces, TSQL Parser . You can also use the Microsoft TSQL parser, using the TSqlParser . With either of these, they will break it out a little more granular than you're requesting, which you will then have to piece back together based on parenthesis for example.

Related

Split String and get desired part

Is there any way to get the portion of string after the last "_" forexample;
string1 = "A_110_23_09_ABC"
result1 = "ABC"
string2 = "A_110_23_09_ABC_555"
result2 = "555"
var s = "A_110_23_09_ABC";
var result = s.Substring(s.LastIndexOf('_') + 1);
If you are using .NET 3.5 or higher, you could do it by LINQ to Object. The code would be something like :
var result = string.Split('_').Last();

How do I write a SQL Concat in Linq?

What is the best approach to take to write a concat in Linq? I know that the official word is that you can't but I've heard that there are ways you can accomplish it and I need help to do this. I have a SQL Statement that reads as follows:
CONCAT(
[event_organiser] ,
' ', DATEPART(dd,[event_start]),
'/', DATEPART(mm, [event_start]))
AS organiser_info
I need to create this in Linq but I'm not sure how to based on my current setup. Here is my current select statement.
var datacontext = db.tbl_events.AsQueryable();
IQueryable<EventsViewModel> theevent = (
from v in datacontext
where v.event_start == null
select new EventsViewModel
{
event_idx = v.event_idx,
event_name = v.event_name
...concat goes here..
});
Thank you for the feedback on this question your comments and examples led me to the answer based on what you have shown me. Here is what worked for my particular scenario
next_charterer_info = string.Concat(p.fixture_charterer ?? "", " ", p.fixture_start.Value.Day, "/", p.fixture_start.Value.Month),
Thanks again
Just use "+" to join the strings?
from v in datacontext
where v.event_start == null
select new EventsViewModel
{
event_idx = v.event_idx,
event_name = v.event_name
organiser_info = event_organiser + ' ' + ...
});
You can use SqlFunctions (https://msdn.microsoft.com/en-us/library/system.data.objects.sqlclient.sqlfunctions.datepart(v=vs.110).aspx)
IQueryable<EventsViewModel> theevent = (
from v in datacontext
where v.event_start == null
select new EventsViewModel
{
event_idx = v.event_idx,
event_name = v.event_name
organiser_info = v.event_organiser + ' ' + DatePart("dd", v.event_start)
});
Other option is to include all needed columns and extend your EventsViewModel with a getter property:
public class EventsViewModel
{
...
public string organiser_info
{
get
{
return string.format("{0} {1} / {2}",
event_organiser,
event_start.ToString("dd"),
event_end.ToString("MM"))
}
}
}
Using this approach you will not be confronted with any non-translatable code constructs in Linq to Entities
var theevent = (
from v in datacontext
where v.event_start == null
select new EventsViewModel
{
event_idx = v.event_idx,
event_name = v.event_name
organiser_info = string.Format("{0} {1}/{2}", event_organiser ?? "", event_start.Date.ToString("d"), event_start.Date.ToString("M"))
});
UPDATE
String.Concat(string, string, string) is significantly faster than String.Format(). Also you can write that like this:
organiser_info = string.Concat(event_organiser ?? ""," ", event_start.Date.ToString("d"), event_start.Date.ToString("M"))
UPDATE2
Solution for retrive IQueryable odject:
IQueryable<EventsViewModel> theevent = (
from v in datacontext
where v.event_start == null
select new EventsViewModel
{
event_idx = v.event_idx,
event_name = v.event_name,
organiser_info = v.event_organiser ?? "" +
v.event_organiser ? " " : "" +
v.event_end ? SqlFunctions.DatePart("Day", v.event_end) : "" +
v.event_end ? SqlFunctions.DatePart("Month", v.event_end) : ""
}
Dont forget add using System.Data.Objects.SqlClient for SqlFunctions.DatePart.
From MSDN
This function is translated to a corresponding function in the
database. For information about the corresponding SQL Server function,
see DATEPART (Transact-SQL).

Retrieve The Second Name Using Regex

I want to use Regex to retrieve the person and its address.
The result wild be :
All Frank Anderson and its address inside of a string list.
Problem:
The problem I'm facing is that I cannot retrieve the second name that is "Frank Andre Anderson" based on my regex.
It also might be other people who can have another second name.
Thank you!
string pFirstname = "Frank"
string pLastname = "Anderson";
string input = w.DownloadString("http://www.birthday.no/sok/?f=Frank&l=Anderson");
Match theRegex8 = Regex.Match(input, #"(?<=\><b>)" + pFirstname + "(.+?)" + pLastname + "</b></a></h3><p><span>(.+?<)", RegexOptions.IgnoreCase);
foreach (var matchgroup in theRegex8.Groups)
{
var sss = matchgroup;
}
The current result that I'm using the code is:
You must be looking for something like
(?<=>[^<]*<b>)Frank([^<]+)Anderson</b></a></h3><p><span>([^<]+)
See concise RegexStorm demo
In C#, the regex declaration will be
Match theRegex8 = Regex.Match(input, #"(?<=>[^<]*<b>)" + pFirstname + "([^<]+)" + pLastname + "</b></a></h3><p><span>([^<]+)", RegexOptions.IgnoreCase);
The problem you had was with . matching any character while we need to restrict to a non-angle bracket.
Update
Perhaps, you could leverage HtmlAgilityPack by getting all <a> tags that have <b> as the first child, and then get the InnerText that meets your conditions:
var conditions = new[] { pFirstname, pLastname};
var seconds = new List<string>();
var webGet = new HtmlAgilityPack.HtmlWeb();
var doc = webGet.Load("http://www.birthday.no/sok/?f=Frank&l=Anderson");
var a_nodes = doc.DocumentNode.Descendants("a").Where(a => a.HasChildNodes && a.ChildNodes[0].Name == "b");
var res = a_nodes.Select(a => a.ChildNodes[0].InnerText).Where(b => conditions.All(condition => b.Contains(condition))).ToList();
foreach (var name in res)
{
var splts = name.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries);
if (splts.GetLength(0) > 2) // we have 3 elements at the least
seconds.Add(name.Trim().Substring(name.Trim().IndexOf(" ") + 1, name.Trim().LastIndexOf(" ") - name.Trim().IndexOf(" ") - 1));
}
This way, you will get just the second names. I could not test this code, but I think you get the gist.

String check null or empty before assigning

string TEST1 = "abc def"
classA.detailList= (from tbl1 in ds.Table[0].AsEnumerable()
where tbl1["column1"] = 'aaaa'
select new classdetail(){
Var A = ToString().Substring(0, tbl1["Vehicle_Make_Model"].ToString ().IndexOf(' ')).Trim()
Var B = ToString().Substring(tbl1["Vehicle_Make_Model"].ToString().IndexOf(' ') + 1).Trim()
}).ToList();
It works fine if i have string as TEST1 but how to handle if
TEST1="abc"
want to check whether second part is exists after space or not?
Please help me here
you can try something like this:
string[] outputParts = TEST1.Trim().Split(' ');
if (outputParts.Length == 2)
{
//do something
}

WebMatrix internal search engine

I've wrriten a code which searchs the database but i don't know why when i search for some specific keywords it'll show other links which are unrelated. here's the code and the result.
Page.Title = "Catalog Search";
var db = Database.Open("Shopping");
var searchWords = Request["searchTerm"].Split(' ');
IEnumerable<dynamic> result = Enumerable.Empty<string>();
var sqlSelect = "SELECT ProductId, ProductTitle FROM Products WHERE " +
"ProductTitle LIKE #0";
foreach(var word in searchWords)
{
result = result.Concat(db.Query(sqlSelect, "%" + word + "%").ToList());
}
so i searched for "Samsung LCD" and here's the result.
Samsung - 15" Series 9 Ultrabook Laptop
Samsung - Galaxy Tab 2 7.0
Samsung - 32" Class - LCD
Samsung - 32" Class - LCD
i've seen a php code which is exactly what i want but unfortunately i don't know how to convert it. here's the php code.
$searchTerms = explode(' ', $bucketsearch);
$searchTermBits = array();
foreach ($searchTerms as $term) {
$term = trim($term);
if (!empty($term)) {
$searchTermBits[] = "bucketname LIKE '%$term%'";
}
}
...
$result = mysql_query("SELECT * FROM buckets WHERE ".implode(' AND ', $searchTermBits).");
and the result of the php search code.
SELECT * FROM buckets WHERE bucketname LIKE '%apple%' AND bucketname LIKE '%and%' AND bucketname LIKE '%pear%'
I took the liberty of adding a few null checks and such, but the code for C# would pretty much look like this:
// make sure search terms are passed in, and remove blank entries
var searchTerms = Request["searchTerms"] == null ?
new string[] {} :
Request["searchTerms"].Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
// build the list of query items using parameterization
var searchTermBits = new List<string>();
for (var i=0; i<searchTerms.Length; i++) {
searchTermBits.Add("bucketname LIKE #" + i);
}
// create your sql command using a join over the array
var query = "SELECT * FROM buckets";
if (searchTerms.Length > 0) {
query += " WHERE " + string.Join(" AND ", searchTermBits);
}
// ask the database using a lambda to add the %
var db = Database.Open("StarterSite");
var results = db.Query(query, searchTerms.Select(x => "%" + x + "%").ToArray());
// enjoy!
Response.Write(results.Count());
Let me know if you run into any more trouble!

Categories

Resources