How to convert VARCHAR2 to FLOAT in select statement in Oracle SQL - sql

select mudel
from mudel
where 50 > TO_NUMBER(voimsus)
ERROR: ORA-01722: invalid number
Voimsus is a float number ex. 50.21 but datatype is VARCHAR2. Any idea how to convert it. Also I cant change datatype because there is data and there are child records.
Data
Datatypes
SOLUTION: I changed every comma to decimal with
UPDATE mudel
SET voimsus = REPLACE(voimsus, ',', '.')
WHERE voimsus LIKE '%,%'
and it worked

Assuming that your session's nls_numeric_characters setting specifies that a period is your decimal separator and a comma is your grouping separator (i.e. it has a value of ".,")
select *
from nls_session_parameters
where parameter = 'NLS_NUMERIC_CHARACTERS'
while the data in your table uses a comma as the decimal separator, that would be the problem. You could specify the NLS parameters you want to use in your to_number call
create table my_table( incorrect_data_type varchar2(10) );
insert into my_table( incorrect_data_type ) values( '123,45');
select to_number( incorrect_data_type,
'9999D99',
q'{nls_numeric_characters=',.'}')
from my_table;
Or you could change your session's settings
alter session set nls_numeric_characters = ',.'
select to_number( incorrect_data_type) from my_table;
Of course, if you solve the problem by changing your session's settings, that means that when you (or someone else) starts a new session, they'll need to change their session's settings as well (assuming they use the same NLS settings to establish the connection that you are).
The right answer, of course, is to use the correct data type for the column in the first place. Storing numeric data in a character column is going to cause plenty of grief-- this is just one of the ways that tends to go wrong. Fixing the data type now will save you lots of grief down the line.
Here's a fiddle showing the options working (and failing).

When converting strings to numbers, then don't rely on session settings by merely using
to_number(voimsus)
but specify the format stored in the string. For this you must tell the DBMS what the decimal separator is with NLS_NUMERIC_CHARACTERS. E.g.:
TO_NUMBER(voimsus, '9999999999D.99', 'NLS_NUMERIC_CHARACTERS='',.''')
But well, it is of course much better not to store numbers in string columns in the first place. Use a proper number type such as NUMBER(12,2) instead. (And I recommend not to use any float data type, such as (BINARY_FLOAT), because then your stored numbers are not exact, but approximate, e.g. 1.3 may be stored as something like 1.3000001).

Related

Convert a type to another in Postgres

I have a table of cars in my Postgres database, but a created the price column with varchar.
I want to convert this type to numeric or integer.
car database
You can change the table definition with ALTER TYPE, but you'll need a USING clause with your particular conversion. Related:
Rails Migrations: tried to change the type of column from string to integer
If your data sample tells the full story, this should work:
ALTER TABLE tbl
ALTER COLUMN price TYPE numeric USING right(price, -1)::numeric
right(price, -1) trims the first character, which is always $ in your sample. Remaining leading and trailing white space is no problem. Related:
Postgres data type cast
For anything else, adapt the expression.
The operation triggers a table rewrite, taking an exclusive lock on the table for the duration.
I chose numeric to cover fractional digits. See:
Which datatype should be used for currency?

How to save Json Object with arabic characters in Sql [duplicate]

