Search Varchar and Integer Columns in T-SQL - sql-server

I have a search functionality in my application which searches a string value of a particular column. The search text is passed as a parameter to the procedure. Now I have to search in another column which is an integer from another table. The input param is one but now I have to search in both the columns and return the result according to that.
//Query:
#SearchText VARCHAR(8000) = ''
SELECT DISTINCT Id, TransactionId, wfdFieldValue
where (wfdFieldValue LIKE '%' + #SearchText + '%' OR #SearchText = '')
In the above query I have to include the TransactionId in the where condition. So that if the user searched using the TransactionId or the Fieldvalue the query will return the result.
Note: The TransactionId is an Integer DataType.

If I understand you correctly, you'll want a hit in either column to make the row show up in search results. In that case, you'll need a simple OR;
SELECT DISTINCT Id, TransactionId, wfdFieldValue
FROM bop
WHERE #SearchText='' OR
wfdFieldValue LIKE '%' + #SearchText + '%' OR
TransactionId LIKE '%' + #SearchText + '%'
(You can just use LIKE on the integer column right away without manually converting.)
Of note though, this kind of wildcard search with a leading % does not use indexes in an optimal way, performance of this query will most likely not be great as the table grows.

SELECT DISTINCT Id, TransactionId, wfdFieldValue
where wfdFieldValue LIKE '%' + #SearchText + '%'
OR #SearchText = ''
OR CAST(TransactionId AS VARCHAR(50)) LIKE '%' + #SearchText + '%'
A cast should solve it, but I would first think about possible design improvements.

Related

Compare String values in SQL

I have a stored procedure which is called from a program. This stored procedure is passed 2 names and needs to find similar names in the database. However when I try to compare - 'AFC Bournemouth' with the name in the db which is 'Bournemouth'.
bet.searchFixtureForResult
#homeTeam NVARCHAR(MAX),
#awayTeam NVARCHAR(MAX),
#date DATE
AS
SELECT fixtureId
FROM bet.fixture
WHERE homeTeam IN (SELECT teamId
FROM bet.team
WHERE team LIKE '%' + #homeTeam + '%')
AND awayTeam IN (SELECT teamId
FROM bet.team
WHERE team LIKE '%' + #awayTeam + '%')
AND fixtureDate = #date
This supposedly returns the Id of the fixture that falls within the parameters given. How can compare similar strings such that I compare in the same way you compare with .Contains in C#?
I don't think you need bet.team there at all, your query will be like
SELECT fixtureId
FROM bet.fixture
WHERE (HomeTeam LIKE '%' + #HomeTeam + '%' OR #HomeTeam LIKE '%' + HomeTeam + '%')
AND
(AwayTeam LIKE '%' + #AwayTeam + '%' OR #AwayTeam LIKE '%' + AwayTeam + '%')
AND
fixtureDate = #date;
Here is a little Demo

SQL concat / + operator behaving strangely?

So basically to explain my situation I have a program where a user can select code numbers, that are alpha numeric. These codes are stored in my SQL database as datatype char.
When they select all the codes they want, the program then sends a few parameters(the codes being one of them). The codes are strung together and look something like this:
',01,1,A3' etc. etc. with commas separating the codes. I have the comma in front, but changing the comma to the back does not change anything.
the #reasonCode variable is the reason codes strung together.
In my where clause I have a statement that is this:
(#reasonCode = 'ALL') OR
((#reasonCode <> 'ALL' AND (charindex(',' + ro_reason_code, #reasonCode) > 0)))
Basically I want to restrict my results to just those that have those specific reason codes the user selected(among other parameters). I am trying to achieve that by stringing together the codes, and then searching through them using charindex, seperated by commas.
However I am running into an issue. Here are the results using a few different variations of reason codes:
',1' = 625 records (correct number)
',01' = 1015(correct number)
',01,1 = 1640(correct number)
',1,01' = 1015(for whatever reason it isn't picking up the 1 reason codes)
That is my issue right there.
When I put the 1 in front of the 01, it doesn't pick up the 1 reason codes. But if I do it flip-flopped it works fine...
Any ideas as to why this happens?
(I have tried also using the concat function and get the same results, and also tried forcing everything to be char datatype.)
In the end I would like the same result, regardless if it is ,01,1 or ,1,01.
I'm pretty sure this is because you said you're using the char type instead of varchar. Try replacing your charindex expression with this:
charindex(',' + rtrim(ro_reason_code), #reasonCode)
When I used a type of char(2) in the table and char(16) for the #reasonCode, I could reproduce your result, and I found that adding the rtrim fixed the problem. But unfortunately I can't explain exactly what's going here, why having ',1' at the end of the string should work without the trim whereas having it at the beginning does not. Hopefully someone can provide a more in-depth answer that gets into the "why," but I thought I'd still post this for the time being to get you running.
Reproduction:
-- Forgive the "hackish" way of populating this table. I'm assuming sysobjects has >=1015 records.
declare #Code table (ro_reason_code char(2));
insert #Code select top 625 '1' from sysobjects;
insert #Code select top 1015 '01' from sysobjects;
declare #reasonCode char(16);
set #reasonCode = ',1,01';
select count(1) from #Code where #reasonCode = 'ALL' or charindex(',' + ro_reason_code, #reasonCode) > 0; -- Result: 1015
select count(1) from #Code where #reasonCode = 'ALL' or charindex(',' + rtrim(ro_reason_code), #reasonCode) > 0; -- Result: 1640
set #reasonCode = ',01,1';
select count(1) from #Code where #reasonCode = 'ALL' or charindex(',' + ro_reason_code, #reasonCode) > 0; -- Result: 1640
select count(1) from #Code where #reasonCode = 'ALL' or charindex(',' + rtrim(ro_reason_code), #reasonCode) > 0; -- Result: 1640
Because you are using char, which is a fixed length field, your data is stored padded out to the length of the field. So '1' is stored as '1 '
DECLARE #Code CHAR(2)
SET #Code = '1'
SELECT '''' + #Code + ''''
-- Printes '1 '
For that reason, when you add ',' to the value, you now have ',1 ' (notice the trailing whitespace)
DECLARE #Code CHAR(2)
SET #Code = '1'
SELECT '''' + ',' + #Code + ''''
-- prints ',1 '
Now if you're comparing off another char field, there will also be padded whitespace if the character data is less than the length of the field. So what appers to be ',11,1' is actually something like ',11,1 ' which does match the pattern of ',1 '
BUT, when you reverse the order, ',1,11' becomes ',1,11 ' which does not match the pattern of ',1 '
Unrelated
I just want to point out there is a subtle issue with the implementation. By only appending the leading comma, you may get false positives depending on your data. For example, ,2 will match the pattern ,25.
,2 does match 1,11,25,A01
You've gotta append the comma on both sides of each side of the evaluation.
CHARINDEX( ',' + RTRIM(ro_reason_code) + ',',
',' + RTRIM(#reasonCode) + ',') > 0
So to illustrate the difference it becomes
,2, does not match ,1,11,25,A01,

Find strings in non alphabetic strings

I have to find all occurence of alphabetic strings in table. To do it, I use below algorithm (I iterate through another table in loop to get this #TableName value):
UPPER(rows_value) like '%' + #TableName + '%')
This condition is wrong because it's also shows me string contained in another string.
Let's assume that #TableName = test. I would like to find records in table, which contains this string (also surrended by non alphabetical characters). My algorithm returns me rows contained:
test
(test)
test0x
test02
_test_2222
pretest <---
uptest <----
...
I don't need last two, because these are different words. How to modify my condition to exclude non needed results?
Try next query:
DECLARE #TableName VARCHAR(128) = 'test' -- Replace with propper data type and max length
SELECT *
FROM (VALUES
('test'),
('(test)'),
('test0x'),
('test02'),
('_test_2222'),
('pretest '),
('uptest'),
('testAlpha'),
('13223 tes3432')
) t(Col1)
WHERE t.Col1 LIKE '%' + #TableName + '%'
AND NOT(t.Col1 LIKE '%[a-z]' + #TableName + '%' OR t.Col1 LIKE '%' + #TableName + '[a-z]%')

Do not return all values when SSRS wildcard search is blank

How can a SSRS wildcard search be stopped from returning all values when left blank? Currently, if I enter a value for SKU (generated by the script below) and don't enter at least one value for SKU_Description the report returns all records rather than just the SKU record.
I have parameters set to allow blanks and multiple values because I need the ability to enter either an SKU or an SKU_Description or both, depending on what is know about each product.
WHERE A.sku in (#SKU)
OR B.sku_desc like '%' + #SKU_Description + '%'
I thought something like this might work, but it doesn't:
IIf(Parameters!SKU_Description.Value="", "WHERE A.sku in (#SKU)"
, "WHERE A.sku in (#SKU) or B.sku_desc like '%' + #SKU_Description + '%'")
Every thread I can find is about returning all values when left blank, which is the opposite of what I need to do.
your query might need to look like this instead.
WHERE (#SKU = '' OR A.sku in (#SKU))
AND (#SKU_Description = '' OR B.sku_desc like '%' + #SKU_Description + '%')
if #SKU or #SKU_Description can be NULL then you'll probably want
WHERE (ISNULL(#SKU,'') = '' OR A.sku in (#SKU))
AND (ISNULL(#SKU_Description,'') = '' OR B.sku_desc like '%' + #SKU_Description + '%')
Edit:
you can use this if the Sku and SKU_Description dont have to match for same record.
WHERE A.sku in (#SKU)
OR (#SKU_Description <> '' AND B.sku_desc like '%' + #SKU_Description + '%')

How to find fields containing the TAB character in SQL Server

In SQL Server, what is the best way to identify all rows in a table where a certain column contains the TAB character (CHAR(9))
Is it as simple as
SELECT * FROM MyTable WHERE Field1 LIKE '%' + CHAR(9) + '%'
RTRIM CHAR columns. like this:
SELECT *
FROM MyTable
WHERE (RTRIM(Field1) LIKE '%' + CHAR(9) + '%')
Previous query fails, with: "missing expression" message,
In Oracle, this is the correct syntax
select *
from MyTable
where Field1 '%' || CHR(9) || '%';
Other solution can be:
Select *
from MyTable
where instr(Field1, CHR(9)) <> 0;
Cheers!

Resources