How to change value for NLS_CHARACTERSET - oracle12c

in Oralce 12, can I change the NLS_CHARACTERSET value without having to take a backup.
Query: SELECT * FROM nls_database_parameters;
Result: NLS_CHARACTERSET
WE8MSWIN1252
I want to change it to
AL32UTF8

Related

SQL Developer DEFINE date

Is there a way to change the &_DATE variable in SQL Developer?
Whenever I run the following code, it just shows todays date:
DEFINE RUN_DATE = &_DATE
I'd like to find a way to format the query so it finds the last day in the month.
Also, if possible, to change the format to show as YYMMDD?
SQL> select '&_DATE' from dual;
old 1: select '&_DATE' from dual
new 1: select '23-JUN-20' from dual
'23-JUN-2
---------
23-JUN-20
SQL> alter session set NLS_DATE_FORMAT='YYYYMMDD';
Session altered.
SQL> select '&_DATE' from dual;
old 1: select '&_DATE' from dual
new 1: select '20200623' from dual
'2020062
--------
20200623
SQL>
_DATE is defined to store result of the SYSDATE function in the database. It's output is based on the NLS_DATE_FORMAT setting for your session.
Or in SQL Developer -
But, you want the last day of the month...we'll, we have the LAST_DAY() function for you!
select LAST_DAY('&_DATE')
from DUAL;
Returns '20200630' because we submitted _DATE which returns June 23 2020, so the function returns the last day of June 2020.

Postgres date format with Greek day inside

I am trying to store a date in a Postgres table with the below SQL command
update card_order set valid_until = to_date('23/12/17,Σαβ 11:00πμ', 'YYYY-MM-DD,Day HH:MIa');
But I get the error:
ERROR: invalid value "Σαβ 11" for "Day"
DETAIL: The given value did not match any of the allowed values for this field.
I have setup my db with
Encoding UTF8
Collation Greek_Greece.1253
Character type Greek_Greece.1253
You'd need to set lc_time to a Greek locale and use the TM modifier as in TMDY.
But that still won't help, because, as the documentation says:
to_timestamp and to_date ignore the TM modifier.

SQL Command to insert Chinese Letters

I have a database with one column of the type nvarchar. If I write
INSERT INTO table VALUES ("玄真")
It shows ¿¿ in the table. What should I do?
I'm using SQL Developer.
Use single quotes, rather than double quotes, to create a text literal and for a NVARCHAR2/NCHAR text literal you need to prefix it with N
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE table_name ( value NVARCHAR2(20) );
INSERT INTO table_name VALUES (N'玄真');
Query 1:
SELECT * FROM table_name
Results:
| VALUE |
|-------|
| 玄真 |
First, using NVARCHAR might not even be necessary.
The 'N' character data types are for storing data that doesn't 'fit' in the database's defined character set. There's an auxiliary character set defined as the NCHAR Character set. It's kind of a band aid - once you create a database it can be difficult to change its character set. Moral of this story - take great care in defining the Character Set when creating your database and do not just accept the defaults.
Here's a scenario (LiveSQL) where we're storing a Chinese string in both NVARCHAR and VARCHAR2.
CREATE TABLE SO_CHINESE ( value1 NVARCHAR2(20), value2 varchar2(20 char));
INSERT INTO SO_CHINESE VALUES (N'玄真', '我很高興谷歌翻譯。' )
select * from SO_CHINESE;
Note that both the character sets are in the Unicode family. Note also I told my VARCHAR2 string to hold 20 characters. That's because some characters may require up to 4 bytes to be stored. Using a definition of (20) would give you only room to store 5 of those characters.
Let's look at the same scenario using SQL Developer and my local database.
And to confirm the character sets:
SQL> clear screen
SQL> set echo on
SQL> set sqlformat ansiconsole
SQL> select *
2 from database_properties
3 where PROPERTY_NAME in
4 ('NLS_CHARACTERSET',
5 'NLS_NCHAR_CHARACTERSET');
PROPERTY_NAME PROPERTY_VALUE DESCRIPTION
NLS_NCHAR_CHARACTERSET AL16UTF16 NCHAR Character set
NLS_CHARACTERSET AL32UTF8 Character set
First of all, you should to establish the Chinese character encoding on your Database, for example
UTF-8, Chinese_Hong_Kong_Stroke_90_BIN, Chinese_PRC_90_BIN, Chinese_Simplified_Pinyin_100_BIN ...
I show you an example with SQL Server 2008 (Management Studio) that incorporates all of this Collations, however, you can find the same characters encodings in other Databases (MySQL, SQLite, MongoDB, MariaDB...).
Create Database with Chinese_PRC_90_BIN, but you can choose other Coallition:
Select a Page (Left Header) Options > Collation > Choose the Collation
Create a Table with the same Collation:
Execute the Insert Statement
INSERT INTO ChineseTable VALUES ('玄真');

