why do i have a date error in my sql query? - db2

I am doing an SQL SELECT query but I have the error message:
"SQL Error [22007]: [SQL0181] A value of date, time, or timestamp
string is incorrect."
Here is my request:
SELECT *
FROM ROXDTA400.STKF0300 A
JOIN ROXDTA400.TABJ00141 B ON A.STNSIT = B.CDSITE
WHERE ( A.STNLIB <> '-- Trémie --'
AND A.STNSIT <> 40
AND DATE(LEFT(STNDAV,4) || '-' || substr(STNDAV,5,2) || '-' || RIGHT(STNDAV,2))
BETWEEN DATE('2019-01-01') AND DATE('2019-01-04') );
The problem seems to come from the date created with the STNDAV field, because if I replace with for example DATE ('2019-01-03'), it works.
DATE (LEFT (STNDAV, 4) || '-' || substr (STNDAV, 5,2) || '-' || RIGHT (STNDAV, 2)) Gives me the correct date format.
Where would the problem come from?
thank you,

Ensure that dates stored in STNDAV are valid. I mean, check there is any invalid date such as February 30th or '99999999'. If the source is an IBM i (iSeries or AS/400), it will be faster if you avoid functions in the WHERE portion, so STNDAV BETWEEN '20190101' AND '20190104' will perform better.

Related

case when in where clause postresql

select service_code,service_cat_code,mobile_no,upper(applicant_name_eng) as name,to_char(license_date,'dd/mm/yyyy')as license_from,to_char(license_valid_upto,'dd/mm/yyyy')as license_to,Upper(license_no),district_code,taluk_code,CONCAT(address_building,', ', address_cityvillage,', ',address_locality,', ',address_landmark,', ',address_street) as address
from mst_license
WHERE cast(license_valid_upto as date) = case
WHEN license_valid_upto < now()
THEN
case
when license_valid_upto = '2021-06-30'
then 1 else 0
END
ELSE
case when license_valid_upto > now()
then 1 else 0
End
END
and Upper(license_no)='1SP146924BJP'
I want license valid should be either greater than now or if license valid less than now it must be with the date ''30/06/2021' but when i use above query i get error
ERROR: operator does not exist: date = integer
LINE 3: WHERE cast(license_valid_upto as date) = case
^
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
SQL state: 42883
Character: 418
Help me out guys
The main issue you have is that your case statement returns an integer (1 or 0) but you are trying to compare that to a date, which you cannot do as Postgres is a strict data typing. Even if it did work it would always be false (well except for 1969-12-31/1970-01-01). Moreover the case structure is not needed. The best/correct to compare dates is just use date values. Since you did not indicate the data type for column license_valid_upto so based on how it is used I'll assume it is timestamp with timezone as that is what NOW() returns. Your query becomes:
select service_code
, service_cat_code
, mobile_no
, upper(applicant_name_eng) as name
, to_char(license_date,'dd/mm/yyyy')as license_from
, to_char(license_valid_upto,'dd/mm/yyyy')as license_to
, upper(license_no) as license_no
, district_code
, taluk_code
, concat(address_building,', '
,address_cityvillage,', '
,address_locality,', '
,address_landmark,', '
,address_street) as address
from mst_license
where and upper(license_no)='1SP146924BJP'
and ( cast(license_valid_upto as date) > cast( now() as date)
or (cast (icense_valid_upto as date) < cast( now() as date)
and cast (icense_valid_upto as date) = date '2021-06-30'
)
);
Also, learn for format your queries for readability and so you do not need to scroll right. You, and others looking at your queries later will appreciate it later.

Postgres SQL - different results from LIKE query using OR vs ||

