Null substitution in SQLite: - tsql

In Sybase and MSSqlServer TransactSQL, we have a function IsNull(columnName,valueForNull) to return a typed default value when a column value is null. How can I replicate this functionality in SQLite?
Example in TransactSQL:
select IsNull(MyColumn,-1) as MyColumn from MyTable
If MyColumn is null, this expression will return -1 as the value of MyColumn. Want to do something similar in SQLite.
(Yes, I know I can write my own wrapper function to handle this - that's not the answer I'm looking for)
TIA

You should use the standard COALESCE function:
select coalesce(MyColumn, -1) as MyColumn from MyTable
Any database that understands standard ANSI SQL will support COALESCE so using it is a good habit to get into.

You can use ifnull:
select ifnull(MyColumn,-1) as MyColumn from MyTable

The SQL standard way to do this is with CASE:
SELECT CASE WHEN MyColumn IS NULL THEN -1 ELSE MyColumn END FROM MyTable
Considerably more verbose than engine-specific IFNULL, ISNULL, NZ functions, but more portable.
(Or, as mu points out, you can use the much better COALESCE for this).

SQLite has the IFNULL() built-in function which would do what I think you're trying here.

Related

Determinate if a column contain numeric value in JPQL

I have to determinate if a column contains a numeric or a alphanumeri value.
My sql code is:
select
case when trim(TRANSLATE(my_column, '0123456789-,.', ' ')) is null
then 'integer'
else 'char'
end
from my_table
and i have to traslate it in JPQL.
Thanks !
Your requirement is easy to come by using a native Oracle query:
SELECT *
FROM my_table
WHERE REGEXP_LIKE(my_column, '[A-Za-z0-9]');
The above will match any record having at least one alphanumeric character in the my_column column. You can't do this from JPQL directly. The best you might be able to do is to use a large number of LIKE statements, e.g.
SELECT *
FROM my_table
WHERE my_column LIKE '%A%' OR
my_column LIKE '%B%' OR
...
for every alphanumeric value. But this is unwieldy, and probably should be avoided. There is nothing wrong with using a native query if the situation merits that one should be used.

PostgreSQL exception handling on select statements with calculations

I'm having issues with the exception handling of postgresql, and I'm looking for some tips/advice how to tackle this.
Say I want to do the following:
SELECT col1 / col2
FROM table
The first problem that arises is that if at some point a value in col2 = 0, the query throws an exception. A solution to this is to add a NULLIF() in the denominator.
In our case, users can make their own formulas, which have to be parsed by the database, so we do not have the knowledge about the division in advance. We could make a fancy formula parser that adds NULLIF() in the right places, but then don't get me started on taking square root of negative numbers..
So I'm wondering if there is a better solution to the problem. Does something like this exist?
SELECT col1 / col2
exception
return null
FROM table
Or do I need to make use of the 'function' feature of postgresql? Is it possible to combine two columns like this?
CREATE OR REPLACE FUNCTION somefunction(col1, col2) RETURNS real AS $$
BEGIN
RETURN col1 / col2;
exception when division_by_zero then
return null;
END;
$$ LANGUAGE plpgsql;
SELECT somefunction(col1, col2, ..)
FROM table;
So keep in mind that we do not know the formula in advance!
Thanks!
In PostgreSQL you can define your own operators. Given your function, you could
CREATE OPERATOR public./ (
LEFTARG = real,
RIGHTARG = real
FUNCTION = public.somefunction
);
SET search_path = public, pg_catalog;
This would use your custom function for every division.
Allowing your users to run SQL statements is a bad idea. SQL is so powerful that they can do anything - they can change the search_path, and they can easily bring your database server to its knees.

How to replace ORA_HASH function of Oracle in Postgres?

How to replace ORA_HASH function of Oracle in Postgres? I am looking to implement the Batch and merge logic thats been written into Oracle and same I am looking to implement it into Postgres.
SELECT DISTINCT ACCNT_TYPE,ACCNT_SUB_TYPE,ACCNT_FROM_VAL,ACCNT_TO_VAL AS T_ACCNT_TO_VAL,
ORA_HASH("NAME"||TO_CHAR(LIFECYCLE_DATE,'DD-MM-YYYY HH24:MI:SS')||LEGACY_ICA_TYPE||TO_CHAR(PURGE_DATE,'DD-MM-YYYY HH24:MI:SS')
||HUB_STATE_IND||LIFECYCLE_STATUS_CD||VAT_ID||LICENSED_SW||PRIMARY_ICA||TOKEN_ACCT_SRV_DESC) AS HASH_VAL
FROM C_ACCNT
All the fields mentioned in the ORA_HASH is used to evaluate if INSERT should be done UPSERT should be done by considering all these fields.
Almost the same query but table name is different doing the left outer join. Also if the HASH VALUE is different then it would be considered for UPSERT.
Why this query always gives me null response?
select md5(p.src_id || p.type || p.accountName)
FROM ACCOUNT p;
If type value is NULL is DB then md5 results in NULL. This is bad.
If all you need is a hash function for a string, use the PostgreSQL built-in hashtext.
For the concatenation, you could use
hashtext(concat(p.src_id, p.type, p.accountName))

Changing Jet SQL IsNull to to SQL IsNull Function

I have a query in MS Access that I am trying to change to SQL view
One of the select statement part is
IIf(IsNull([Book ID]),-1,[Book ID]) AS SubBookID
Unlike in Access T-SQL wants 2 parameters for the IsNull function.
What I need to do is something like
IIf(IsNull([Book ID],true),-1,[Book ID]) AS SubBookID
But we cannot use true like that cause T-SQL thinks that it is a column name
you are going to check if [Book ID] is null or not. If it is null then you are going to return -1 else you are going to return the [Book ID].
To achieve this you need to right it as:
ISNULL([Book ID],-1) AS SubBookID
As you see you do not need the IIF function anymore in this situation.
Read more about ISNULL in T-SQL: https://learn.microsoft.com/en-us/sql/t-sql/functions/isnull-transact-sql?view=sql-server-2017

syb_describe in DBD::Sybase

I am looking to extract Sybase datatype for all the columns in a table. When I try to achieve this using $sth->{TYPE}, I get a numeric version of the datatype (i.e. instead of sybase datatype varchar, I get 0).
From the DBD::Sybase documentation, I noticed that SYBTYPE attribute of syb_describe function might be able to produce what I am looking for. But it seems that my understanding is not proper. SYBTYPE also prints datatype in numeric form only.
Is there any way to fetch the textual representation of actual Sybase datatype (instead of the number)?
It sounds like you wish to reverse engineer the create table definition. Here is an SQL script you can use for Sybase or SQL Server tables.
select c.name,
"type(size)"=case
when t.name in ("char", "varchar") then
t.name + "(" + rtrim(convert(char(3), c.length)) + ")"
else t.name
end,
"null"=case
when convert(bit, (c.status & 8)) = 0 then "NOT NULL"
else "NULL"
end
from syscolumns c, systypes t
where c.id = object_id("my_table_name")
and c.usertype *= t.usertype
order by c.colid
go
Note: This could still be edited with a nawk script to create a real SQL schema file.
The nawk script would strip the header, add "create table my_table_name", add commas, strip the footer and add a "go".
Good SQL, good night!
I found a workaround (Note: This does not answer the question though):
What I did was simply joined the sysobjects, systypes and syscolumns system tables.