storing multibyte character in a single byte characterset environment oracle 12c - oracle

Earlier we were storing JSON containing latest 10 conversations in an NCLOB column in database for caching purpose. But now we have to store all the conversations in JSON format and also provide search functionality. To utilize oracle's text search, we tried using BLOB datatype instead of NCLOB. However we are facing problems storing multibyte characters and searching it. Any suggestions on how to use BLOB datatype?
Here's an example of what i'm attempting
--create table with blob column---
create table departments_json (
department_id integer not null primary key,
department_data blob not null
);
---add JSON check constraint ---
alter table departments_json
add constraint dept_data_json
check ( department_data is JSON FORMAT JSON STRICT );
---------------index json column for text search-------
create index deptj_ctx_ix on departments_json (department_data)
indextype is ctxsys.context parameters ('section group CTXSYS.JSON_SECTION_GROUP sync (on commit)');
--Insert Json With Multibyte Characters
insert into departments_json
values ( 100, utl_raw.cast_to_raw ('{"department_list":[{"Deptname":"DEPT-A", "value" : "məharaːʂʈrə"}]}'));
Insert fails with :
ORA-02290: check constraint (REGCOA_SPM.DEPT_DATA_JSON) violated

Related

SQL datatype to store 8000 characters in a column and should also be a primary key

I need a column which should store more than 4000 characters(to be exact: between 4000 to 8000). And I want that particular column to be a primary key. Since I have dependency in UI end for that particular column to be primary key.
I tried CLOB and varchar(max) but those datatypes doesn't allow primary key property.
Can anyone help me with a proper datatype which can satisfy both conditions?
I'm using Oracle SQL developer 18.3.0.277
You cannot specify a primary key or unique constraint on a CLOB column. If you try then you get the exception:
ORA-02329: column of datatype LOB cannot be unique or a primary key
You can have a composite primary key with two VARCHAR2(4000) columns:
CREATE TABLE table_name (
value_start VARCHAR2(4000),
value_end VARCHAR2(4000),
CONSTRAINT table_name__value__pk PRIMARY KEY (value_start, value_end)
);
Or, from Oracle 12, you can set the system setting MAX_STRING_SIZE to be extended and can use:
CREATE TABLE table_name (
value_start VARCHAR2(8000) PRIMARY KEY
);
However
I would question the design choice of using a VARCHAR2(8000) column as a primary key as you will need to duplicate the (large) column value in all the referential constraints. Instead, make the value UNIQUE and provide a IDENTITY column which can act as the primary key with a one-to-one correspondence to the large string values.

Is it possible to set a BLOB size when creating table?

I am new to Oracle sql, but I have some experience with MSSQL. I was sent a script to create some tables, but because of the BLOB columns, I am getting a couple errors when I try to limit the size.
I tried asking my co-workers about this, but they aren't sure either. This was basically grabbed from somewhere else, so they're not sure how to fix this.
Essentially, the table looks something like this (table and column names were changed):
CREATE TABLE table1
(
ID CHAR(32),
NAME CHAR(50),
KEY $(BLOB)(64),
BUFFER $(BLOB)(20),
SORTNO NUMERIC(8) CONSTRAINT UK_WIU UNIQUE,
CONSTRAINT PK_ID PRIMARY KEY (ID)
)
;
When running this, I get the error "invalid character" because of the dollar sign ($). But if I change data type to BLOB(64), I get an error saying "missing right parenthesis." If I just do "BLOB," it runs fine. Is there any way to define the length for BLOB?
Thank you
BLOB column's size can't be restricted. It allows you to store up to [(4 gigabytes - 1) * (database block size)] data, and that's it. If you need less than that, fine, no problem.
More about BLOB (and other Oracle 18c datatypes) here: https://docs.oracle.com/en/database/oracle/oracle-database/18/sqlrf/Data-Types.html#GUID-1A71C635-188E-4EC9-B821-1DBEC2B45451
Table you meant to create would in Oracle look like this:
SQL> create table table1
2 (id varchar2(32) constraint pk_id primary key,
3 name varchar2(50),
4 sortno number(8) constraint uk_wiu unique,
5 key blob,
6 buffer blob
7 );
Table created.
SQL>
Yet another objection regarding your code: don't use CHAR but VARCHAR2 (unless you have to); CHAR will right-pad values with spaces, up to the maximum length of the column.
No, columns are just defined as a CLOB or BLOB.
There is no size associated with the column. You can put in something as big or small as you like, with a few restrictions.
"Maximum size: (4 GB - 1) * DB_BLOCK_SIZE initialization parameter (8 TB to 128 TB)"..as of 11g of Oracle.
To limit the size, you could, do so at the application layer - prevent folks from uploading files larger than X, although someone with DB access could do this.
You could write a stored procedure for handling INSERT/UPDATES, and have logic in there to prevent DML if the size is 'too large.'
You might be able to do a check constraint using a function call to get the length of the lob...an example here