I have seen prefix N in some insert T-SQL queries. Many people have used N before inserting the value in a table.
I searched, but I was not able to understand what is the purpose of including the N before inserting any strings into the table.
INSERT INTO Personnel.Employees
VALUES(N'29730', N'Philippe', N'Horsford', 20.05, 1),
What purpose does this 'N' prefix serve, and when should it be used?
It's declaring the string as nvarchar data type, rather than varchar
You may have seen Transact-SQL code that passes strings around using
an N prefix. This denotes that the subsequent string is in Unicode
(the N actually stands for National language character set). Which
means that you are passing an NCHAR, NVARCHAR or NTEXT value, as
opposed to CHAR, VARCHAR or TEXT.
To quote from Microsoft:
Prefix Unicode character string constants with the letter N. Without
the N prefix, the string is converted to the default code page of the
database. This default code page may not recognize certain characters.
If you want to know the difference between these two data types, see this SO post:
What is the difference between varchar and nvarchar?
Let me tell you an annoying thing that happened with the N' prefix - I wasn't able to fix it for two days.
My database collation is SQL_Latin1_General_CP1_CI_AS.
It has a table with a column called MyCol1. It is an Nvarchar
This query fails to match Exact Value That Exists.
SELECT TOP 1 * FROM myTable1 WHERE MyCol1 = 'ESKİ'
// 0 result
using prefix N'' fixes it
SELECT TOP 1 * FROM myTable1 WHERE MyCol1 = N'ESKİ'
// 1 result - found!!!!
Why? Because latin1_general doesn't have big dotted İ that's why it fails I suppose.
1. Performance:
Assume your where clause is like this:
WHERE NAME='JON'
If the NAME column is of any type other than nvarchar or nchar, then you should not specify the N prefix. However, if the NAME column is of type nvarchar or nchar, then if you do not specify the N prefix, then 'JON' is treated as non-unicode. This means the data type of NAME column and string 'JON' are different and so SQL Server implicitly converts one operand’s type to the other. If the SQL Server converts the literal’s type
to the column’s type then there is no issue, but if it does the other way then performance will get hurt because the column's index (if available) wont be used.
2. Character set:
If the column is of type nvarchar or nchar, then always use the prefix N while specifying the character string in the WHERE criteria/UPDATE/INSERT clause. If you do not do this and one of the characters in your string is unicode (like international characters - example - ā) then it will fail or suffer data corruption.
Assuming the value is nvarchar type for that only we are using N''

How to get data from sql server table. If values contains some special character [duplicate]

I have seen prefix N in some insert T-SQL queries. Many people have used N before inserting the value in a table.
I searched, but I was not able to understand what is the purpose of including the N before inserting any strings into the table.
INSERT INTO Personnel.Employees
VALUES(N'29730', N'Philippe', N'Horsford', 20.05, 1),
What purpose does this 'N' prefix serve, and when should it be used?
It's declaring the string as nvarchar data type, rather than varchar
You may have seen Transact-SQL code that passes strings around using
an N prefix. This denotes that the subsequent string is in Unicode
(the N actually stands for National language character set). Which
means that you are passing an NCHAR, NVARCHAR or NTEXT value, as
opposed to CHAR, VARCHAR or TEXT.
To quote from Microsoft:
Prefix Unicode character string constants with the letter N. Without
the N prefix, the string is converted to the default code page of the
database. This default code page may not recognize certain characters.
If you want to know the difference between these two data types, see this SO post:
What is the difference between varchar and nvarchar?
Let me tell you an annoying thing that happened with the N' prefix - I wasn't able to fix it for two days.
My database collation is SQL_Latin1_General_CP1_CI_AS.
It has a table with a column called MyCol1. It is an Nvarchar
This query fails to match Exact Value That Exists.
SELECT TOP 1 * FROM myTable1 WHERE MyCol1 = 'ESKİ'
// 0 result
using prefix N'' fixes it
SELECT TOP 1 * FROM myTable1 WHERE MyCol1 = N'ESKİ'
// 1 result - found!!!!
Why? Because latin1_general doesn't have big dotted İ that's why it fails I suppose.
1. Performance:
Assume your where clause is like this:
WHERE NAME='JON'
If the NAME column is of any type other than nvarchar or nchar, then you should not specify the N prefix. However, if the NAME column is of type nvarchar or nchar, then if you do not specify the N prefix, then 'JON' is treated as non-unicode. This means the data type of NAME column and string 'JON' are different and so SQL Server implicitly converts one operand’s type to the other. If the SQL Server converts the literal’s type
to the column’s type then there is no issue, but if it does the other way then performance will get hurt because the column's index (if available) wont be used.
2. Character set:
If the column is of type nvarchar or nchar, then always use the prefix N while specifying the character string in the WHERE criteria/UPDATE/INSERT clause. If you do not do this and one of the characters in your string is unicode (like international characters - example - ā) then it will fail or suffer data corruption.
Assuming the value is nvarchar type for that only we are using N''

