I have a query that I'm building for an application. The database is setup in SQL Server 2008. I want to use a query similar to below, however, I will be using this 'Where' clause for about 4 other columns using the same requirements. Is this the appropriate way to test for null or '' in a column that is VarChar(255) and does allow nulls.
Ideally, if the variable #UutSerialNumber is null or empty (''), I want all the results, but if it is not, I want to use the 'LIKE' clause. Is this the proper way of doing this and will it work? It seems to work until I start adding more columns to the Where clause.
Also, how would I handle a "text" datatype using the same type of query?
SELECT DeviceName, UutStatus
FROM MyTable
WHERE (UutSerialNumber LIKE '%' + #UutSerialNumber + '%' OR UutSerialNumber LIKE '%%' AND (#UutSerialNumber = '' OR #UutSerialNumber IS NULL)) AND ...
Help is appreciated. Thanks everyone!
It amy seem like duplication of SQL but the best way to do this is in terms of performace is using IF ... ELSE
IF ISNULL(#UutSerialNumber, '') = ''
BEGIN
SELECT DeviceName, UutStatus
FROM MyTable
-- MORE EXPRESSIONS
END
ELSE
BEGIN
SELECT DeviceName, UutStatus
FROM MyTable
WHERE (UutSerialNumber LIKE '%' + #UutSerialNumber + '%'
-- MORE EXPRESSIONS
END
It can be done within the WHERE clause if you are doing it on multiple columns and the query you posted wasn't far off it was just missing additional parenthesis along with having a redundant clause.
SELECT DeviceName, UutStatus
FROM MyTable
WHERE (ISNULL(#UutSerialNumber, '') = '' OR UutSerialNumber LIKE '%' + #UutSerialNumber + '%')
AND (ISNULL(#AnotherParameter, '') = '' OR AnotherColumn LIKE '%' + #AnotherParameter + '%')
Convert the text type to VARCHAR(MAX).
as a footnote, I personally would use the CHARINDEX rather than concatenating strings in the like:
WHERE (ISNULL(#UutSerialNumber, '') = '' OR CHARINDEX(#UutSerialNumber, UutSerialNumber) > 0)
This is nothing more than a footnote however as I have done no performance testing, I just think it is easier on the eye!
SELECT DeviceName, UutStatus
FROM MyTable
WHERE ((#UutSerialNumber = '') OR (#UutSerialNumber is null)) OR (UutSerialNumber like #UutSerialNumber)
add '%' to the last #UutSerialNumber if you think you need
Related
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)
What is the equivalent of SQL Server query form for the below Oracle query in a LIKE statement:
((UPPER(ADDRESS) like '%'|| UPPER(:VALUE1) || '%' ) OR (ADDRESS IS NULL AND :VALUE1 IS NULL))
I am stuck with the syntax '%'||------||'%'.
|| is Oracle's concatenation operator. SQL Server's equivilent is +.
((UPPER(ADDRESS) like '%' + UPPER(#VALUE1) + '%' )
OR (ADDRESS IS NULL AND #VALUE1 IS NULL))
Incidentally, || is the SQL standard, + is used by some databases, like SQL Server instead of following the standard.
((UPPER(ADDRESS) like '%' + UPPER(VALUE1) + '%' ) OR (ADDRESS IS NULL AND VALUE1 IS NULL))
Note that using upper is only necessary depending on the collation setting.
You can use + instead of || to concatenate the strings
((UPPER(ADDRESS) like '%'+ UPPER(VALUE1) + '%' ) OR (ADDRESS IS NULL AND VALUE1 IS NULL))
You also do not need to use upper in comparison for SQL Server. Comparisons in SQL Server are case insensitive.
Is this part of a where clause or something?
I want to apply the conditional where clause That is if my barcode parameter comes null then i want to fetch all the records and if it comes with value then i want to fetch only matching records for the second part i am able to fetch the matching records but i am stuck at fetching the all records in case of null value i have tried as below ,
SELECT item
FROM tempTable
WHERE
((ISNULL(#barcode,0)=1)
// but this is not fetching all the records if barcode is null
OR
ISNULL(#barcode,0!= 1 AND tempTable.barcode LIKE #barcode+'%'))
//THis is working perfect
so any help will be great
I might have misunderstood what you ask, but the logic OR operator might help:
SELECT item
FROM tempTable
WHERE
#barcode IS NULL OR tempTable.barcode LIKE #barcode+'%'
If #barcode is NULL, it returns all the records, and when it is not NULL, it returns all of the records that fulfill the condition LIKE #barcode+'%'
Important
Also, bear in mind that using the OR operator can seemingly cause funny results when used with several complex conditions AND-ed together, and not enclosed properly in braces:
<A> AND <B> AND <C> OR <D> AND <E> AND <F>
Should most likely actually be formulated as:
(<A> AND <B> AND <C>) OR (<D> AND <E> AND <F>)
Remember, the parser does not know what you want to achieve, you have to describe your intents properly...
I think you could simplify it to:
SELECT item
FROM tempTable
WHERE #barcode IS NULL OR tempTable.barcode LIKE #barcode+'%'
so when #barcode is null you'll get everything - i.e. the Like part of the where won't need to execute. If #barcode has a value then the Like will be executed.
If the barcode field is non-null, then this is the method I would use -
SELECT item
FROM tempTable
WHERE barcode like isnull(#barcode, barcode) + '%'
If #barcode is null all records are returned and if it is non null then only matching records are returned.
If the barcode field is nullable then -
SELECT item
FROM tempTable
WHERE isnull(barcode, '') like isnull(#barcode, isnull(barcode, '')) + '%'
Same as the first but here we convert the null values in the barcode field to blank strings before doing the compare.
An alternate answer and an attempt at the bounty
declare #barcode nvarchar(10) -- chose nvarchar not necessarily should be nvarchar
select #barcode= NULL
--select #barcode='XYZ'
if #barcode is null
select item from temptable;
else
select item from temptable where temptable.barcode like #barcode+'%';
If I have to do this, I would have done like
SELECT item
FROM tempTable
WHERE
( ( ISNULL(#barcode,'') <> '') AND ( tempTable.barcode LIKE #barcode+'%' ) )
( ISNULL(#barcode,'') <> '') would also check if the variable is blank then it should not return anything. But if you just check for null, then in case when the #barcode is blank, you will be getting all item selected from the tempTable.
If column barcode would be non-nullable, you could greatly simplify the query.
This is based on the fact that the pattern '%' matches any string; even an empty (i.e. zero-length) string.
Consequently, the following WHERE clause matches all records:
WHERE barcode LIKE '%'
You may notice that this has a very close resemblance to the WHERE clause you are using to filter records on a specific barcode:
WHERE barcode LIKE #barcode + '%'
In fact, they are so similar that we may as well use a single WHERE clause for both cases; after all, '' + '%' equals '%'!
IF #barcode IS NULL SET #barcode = ''
SELECT item FROM tempTable WHERE barcode LIKE #barcode + '%'
There is an even shorter version, which preserves the original value of #barcode:
SELECT item FROM tempTable WHERE barcode LIKE ISNULL(#barcode, '') + '%'
As mentioned earlier, this works only if column barcode is non-nullable.
If column barcode is nullable (and you are genuinely interested in records where barcode IS NULL), then the following query might work for you:
SELECT item FROM tempTable
WHERE ISNULL(barcode, '') LIKE ISNULL(#barcode, '') + '%'
However, this version has two disadvantages:
It may perform much slower, because the query optimizer may not benefit from an index on column barcode.
If #barcode = '', then it will match not only the non-null barcodes, but also the records with barcode IS NULL; whether this is acceptable, is up to you.
One last simplification: you may want to reach consensus with the outside world that they should set #barcode = '' instead of NULL to retrieve all records. Then you could replace ISNULL(#barcode, '') by #barcode.
Apart of ppeterka's solution (which will causes an Index/Table Scan) there are at least three other solutions. These solutions could use an Index Seek if #barcode isn't NULL and, also, if there is an index on barcode column:
Solution #2: The execution plan isn't cached and reused:
SELECT item
FROM tempTable
WHERE #barcode IS NULL OR tempTable.barcode LIKE #barcode+'%'
OPTION(RECOMPILE);
Solution #3: The execution plan is cached (it can be used if the num. of optional parameters is small):
IF #barcode IS NULL
SELECT item
FROM tempTable;
ELSE
SELECT item
FROM tempTable
WHERE tempTable.barcode LIKE #barcode+'%';
Solution #4: The execution plans are cached (it can be used if the num. of optional parameters is high):
DECLARE #SqlStatement NVARCHAR(MAX);
SET #SqlStatement = N'
SELECT item
FROM tempTable
WHERE 1=1 '
+ CASE WHEN #barcode IS NULL THEN N'' ELSE N'AND tempTable.barcode LIKE #pBarcode+''%''; ' END;
-- + CASE WHEN #anotherparam IS NULL THEN N'' ELSE 'AND ...' END ;
EXEC sp_executesql #SqlStatement, N'#pBarcode VARCHAR(10)', #pBarcode = #barcode;
Note: Use the proper type and max. lenght/precision & scale for #pBarcode parameter.
IF #barcode is null
begin
SELECT item FROM tempTable
end
else
SELECT item FROM tempTable where tempTable.barcode LIKE #barcode+'%'
I am using SQL Server 2008 R2.
I am facing problem while fetching records from database in Role Based Access.
I have a Table let us say TableA. I have 5 Columns in it i.e, ID (primary key), FirstName, LastName, RegistrationNumber, EmployeeIdent.
All the columns except ID are of Varchar type.
I have a stored procedure to search the records. I am passing string to it and finding matching records from all five columns.
Now, the problem I am facing is in Role Based Access.
The requirement is when user is of "Admin" type then find matching records from all five columns but when is of "naive" user type then search matching records from only ID column.
I have passed the variable #userType to stored procedure from which I can determine the user type.
One way to resolve this problem is If Condition. Like if (#userType) = 'Admin' then some query Else Some other.
But I don't want to write query in If Condition.
Another way to resolve this is to store query in varchar type of variable and then execute is using EXEC (), but I have heard that it creates more overhead on server (I am not sure about it).
So any other way to fulfill this requirement?
The query to search records is
DECLARE #SearchText VARCHAR(MAX)= ''
SELECT *
FROM TableA
WHERE
Convert(varchar,ID) LIKE CASE WHEN LEN(#SearchText) = 0 THEN Convert(varchar,ID) ELSE '%'+ ISNULL(#SearchText,'0') + '%' END OR
FirstName LIKE CASE WHEN LEN(#SearchText) = 0 THEN FirstName ELSE '%'+ ISNULL(#SearchText,'') + '%' END OR
LastName LIKE CASE WHEN LEN(#SearchText) = 0 THEN LastName ELSE '%'+ ISNULL(#SearchText,'') + '%' END OR
RegistrationNumber LIKE CASE WHEN LEN(#SearchText) = 0 THEN RegistrationNumber ELSE '%'+ ISNULL(#SearchText,'') + '%' END OR
EmployeeIdent LIKE CASE WHEN LEN(#SearchText) = 0 THEN EmployeeIdent ELSE '%'+ ISNULL(#SearchText,'') + '%' END
SELECT
*
FROM TABLEA
WHERE
(#userType = 'admin'
--add any other criteria for admin type here
) or (
#userType = 'naive'
--add any other criteria for naive type here
)
I create Insert statement for organization table like this:
select'Insert into Organizations(Name,ContactPerson,ContactNumber,Mobilenumber)values('''+Nameofthecompany+''+','+Nameofthepersonresponsibleforrecruitment+','+PhoneNumber+','+MobileNumber+''')' from Organization
When I execute this statement I get insert statement. But the issue is where the value is null, it shows all columns null.
Example: (in database)
Name: xxxx
ContactPerson: zzzz
ContactNumber:444444
MobileNumber: null
so my insert statement looks like:
Null.
I want only that column provide null. other details showing properly. Is there any way in sql server? Help me anyone...
The result of concatenating anything to NULL, even itself, is always NULL. Workaround with ISNULL function:
select'Insert into Organizations(Name,ContactPerson,ContactNumber,Mobilenumber)
values('''+ISNULL(Nameofthecompany, 'NULL')+''+','
+ISNULL(Nameofthepersonresponsibleforrecruitment, 'NULL')+','
+ISNULL(PhoneNumber, 'NULL')+','
+ISNULL(MobileNumber, 'NULL')+''')'
from Organization
Demo on SQLFiddle
Sure - just use ISNULL(..) to turn a NULL into e.g. an empty string:
SELECT
'INSERT INTO Organizations(Name, ContactPerson, ContactNumber, Mobilenumber) VALUES(''' +
ISNULL(Nameofthecompany, '') + '' + ',' +
ISNULL(Nameofthepersonresponsibleforrecruitment, '') + ',' +
ISNULL(PhoneNumber, '') + ',' + ISNULL(MobileNumber,'') + ''')'
FROM Organization
When you are adding each of the parameters to the SQL statement, you need to check whether they're null, and if so use the keyword NULL, otherwise include a literal string surrounded with single quotes, but bearing in mind that if the string contains any single quotes, they need to be replaced with two single quotes.
Update the SQL for each parameter something like the following:
CASE WHEN MobileNumber IS NULL THEN 'NULL' ELSE '''' + REPLACE(MobileNumber, '''', '''''') + '''' END