SQL like statement, issue with singular, plural keyword - sql

for (String column : searchCols) {
for (String keyword : keywords) {
listAllSql.append(getDBColumnName(column));
listAllSql.append(" like "); //like
listAllSql.append("'%"); //'%vision%'
listAllSql.append(keyword);
listAllSql.append("%'");
listAllSql.append(" or ");
}
Here is a snippet of of the code. I pass a keyword for example "Networks" to be searched for. I want the statement to return me result event if it finds "Network" (Singular) as well as those which contains "Networks" (plural). What changes to do I make to the above statement to achieve this. I am actually working with 'SQLite' Manager as an add on on Mozilla Firefox FYI.

You could just add to the top (not sure on the language):
for (String keyword : keywords) {
if right(keyword,1) = "s" and length(keyword) > 1 then
keyword = left(keyword,length(keyword)-1)
end if
listAllSql.append.....
you may run into problems where they search for 'as' and returns all which contain 'a' but finding words that are plural and not just ending with s will be MUCH harder, also generally false positives in a search are better than false negatives (in my opinion).

Related

tdbc::tokenize documentation and use

I'm using tdbc::odbc to connect to a Pervasive (btrieve type) database, and am unable to pass variables to the driver. A short test snippet:
set customer "100000"
set st [pvdb prepare {
INSERT INTO CUSTOMER_TEMP_EMPTY
SELECT * FROM CUSTOMER_MASTER
WHERE CUSTOMER = :customer
}]
$st execute
This returns:
[Pervasive][ODBC Client Interface]Parameter number out of range.
(binding the 'customer' parameter)
Works fine if I replace :customer with "100000", and I have tried using a variable with $, #, wrapping in apostrophes, quotes, braces. I believe that tdbc::tokenize is the answer I'm looking for, but the man page gives no useful information on its use. I've experimented with tokenize with no progress at all. Can anyone comment on this?
The tdbc::tokenize command is a helper for writing TDBC drivers. It's used for working out what bound variables are inside an SQL string so the binding map can be supplied to the low level driver or, in the case of particularly stupid drivers, string substitutions performed (I hope there's no drivers that need to do this; it'd be annoyingly difficult to get right). The parser knows enough to handle weird cases like things that look like bound variables in strings and comments (those aren't bound variables).
If we feed it (it's calling syntax is trivial) the example SQL you've got, we get this result:
{
INSERT INTO CUSTOMER_TEMP_EMPTY
SELECT * FROM CUSTOMER_MASTER
WHERE CUSTOMER = } :customer {
}
That's a list of three items (the last element just has a newline in it) that simplifies processing a lot; each item is either trivially a bound variable or trivially not.
Other examples (bear in mind in the second case that bound variables may also start with $ or #):
% tdbc::tokenize {':abc' = :abc = ":abc" -- :abc}
{':abc' = } :abc { = ":abc" -- :abc}
% tdbc::tokenize {foo + $bar - #grill}
{foo + } {$bar} { - } #grill
% tdbc::tokenize {foo + :bar + [:grill]}
{foo + } :bar { + [:grill]}
Note that the tokenizer does not fully understand SQL! It makes no attempt to parse the other bits; it's just looking for what is a bound variable.
I've no idea what use the tokenizer could be to you if you're not writing a DB driver.
Still could not get the driver to accept the variable, but looking at your first example of the tokenized return, I came up with:
set customer "100000"
set v [tdbc::tokenize "$customer"]
set query "INSERT INTO CUSTOMER_TEMP_EMPTY SELECT * FROM CUSTOMER_MASTER WHERE CUSTOMER = $v"
set st [pvdb prepare $query]
$st execute
as a test command, and it did indeed successfully pass the command through the driver

Rally custom list query not working on string custom field

I have a custom field being added on user story (HierarchicalRequirement) level.
The WSAPI documentation shows the following details for the field:
c_CustomFieldName
Required false
Type string
Max Length 32,768
Sortable true
Explicit Fetch false
Query Expression Operators contains, !contains, =, !=
When trying to create a report using Custom List to identify user stories where this field is empty, I add (c_CustomFieldName = "") to the query.
And yet, the result shows rows where this field is not empty.
How can that be?
I tried querying on null, but it didn't work.
thx in advance
What you're doing should work- are you getting errors, or just incorrect data? It almost seems like it's ignoring your query altogether.
I tried to repro both with the custom list app and against wsapi directly and the following all worked as expected:
(c_CustomText = "") //empty
(c_CustomText = null) //empty
(c_CustomText != "") //non-empty
(c_CustomText != null) //non-empty
It's possible you're running into some weird data-specific edge case in your data. It may be worth following up with support.

Search multi word phrase with wild cards in lucene

Using the following code block:
public void MultiField(string fieldValue, string[] fieldList)
{
List<Occur> occurs = new List<Occur>();
foreach (string field in fieldList)
{
occurs.Add(Occur.SHOULD);
}
MultiFieldQueryParser parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_30, fieldList, analyzer);
parser.AllowLeadingWildcard = true;
Query qry = parser.Parse(fieldValue.ToLower());
booleanQuery.Add(qry, Occur.MUST);
}
where fieldValue is a user input and fieldList is a set list of fields. I am using a standard analyzer.
I need to be able to search multiple words with wildcards enabled. In it's current state when a user enters a search term (for instance "search") the logic in my application will add * to either side making it "*search*". This brings back the expected results.
If, however a user entered "search s" it would search all fields for "*search" and then all fields again for "s*"; returning way more than the desired results. I have tried to escape special characters/whitespace however this also removes the wildcard search as "*" is a special character. I've tried this using the escape method and by adding "\"" in to the fieldValue string. Is there a way to encapsulate the whole phrase to search and append asterisks at the start and end of the search term?

Do I need to implement full text search in this case? alternatives?

I have two columns in a table first_name and last_name(PostgreSQL).
In front end, I have an input to allow users to search for people. It is an auto-complete field that calls a web service for searching people by first and/or last names.
Currently, I have made a query (using my query builder):
$searches = preg_split('/\s+/', $search);
if (!empty($search)) {
$orX = $query->expr()->orX();
$i = 0;
foreach ($searches as $value) {
$orX->add($query->expr()->eq('c.firstName', ':name'.$i));
$orX->add($query->expr()->eq('c.lastName', ':name'.$i));
$query->setParameter('name'.$i, $value);
$i++;
}
$query->andWhere($orX);
}
But this query is not as precise as it is required, it uses OR for every word so if I am looking for "Rasmus Lerdorf" it also gives me "Rasmus Adams" and "Adel Lerdorf". It works only if I enter a single word ("Rasmus" for example), in this case it gives me all people with "Rasmus" as first_name or last_name.
I read about MATCH AGAINST but I am using PostgreSQL. I also heard about Full text search feature in PostgreSQL as the equivalent of MATCH AGAINST, but I am wondering if implementing a full text search would be an overkill for such an objective (especially that the maximum number of words in both columns wouldn't exceed 4).
I ask you please your advices, your usual help is always appreciated. Thanks
You don't need fulltext search.
Just add the different search terms with AND instead of OR:
$i = 0;
foreach ($searches as $value) {
$orX = $query->expr()->orX();
$orX->add($query->expr()->eq('c.firstName', ':name'.$i));
$orX->add($query->expr()->eq('c.lastName', ':name'.$i));
$query->setParameter('name'.$i, $value);
$i++;
$query->andWhere($orX);
}
I would also suggest using LIKE instead of an equality comparison (add '%' to the start and end of the users search term), and probably also make everything case insensitive by adding $query->expr()->lower() appropriately.

MongoDB query returns 3 dots instead of answer

I am following an online course on a website and when I am trying to submit a query on my local MongoDB, it returns ... instead of the answer.
The query I submit is
db.scores.find( { "type" : "essay", "score" : 50 }, { student : true, _id : false ).pretty()
The "..." that I get as an "answer" from the local MongoDB server indicates that the server is expecting from me to provide it with more input.
I clearly have a syntax error on my query, I forgot to close a curly bracket.
The correct query db.scores.find( { "type" : "essay", "score" : 50 }, { student : true, _id : false } ).pretty() does not return "..."
HINT: In case the forgotten input is not in the end of the query, but somewhere in the middle (as happened in this query) you can escape the "..." mode by hitting the "enter" two times and then try to type in the new query again.
When I had this same error, its was the result of a string value being terminated prematurely due to a ' or " in the string. Look for any extraneous quotation marks or apostrophes in the values you're adding which may interfere with the declaration.
Just as addition: watch out the password string. Be aware it not to contain quotation mark which interfers with quotation mark of declaration of it, like in my case. I got ... too.