Oracle PL/SQL How to Get All Rows When the Date Parameter is Null? - oracle

This is where statement of my query:
WHERE date_column LIKE
(CASE
WHEN :date_parameter IS NOT NULL
THEN
:date_parameter
ELSE '%%'
END)
...
If the parameter is null, I want to get all rows. How can I do this?

Try
WHERE (:date_parameter is null
OR date_column = :date_parameter)
I used to write
WHERE date_column = nvl(:date_parameter,date_column)
But I think people find it confusing to read.

This should be work:
WHERE (date_column = :date_parameter AND :date_parameter IS NOT NULL) OR :date_parameter IS NULL

Related

Oracle decode null date variable

I have a query as part of a larger function and having trouble making DECODE work with null dates. This portion of my query is in the WHERE condition of the query:
NVL(datRunDate,SYSDATE)
BETWEEN NVL(EFFECTIVE_DATE,NVL(datRunDate,SYSDATE-1))
AND DECODE(STOP_DATE, NULL, NVL(datRunDate,SYSDATE + 1), STOP_DATE + (59/86400))
Where:
datRunDate DATE
EFFECTIVE_DATE DATE
STOP_DATE DATE
My issue is that the STOP_DATE is typically NULL and the DECODE doesn't work. Any ideas / help to work around this is appreciated.
EDIT
Adding some sample data as suggested:
datRunDate 2016-01-14 06:41:54
EFFECTIVE_DATE 2013-04-01 09:53:00
STOP_DATE NULL
EDIT2
Adding the entire query text here as the problem probably lies here. Note: I have replaced the variables manually. These variables are populated before this query with simple SELECT INTO statements.
datRunDate DATE;
SELECT COMP_DATE INTO datRunDate where IDL_SEQ = 2320;
SELECT EFFECTIVE_DATE, STOP_DATE from IDLS where IDL_SEQ = 2320;
DESC IDL_TABLE
DESC SCHEDULES COMP_DATE = datRunDate
...
SELECT I.IDL_SEQ
FROM IDLS I, IDL_CMPS IC
WHERE I.RECORD_TYPE = 'M'
AND IC.IDL_SEQ = I.IDL_SEQ
AND IC.CMP = '71-43-2'
AND I.METHOD = 'N0'
AND ((I.RUN_INSTRU = '') OR (I.RUN_INSTRU IS NULL))
AND ((I.PREP_METHOD = 'K9') OR (I.PREP_METHOD IS NULL))
AND ((I.MATRIX = 'SO') OR (I.MATRIX IS NULL))
AND ((I.COLUMN_ID = '') OR (I.COLUMN_ID IS NULL))
AND COALESCE(datRunDate, SYSDATE)
BETWEEN COALESCE(I.EFFECTIVE_DATE, datRunDate, SYSDATE - 1)
AND COALESCE(I.STOP_DATE + (59/86400), datRunDate, SYSDATE + 1)
AND ((I.SAMPLE_TYPE = 'SAMPLE') OR (SAMPLE_TYPE IS NULL))
AND ((I.CUST_SAMPLE_ID = 'SB-7') OR (CUST_SAMPLE_ID IS NULL))
AND ((I.LOCATION = '') OR (LOCATION IS NULL))
AND (
(OTHER_CRITERIA IS NOT NULL AND 404324 IS NOT NULL AND OTHER_CRITERIA = 'P|'||404324) OR
(OTHER_CRITERIA IS NOT NULL AND 28936 IS NOT NULL AND OTHER_CRITERIA = 'R|'||28936) OR
(OTHER_CRITERIA IS NOT NULL AND 'ECO' IS NOT NULL AND OTHER_CRITERIA = 'C|'||'ECO') OR
(OTHER_CRITERIA IS NULL));
Now when I run this I get: ORA-00932: inconsistent datatypes: expected CHAR got DATE
I would write this as:
COALESCE(datRunDate, SYSDATE) BETWEEN COALESCE(EFFECTIVE_DATE, datRunDate, SYSDATE - 1) AND
COALESCE(STOP_DATE + (59/86400), dateRunDate, SYSDATE + 1)
The ANSI standard function COALESCE() is simpler than using NVL() and DECODE() (which should be obsoleted anyway).

How to compare multiple columns under same row in a table?

