I have a complex select statement for an Access 2010 database which grabs data from multiple tables using several LEFT JOIN statements. The query works as expected and I get the entire table.
So now I want to add search functionality.
One way was to add a WHERE clause at the end of the query and reference one of the JOINed tables' text field and compare it against some text (WHERE [All Names].Name LIKE "*Mark*").
Second option I tried was select * from (**complex sql here**) where **condition**
Now in both cases, when my condition is something simple like ([ID]<15), it works like a charm, but when I change it to ([Employee Name] LIKE "\*Mark\*") or the one in option 1, it produces an empty data table as if the request goes through, there is no error or exception, all the field names are present, but no rows are returned.
However, if I grab the full string of the generated SQL string (either option) using the debugger (or just dump it into a text file), and then with literally no changes put that string directly into a new Access query, it works fine and returns several fields where the name contains "Mark"
Very simply put, a query that works fine within Access, does not work from within C#.
So I am now confused
You're using OleDb to connect to the Access db file. In that situation you must use ANSI wild cards (% and _) for a Like comparison instead of * and ?.
Use a pattern like this in your WHERE clause.
WHERE [Employee Name] LIKE "%Mark%"
If you want a query which works the same within an Access session as it does from an OleDb connection, use ALIKE instead of LIKE. ALIKE always uses the ANSI wild cards.
WHERE [Employee Name] ALIKE "%Mark%"
Simon's question and HansUp's answer ended up solving my problem.
For those curious or having a similar problem, here is full query:
string query=
"SELECT Employees.ID, " +
"[All Names E].Name AS [Employee Name], " +
"Titles.Title, " +
"[All Names S].Name AS [Supervisor Name], " +
"Employees.[Phone #], " +
"Offices.[Office Location], " +
"PCs.PC " +
"FROM (((((Employees LEFT JOIN [All Names] as [All Names E] ON Employees.Employee = [All Names E].ID) " +
"LEFT JOIN [All Names] as [All Names S] on Employees.Supervisor=[All Names S].ID) " +
"LEFT JOIN Titles on Employees.Title=Titles.ID) " +
"LEFT JOIN Offices on Employees.[Office Location]=Offices.ID) " +
"LEFT JOIN PCs on Employees.PC=PCs.ID) " +
"ORDER BY Employees.ID";
Adding a where clause before ORDER BY that is WHERE ([All Names E].Name LIKE \"*Mark*\") did work from within Access.
The second way was:
string searchQuery="select * from ("+query+") where ([Employee Name] like \"*Mark*\")";
Both methods worked perfectly in Access, but I had no idea there was a different wildcard symbol for use with OleDB.
So changing the asterisk to a percentage sign fixed the issue.
Thanks again.
Related
I need to make a search button for ASP.NET C# web site. Making a button with 1 kind of search key is easy. For example:
Select * from table where name like '%' + search_criteria + '%'
But what I really need is to make a search button that will contain more "like" from different though tables. I have in my DB
Category.Category_Name nchar
Product.Description nchar
Product.Product_Cost float
Manufacturer.Manufacturer_Name nchar
And you can see which ones are in which table. Also with the help of GridView I want to show on my webpage only the first 3. But I want a single textBox with a single button and when I try to search something, search either category name or description or cost or manufaturer name all in 1.
I have read that you can only search multiple things from one table or use contain statement in order to search from different tables. I've looked many hour in internet but in vain. Can someone help me figure out what do I need to right in WHERE clause so I can put that in aspx.cs C# code in LIKE filter and have my button worked?
I don't know if this exactly answers your question, but I will try. Although, to be fair, it is not supremely clear what you need and the question is bordering Too Broad
void btnSearch_Click (object sender, EventArgs e)
{
string sql = "select Product_name from Product p inner join Category c on p.Category_id = c.Category_id WHERE c.Category_Name Like '%{0}%' UNION ALL " +
"select Product_name from Product where Description Like '%{0}%' UNION ALL " +
"select Product_name from Product p inner join Manufacturer m on p.Manufacturer_id = m.Manufacturer_id WHERE m.Manufacturer_id Like '%{0}%' ";
decimal price;
if (decimal.TryParse(txtSearch.Text.Trim(), out price)
sql += "UNION ALL select Product_name from Product where Product_Cost >= {0} "
Search(string.Format(sql, txtSearch.Text.Trim());
}
void Search (string sql)
{
// use your sql here to fill the grid, etc.
}
NOTE #JoelCoehoorn noted about possibility of Sql Injection with this code [which is security concern]. I don't know if you care about it at this time. But to prevent Sql Injection you will need to use query parametrization. There will need to be slight change to the query but more changes to Command object setup.
I'm trying to do a simple SELECT statement from a MySQL Database.
My table names contains underscores (_) and they could contain spaces ( ) as well. I put the table name in backticks but I get SQL Syntax error.
Example of one of my query:
"SELECT * From '" + ID + "_" + objectName + "' ORDER BY date DESC LIMIT 1"
If I do not use the backticks and the object name does not have any space in it, the query works.
Any idea what could be the problem?
You have not "put the table name in backticks", but rather in single quotes. Use instead:
"SELECT * From `" + ID + "_" + objectName + "` ORDER BY date DESC LIMIT 1"
Beware: having variable table names of this sort generally indicates that one's schema violates the Principle of Orthogonal Design, which can lead to a whole world of pain. You may wish to consider combining all such records into a single table, with a column whose value indicates whatever differentiation exists between the existing tables.
We are using Abra Suite Software that is using a VFP db. I have a small program in C# that I would like to use to retrieve data from the db and generate a csv file from it. At this point my problem is to get the data based on the range of date that I specified in the SQL statement. Below is my SQL statement and for whatever reason I see that there are records from 2008 (i.e. 06/09/2008). What am I doing wrong here? Because when I read how SQL works I should have been able to do "WHERE chkdate BETWEEN '2007-06-01' '2007-06-06'" but I always get 'Operator/operand type mismatch', that's why I am using CAST in my current SQL statement.
string SelectCmd = "SELECT TOP 100 p_empno, p_fname, p_lname, chknumber, chkamount, CAST(chkdate AS varchar(10)) " +
"FROM hrpersnl " +
"INNER JOIN prckhist ON hrpersnl.p_empno = prckhist.empno " +
"WHERE CAST(chkdate AS varchar(10)) BETWEEN '06/06/2007' AND '06/09/2007' " +
"ORDER BY p_empno";
Put braces instead of apostrophes around your two between dates, like {06/06/2007} AND {06/09/2007}
I started by asking this question I wish to Select all rows which contain any element from an array
And while my current question is almost identical, it serves a whole different purpose, and so I fear the answer may be different which would obscure the previous one, with that said.
I am working on a search engine type thing. I need to search a title stored in a database to see if it contains any of the words in the search textbox. I plan to then iterate through each of those rows, counting how many words match and ranking the results accordingly. I am sure this has been done many times by now. I just can't seem to figure out how to do it without
select * from table
then sorting it in c#
one way in sql server is
push the word in temp table like this
DECLARE #SearchWords TABLE (
word varchar(30) )
INSERT INTO #SearchWords
(word)
VALUES ('Jack')
,('Pontiac')
,('Bloggs');
than join this table with the actual table
SELECT a.* FROM table_data a
INNER JOIN #SearchWords b on a.record_desc like '%' + b.word + '%'
You could try something like this:
SELECT * FROM table WHERE name LIKE '%word1%' OR name LIKE '%word2%';
The % signs are the analogous to * in typical searches.
To take the string and create this query for multiple words you could do something like this:
String inputString = "hello my friend";
String[] wordlist = inputString.split(" ");
String query = "SELECT * FROM table WHERE 0=0 ";
for(String word : wordlist) {
query += "OR name LIKE '%" + word + "%' ";
}
The spaces at the end of the strings are important, don't forget those! Also, you'll probably want to sanitize the string before you split it (remove extra punctuation, maybe even remove words like "a" or "the" or "to" etc.)
I have an SQL query of this form
string cmdText = "Select * from " + searchTable
+ "WHERE " + searchTable
+ "Name =' " + searchValue + "'";
Basically what I am trying to do is get a particular actor's info from the database's Actors table. The variable searchTable has the value 'Actor' which is the table name and searchValue has the actor's name (which is represented by the ActorName attribute in the Actor's table, here I am trying to form the name of the attribute by concatenating the words 'Actor' and 'Name' )
So, well, all this concatenation results in (or at least should result in) a query of the form:
Select * from Actor where ActorName ='some actor';
But when I try to run this it gives me the error "Incorrect syntax near '=' " in the browser. Could anyone please help?
You can put (and should!) parameters into your SQL queries for the values in e.g. your WHERE clause - but you cannot parametrize stuff like your table name.
So I'd rewrite that query to be:
SELECT (list of columns)
FROM dbo.Actor
WHERE ActorName = #ActorName
and then pass in just the value for #ActorName.
If you need to do the same thing for directors, you'd have to have a second query
SELECT (list of columns)
FROM dbo.Directors
WHERE DirectorName = #DirectorName
Using parameters like this
enhances security (prohibits SQL injection attacks!)
enhances performance: the query plan for that query can be cached and reused for second, third runs
PS: the original problem in your setup is this: you don't have any space between the first occurence of your table name and the WHERE clause - thus you would get:
SELECT * FROM ActorWHERE ActorName ='.....'
If you really insist on concatenating together your SQL statement (I would NOT recommend it!), then you need to put a space between your table name and your WHERE !
Update: some resources for learning about parametrized queries in ADO.NET:
The C# Station ADO.NET Tutorial / Lesson 06: Adding Parameters to Commands
Using Parameterized Queries with the SqlDataSource
You shouldn't concatenate string to SQL, as this will open you up to SQL Injection attacks.
This is a rather long read about dynamic SQL, but worth reading to understand the risks and options.
You should be using parameterized queries instead, though the only way to use a table name as a parameter is to use dynamic SQL.
I urge you to change your approach regarding table names - this will lead to problems in the future - it is not maintainable and as I mentioned above, could open you to SQL Injection.
The error you are seeing is a result of the concatenation you are doing with the "Where " clause - you are missing a space before it. You are also adding a space after the ' in the parameter ending with "Name".
Your resulting string, using your example would be:
Select * from ActorWHERE ActorName =' some actor';
There is a blank missing and one too much:
searchTable + "Name =' "
should read
searchTable + " Name ='"
Beside that, use SQL parameters to prevent SQL injection.
string cmdText = "Select * from " + searchTable + " WHERE Name = '" + searchValue + "'";