Find string in SQL column - c#

I have the next code(found here at stack overflow):
string [] arr = {"One","Two","Three"};
var target = "One";
var results = Array.FindAll(arr, s => s.Equals(target));
This code good for search string on array... i need to find string in sql column.
Let's say i have table ("Names"), and i want to find "Jhon".. how can i do that?
I don't need connectionstring or the whole method, that's i know to do, but i can't think on method to search specific string at sql table.
Will be great to see version of search: "Jh" and it will find "Jhon" if is there...

Well to avoid sql injection if target is user provided
string connectionString= ...
string target="jh";
using (var conn=new SqlConnection(connectionString)) {
conn.Open();
using (var cmd=conn.CreateCommand()) {
cmd.CommandText="select Name from Names where Name like '%'+#value+'%'";
cmd.Parameters.AddWithValue("#value",target);
using (var reader=cmd.ExecuteReader()) {
while (reader.Read()) {
Console.WriteLine(reader[0]);
}
}
}
}
Use like '%'+#value+'%' for contains
Use like #value+'%' for starts with
Use like '%'+#value for ends with

SELECT NAME
FROM NAMES
WHERE NAME='Jhon'
Is this what you're looking for?
If only a part of it needs to match:
...
WHERE NAME LIKE 'Jh%'
LIKE

Related

How would you match a record from a select statement against a string in c#?