Date Conversion Function PostgreSQL

I have the following function:
CREATE function SEMANA_ISO (fecha date) returns text as $$
select to_char(fecha, 'mm-dd-yyyy');
$$ LANGUAGE sql;
It works with:
Select SEMANA_ISO ('28/12/2014');
Select SEMANA_ISO ('01/01/2015');
Select SEMANA_ISO ('01/07/2015');
As you may see below
But not with:
Select SEMANA_ISO ('12/31/2014');
It shows:
********** Error **********
ERROR: The value of time / date is out of range "12/31/2014"
SQL state: 22008
Hint: You may need a different configuration of "dateStyle".
Character: 20
Do you have any suggestion without having to change the datestyle so I can enter
Select SEMANA_ISO ('12/31/2014');
And get an output of:
12-31-2014
using just one function to "parse" all dates?
Your function is declared to get a parameter of type date so you also need to pass such a value. '12/31/2014' is a character value, not a date.
When you pass a character literal (aka string) to the function Postgres is forced to do an implicit data type conversion based on the current datestyle - not something you should rely on.
If you want to call the function independently of the datestyle you need to pass a proper date literal, e.g. DATE '2014-12-31'
For more details on specifying date values, please see the manual: http://www.postgresql.org/docs/current/static/datatype-datetime.html#DATATYPE-DATETIME-INPUT
If you want 12/31/2014 accepted as a date set datestyle to iso, dmy;
if you want 31/12/2014 accepted as a date set datestyle to iso, mdy;
you can't have both at the same time, else 4/1/2015 is ambiguos, and must be rejected.
There is to_date() to input date literals with an arbitrary (given) format:
SELECT to_date('12/31/2014', 'MM/DD/YYYY') AS date1
, to_date('31/12/2014', 'DD/MM/YYYY') AS date2;
That's "without changing any datestyle". Obviously, you need to provide a matching format pattern, though.
To output the same in any desired format, use to_char():
SELECT to_char(to_date('12/31/2014', 'MM/DD/YYYY'), 'DD/MM/YYYY') AS date_as_text

How to convert date strings to timestamp without knowing the date format

I am trying to write a query to insert a value into a timestamp with no timezone data type field. The value is coming from CSV file.
The version I am working with is PostgreSQL 8.1.21.
The CSV file upload is done by the client and it has a date column. The date sometimes comes as '28-Sep-13' and sometimes as '28/09/2013' formats.
I tried to use the following to cast the string into timestamp:
str_date::timestamp.
This works fine if str_date is something like '28-Sep-13' but it won't work if the incoming date has the format '28/09/2013', when this error occurs:
ERROR: date/time field value out of range: "28/09/2013"
HINT: Perhaps you need a different "datestyle" setting
Basically the client keeps changing the date format in the uploaded CSV file.
Is there a way to convert the date strings into timestamp depending on its actual format?
You need to set your datestyle to "ISO, DMY". It is set to "ISO, MDY" by default, and would cause your example to fail:
> show datestyle;
DateStyle
-----------
ISO, MDY
(1 row)
> select '28-Sep-13'::date;
date
------------
2013-09-28
(1 row)
> select '28/09/2013'::date;
ERROR: date/time field value out of range: "28/09/2013"
LINE 1: select '28/09/2013'::date;
^
HINT: Perhaps you need a different "datestyle" setting.
> set datestyle = 'ISO, DMY';
SET
> select '28-Sep-13'::date;
date
------------
2013-09-28
(1 row)
> select '28/09/2013'::date;
date
------------
2013-09-28
(1 row)
(examples done in PostgreSQL 9.1, but the DateStyle setting and associated behavior are ancient, so should work fine)
You can circumvent the problem with these steps:
Create an empty temporary table with the same structure as target table:
CREATE TEMP TABLE tmp AS SELECT * FROM real_tbl LIMIT 0;
Change the type of the problematic column to text:
ALTER TABLE tmp ALTER COLUMN str_date TYPE text;
Import data to the temp table. Should work fine now:
COPY tmp FROM '/path/to/my/file.txt';
INSERT into target table depending on depending on the actual content of the column:
INSERT INTO real_tbl (col1, col2, col3, date_col)
SELECT col1, col2, col3
, CASE WHEN str_date ~~ '%/%'
THEN to_date(str_date, 'DD/MM/YYYY')
WHEN str_date ~~ '%-%'
THEN to_date(str_date, 'DD-Mon-YYYY')
-- more cases?
ELSE ???
END AS date_col
FROM tmp;
-- DROP TABLE tmp; -- optional; dropped at end of session automatically
I agree with Erwin, but I would try create database function (PL/pgSQL, PL/Python or other language) that can convert various date strings into date. In Erwins answer you can see WHEN ... THEN and you can use it. Such function will be easier to test and maintain.