WHERE clause with OR operator not giving intended result - sql

I want to write a stored procedure for a search function. I have a database of movies and I should be able to search a movie by Movie.Name, Movie.Producer, Movie.Director and appearing Cast.Name.
CREATE PROCEDURE RetrieveSearchResults
#tokenParam VarChar
AS
Select *
from
(Movie
join
Cast on Movie.MovieID = Cast.MovieID)
join
Actor on Actor.ActorID = Cast.ActorID
where
(Movie.Name like '%' + #tokenParam + '%')
or (Movie.Producer like '%' + #tokenParam + '%')
or (Movie.Director like '%' + #tokenParam + '%')
or (Actor.Name like '%' + #tokenParam + '%')
Upon execution
RetrieveSearchResults 'Almighty'
I get almost all tuples with no similar literal as 'Almighty'
Am I missing something?

Try declaring the varchar limit. VARCHAR(100) or something like that. It may be making assumptions on the length and cutting it down to a VARCHAR(1) or similar. The problem with declaring VARCHAR without a length is the system will assign for you and it may not be what you expect.

Related

Two Optional parameters on one column in stored procedure

I have table eRx (store electronic prescription) which has a pharmacy column. I am passing two optional parameters for pharmacy.
I declared the parameters like this:
DECLARE #pharmacy varchar(50) = null,
#Pharmacy1 varchar(50) = null
and use them in the where clause
WHERE (eRx.Pharmacy LIKE '%' + #Pharmacy + '%'
OR #Pharmacy IS NULL
OR eRx.Pharmacy LIKE '%' + #Pharmacy1 + '%'
OR #Pharmacy1 IS NULL)
If I am passing only one parameter, I am getting all records. It is not working as expected.
For example, if I will pass #pharmacy = 'CVS', I am getting all the rows. If I will pass both the parameter, then result is returned as expected.
Please help me
You want to find records that match both conditions:
match #Pharmacy when given AND
match #Pharmacy1 when given
You have OR instead. You are saying: select the row when #Pharmacy matches or #Pharmacy is null or ... So when #Pharmacy is null the whole condition is matched.
You want
WHERE (eRx.Pharmacy LIKE '%' + #Pharmacy + '%' OR #Pharmacy IS NULL)
AND (eRx.Pharmacy LIKE '%' + #Pharmacy1 + '%' OR #Pharmacy1 IS NULL)
I think the logic you want is that all rows are returned only when both values are NULL. Otherwise rows matching either values are returned.
If so, you can be explicit like this:
WHERE eRx.Pharmacy LIKE ('%' + #Pharmacy + '%') OR
eRx.Pharmacy LIKE ('%' + #Pharmacy1 + '%') OR
(#Pharmacy IS NULL AND #Pharmacy1 IS NULL)
Note that + returns NULL if any arguments are NULL. This works because with NULL values the first two conditions return NULL which is equivalent to FALSE in this context.

Can you use a parameter to reference a column in a select statement?

I am trying to reference a table column based on a parameter. The last line of my where clause is
'GRAD_' +LEFT(#REPORTING_DATE-20000,4) LIKE '%' + #PROGRAM + '%'
I hoping to get my the code to look like GRAD_2018 LIKE '%BIOL%' but when I run the code I get a '0' in the result set where I know I should be getting 18.
Below is my sample code
DECLARE
#REPORTING_DATE INT,
#PROGRAM VARCHAR(4)
SET #REPORTING_DATE = '20201101'
SET #PROGRAM = 'BIOL'
SELECT COUNT(ID)
FROM PROGRAM_DATA
WHERE PROGRAM LIKE '%' + #PROGRAM + '%' AND REPORT_DATE IN (#REPORTING_DATE-60000) AND
'GRAD_' +LEFT(#REPORTING_DATE-20000,4) LIKE '%' + #PROGRAM + '%'
I am using MSSQL and SSRS.
Unfortunately, you can't reference fields like that. You would need to use dynamic SQL to do this.
You build the SQL as a string and then EXECUTE it.
DECLARE #SQL VARCHAR(8000)
SET #SQL ='
SELECT COUNT(ID)
FROM PROGRAM_DATA
WHERE #PROGRAM LIKE ''%' + #PROGRAM + '%''
AND REPORT_DATE IN (''' + #REPORTING_DATE-60000 + ''')
AND GRAD_' + LEFT(#REPORTING_DATE-20000,4) + ' LIKE ''%''' + #PROGRAM + '''%''
'
EXEC(#SQL);
Another way to do this in SSRS is by creating your dataset from an expression.
In this example, I've assumed you actually want to pass the variable values from report parameters.
Create parameters to hold you two variables, called pReportDate and pProgram.
In the dataset properties, click the expression button against the query [fx] .
Make sure you include the equal sign and set the whole sql statement in quotes something like.
="
SELECT COUNT(ID)
FROM PROGRAM_DATA
WHERE PROGRAM LIKE '%" & Parameters!pProgram.Value & "%' AND REPORT_DATE IN (" & Parameters!pReportDate.Value & "-60000) AND
'GRAD_' +LEFT(&" Parameters!pReportDate.Value &"-20000,4) LIKE '%" & Parameters!pProgram.Value & "%'"
I've also assumed that #PROGRAM was a typo in the first part of your where clause.
The drawback with this approach is the you will probably have to manually add all the query fields to the dataset as SSRS may not be able to detect them automatically.
One more thought... since a table generally has a fixed number of columns, have you considered writing your where clause to simply spell out all of the columns with 'and' or 'or' as applies to your case?

Compare variable against multiple columns of different data types?

I am trying to lookup a search term passed into #Search in both an INT column and a NVARCHAR column.
I have done searching multiple columns in the past similar to below but have never had to compare against different column types.
#Search NVARCHAR(1000)
SELECT
[Stuff]
FROM
[Tables]
WHERE
[IDColumn] = ISNULL(#Search, [IDColumn])
OR
[TextColumn] LIKE '%' + TRIM(#Search) + '%'
How can the passed in variable be checked against multiple columns of different data types?
You need to convert the values. If it is a character, I would suggest try_convert():
WHERE IDColumn = TRY_CONVERT(INT, #Search) OR
TextColumn LIKE CONCAT('%', TRIM(#Search), '%')

If Else Statement in SQL Server stored procedure

In SQL Server, on .NET you can add together a SQL statement and therefor use either 'or' or 'and'.
I am stuck how to do this in a SQL Server stored procedure.
Question:
What is it called what you add together SQL statements? I have a feeling it starts with a 'c' concocations??
I believe I am close with the below code to having a 'variable' SQL?
Code:
BEGIN
SELECT *
FROM TblEmployee
WHERE
FirstName LIKE '%' + LTRIM(RTRIM((#sFirstName))) + '%'
or
Surname LIKE '%' + LTRIM(RTRIM((#sSurname ))) + '%'
and
IF (LTRIM(RTRIM((#sOfficeBase))) = 'xyz1234')
and OfficeBase = LTRIM(RTRIM((#sOfficeBase)))
ELSE
or
OfficeBase= LTRIM(RTRIM((#sOfficeBase)))
END
There are simular queries such as If else in stored procedure sql server
But I have a feeling I searching for the 'wrong' question. Thanks in advance
The where clause allows you to embed conditional logic - you don't need if/then/else, which is just as well, because afaik, that's not supported by any SQL dialect in a where clause.
BEGIN
SELECT *
FROM TblEmployee
WHERE
FirstName LIKE '%' + LTRIM(RTRIM((#sFirstName))) + '%'
or
Surname LIKE '%' + LTRIM(RTRIM((#sSurname ))) + '%'
and
(OfficeBase = 'xyz1234'
or
OfficeBase= LTRIM(RTRIM((#sOfficeBase)))
END
I am pretty sure you have some missing parenthesis in your original query. Not sure why you are adding LTRIM and RTRIM to your parameters. Taking a shot in the dark I suspect you could boil down your query to this.
SELECT * --This should be the column names actually needed, * is not good for production code
FROM TblEmployee
WHERE
(
FirstName LIKE '%' + #sFirstName + '%'
or
Surname LIKE '%' + #sSurname + '%'
)
and OfficeBase in ('xyz1234', #sOfficeBase)

Writing SQL code: same functionality as Yell.com

Can anyone help me with the trying to write SQL (MS SqlServer) - I must admit this is not by best skill.
What I want to do is exactly the same functionality as appears for the search boxes for the Yell website i.e.
Search for company type
AND/OR company name
AND/OR enter a company name
in a Location
if anyone can suggest the SQL code you would need to write in order to get the same functionality as Yell - that would be great.
Typically, one does something like this:
-- All these are NULL unless provided
DECLARE #CompanyType AS varchar
DECLARE #CompanyName AS varchar
DECLARE #Town AS varchar
SELECT *
FROM TABLE_NAME
WHERE (#CompanyType IS NULL OR COMPANY_TYPE_COLUMN LIKE '%' + #CompanyType + '%')
AND (#CompanyName IS NULL OR COMPANY_NAME_COLUMN LIKE '%' + #CompanyName + '%')
AND (#Town IS NULL OR TOWN_COLUMN LIKE '%' + #Town + '%')
Or this (only match start of columns with the wildcards):
-- All these are NULL unless provided
DECLARE #CompanyType AS varchar
DECLARE #CompanyName AS varchar
DECLARE #Town AS varchar
SELECT *
FROM TABLE_NAME
WHERE (#CompanyType IS NULL OR COMPANY_TYPE_COLUMN LIKE #CompanyType + '%')
AND (#CompanyName IS NULL OR COMPANY_NAME_COLUMN LIKE #CompanyName + '%')
AND (#Town IS NULL OR TOWN_COLUMN LIKE #Town + '%')
Can you provide the database layout (schema) that the sql would run against? It would be necessary to give you an exact result.
But generally speaking what you are looking for is
SELECT * FROM tablename WHERE companyType = 'type' OR companyName = 'companyName'
What you need first is not SQL code, but a database design. Only then does it make any sense to start writing SQL.
A simple table schema that matches Yell's functionality might be something like:
CREATE TABLE Company (
company_id INT NOT NULL PRIMARY KEY IDENTITY(1,1),
company_name VARCHAR(255) NOT NULL,
location VARCHAR(255) NOT NULL
)
and then you'd search for it by name with SQL like:
SELECT * FROM Company WHERE company_name like '%text%'
or by location like:
SELECT * FROM Company WHERE location = 'Location'
Of course, a real-world location search would have to use either exact city and state, or a zip code lookup, or some intelligent combination thereof. And a real table would then have lots more fields, like descriptions, etc. But that's the basic idea.