I'm trying to create a statement to check data from a foxpro database against a string in c#
however I can't seem to get it working, would using parameterised queries here help to achieve what I'm trying to do?
string PROPCODE = "IMPORT_" + ID;
string leadtenant = clcodet;
using (OleDbCommand tenantpopulation = new OleDbCommand(#"SELECT
CLCODE,
CLCODEDESC
FROM CLIENT WHERE PROPCODET = " + PROPCODE, importConnection))
{
string tenants = "";
if (#"CLCODE" = leadtenant)
{
if (tenants != String.Empty)
{
//do something
}
}
}
To Clarify, i want to check whether CLCODE, called from tenantpopulation, matches leadtenant, defined elsewhere in the code
As others already noted using parameters is the way to go (not only in VFP but any SQL database). They are not only for preventing SQL injection attacks, using parameters the drivers take care of converting into correct string, adding/removing braces, quotes etc.
string PROPCODE = "IMPORT_" + ID;
string leadtenant = clcodet;
using (OleDbCommand tenantpopulation = new OleDbCommand(#"SELECT
CLCODE
FROM CLIENT WHERE PROPCODET = ?", importConnection))
{
tenantpopulation.Parameters.AddWithValue("p", PROPCODE);
// rest of code seem to be meaningless
// and I didn't see any code where you run your query
// depending on your requirement, I assume PROPCODET is a primary key?
// if so then you to do the check you only need to return the CLCODE
// with ExecuteScalar:
importConnection.Open();
var clcode = (string)tenantpopulation.ExecuteScalar();
importConnection.Close();
string tenants = "";
// in C# equality check is done with == NOT = (assingment)
if (clcode == leadtenant)
{
// tenants is always String.Empty here
if (tenants != String.Empty)
{
//do something
}
}
}
PS: Have you ever thought, using Tom Brother's LinqToVFP from codeplex? With Linq, you don't need to know these SQL dialects much and instead you use Object query (and intellisense).

How to get query names that references the particular iteration path

With selected project name, I had loaded iteration paths. Now I need to get the query names that references the selected iteration path.
Code to load iteration paths passing project name:
private void LoadIterationPaths(string projectName)
{
var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(_tfs.Uri);
var wiStore = tfs.GetService<WorkItemStore>();
var projCollections = wiStore.Projects;
var detailsOfTheSelectedProject = projCollections.Cast<Project>().Where(project => !String.IsNullOrEmpty(_selectedTeamProject.Name))
.FirstOrDefault(project => project.Name.Contains(_selectedTeamProject.Name));
var iterationPathsList = GetIterationPaths(detailsOfTheSelectedProject);
foreach (var iterationPath in iterationPathsList.Where(iterationPath => iterationPath.Contains(projectName)))
{
cmbIterationPath.Items.Add(iterationPath);
}
cmbIterationPath.Enabled = cmbIterationPath.Items.Count > 0;
}
Now, I need to get the list of Query names that references the selected iteration Path. Thanks.
Note: I am able to get all the query names in a project but that i don't need.
For that I used the below code
foreach (StoredQuery qi in detailsOfTheSelectedProject.StoredQueries)
{
cmbQueries.Items.Add(qi.Name);
}
Your code should looks like this
string selectedIterationPath = ...
foreach (StoredQuery qi in detailsOfTheSelectedProject.StoredQueries) {
if (qi.QueryText.Contains(selectedIterationPath) {
cmbQueries.Items.Add(qi.Name);
}
}
This is what me and Beytan Kurt suggested in the comments.
Instead of a dumb Contains, you should use a Regular Expression to account for false positives and negatives.

What is the efficient way to get only first Lookupvalue from SpFieldLookupValueCollection in SharePoint 2010?

I want to Access only first Lookupvalue of SpFieldLookupValueCollection presently I am doing something like this
string abc = string.Empty;
foreach (SPFieldLookupValue value in SpFieldLookupValueCollection)
{
abc = value.LookupValue;
break;
}
Am Fresher to sharepoint please tell me better and faster way to access lookup Values
Thank you
SPFieldLookupValue fieldValue=SpFieldLookupValueCollection.FirstOrDefault();
and
SpFieldLookupValueCollection.First();
this will give the desired result.
You can simply use Linq query as follows,
var firstElement = SpFieldLookupValueCollection.FirstOrDefault();
Note: you will have to include System.Linq; namespace
It's better to get the value of a specific column rather than retrieveing all columns.The following code should work for you.
string fieldValue = "";
if (item["fieldname"] != null)
{
var val= (SPFieldLookupValue)item["fieldname"];
fieldValue = fieldValue .LookupValue;
}

Dapper parameters not working

I'm trying to use the Dapper orm with the following simple query:
var sqlString = new StringBuilder();
sqlString.Append("select a.acct AccountNumber,");
sqlString.Append(" b.first_name FirstName,");
sqlString.Append(" b.last_name LastName,");
sqlString.Append(" a.rr RrNumber,");
sqlString.Append(" c.addr1 AddressLine1,");
sqlString.Append(" c.addr2 AddressLine2,");
sqlString.Append(" c.addr3 AddressLine3,");
sqlString.Append(" c.addr4 AddressLine4,");
sqlString.Append(" c.addr5 AddressLine5,");
sqlString.Append(" c.addr6 AddressLine6,");
sqlString.Append(" c.addr7 AddressLine7,");
sqlString.Append(" c.addr8 AddressLine8 ");
sqlString.Append("from (pub.mfclac as a left join pub.mfcl as b on a.client=b.client) ");
sqlString.Append("left join pub.mfclad as c on a.client=c.client ");
sqlString.Append("where a.acct = '#ZYX'");
var connection = new OdbcConnection(_connectionString);
var result = connection.Query(sqlString.ToString(),
new
{
ZYX = accountNumber
});
However when I execute this with an accountNumber known to exist, dapper returns nothing. So I tried to remove the quotes to verify that the parameter is in fact being replaced with the account number, however the error being returned from the server indicates a syntax error around "#ZYX". Which means dapper is not replacing the parameter with it's given value. Any ideas why this is happening? From the limited documentation out there, this should 'just work'.
Edit1
Couldn't get this to work. Using string.format to insert the parameter as a work around.
There are two issues here; firstly (although you note this in your question) where a.acct = '#ZYX', under SQL rules, does not make use of any parameter - it looks to match the literal string that happens to include an # sign. For SQL-Server (see note below), the correct usage would be where a.acct = #ZYX.
However! Since you are use OdbcConnection, named parameters do not apply. If you are actually connecting to something like SQL-Server, I would strongly recommend using the pure ADO.NET clients, which have better features and performance than ODBC. However, if ODBC is your only option: it does not use named parameters. Until a few days ago, this would have represented a major problem, but as per Passing query parameters in Dapper using OleDb, the code (but not yet the NuGet package) now supports ODBC. If you build from source (or wait for the next release), you should be able to use:
...
where a.acct = ?
in your command, and:
var result = connection.Query(sqlString.ToString(),
new {
anythingYouLike = accountNumber
});
Note that the name (anythingYouLike) is not used by ODBC, so can be... anything you like. In a more complex scenario, for example:
.Execute(sql, new { id = 123, name = "abc", when = DateTime.Now });
dapper uses some knowledge of how anonymous types are implemented to understand the original order of the values, so that they are added to the command in the correct sequence (id, name, when).
One final observation:
Which means dapper is not replacing the parameter with it's given value.
Dapper never replaces parameters with their given value. That is simply not the correct way to parameterize sql: the parameters are usually sent separately, ensuring:
there is no SQL injection risk
maximum query plan re-use
no issues of formatting
Note that some ADO.NET / ODBC providers could theoretically choose to implement things internally via replacement - but that is separate to dapper.
I landed here from dublicate question: Dapper must declare the scalar variable
Error: Must declare the scalar variable "#Name".
I created queries dynamically with this piece of code:
public static bool Insert<T>(T entity)
{
var tableName = entity.GetType().CustomAttributes.FirstOrDefault(x => x.AttributeType.Name == nameof(TableAttribute))?.ConstructorArguments?.FirstOrDefault().Value as string;
if (string.IsNullOrEmpty(tableName))
throw new Exception($"Cannot save {entity.GetType().Name}. Database models should have [Table(\"tablename\")] attribute.");
DBSchema.TryGetValue(tableName.ToLower(), out var fields);
using (var con = new SqlConnection(ConnectionString))
{
con.Open();
var sql = $"INSERT INTO [{tableName}] (";
foreach (var field in fields.Where(x => x != "id"))
{
sql += $"[{field}]"+",";
}
sql = sql.TrimEnd(',');
sql += ")";
sql += " VALUES (";
foreach (var field in fields.Where(x => x != "id"))
{
sql += "#"+field + ",";
}
sql = sql.TrimEnd(',');
sql += ")";
var affectedRows = con.Execute(sql, entity);
return affectedRows > 0;
}
}
And I got the same error when my models was like this:
[Table("Users")]
public class User
{
public string Name;
public string Age;
}
I changed them to this:
[Table("Users")]
public class User
{
public string Name { get; set; }
public string Age { get; set; }
}
And it solved the problem for me.

C# Retrieve Values from URL and insert records

In my code I have received, by way of a url, a comma delimited list of id's e.g.
12,13,14,15,16 etc..
I have got these into a string (Tools) which I have Split.
I now need to loop through each value and use it in an insert statement but I have got stuck can anyone help.
The C# below is based on an SDK so it is uses some functions that you may not have seen.
string userc = GetContextInfo("User", "UserId");
string tools = Dispatch.EitherField("selectedTools");
tools.Split(',');
string pID = Dispatch.EitherField("key16");
Record recRelTool = new Record("RelatedTools");
recRelTool.SetField("rato_CreatedBy", userc);
recRelTool.SetField("rato_Status", "active");
recRelTool.SetField("rato_server", pID);
recRelTool.SetField("rato_tool", tools);
recRelTool.SaveChanges();
Dispatch.Redirect(Url("1453"));
Where the ("rato_tools", tools) needs to be one of the tool id's in the value I have. I need to loop through until all of the tool id's have been used.
The call to split does not split your string, it returns an array of strings. You need to enumerate through this array to use one tool id at a time. Try the following:
string userc = GetContextInfo("User", "UserId");
string tools = Dispatch.EitherField("selectedTools");
string[] toolIds = tools.Split(',');
foreach (string toolId in toolIds)
{
Record recRelTool = new Record("RelatedTools");
recRelTool.SetField("rato_CreatedBy", userc);
recRelTool.SetField("rato_Status", "active");
recRelTool.SetField("rato_server", pID);
recRelTool.SetField("rato_tool", toolId);
recRelTool.SaveChanges();
}
Dispatch.Redirect(Url("1453"));
you have to assign your split return value:
var splitted = tools.Split(',');
http://msdn.microsoft.com/en-us/library/tabh47cf.aspx
and then you can iterate the collection:
foreach(string item in splitted)
{
//do something
}

Categories