Eliminate whitespaces in table columns - sql

I have a scenario where I have to convert varchar column into number column. While doing that I'm getting error invalid number. After debugging the values some has whitespaces and some other values entered as 56.678.90. Below is the query I tried to convert varchar into number,
select cast('45.56.78' as number) from dual or
select cast (' ' as number) from dual
Both the values which I have entered in the above query will be there under column 'lddfc' in table entry_header. Column lddfc has records as 456.99, 456.89.43, and whitespace. How can I display these values as number?

You haven't mentioned what variant of SQL you are using but if it's T-SQL you could remove leading and trailing spaces using LTRIM(RTRIM(yourValue)). Not sure about syntax for PL/SQL.
So your code would be select cast(LTRIM(RTRIM('45.56.78')) AS NUMBER) FROM DUAL
I don't think that you can convert '45.56.78' to a number though without removing one of the decimal points.

Related

TERADATA: Unwanted whitespaces generated while updating a row

I have a table called UDB.feed_counter (feed_name VARCHAR(255), feed_counter VARCHAR(255)) which keeps track of the highest number from some other table:
when updating the number (feed_counter) I use this query:
update UDB.feed_counter from(select max(distinct LFD_NR) AS LFD_NR from DWH.ART) A SET feed_counter=A.LFD_NR where feed_name='devicecataloglocal_art';
For some reason when I update feed_counter with this query I get some whitespaces in front of a number
Why is that happening??
When I do this: select max(distinct CAST(LFD_NR AS INTEGER)) from DWH.ART; I don't get any whitespaces
Can someone explain?
Additionally I should add that LFD_NR from DWH.ART is a string containing a number.
Generally, when VARCHAR columns values are updated from CHAR column values, the targeted VARCHAR columns are populated with exactly same value as that of CHAR column value from source by removing trailing whitespaces. But no whitespaces are addded in front.
I guess, the issue is with LFD_NR column of DWH.ART table.
Try selecting values from DWH.ART without casting as INTEGER:
select max(distinct LFD_NR) from DWH.ART;
There is a chance the LFD_NR column has whitespaces in front for the values.

db2 casting double to varchar without losing zeros

I have to check for wrong values using regexp_like expression. As far as I am concern I can do this only on strings and my data is saved in database as double.
I tried to cast it
SELECT column
FROM table
WHERE NOT REGEXP_LIKE(CAST(DECFLOAT(column) as VARCHAR(25)), '(\d{6}\.?\d{2})|(\d{7}\.?\d)')
Unfortunately values like 1234567.0 are converted into 1234567 and as a result this query is returning it as a mistake.
The other solution like
SELECT column
FROM table
WHERE NOT REGEXP_LIKE(CAST(CAST(column AS DECIMAL(8,1)) AS VARCHAR(25)), '(\d{6}\.?\d{2})|(\d{7}\.?\d)')
leads to a problem where values like 134567.89 are converted to 1234567.8 and are not returned by the query as an incorrect value.
Is there a way to cast it to varchar without giving it a range?
For 1st Query, Don't Convert column to DECFLOAT.
SELECT column
FROM table
WHERE NOT REGEXP_LIKE(CAST(CAST(column as DECIMAL(8,2)) as VARCHAR(25)), '(\d{6}\.?\d{2})|(\d{7}\.?\d)')
For 2nd Query, Increase the fraction part of the DECIMAL(8,1) to DECIMAL(8,2) to get the desired Result.
SELECT column
FROM tabel
WHERE NOT REGEXP_LIKE(CAST(CAST(column AS DECIMAL(8,2)) AS VARCHAR(25)), '(\d{6}\.?\d{2})|(\d{7}\.?\d)')

SQL secondary headers within data

