pl sql decode function for use to check two values - plsql

In the select statement i need to return a value based on the data on other two colomns. For example,
select clarify, clarify_rece_date, clarify_process_date
from test_db;
So the clarify should return yes if both clarify_rece_date and clarify_process_date is not null and if they null clarify should return No.
I could have use decode here if i want to check only onle column as below,
select decode(clarify_rece_date, null,'Yes','No') clarify, clarify_rece_date, clarify_process_date
from test_db;
But how can i check for both columns in this scenario?

You could have a rather complex DECODE. However, it would make far more sense to use a CASE statement
SELECT (CASE WHEN clarify_rece_date IS NOT NULL AND
clarify_process_date IS NOT NULL
THEN 'Yes'
ELSE 'No'
END) clarify,
clarify_rece_date,
clarify_process_date
FROM test_db

Related

SQL Server - query not showing rows where column value is null

I have a Users table like this -
Table View
I am using the following query to retrieve rows where Faculty ID is CSE001, Designation is not student and User Role is not Marketing Coordinator -
Query view
But it's not giving me the result I need, cause the 2 rows I was expecting to have in return, has null in their UserRole column. So, it returns nothing.
Query Result
So, how can I write the query, so that it returns me the rows even if they have null in UserRole column? Can anyone help me, please? Thanks...
Check for both Designation and UserRole if they contain NULL values.
Use IS NULL or IS NOT NULL for these kind of checks. This is because you cannot compare NULL with specific values.
SELECT * FROM Users
WHERE FacultyId = 'CSE001'
AND (Designation <> 'Student' OR Designation IS NULL)
AND (UserRole <> 'Marketing Coordinator' OR UserRole IS NULL)
Hope this helps.
In SQL Server, values can be missing but applicable, such as the value of a hair's color that has not been supplied for a person, or can be missing but inapplicable, such as the value for a bold person. In either case, SQL Server will mark missing values as NULL. A NULL is neither TRUE, nor FALSE, but UNKNOWN. This is the third value in three-valued logic. In other words, you can determine whether X = Y is TRUE or FALSE when you know the values of both X and Y, but what if X is missing? SQL Server will return UNKNOWN, marked as NULL. This is your case: you know that Y is known (equals 'Marketing Coordinator'), but X might be missing. Because WHERE returns only those rows which match the conditions (i.e. each predicate is evaluated as TRUE), UNKNOWN results will be filtered out.
You will need to write queries that use three-valued logic to account for three possible outcomes: TRUE, FALSE and UNKNOWN. In ON, WHERE and the HEAVING clauses, SQL Server will treat NULL as FALSE. On the other hand, ORDER BY sorts the NULLs together and first.
You can test for NULL values with IS NULL or IS NOT NULL operators rather than equal.
You have explicitly ask for NULL values because they're quite special in relational databases.
This would be right one:
SELECT *
FROM Users
WHERE FacultyId <>'CSE001'
AND Designation <> 'Student'
AND (UserRole <> 'Marketing Coordinator' OR UserRole IS NULL);

how to pass current row into a oracle user defined function

I want to create an inline oracle function which will refer the column values of the current row being fetched and to return a value as per my conditions. I tried the same by passing ROWID into function and in the function body current row will be fetched using ROWID and manipulate the values.
CREATE FUNCTION CHECK_STATUS(P_ROWID) RETURN VARCHAR2 IS
V_ROW MY_TBL%TYPE
BEGIN
SELECT * INTO V_ROW FROM MY_TBL WHERE ROWID=P_ROWID;
IF V_ROW.COL1 IS NOT NULL AND
V_ROW.COL2 IS NOT NULL AND
V_ROW.COL3 IS NOT NULL THEN
RETURN 'OK';
ELSE
RETURN 'INCOMPLETE';
END IF;
END;
This function is further called at various places as
SELECT A.*,CHECK_STATUS(ROWID) FROM MY_TBL A;
it works but slows down the query badly over a thousand records because on each fetch of rows function will again do a select query for getting the column values. I know that this can also be done as
CREATE FUNCTION CHECK_STATUS(COL1,COL2,COL3) RETURN VARCHAR2 IS
here the problem is that i want to nearly check 9 column values in the function and it looks odd to write the column name during every call of the function. I doubt is there any method that the function can refer the current row being fetched without receiving ROWID/ COLUMNS through parameter something like (THIS.COL1,THIS.COL2,THIS.COL3)
You could add a virtual column for this, using a case expression, and not have a function at all:
alter table my_tbl add (status generated always as
(case when column1 is null or column2 is null or column3 is null
-- etc., all 9 columns or whatever else you want to check
then 'INCOMPLETE' else 'OK' end) virtual);
You can then query it with:
select column1, column2, ..., status from my_tbl
You can also add an index on the virtual column if that's useful for how you'll use it.
You could still use a (deterministic) function if you wanted to, with all the column values passed in - the 'looks odd' part would be hidden in the DDL, so queries wouldn't see it. It doesn't sound like using a function would add much in this case though.