Is there any option to store a number as text with a specific format (comma as thousands separator and period as decimal separator) in Snowlake?

Due to project requirements I need to store a number as text, since depending on a column I round it to some decimal places or others, and with a specific format: comma as thousands separator and period as decimal separator.
If for example I had to round to two digits and I have this 12500.987589 I would need to get this another 12,500.98.
The only solution I have found in Snowflake is something similar to this:
SELECT
TO_VARCHAR(TO_NUMBER(TO_VARCHAR(ROUND(12500.987589 ,2)),'9,999,999.99',38,2))
FROM DUAL;
Do you know any option to do this?
Thank you very much and greetings,
Why do you need to use the round function at all? You should be able to use
select to_varchar(12500.987589, '9,999,999.99')
this produces: 12,500.99
Number should be stored as number data type. Formatting of the number is a matter of application layer. Storing them as a text could lead to problems with implicit conversion, arithmetic operations, etc.
If that is not possible you could:
Create a view on top of a table that provides additional column with formatted string
CREATE VIEW v_tab
AS
SELECT *, ... AS number_formatted
FROM tab;
Create a computed column:
ALTER TABLE tab
ADD COLUMN number_formatted VARCHAR(100) AS (...);
The expression to get desired formatting:
SELECT TO_VARCHAR(TO_NUMBER(ROUND(12500.987589,2),38,2),'9,999,999.99')

insert timestamp oracle

I have a table with the following format:
CREATE TABLE perflog(
REQ_TIME TIMESTAMP,
RESP_TIME TIMESTAMP,
OPERATION VARCHAR2(50),
STATUS_CODE VARCHAR2(10),
STATUS_BODY VARCHAR2(30)
);
-I want to insert a timestamp in the following format: e.g. 2020-07-27T23:33:41.427330
-I'm getting the following error:
SQL> insert into perflog(REQ_TIME) VALUES(2020-07-27T23:33:41.427330);
SP2-0552: Bind variable "33" not declared.
I don't get how to declare the timestamp in order to insert dates like the above. Sorry if it is a noob question but I'm a begginer.
Simply wrapping your value in single quotes isn't enough:
insert into perflog(REQ_TIME) VALUES('2020-07-27T23:33:41.427330');
ORA-01843: not a valid month
The actual error you get will depend on your session's NLS settings (and it's possible it would work - for you, if you set your session up in a certain way - but then not necessarily for anyone else.)
Oracle has timestamp literals which you can use instead of to_timestamp(), but unfortunately they don't allow the "T":
insert into perflog(REQ_TIME) VALUES(TIMESTAMP '2020-07-27T23:33:41.427330');
ORA-01861: literal does not match format string
and you can't remove it within the call (e.g. with replace) as that then isn't a literal; so you would have to change the "T" to a space externally:
insert into perflog(REQ_TIME) VALUES(TIMESTAMP '2020-07-27 23:33:41.427330');
If you're stuck with a string with that format then use an explicitly to_timestamp() call to convert your string to the data type you want, supplying the matching format mask, including a character-literal `"T"':
insert into perflog(REQ_TIME)
VALUES(TO_TIMESTAMP('2020-07-27T23:33:41.427330', 'YYYY-MM-DD"T"HH24:MI:SS.FF6'));
db<>fiddle
It's worth noting that timestamps (and dates) do not have a specific human-readable format when stored in the database. Oracle uses one of several internal representations, depending on the flavour of datetime you're using. Your client, IDE or application will format that as a readable string when you query the data, usually using your session NLS settings again. To get the data back as a string in a specific format you should use to_char() with the appropriate format supplied.
db<>fiddle with some examples.
Use a timestamp literal using a space character instead of a T:
insert into perflog(REQ_TIME) VALUES( TIMESTAMP '2020-07-27 23:33:41.427330');
db<>fiddle