I am having an issue that I haven't found an answer to. I wrote an SQL Query to generate a report that runs fine and outputs mostly numeric fields. The issue I'm running into is that we are putting it into a program that emails out files and it can only email out a .csv that does not include the header rows.
Is there a way to input the headers into the data? I've found a few solutions on here that didn't work for me. It seems like no matter what I do I get a data type error. This is all on an Oracle Database, the program we are using to send data out is called IQAlert, it's part of IQMS which is a manufacturing/erp system.
So far I've tried casting the headers as a number of numerical fields, a number of other solutions I found on here and other places on the internet such as changing to titles to varchar. The error I'm currently getting is
"ORA-01790: expression must have the same datatype as corresponding
expression"
Here is an extremely parsed down sample of the code. Adding the title "itemno' works fine because that field is text, when I try to add the header to onhand I get the data type error referenced above.
select 'itemno' as itemno, 'OnHand' as OnHand
from iqms.arinvt
union
select arinvt.itemno, arinvt.onhand
from iqms.arinvt
where itemno='10-00000000'
According to the documentation regarding The UNION [ALL], INTERSECT, MINUS Operators
You can combine multiple queries using the set operators UNION, UNION
ALL, INTERSECT, and MINUS. All set operators have equal precedence. If
a SQL statement contains multiple set operators, then Oracle Database
evaluates them from the left to right unless parentheses explicitly
specify another order.
The corresponding expressions in the select lists of the component
queries of a compound query must match in number and must be in the
same data type group (such as numeric or character).
If component queries select character data, then the data type of the
return values are determined as follows:
If both queries select values of data type CHAR of equal length, then
the returned values have data type CHAR of that length. If the queries
select values of CHAR with different lengths, then the returned value
is VARCHAR2 with the length of the larger CHAR value.
If either or both of the queries select values of data type VARCHAR2,
then the returned values have data type VARCHAR2.
If component queries select numeric data, then the data type of the
return values is determined by numeric precedence:
If any query selects values of type BINARY_DOUBLE, then the returned
values have data type BINARY_DOUBLE.
If no query selects values of type BINARY_DOUBLE but any query selects
values of type BINARY_FLOAT, then the returned values have data type
BINARY_FLOAT.
If all queries select values of type NUMBER, then the returned values
have data type NUMBER.
In queries using set operators, Oracle does not perform implicit
conversion across data type groups. Therefore, if the corresponding
expressions of component queries resolve to both character data and
numeric data, Oracle returns an error.
In short: in a query using one of the SET operators, for example like this:
SELECT x FROM table
UNION
SELECT y FROM table
where x is of numeric datatype, and yis of character datatype (or vice versa), then Oracle does not perform implicit conversion across data type groups and returns an error
Two simple examples:
SELECT 1 as X FROM dual
UNION
SELECT 'John' as Y FROM dual
ORA-01790: expression must have same datatype as corresponding expression
SELECT 'John' as X FROM dual
UNION ALL
SELECT 123 as Y FROM dual;
ORA-01790: expression must have same datatype as corresponding expression
Because Oracle does not perform implicit conversion, you must do an explicit conversion of one datatype to another datatype, the easiest one is to convert numbers to strings using TO_CHAR conversion function, like in this example:
SELECT 'John' as X FROM dual
UNION ALL
SELECT to_char(123) as Y FROM dual;
X
----
John
123
Maybe this will help. The first number is just sequence, the ROWNUM or ROW_NUMBER() can be used instead. The rest of numbers is simulated values:
SELECT itemno, onhand FROM
(
select 1 row_seq, NULL itemno, to_number(null) onhand from dual
union all
select 2, '5', 6 from dual
union all
select 3, '7', 8 from dual
)
WHERE row_seq > 1
/
Output:
ITEMNO ONHAND
5 6
7 8

PostgreSQL - empty values that are not null and not empty strings

I ran this query on a PostgreSQL table:
select * wkt from table where column <>'' and column is not null
..and unexpectedly received several rows with no visible value in that column. Why is this? Is there some 'hidden' value in that column for those rows, or a corrupted table, or something else?
t=# select ascii(chr(9));
ascii
-------
9
(1 row)
thus
select ascii(column) from table where column <>'' and column is not null
should give the idea
https://www.postgresql.org/docs/current/static/functions-string.html
ASCII code of the first character of the argument. For UTF8 returns
the Unicode code point of the character. For other multibyte
encodings, the argument must be an ASCII character.