use sqlite check to validate whether date with proper format is entered in the column

I have created a table as below:
CREATE TABLE case_status(data_entry_timestamp DATETIME DEFAULT (datetime('now','localtime')) NOT NULL,
case_number TEXT PRIMARY KEY NOT NULL,
case_name TEXT DEFAULT MISSING,
death_reportdate DATE CONSTRAINT death_reportdate_chk CHECK (death_reportdate==strftime('%Y-%m-%d',death_reportdate)),
);
The column death_reportdate need to have a date with pre-defined format (e.g. 2000-12-31). I created the table, inserted some rows of data, and then try to modified data in death_reportdate, the check rule seems to be bypassed when I enter some random string to it.
What have I done wrong?
You had an extra comma at the end. Correct code:
CREATE TABLE case_status(data_entry_timestamp DATETIME DEFAULT (datetime('now','localtime')) NOT NULL,
case_number TEXT PRIMARY KEY NOT NULL,
case_name TEXT DEFAULT MISSING,
death_reportdate DATE CONSTRAINT death_reportdate_chk CHECK (death_reportdate==strftime('%Y-%m-%d',death_reportdate))
)
it is an old Topic but i had the the same Problem. if the strftime method Fails to Format the string( a bad Input) it retuns null, so you have to check is not null in the end
Here is another solution which works like a charm:
`date` DATE CHECK(date IS strftime('%Y-%m-%d', date))
This also works with the time:
`time` TIME CHECK(time IS strftime('%H:%M:%S', time))
Use this to define your column. I think that is a more elegant solution than checking for null value.
First, two small notes.
I'm using the TEXT type since SQLite does not have "real types." It has 5 column "affinities", INTEGER, TEXT, BLOB, REAL, and NUMERIC. If you say DATE then it uses NUMERIC which can behave a little weirdly in my opinion. I find it best to explicitly use one of the 5 affinities.
I'm using date(...) instead of strftime('%Y-%m-%d', ...) because they are the same thing.
Let's break down why the original question did not work.
DROP TABLE IF EXISTS TEMP.example;
CREATE TEMPORARY TABLE example (
deathdate TEXT CHECK (deathdate == date(deathdate))
);
INSERT INTO TEMP.example (deathdate) VALUES ('2020-01-01');
INSERT INTO TEMP.example (deathdate) VALUES ('a');
INSERT INTO TEMP.example (deathdate) VALUES (NULL);
SELECT * FROM TEMP.example;
Running this lets all three values get into the database. Why? Let's check the documentation for CHECK constraints.
If the result is zero (integer value 0 or real value 0.0), then a constraint violation has occurred. If the CHECK expression evaluates to NULL, or any other non-zero value, it is not a constraint violation.
If you run SELECT 'a' == date('a'); you'll see it is NULL. Why? Check SELECT date('a'); and you'll see it is also NULL. Huh, maybe the documentation for == can help?
Note that there are two variations of the equals and not equals operators. Equals can be either = or ==. [...]
The IS and IS NOT operators work like = and != except when one or both of the operands are NULL. In this case, if both operands are NULL, then the IS operator evaluates to 1 (true) and the IS NOT operator evaluates to 0 (false). If one operand is NULL and the other is not, then the IS operator evaluates to 0 (false) and the IS NOT operator is 1 (true). It is not possible for an IS or IS NOT expression to evaluate to NULL.
We need to use IS, not ==, and trying that we see that 'a' no longer gets in.
DROP TABLE IF EXISTS TEMP.example;
CREATE TEMPORARY TABLE example (
deathdate TEXT CHECK (deathdate IS date(deathdate))
);
INSERT INTO TEMP.example (deathdate) VALUES ('2020-01-01');
INSERT INTO TEMP.example (deathdate) VALUES ('a');
INSERT INTO TEMP.example (deathdate) VALUES (NULL);
SELECT * FROM TEMP.example;
If you don't want NULL to get in, simple change it to deathdate TEXT NOT NULL CHECK (deathdate IS date(deathdate))