how to store an integer value in to sql table

i created this table and i want to be able to add Integer value of 99 in to Assgn_Id and Ben_Id. so i am very confident with my create table query.
Create table Advisor (
Advisor# Integer,
AdvisorName Varchar2(15),
Assgn_Id Integer,
Ben_Id Integer);
my second query is where i get confused. after i inserted the values into the table it seems like it work fine, but when i describe the table i see Number(38) datatype into both columns instead of Integers(99).
Insert Into Advisor (Assgn_Id, Ben_Id)
Values(99, 99);
Integer, INT, smallint are ansi defined data types - that Oracle has implemented as a number
I like to use integer for my tables because I'm lazy, it's easier to type.
From the docs..
SQL statements that create tables and clusters can also use ANSI data
types and data types from the IBM products SQL/DS and DB2. Oracle
recognizes the ANSI or IBM data type name that differs from the Oracle
Database data type name. It converts the data type to the equivalent
Oracle data type, records the Oracle data type as the name of the
column data type, and stores the column data in the Oracle data type
based on the conversions shown in the tables that follow.

Automatic adjustment of a field in Oracle

Hello I'm trying to create a table under Oracle 18.1 (SQL Dev).
But I have an error "ORA-00906: missing right parenthesis"
CREATE TABLE DIM_TAB (
ID Number PRIMARY KEY,
TEST nvarchar2,
TEST_2 nvarchar,
DATE DATE not null
);
How to create a field without specifying the size of it in nvarchar (or nvarchar2) on Oracle? (I want the field size to adjust automatically)
Thank you
You have three problems. One, you must specify a maximum number of characters for a VARCHAR2 or NVARCHAR2 column. If you have data that will exceed 4000 bytes (not characters), then just use a CLOB. Second, there is no NVARCHAR data type. Third, you cannot create a column named "date," since that's a reserved word. What you want is something like this:
CREATE TABLE DIM_TAB (
id number PRIMARY KEY,
test nvarchar2(30),
test_2 nvarchar2(30),
the_date date not null
);
Personally, I would use a NUMBER(10) for your id, but that's a minor quibble.
You might want to read up on the NCHAR and NVARCHAR data types.

Changing Storage Option for XMLType column in Oracle 11g

I am using XMLType column in some of my oracle database table. Earlier(in 11.2.0.2) the default storage type considered is CLOB. So If you issue a query for the XMLType columns, I can see the content of the column as XML string. But when I drop and re-create all the tables and inserted some data, I could not get the content of the XMLType columns. It simpley display the XMLType in the cloumn value. I have a doubt that whether the storage type is chaged in BINARY XML? So I issue the following alter statement:
ALTER TABLE "MYSCHEMA"."SYSTEMPROP"
MODIFY ("XMLCOL")
XMLTYPE COLUMN "XMLCOL" STORE AS CLOB;
Please note that there are already some data present in the table. Event after when I delete and insert a row, the content is showing as XMLType. I am using SQL developer UI tool. Can anybody suggest a way to fix this issue?
Edit:
Ok, Now we have decided that we will store the XMLType column content as SECURE FILE BINARY XML. So we have table like this:
CREATE TABLE XMYTYPETEST
(
ID NUMBER(8) NOT NULL,
VID NUMBER(4) NOT NULL,
UserName VARCHAR2(50),
DateModified TIMESTAMP(6),
Details XMLType
)XMLTYPE COLUMN Details STORE AS SECUREFILE BINARY XML;
Insert into XMYTYPETEST values(10001,1,'XXXX',sysdate,'<test><node1>BLOBTest</node1></test>');
Select * from XMYTYPETEST;
The XMLType colum is displayed as "SYS.XMLType" in sql developer. So how to get the content of the binary XML?
Edit:
SELECT x.ID,x.Vid, x.details.getCLOBVal() FROM XMYTYPETESTx where x.ID=100000;
The above query works out for me finally.
The underlying storage for xmldata inside oracle database is either CLOB or Binary.
And it defaults to Binary storage in 11g.
But irrespective of the storage, your queries on the xmltype column should yield you consistent results.
>>>> So how to get the content of the binary XML?
The way to get the content of an xmltype column using queries does not change.
select xmlquery(..)
select xmlcast(xmlquery(...))
select extract(), extractValue(), ...
These are some of the ways data within xml is extracted.
Hope this helps.

Resources