I am trying to develop a PUT method for a website. I am using the following code to make sure the information the user is entering is different from what we already have before making changes to the database (also to prevent a whole bunch of log files in case the user hits submit too many times):
SELECT COUNT(*) AS count
FROM iam.credential
WHERE iam.credential.CREDENTIAL_TYPE = :1
AND iam.credential.CREDENTIAL_NAME = :2
AND iam.credential.LOST_OR_STOLEN = :3
AND iam.credential.STATUS = :4
AND iam.credential.EXPIRATION_DATE = :5
AND iam.credential.ISSUING_LOCATION = :6
AND iam.credential.PHYSICAL_FORM = :7
AND iam.credential.ASSOCIATED_DEVICE = :8
AND iam.credential.DISPLAY_NAME = :9;
I am grabbing the values from my webpage, but I am running into issues when the value is NULL. I want to be able to do something like the following:
SELECT COUNT(*) AS count
FROM iam.credential
WHERE
IF iam.credential.CREDENTIAL_TYPE is not null THEN
iam.credential.CREDENTIAL_TYPE = :1
ELSE
iam.credential.CREDENTIAL_TYPE is null
END IF
AND
IF iam.credential.CREDENTIAL_NAME is not null THEN
iam.credential.CREDENTIAL_NAME = :2
ELSE
iam.credential.CREDENTIAL_NAME is null
END IF
//and so on
I can't use
SELECT COUNT(*) AS count
FROM iam.credential
WHERE (iam.credential.CREDENTIAL_TYPE = :1
OR iam.credential.CREDENTIAL_TYPE is null)
because that will return a count of 2 when I only want the one that matches what the user input.
Basically I want the count to either return a 1 or a 0 for if the record exists or if it doesn't.
I want the WHERE clause to be dynamically changed based on what the user provides.
If the user doesn't provide a value because it is not required it will be null. I need query to change to
credential_name is null
because
credential_name = null
doesn't work in oracle.
if it is not null then I need it to be
credential_name = :1
and it will be filled with the value that the user provided.
credential_name is :1
doesn't work in oracle either.
I will get two records back if I have two credentials of the same type but one record has a (null) value for CREDENTIAL_NAME and the other has 'DaisyDuck'.
You may just want to check that both the column value and the supplied value are null, or the column and the supplied value match:
SELECT COUNT(*) AS count
FROM iam.credential
WHERE (iam.credential.CREDENTIAL_TYPE = :1
OR (iam.credential.CREDENTIAL_TYPE is null AND :1 is null))
AND (iam.credential.CREDENTIAL_NAME = :2
OR (iam.credential.CREDENTIAL_NAME is null AND :2 is null))
AND ...
You may not have to do that for every value if you have table columns that are not nullable and you're checking that the matching user-supplied value is not null before you reach this point.
Your approach has a potential flaw though. In a multi-user system two sessions could enter the same values, both check and get a count of zero, and both then insert - causing a duplicate row unless you also have a unique constraint across all the values. If you do have such a constraint then the count will prevent a violation on insert some of the time, but not always, so may not be worth the extra trip to the database.
Related
I have a subject table that has subject_id column. In the table I have one row that has subject_id null other than that subject_id has a distinct value.
I am looking for single query I can fetch the data on basis of subject_id.
Select * from subject where subject_id = x;
If there is no data found w.r.t x than it should return the row with subject_id = null
In general this is a terrible pattern for tables. NULL as a primary key value is only going to cause you pain and suffering in the long run. Using a NULL-keyed row as a default for when your query matches no other rows will lead to strange behavior somewhere unexpected.
The simplest way would be to simply include the NULL row as the last row of any query and then only fetch the first row. But that only works when your query can only return at most one valid result.
select *
from subject
where subject_id = ? or subject_id is null
order by subject_id asc nulls last
Possibly the biggest problem with a NULL PK for your default/placeholder row in subject is that anywhere else you have a NULL subject_id cannot simply join to that row using x.subject_id = y.subject_id.
If you really need such a row, I suggest using -1 instead of NULL as the "not exists" value. It will make your life much easier across the board, especially if you need to join to it.
I am trying fetch rows when a certain where condition satisfies
select * from users where userid = :userid and objnum = :objnum;
users table has userid(non nullable column) and objnum(nullable column).
Now when I want to fetch users with null "objnum" values,it does not work since null values are not comparable.And when I want to fetch objnum value = 1,then above will work.
For null value, I very well get results with below query.
select * from users where userid = :userid and objnum is null;
But my application code is sending the :objnum bind variable as null or integer values and I want to check it directly in single query.Is there a way out to do this in a single query ?
If you want to compare a column value to a bind variable and have them match for both NULL and non-NULL values then for the NULL values you need to compare both sides to NULL:
SELECT *
FROM users
WHERE (userid = :userid OR (userid IS NULL AND :userid IS NULL))
AND (objnum = :objnum OR (objnum IS NULL AND :objnum IS NULL));
Hello I have a somewhat unique problem I need to select the first row that has NULL in the Status column and change its value to the text (processing)
To clarify I will use SQLite in a program that will need to process entries in a database.
The columns are
URL
Name
Status
The Name and URL is not something that I can control.
The Status column is used for the program all new entries come in with a NULL value I need to mark the first one with the text (processing) and then the program will refer to the row that has a value of (processing) in the status column and after it finishes change it to [FINISHED]
Also I don't want to select any row that also has NULL in the URL column.
I tried this code only its not getting me anywhere
SELECT * FROM List WHERE Status IS NULL ORDER BY ROWID ASC LIMIT 1
update List set Status = replace ( Status, NULL ,'(processing)')
commit;
What I definitively don't want to do is change all NULL values in the column Status at the same time. Only the first.
You need a WHERE clause in the UPDATE statement:
UPDATE List
SET Status = '(processing)'
WHERE rowid = (SELECT MIN(rowid) FROM List WHERE Status IS NULL)
If you want also this condition:
Also I don't want to select any row that also has NULL in the URL
column.
then:
UPDATE List
SET Status = '(processing)'
WHERE rowid = (SELECT MIN(rowid) FROM List WHERE Status IS NULL)
AND URL IS NOT NULL
or:
UPDATE List
SET Status = '(processing)'
WHERE rowid = (SELECT MIN(rowid) FROM List WHERE Status IS NULL AND URL IS NOT NULL)
Hi i want to do is a query which do the following thing:
If i execute the query ,all rows will set to 0 except certain id in the where(which supposed to be always 1 and only one row can be active at the moment)
tbl_menu
id | serial
starter | varchar
plate | varchar
beverage | varchar
status | smallint
So if i have one registry with status in 1 and everything else in 0, when i execute this query, certain id i choose will change to 1 and the others to 0
also only one row status = 1
Try this:
UPDATE tbl_menu
set status = CASE WHEN id = 4 or status = 1 THEN 1 ELSE 0 END;
I think you have two choices with the design as it is.
1) Do it with two easy queries.
2) Write one more complicated query with a case statement.
I personally like easy:
UPDATE tblmenu SET status = 0 WHERE status = 1;
UPDATE tblmenu SET status = 1 WHERE id = n;
Although, having said that, I think a better approach is this...
Get rid of your status column
Create a new table called, say tblstatus with one column id
One record with the id of the record
Foreign key to your main table
Now all you have to do is:
UPDATE tblstatus SET id = n;
Faster, easier, more robust...
This is a basic update statement. But if you could give more info on the column names and on what condition you want to do the updates it would be helpful.
UPDATE tbl_menu SET (column) = value
WHERE (condition)
This doesn't solve the problem of the update, but it does solve the problem of enforcing that (at most) one row is active. Use a partial unique index:
create unique index unq_menu_active on tblmenu(flag) where flag = 1;
I am working on a legacy system, and many of the database structures are horrendous (key / value pairs).
I have the following select statement:
(
SELECT D.F_VALUE
FROM T_WEB_QUOTES_DATA D
WHERE
D.F_QUOTE_ID = TO_CHAR(VR_RENTAL.QUOTEID)
AND D.F_KEY = 'Secondary_Driver_Forename'
) AS "SECONDARY_DRIVER_FORENAME"
So as you can see it is looking for a record where the F_Key column has a value of Secondary_Driver_Forename. The problem is there is another F_Key that holds the same exact information and I need to check for both keys.
So what I want to do is:
If there are no records where F_Key = Secondary_Driver_Forename or of such a record exists, but the value is an empty string or null, then I would like to go and look for a record where the F_Key is 2ndary_Driver_FirstName and if that does not exist (or is null), I would like to return a string saying No Key
How can I achieve this in Oracle SQL?
I am thinking of something like this:
(
SELECT (case when max(case when D.F_KEY in 'Secondary_Driver_Forename' then 1 else 0 end) = 1
then max(case when D.F_KEY in 'Secondary_Driver_Forename' then D.F_VALUE end)
else max(D.F_Value)
end)
FROM T_WEB_QUOTES_DATA D
WHERE
D.F_QUOTE_ID = TO_CHAR(VR_RENTAL.QUOTEID)
AND D.F_KEY in ('Secondary_Driver_Forename', '2ndary_Driver_FirstName')
) AS "SECONDARY_DRIVER_FORENAME";
That is, do a conditional aggregation of the values. If the primary value is present, then use it. Otherwise, just choose the value that is there (either NULL or the value from the second key).