Return 'something' instead of null - sql

I have this code:
select f.name
from Firms F
where
f.id = #{_firmID}
Code select name of firm by inserted ID. But if I insert bad ID (nonexisting ID), table return null. I need to rewrite this code to return 'wrong ID' if id not exist for example.
How can I achieve this? Thanks for all reply

Untested syntax, but you get the idea, I hope:
select f.name
from Firms F
where
f.id = #{_firmID}
union
select 'wrong ID' as name
from firms
where #{_firmID}
not in (select id from firms)

If you really want to do it with SQL rather than in application side, then using selectable stored procedure is perhaps easiest way:
CREATE PROCEDURE GetFirmName(aID INTEGER)
RETURNS(Name VARCHAR(255))
AS
BEGIN
Name = NULL;
SELECT Name FROM Firms WHERE id = :aID INTO :Name;
IF(Name IS NULL)THEN Name = 'wrong ID';
END
and then
SELECT Name FROM GetFirmName(42);

Related

Return names which dont exist in the database from the list provided

Let's assume I have a list of company names like so:
CompA
CompB
CompC
How would I go about only returning the names which don't exist in the database.
SELECT * FROM db.companies dc WHERE dc.name NOT IN ('CompA','CompB','CompC')
I have tried using NOT EXISTS and NOT IN but this returns all the company names which are not in the list but present in the database, but I need only the names from the specified list which does not exist.
So for example if CompC was not an existing company it should just return CompC
Make your list of companies into a table, and then query from it.
create temp table tmp_companies (name varchar(100));
insert into tmp_companies
values
('CompA'),
('CompB'),
('CompC');
select *
from tmp_companies c
where not exist (
select 1
from db.companies dc
where dc.name = c.name
)
You could define a CTE with contain all company names which you want to check. Then query from defined CTE.
WITH list_names AS (
SELECT 'CompA' as name
UNION ALL
SELECT 'CompB' as name
UNION ALL
SELECT 'CompC' as name
)
SELECT ln.*
FROM list_names ln
WHERE NOT EXISTS (SELECT 1 FROM db.companies dc WHERE dc.name = ln.name)
Without a temp table, abit more complex and requiring a new line for each name you want to search:
select
case when (select count() from db.companies dc where dc.name = 'CompA') > 0 then 'exists' else 'not found' end CompA,
case when (select count() from db.companies dc where dc.name = 'CompB') > 0 then 'exists' else 'not found' end CompB

Oracle:Select Statement with If else in Oracle

I have following two tables TestCustomer and TestEmail.I would like to retrieve emailAddress based on email_stat on TestCustomer and outside boolean parameter "noFlag".If noFlag is "true" get all the email addresses associated with customer_id other get only "A" ones.Any Help would be appreciated.
create table TestEmail(emai_id varchar(18),emailaddress varchar(20))
create table TestCustomer(customer_id varchar(18),emai_id varchar(18),email_stat char(1))
Insert Into TestEmail(emai_id,emailaddress)values('12345','abc#gmail.com');
Insert Into TestEmail(emai_id,emailaddress)values('123456','abcd#gmail.com');
Insert Into TestEmail(emai_id,emailaddress)values('123457','abcde#gmail.com');
Insert Into TestCustomer(customer_id,emai_id,email_stat)values('223459','12345','A');
Insert Into TestCustomer(customer_id,emai_id,email_stat)values('223458','123456','I');
Insert Into TestCustomer(customer_id,emai_id,email_stat)values('223459','123457','A');
Expected Input:
customer_id=223458 and noFlag='true'
Expected Output
Expected Input:
customer_id=223458 and noFlag='false'
Expected Output
Empty Result.
SELECT [DISTINCT] emailaddress
FROM TestEmail
JOIN TestCustomer USING (emai_id)
-- insert parameter-1 instead of 223458
WHERE TestCustomer.customer_id = 223458
-- insert parameter-2 instead of 'noFlag'
AND TestCustomer.email_stat = CASE WHEN noFlag = 'true'
THEN TestCustomer.email_stat
ELSE 'A'
END
fiddle
If you just want the emails, you can use exists:
select e.emailaddress
from testemail e
where exists (select 1
from testcustomer c
where c.email_id = e.email_id and
c.customer_id = :customer_id and
(c.email_stat = 'A' or :noflag = 'true')
);