Modify a column to NULL - Oracle

I have a table named CUSTOMER, with few columns. One of them is Customer_ID.
Initially Customer_ID column WILL NOT accept NULL values.
I've made some changes from code level, so that Customer_ID column will accept NULL values by default.
Now my requirement is that, I need to again make this column to accept NULL values.
For this I've added executing the below query:
ALTER TABLE Customer MODIFY Customer_ID nvarchar2(20) NULL
I'm getting the following error:
ORA-01451 error, the column already allows null entries so
therefore cannot be modified
This is because already I've made the Customer_ID column to accept NULL values.
Is there a way to check if the column will accept NULL values before executing the above query...??
You can use the column NULLABLE in USER_TAB_COLUMNS. This tells you whether the column allows nulls using a binary Y/N flag.
If you wanted to put this in a script you could do something like:
declare
l_null user_tab_columns.nullable%type;
begin
select nullable into l_null
from user_tab_columns
where table_name = 'CUSTOMER'
and column_name = 'CUSTOMER_ID';
if l_null = 'N' then
execute immediate 'ALTER TABLE Customer
MODIFY (Customer_ID nvarchar2(20) NULL)';
end if;
end;
It's best not to use dynamic SQL in order to alter tables. Do it manually and be sure to double check everything first.
Or you can just ignore the error:
declare
already_null exception;
pragma exception_init (already_null , -01451);
begin
execute immediate 'alter table <TABLE> modify(<COLUMN> null)';
exception when already_null then null;
end;
/
You might encounter this error when you have previously provided a DEFAULT ON NULL value for the NOT NULL column.
If this is the case, to make the column nullable, you must also reset its default value to NULL when you modify its nullability constraint.
eg:
DEFINE table_name = your_table_name_here
DEFINE column_name = your_column_name_here;
ALTER TABLE &table_name
MODIFY (
&column_name
DEFAULT NULL
NULL
);
I did something like this, it worked fine.
Try to execute query, if any error occurs, catch SQLException.
try {
stmt.execute("ALTER TABLE Customer MODIFY Customer_ID nvarchar2(20) NULL");
} catch (SQLException sqe) {
Logger("Column to be modified to NULL is already NULL : " + sqe);
}
Is this correct way of doing?
To modify the constraints of an existing table
for example... add not null constraint to a column.
Then follow the given steps:
1) Select the table in which you want to modify changes.
2) Click on Actions.. ---> select column ----> add.
3) Now give the column name, datatype, size, etc. and click ok.
4) You will see that the column is added to the table.
5) Now click on Edit button lying on the left side of Actions button.
6) Then you will get various table modifying options.
7) Select the column from the list.
8) Select the particular column in which you want to give not null.
9) Select Cannot be null from column properties.
10) That's it.

SQLite Boolean WHERE to check for 0 and NULL value

I'm looking for a SQLite WHERE clause which will give me the records if they are:
0 (false)
NULL (false)
1 (true)
So besides 0 and 1 i also have records with NULL.
I now do a
SELECT * FROM my_table WHERE (MyBoolean IS NULL OR MyBoolean = 0) AND SomeOtherValue NOT NULL;
When using
SELECT * FROM my_table WHERE NOT MyBoolean AND SomeOtherValue NOT NULL;
The value=NULL records are not found, only the value=0 records :o(
Do i have to cast my column as a boolean?
Casting won't help here (CAST (null AS sometype) is still NULL). Anything that you can use will be more or less equivalent of the expression you use now: I find WHERE NOT COALESCE(MyBoolean,0) a bit more readable, but that's a personal preference.
Handling NULL booleans is really tricky indeed.
I don't know anything about the architecture of your code, but try to consider the following:
Make your MyBoolean NOT NULL DEFAULT TRUE (or FALSE, depends).
It might require minor code refactoring, but it will keep all the SELECTs clean, readable, and will escape you from using hacky methods.
I will repeat myself: this solution might not work if somehow your architecture is very inflexible and you cannot do this sort of refactors.
Hope this helps anybody.
json_quote translate null and false to 0, and true to 1. just use it : json_quote(X)='1'

Resources