I have a table with an integer column. It has 12 records numbered 1000 to 1012. Remember, these are ints.
This query returns, as expected, 12 results:
select count(*) from proposals where qd_number::text like '%10%'
as does this:
SELECT COUNT(*) FROM "proposals" WHERE (lower(first_name) LIKE '%10%' OR qd_number::text LIKE '%10%' )
but this query returns 2 records:
SELECT COUNT(*) FROM "proposals" WHERE (lower(first_name) || ' ' || qd_number::text LIKE '%10%' )
which implies using || in concatenated where expressions is not equivalent to using OR. Is that correct or am I missing something else here?
You probably have nulls in first_name. For these records (lower(first_name) || ' ' || qd_number::text results in null, so you don't find the numbers any longer.
using || in concatenated where expressions is not equivalent to using ORIs that correct or am I missing something else here?
That is correct.
|| is the string concatenation operator in SQL, not the OR operator.

return one string from colums data

I've result set from query select * from personal."phoneNumbers" like this
prefix
pref |number
-----|--------
"12 "|"4589524"
"077"|"7090701"
"050"|"2561024"
But I want to return data like
(12) 4589524;(077) 7090701; (050) 2561024
How to do this with postgresql ?
You can use the string operators and functions to construct a single phone number in the format that you want:
'(' || btrim(pref) || ') ' || number
This, obviously, yields a string for each record that you process. You can then use the aggregation function string_agg() to string (no pun intended) the extended phone numbers from all the records together into one, with the appropriate separator between phone numbers:
SELECT string_agg('(' || btrim(pref) || ') ' || number, '; ') AS pref_number
FROM personal."phoneNumbers"

Frontbase date formatting functions

I've searched all over and can't find any info in Frontbase documentation or, for that matter, SQL92-related docs...does Frontbase have functions equivalent to datepart/date_part, or date_format as found in other RDBMSes? I need to output a timestamp column as a formatted string, and the correct syntax for Frontbase eludes me.
There may be a better way to do it, but a combination of cast, extract and string concatenation gave me the desired result:
SELECT CAST(EXTRACT(month FROM mytimestampcol) AS VARCHAR(2)) || '/' || CAST(EXTRACT(day FROM mytimestampcol) AS VARCHAR(2)) || '/' || CAST(EXTRACT(year FROM mytimestampcol) AS VARCHAR(4)) AS "Begin Date" FROM mytable
Yields "mm/dd/yyy" formatting.
One of many SQL92 function references: http://www.faircom.com/doc/sqlref/#12959.htm

How to make a function in DB2 database to convert an integer to date, and the case when is 0?

I was trying to make a function to work in db2:
CREATE FUNCTION TO_DATE8(DATE_STRING numeric(8,0))
RETURNS DATE
LANGUAGE SQL
IF DATE_STRING > 0 THEN
// ERROR ->
RETURN DATE ( TO_DATE ( SUBSTR ( DATE_STRING , 1 , 8 ) , 'YYYYMMDD' ) )
ELSE
RETURN DATE ( TO_DATE ( '00000000' , 'YYYYMMDD' ) )
END IF
END
ERROR: DATE IS NOT VALID
What to do?
The form of the procedure required seems to be like this (at least on the iSeries version):
CREATE FUNCTION TO_DATE8(DATE_STRING numeric(8,0))
RETURNS DATE
LANGUAGE SQL
BEGIN
RETURN(CASE WHEN DATE_STRING > 0 THEN DATE(SUBSTR(DATE_STRING, 1, 4) || '-' ||
SUBSTR(DATE_STRING, 5, 2) || '-' ||
SUBSTR(DATE_STRING, 7, 2))
ELSE DATE('0001-01-01')
END);
END
However:
Your procedure is misnamed (reading from a date-8, not to it).
Your DATE_STRING is not a string (or even a char), it's numeric. Please rename it to something that does not include the datatype (dateToConvert works)
You seem to want to return something that is not a valid date (all 0s). I'm returning *loval here, although it's possible it should actually be null.
I didn't put in enough checks for a valid date - this will blow up really easily.
If at all possible, the database should be changed to contain actual dates, not a numeric value. Disk is (relative to programmer/architect headaches) cheap.
You may also find a calendar file helpful, if the 8-digit numeric was one of the included columns.
For the benifit of others, this can be done in one line rather than a function:
CASE WHEN MYDATE = 0 THEN NULL ELSE DATE(INSERT(INSERT(LEFT(CHAR(MYDATE),8),5,0,'-'),8,0,'-')) END
MYDATE was 8 packed in my case.