Following columns of a table should not be equal in my where clause.
cd_delivery_address
cd_mail_delivery_address
cd_st_code
cd_mail_st_code
cd_zip
cd_mail_zip
Please find my code snippet to achieve this:
select * from table cd
where
(
(cd_mail_delivery_address <> cd_delivery_address or
(cd_mail_delivery_address is null and cd_delivery_address is not null) or
(cd_mail_delivery_address is not null and cd_delivery_address is null)
)
and (
cd.cd_city <> cd.cd_mail_city or
(cd.cd_city is null and cd_mail_city is not null) or
(cd_city is not null and cd_mail_city is null))
and (
cd.st_code <> cd.cd_mail_st_code or
(cd.st_code is null and cd_mail_st_code is not null) or
(st_code is not null and cd_mail_st_code is null)
)
and (
cd.cd_zip <> cd.cd_mail_zip or
(cd.cd_zip is null and cd_mail_zip is not null) or
(cd_zip is not null and cd_mail_zip is null)
)
)
All columns are varchar2 and i get correct output for this code. But is it a better way to compare multiple columns in pl sql? can i improve this code? Any suggestion would be helpful.
You could replace your null checks with NVL function something like this:
...
NVL(cd_mail_delivery_address,'_') <> NVL(cd_delivery_address,'_')
...
it's definitively more readable but I'm not sure about query efficency
I have done it for two columns using a join:
select a.cd_delivery_address,b.cd_mail_delivery_address
from cd a inner join cd b
where a.cd_delivery_address <> b.cd_mail_delivery_address and
a.cd_delivery_address = b.cd_delivery_address
Here null checking condition will be omitted and will reduce the number of conditions, but there is a performance impact since join is involved.

Oracle replacing null using NVL check for empty rows

I am running a query to retrieve an integer but want to put a check for nulls. If null I want the query to return 0. How can I do that? I tried this below but it's not working
select NVL(A_COUNT, 0) from MYTABLE where VEH_YEAR = '2003';
If A_COUNT is null I want the query to return 0. In the above case I don't have a value 2003 in VEH_YEAR column. The query works if I have a value 2003 in VEH_YEAR column but A_COUNT is null.
Better version of your uery would be, using an Aggregate function like MAX before using NVL.
select NVL(MAX(A_COUNT),0) from MYTABLE where VEH_YEAR = '2003';
SELECT NVL((select A_COUNT from MYTABLE where VEH_YEAR = '2003'), 0) A_COUNT from dual;
This worked.

If condition with select query in oracle

How to Use IF Condition with Select Query in Oracle. Please suggest
IF (SELECT ptr_forecast_dt from ptr_details WHERE ptr_line_id = prmptr_line_id AND ptr_actual_dt IS NULL) IS NOT NULL THEN
SELECT ptr_forecast_dt INTO Forcast_dt from ptr_details WHERE ptr_line_id = prmptr_line_id AND ptr_actual_dt IS NULL;
END IF;
You can simply add another condition in the WHERE clause, as below:
SELECT ptr_forecast_dt
INTO Forcast_dt
FROM ptr_details
WHERE ptr_line_id = prmptr_line_id
AND ptr_actual_dt IS NULL
AND ptr_forecast_dt IS NOT NULL;
If you want to insert an alternate value if ptr_forecast_dt is NULL, then you can use the NVL function, as below:
SELECT NVL(ptr_forecast_dt, TO_DATE('01/01/2014', 'MM/DD/YYYY'))
INTO Forcast_dt
FROM ptr_details
WHERE ptr_line_id = prmptr_line_id
AND ptr_actual_dt IS NULL;

Linq and sorting null fields

I have a table that has (for example) 4 columns.
pk_table_id INT NOT NULL
username VARCHAR(100) NOT NULL
start_date DATETIME NOT NULL
end_date DATETIME NULL
My requirement is to return all rows in descending order of end_date - BUT the NULL values must be first, and then descending order of start_date.
I've done it in SQL - but could someone assist me with a LINQ version to do this?
This is the SQL query we use:
SELECT [person_employment_id]
, [party_id]
, [employer_name]
, [occupation]
, [telephone]
, [start_date]
, [end_date]
, [person_employment_type_id]
, [person_employment_end_reason_type_id]
, [comments]
, [deleted]
, [create_user]
, [create_date]
, [last_update_user]
, [last_update_date]
, [version]
FROM [dbo].[person_employment]
WHERE ([party_id]=#party_id)
ORDER BY ISNull([end_date],'9999-DEC-31') DESC, [start_date] DESC
For this problem, you could do a null check on the end_date and use that result as the ordering. So you don't need to use the same SQL constructs to achieve this, but rather use one more natural in your language of choice (C# I'm assuming).
var query =
from row in dc.Table
let isEndDateNull = row.end_date == null
orderby isEndDateNull descending, row.start_date descending
select row;

Resources