SQL error "ORA-01722: invalid number"

A very easy one for someone,
The following insert is giving me the
ORA-01722: invalid number
why?
INSERT INTO CUSTOMER VALUES (1,'MALADY','Claire','27 Smith St Caulfield','0419 853 694');
INSERT INTO CUSTOMER VALUES (2,'GIBSON','Jake','27 Smith St Caulfield','0415 713 598');
INSERT INTO CUSTOMER VALUES (3,'LUU','Barry','5 Jones St Malvern','0413 591 341');
INSERT INTO CUSTOMER VALUES (4,'JONES','Michael','7 Smith St Caulfield','0419 853 694');
INSERT INTO CUSTOMER VALUES (5,'MALADY','Betty','27 Smith St Knox','0418 418 347');
An ORA-01722 error occurs when an attempt is made to convert a character string into a number, and the string cannot be converted into a number.
Without seeing your table definition, it looks like you're trying to convert the numeric sequence at the end of your values list to a number, and the spaces that delimit it are throwing this error. But based on the information you've given us, it could be happening on any field (other than the first one).
Suppose tel_number is defined as NUMBER - then the blank spaces in this provided value cannot be converted into a number:
create table telephone_number (tel_number number);
insert into telephone_number values ('0419 853 694');
The above gives you a
ORA-01722: invalid number
Here's one way to solve it. Remove non-numeric characters then cast it as a number.
cast(regexp_replace('0419 853 694', '[^0-9]+', '') as number)
Well it also can be :
SELECT t.col1, t.col2, ('test' + t.col3) as test_col3
FROM table t;
where for concatenation in oracle is used the operator || not +.
In this case you get : ORA-01722: invalid number ...
This is because:
You executed an SQL statement that tried to convert a string to a
number, but it was unsuccessful.
As explained in:
Oracle/PLSQL: ORA-01722 Error.
To resolve this error:
Only numeric fields or character fields that contain numeric values
can be used in arithmetic operations. Make sure that all expressions
evaluate to numbers.
As this error comes when you are trying to insert non-numeric value into a numeric column in db it seems that your last field might be numeric and you are trying to send it as a string in database. check your last value.
Oracle does automatic String2number conversion, for String column values! However, for the textual comparisons in SQL, the input must be delimited as a String explicitly: The opposite conversion number2String is not performed automatically, not on the SQL-query level.
I had this query:
select max(acc_num) from ACCOUNTS where acc_num between 1001000 and 1001999;
That one presented a problem: Error: ORA-01722: invalid number
I have just surrounded the "numerical" values, to make them 'Strings', just making them explicitly delimited:
select max(acc_num) from ACCOUNTS where acc_num between '1001000' and '1001999';
...and voilĂ : It returns the expected result.
edit:
And indeed: the col acc_num in my table is defined as String. Although not numerical, the invalid number was reported. And the explicit delimiting of the string-numbers resolved the problem.
On the other hand, Oracle can treat Strings as numbers. So the numerical operations/functions can be applied on the Strings, and these queries work:
select max(string_column) from TABLE;
select string_column from TABLE where string_column between '2' and 'z';
select string_column from TABLE where string_column > '1';
select string_column from TABLE where string_column <= 'b';
In my case the conversion error was in functional based index, that I had created for the table.
The data being inserted was OK. It took me a while to figure out that the actual error came from the buggy index.
Would be nice, if Oracle could have gave more precise error message in this case.
If you do an insert into...select * from...statement, it's easy to get the 'Invalid Number' error as well.
Let's say you have a table called FUND_ACCOUNT that has two columns:
AID_YEAR char(4)
OFFICE_ID char(5)
And let's say that you want to modify the OFFICE_ID to be numeric, but that there are existing rows in the table, and even worse, some of those rows have an OFFICE_ID value of ' ' (blank). In Oracle, you can't modify the datatype of a column if the table has data, and it requires a little trickery to convert a ' ' to a 0. So here's how to do it:
Create a duplicate table: CREATE TABLE FUND_ACCOUNT2 AS SELECT * FROM FUND_ACCOUNT;
Delete all the rows from the original table: DELETE FROM FUND_ACCOUNT;
Once there's no data in the original table, alter the data type of its OFFICE_ID column: ALTER TABLE FUND_ACCOUNT MODIFY (OFFICE_ID number);
But then here's the tricky part. Because some rows contain blank OFFICE_ID values, if you do a simple INSERT INTO FUND_ACCOUNT SELECT * FROM FUND_ACCOUNT2, you'll get the "ORA-01722 Invalid Number" error. In order to convert the ' ' (blank) OFFICE_IDs into 0's, your insert statement will have to look like this:
INSERT INTO FUND_ACCOUNT (AID_YEAR, OFFICE_ID) SELECT AID_YEAR, decode(OFFICE_ID,' ',0,OFFICE_ID) FROM FUND_ACCOUNT2;
I have found that the order of your SQL statement parameters is also important and the order they are instantiated in your code, this worked in my case when using "Oracle Data Provider for .NET, Managed Driver".
var sql = "INSERT INTO table (param1, param2) VALUES (:param1, :param2)";
...
cmd.Parameters.Add(new OracleParameter("param2", Convert.ToInt32("100")));
cmd.Parameters.Add(new OracleParameter("param1", "alpha")); // This should be instantiated above param1.
Param1 was alpha and param2 was numeric, hence the "ORA-01722: invalid number" error message. Although the names clearly shows which parameter it is in the instantiation, the order is important. Make sure you instantiate in the order the SQL is defined.
For me this error was a bit complicated issue.
I was passing a collection of numbers (type t_numbers is table of number index by pls_integer;) to a stored procedure. In the stored proc there was a bug where numbers in this collection were compared to a varchar column
select ... where ... (exists (select null from table (i_coll) ic where ic.column_value = varchar_column))
Oracle should see that ic.column_value is integer so shouldn't be compared directly to varchar but it didn't (or there is trust for conversion routines).
Further complication is that the stored proc has debugging output, but this error came up before sp was executed (no debug output at all).
Furthermore, collections [<empty>] and [0] didn't give the error, but for example [1] errored out.
The ORA-01722 error is pretty straightforward. According to Tom Kyte:
We've attempted to either explicity or implicity convert a character string to a number and it is failing.
However, where the problem is is often not apparent at first. This page helped me to troubleshoot, find, and fix my problem. Hint: look for places where you are explicitly or implicitly converting a string to a number. (I had NVL(number_field, 'string') in my code.)
This happened to me too, but the problem was actually different: file encoding.
The file was correct, but the file encoding was wrong. It was generated by the export utility of SQL Server and I saved it as Unicode.
The file itself looked good in the text editor, but when I opened the *.bad file that the SQL*loader generated with the rejected lines, I saw it had bad characters between every original character. Then I though about the encoding.
I opened the original file with Notepad++ and converted it to ANSI, and everything loaded properly.
In my case it was an end of line problem, I fixed it with dos2unix command.
In my case I was trying to Execute below query, which caused the above error ( Note : cus_id is a NUMBER type column)
select *
from customer a
where a.cus_id IN ('115,116')
As a solution to the caused error, below code fragment(regex) can be used which is added in side IN clause (This is not memory consuming as well)
select *
from customer a
where a.cus_id IN (select regexp_substr (
com_value,
'[^,]+',
1,
level
) value
from (SELECT '115,116' com_value
FROM dual)rws
connect by level <=
length ( com_value ) - length ( replace ( com_value, ',' ) ) + 1)
try this as well, when you have a invalid number error
In this
a.emplid is number and b.emplid is an varchar2 so if you got to convert one of the sides
where to_char(a.emplid)=b.emplid
You can always use TO_NUMBER() function in order to remove this error.This can be included as INSERT INTO employees phone_number values(TO_NUMBER('0419 853 694');