print("select CustomerNo, CustomerName, Address, City, State, Zip,
Phone, Fax, ContactName, Email
from Customers where CustomerName like '%field%'");
Hi all. This is a simple question but I wasn't able to figure since I'm pretty new to tsql and sql in general.
I use the above stored procedure to do search. My question is for '%field%'. What variable do you use or how does it work in tsql? for example, "where Customers = #CustomerNo". how about for wildcard? how do you pass in a variable along with wildcard? I guess i can do "%" + "field" + "%" in the code but is there a way not to do that?
Wildcards are simply part of a string literal, e.g. '%field%' is just a string.
You can concatenate the wildcards onto your string and then use the string:
#Pattern = '%' + #CustomerName + '%';
...WHERE CustomerName LIKE #Pattern
Or else you can write an expression in the SQL involving concatenation:
WHERE CustomerName LIKE '%' + #CustomerName + '%'
There's no other magic solution for this.
It is very simple. "=" and "Like" are both operators. What you can do after one you can do after the other.
So, if in C# and using SQLClient calls, you can say:
string value;
...
value = "Some name";
...
myCommand.CommandText = "Select...from Customers Where CustomerName Like #Var";
myCommand.Parameters.AddWithValue("#Var", "%" + value + "%");
myCommand.ExecuteNonQuery();
If you use =, you say "equal", which won't use wildcards.
If you use LIKE, which only work on text fields, it can use wildcards.
There is no way you can get wildcard matches with =.
Note that depending on the data, a wildcard search might do a table-scan, so I would make sure that's what you want before you allow it.
For instance, this will do a table-scan:
WHERE CustomerID LIKE '%1'
ie. all customers who have a customer identifier (which is text) that ends with a 1. That can't be solved with an index.
Final thoughts. I'm not 100% sure I understand exactly what you're asking. Could you please clarify. What specifically do you mean by "pass in a variable along with wildcard"?
Related
I recently had a request come through to remove some Agent names from the guest surname field in a client's database.
Eg. 'John Smith -Wotif'
When testing using the following UPDATE statement, the entire field was wiped rather than just the specific string.
UPDATE GUEST
SET SURNAME = REPLACE(' -Wotif',' -Wotif','')
WHERE SURNAME LIKE '% -Wotif'
I've since found that simply using the column name as the matching string will allow the full statement to work (even if already specified in the SET section), but I can't work out where the logic of the original statement effectively says 'wipe these fields entirely'.
Unless specified otherwise, surely the '' replacement only applies to the value contained within the substring, regardless of whether the string and substring match?
The first argument in the REPLACE function is the full string that you want to search. So you should be referencing the SURNAME field rather than specifying part of the string.
REPLACE(SURNAME,' -Wotif','')
You update SQL command should be like this -
UPDATE GUEST
SET SURNAME = REPLACE(SURNAME, 'FindValue' , 'ReplaceWithValue')
WHERE SURNAME LIKE '% -Wotif'
If you want to find & replace '-Wotif' with blank, then update command should be like below-
UPDATE GUEST
SET SURNAME = REPLACE(SURNAME, '-Wotif' , '')
WHERE SURNAME LIKE '% -Wotif'
İ have a problem with contains function, when i search with like '%ZAM%' operator, it finds all word that contains ZAM like ZAMANLAMA AZAMI ZAM and etc.. but when I use fts index contains function, it just find ZAM ZAMANLAMA but it doesnt find AZAMI or 123ZAM789. I have also tried CONTAINS (YourColumn, ' "ZAM" ' ) but it doesn't work. Please help me , fts is very fast but it could not find all contains like '%%' operator what should I do ?
You can use "*" before in contain syntax same as like operator . but you need to use double quote before and after the search string.
Try this query once.
SELECT *
FROM YourTable
WHERE CONTAINS(YourColumn,'"*ZAM*"');
(OR)
select * from YourTable where YourColumn like '%ZAM%'
I have a very peculiar case. My ASP.NET page calls a stored procedure of ours that performs a Full-Text Search query on our database. Some of the commonly searched strings include an ampersand because a few brands of our products (well-known brands, too) have an & in their name.
It turns out that in a certain case I get no results unless I escape the ampersand (\&), and in a certain other case I get no results only if I escape the ampersand.
I don't know if this is relevant, but (without giving out the brand names) one ends in &b and the other one in &c.
Is it possible that these strings (&b or &c) have some special meaning of their own? And that by escaping them I'm actually passing a special string to T-SQL?
EDIT
Additional info: after further testing, I proved that the error is in the stored procedure itself. Calling it with & or \& yields different results.
I'll try to post selected parts of the stored procedures. I won't post it all, because most of it isn't really relevant.
The vParamBuca parameter is the one that causes the troubles. Values could be 'word&letter' or word\&letter.
SET #ricercaA = '''FORMSOF(INFLECTIONAL,"' +
REPLACE(LTRIM(RTRIM(#vParamBuca)),' ', '") AND FORMSOF(INFLECTIONAL,"') + '")'''
The variable #ricercaA is then used to create the query string:
[...]
FROM Products AS FT_TBL
LEFT OUTER JOIN CONTAINSTABLE (Products, Sign1, '+ #ricercaA + ') AS ColSign1_0 ON FT_TBL.ID = ColSign1_0.[KEY]
LEFT OUTER JOIN CONTAINSTABLE (Products, ManufacturerAdditionalText, '+ #ricercaA + ') AS ColManufacturerAdditionalText_0 ON FT_TBL.ID = ColManufacturerAdditionalText_0.[KEY]
LEFT OUTER JOIN CONTAINSTABLE (Products, ManufacturerForSearch, '+ #ricercaA + ') AS ColManufacturer_0 ON FT_TBL.ID = ColManufacturer_0.[KEY]
LEFT OUTER JOIN CONTAINSTABLE (Products, TuttaLaRiga, '+ #ricercaA + ') AS ColTuttaLaRiga_0 ON FT_TBL.ID = ColTuttaLaRiga_0.[KEY]
[...]
EDIT 2
Many thanks to #srutzky for pointing me in the right direction! In the meanwhile, I also found a data inconsistency where one of the brands with the & in its name was modified not to have the &, and the other one wasn't modified (bottom line, my current problem is caused by that: a partial fix that was made by someone in the past).
Anyway, back on track. Now I understand that the & character in the CONTAINSTABLE function is treated as a logical AND (non bitwise).
I still need a solution for that. This answer gives a solution that doesn't work for me (the conditions are not the same as mine). How could I perform a CONTAINSTABLE search for a string with an ampersand in it? Preferably without having to transform the ampersand to another safe character?
The odd behavior you are seeing is most likely due to the CONTAINS and CONTAINSTABLE functions (both used with SQL Server's Full Text Search feature) using the ampersand ( & ) character as equivalent to the AND operator. The following statement is taken from the documentation for CONTAINS:
The ampersand symbol (&) may be used instead of the AND keyword to represent the AND operator.
There is no mention of there being any escape character for it (and a back-slash isn't typically an escape character in SQL anyway).
UPDATE
Based on the information now provided in "Edit 2" of the Question, and additional research, I would say that you do not need to escape anything. It seems that putting the search phrases in double-quotes (as a result of using FORMSOF) treats the & as either a literal or a word-breaker, depending on the values on both sides of the &. Try the following examples:
DECLARE #Term NVARCHAR(100);
SET #Term = N'bob&sally'; -- 48 rows
--SET #Term = N'bob\&sally'; -- 48 rows
--SET #Term = N'r&f'; -- 4 rows
--SET #Term = N'r\&f'; -- 24 rows
SET #Term = N'FORMSOF(INFLECTIONAL,"' + #Term + '")';
SELECT * FROM sys.dm_fts_parser(#Term, 1033, 0, 0);
SELECT * FROM sys.dm_fts_parser(#Term, 1033, 0, 1);
SELECT * FROM sys.dm_fts_parser(#Term, 1033, NULL, 0);
SELECT * FROM sys.dm_fts_parser(#Term, 1033, NULL, 1);
The results for bob&sally and bob\&sally are the same, and in both cases bob and sally are separated and never combined into a single exact-match string.
The results between r&f and r\&f, however, are not the same. r&f is only ever treated as a single, exact-match string because r and f alone are not known words. On the other hand, adding in the back-slash separates the two letter since \ is a word-breaker, in which case you get both r and f.
Given that you stated in the Update that you have "data inconsistency, where one of the brands with the "&" in its name was modified not to have the "&", and the other one wasn't", I suspect that when you do not add in the \ character you get the brand that was not modified (since it is an exact match for the full term). But when you do add in the \ character, then you get the brand that was modified to have the & removed, since you are now searching on both pieces, each one matching part of that brand name.
I would fix the data to be consistent: update the brand names that had the & removed to put the ampersands back in. Then when people search using & without the extra \ added, it will be an exact match. This behavior will be consisted across the data, and will not require you adding code to circumvent the natural operation of FTS, which seems to be an error-prone approach.
My stored procedure receives a parameter which is a comma-separated string:
DECLARE #review_status varchar(200)
SET #review_status='CANCELLED,INSPECTED,REJECTED,UNASSIGNED'
I use this variable with LIKE Operator, when value without comma then perfect but it comes with comma then unable to handle.
Now i use this statement
SELECT * FROM tblReview WHERE
review_status LIKE '%' + #review_status + '%'
I need to make from it this statement
SELECT * FROM tblReview WHERE
review_status LIKE '%CANCELLED%' OR --Pass #review_status
review_status LIKE '%INSPECTED%' OR
review_status LIKE '%REJECTED%'.....
What is the best practice for doing this?
You could use a string splitter to do this. Read this article for one of the fastest splitter there is.
Then you need to use the IN operator to do the filtering:
SELECT *
FROM tblReview
WHERE review_status IN(
SELECT item FROM dbo.DelimitedSplit8K(#review_status,',')
)
Since you're using LIKE, you may want to do JOIN instead of IN:
SELECT *
FROM tblReview t
INNER JOIN dbo.DelimitedSplit8K(#review_status, ',') s
ON t.review_status LIKE '%' + s.Item + '%'
Try to first convert varchar with commas to a table as described here http://blogs.msdn.com/b/amitjet/archive/2009/12/11/sql-server-comma-separated-string-to-table.aspx. Then, use the following:
CREATE TABLE #allPattern (
pattern NVARCHAR(max)
);
INSERT INTO #allPattern VALUES ('%CANCELLED%'), ('%INSPECTED%'), ('%REJECTED%');
SELECT t.* FROM tblReview t JOIN #allPattern a ON (t.review_status LIKE a.pattern);
You can add the pre- and trailing comma to yous string, and then use CHARINDEX().
SET #review_status=',CANCELLED,INSPECTED,REJECTED,UNASSIGNED,'
SELECT * FROM tblReview WHERE
charindex(','+review_status+',', '#review_status') >0
Commas at the beginning and at the end of the string are used to make an exact string finding possible - for example, if you have two statuses - one called CAN and the second called CANCELLED, charindex without side commas will find them both.
It's the simplest way, but not the one with the best performance, so don't use it on long CSVs.
I've created a simple stored procedure with some default values to enable customised searching of my "MachineModel" database.
As part of the WHERE clause I have something like this:
Model.[ModelName] LIKE '%' + ISNULL(#ModelName, Model.[ModelName]) + '%'
which should allow for partial matches. This works for the majority of models, however if no value is supplied for #ModelName (and therefore the ISNULL resolves to Model.[ModelName]) and the underlying field data contains square brackets, such as "Lenny's Test Model [2010]", then those records records aren't returned by the SProc.
This isn't a huge problem as only 4 models (of about 120,000) actually have square brackets in their names so I could easily change them, however I'm curious to know what's going on and what's the best way to solve this.
Cheers,
Lenny.
You need to replace the leading bracket by [[]
There are 3 characters with meaning in LIKE: % _ [. You don't need to escape the trailing bracket.
For completeness:
Model.[ModelName] LIKE '%' + ISNULL(
--don't do it the other way around!
REPLACE(REPLACE(REPLACE(#ModelName, '[', '[[]), '%', '[%]), '_', '[_]),
Model.[ModelName]) + '%'
Why are you comparing the model with itself in case of null search parameter? This is expensive.
It is also not great practice to mix ands and ors with SQL Server as its expensive, but could be done:
Where (
#ModelName is null OR
(ModelName is not null AND ModelName LIKE '%' + #ModelName + '%')
)
if performance could be a prob, then introducing an if can help, but you do end up duplicating your select
if #ModelName is null
select * from ...
else
select ...
where ModelName LIKE '%' + #ModelName + '%'
You could, but it will upset your dba, build the sql up in code and use sqlparameters and only add the where when this var is not null