postgres: query results into variables to be used later

I have what will end up being a complex query where certain parts will often be repeated. I would therefore like to store the results of some sub queries into variables which can then be used in the main query.
For example I would like to set the variable 'variable_id' to be equal to a SELECT query and variable_school_id to be equal to another SELECT query:
variable_id integer := (SELECT id FROM account WHERE email = 'test#test.com');
variable_school_id integer := (SELECT school FROM account WHERE email = 'test#test.com');
Then I would like to make use of those variables in a query that would look like:
select * from doctor where account_id = variable_id AND school = variable_school_id ;
How do I go about doing this?
Can't you just use CTEs?
with params as (
SELECT id, school
FROM account
WHERE email = 'test#test.com'
)
select d.*
from params cross join
doctor d
on d.account_id = params.id and d.school = params.school;

Get the table name where data is updated/inserted

Is there any way to get the table name where data is updated/inserted?
UPDATE
a
SET
a.Salary = a.Salary + 5000
FROM
dbo.Employee a
INNER JOIN
dbo.Status b
ON
a.StatusID = b.ID
WHERE
b.Description = 'Regular'
SELECT ##TableUpdated
Ouput should be Employee
It's a hack and can be done only inside a trigger but still you can try this and may help someone to get an idea:
CREATE TRIGGER z ON dbo.Employee
AFTER UPDATE
AS
IF(UPDATE(a))
BEGIN
IF EXISTS(SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Employee'
AND COLUMN_NAME = 'a')
begin
SELECT 'Employee'
end
ELSE // you can add more if statements
begin
SELECT 'Status'
END
end
Once you create trigger, use that update statement you provided in your question, the trigger should return you the name of the table.
You can parse this sql query to get a list of affected table like this:
sstupdate
a(dbo.Employee)(tetUpdate)
StatusID
Salary
Salary
dbo.Employee(tetSelect)
dbo.Status(tetSelect)
ID
Description

Query Blocks with SELECT INTO

QUERY is self explanatory.
DECLARE
ID NUMBER (10);
ISFIRST NUMBER (1);
BEGIN
SELECT M.ID, M.ISFIRST
INTO ID, ISFIRST
FROM MERCHANT M
WHERE M.PHONE = :1;
IF (ISFIRST=1) THEN
SELECT * FROM CUSTOMER C WHERE C.ISFIRST=1 AND C.MERCHANTID = ID;
ELSE
SELECT * FROM CUSTOMER C WHERE C.ISFIRST=0 AND C.MERCHANTID = ID;
END IF;
END;
This query gives me "PLS-00428: an INTO clause is expected in this SELECT statement".
I need to select data from CUSTOMER table depending on MERCHANT.ISFIRST and MERCHANT.ID.
Any workaround or little explanation what went wrong would be appreciated.
PS: The problem is solved with UNION ALL statement. This question needs to be closed.
The SELECT statements have nothing wrong, except that you are not doing anything with them. I mean the last two. What do you want them to do? Produce a result that is going to be discarded? PL/SQL does not allow it.
Just to try if this is correct, you can pick a single field and do SELECT {aField} INTO {aVariable} instead of SELECT *.
IF( ISFIRST = 1 ) THEN
SELECT {aField} INTO {aVariable} FROM CUSTOMER C WHERE C.ISFIRST=1 AND C.MERCHANTID = ID;
ELSE
SELECT {aField} INTO {aVariable} FROM CUSTOMER C WHERE C.ISFIRST=0 AND C.MERCHANTID = ID;
END IF;
Don't forget to declare {aVariable}!!!
I think this query will do the same thing :
SELECT C.*
FROM CUSTOMER C
INNER JOIN MERCHANT M ON C.MERCHANTID = M.ID AND
C.ISFIRST = M.ISFIRST AND
M.PHONE = :1;