Automatic adjustment of a field in Oracle - 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.

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.

Find total number of characters in CLOB and XMLTYPE datatype column

I have Oracle 12c version database.
I created table with CLOB and XMLTYPE datatype columns and Inserted some sample data.
I need to find total number of character in CLOB and XMLTYPE column.
Whatever the character-set used in those columns, just need a count.
Those two columns have huge data. So string operation ( i.e length() ) is not possible.
How to find the total number of character in those two columns.
Thanks in advance.
you can use the getlength in dbms_lob package
select
dbms_lob.getlength(t.clob_col)
,dbms_lob.getlength(t.XML_col.getClobVal())
from table t
db<>fiddle here

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.

Oracle Partition by 2 columns Interval

Im trying to find on google my situation but no one talk about this situation.
i have a table thats is gonna be partitionized with 2 columns.
for 2 columns partitions can anyone show an example for the interval?
In this case i have only one.
For this example how do i use an interval with 2 columns
INTERVAL( NUMTODSINTERVAL(1,'DAY'))
My table:
create table TABLE_TEST
(
PROCESS_DATE DATE GENERATED ALWAYS AS (TO_DATE(SUBSTR("CHARGE_DATE_TIME",1,10),'yyyymmdd')),
PROCESS_HOUR VARCHAR(10) GENERATED ALWAYS AS (SUBSTR("CHARGE_DATE_TIME",12,2)),
ANUM varchar(100),
SWTICH_DATE_TIME varchar(100),
CHARGE_DATE_TIME varchar(100),
CHARGE varchar(100),
)
TABLESPACE TB_LARGE_TAB
PARTITION BY RANGE (PROCESS_DATE, PROCESS_HOUR)
INTERVAL( NUMTODSINTERVAL(1,'DAY'))
Many Thanks,
Macieira
You can't use an interval if your range has more than one column; you'd get: ORA-14750: Range partitioned table with INTERVAL clause has more than one column. From the documentaion:
You can specify only one partitioning key column, and it must be of NUMBER, DATE, FLOAT, or TIMESTAMP data type.
I'm not sure why you're splitting the date and hour out into separate columns (since a date has a time component anyway), or why you're storing the 'real' date and number values as strings; it would be much simpler to just have columns with the correct data types in the first place. But assuming you are set on storing the data that way and need the separate process_date and process_hour columns as you have them, you can add a third virtual column that combines them:
create table TABLE_TEST
(
PROCESS_DATE DATE GENERATED ALWAYS AS (TO_DATE(SUBSTR(CHARGE_DATE_TIME,1,10),'YYYYMMDD')),
PROCESS_HOUR VARCHAR2(8) GENERATED ALWAYS AS (SUBSTR(CHARGE_DATE_TIME,12,2)),
PROCESS_DATE_HOUR DATE GENERATED ALWAYS AS (TO_DATE(CHARGE_DATE_TIME, 'YYYYMMDDHH24')),
ANUM VARCHAR2(100),
SWTICH_DATE_TIME VARCHAR2(100),
CHARGE_DATE_TIME VARCHAR2(100),
CHARGE VARCHAR2(100)
)
PARTITION BY RANGE (PROCESS_DATE_HOUR)
INTERVAL (NUMTODSINTERVAL(1,'DAY'))
(
PARTITION TEST_PART_0 VALUES LESS THAN (DATE '1970-01-01')
);
Table table_test created.
I've also changed your string data types to varchar2 and added a made-up initial partition. process_hour probably wants to be a number type, depending on how you'll use it. As I don't know why you're choosing your current data types it's hard to tell what would really be more appropriate.
I don't really understand why you'd want the partition range to be hourly and the interval to be one day though, unless you want the partitions to be from, say, midday to midday; in which case the initial partition (test_part_0) would have to specify that time, and your range specification is still wrong for that.
Interval partitioning could be built only on one column.
In your case you have proper partition key column - CHARGE_DATE_TIME. Why do you create virtual columns as VARCHAR2? And why do you need to create partition key on them? Interval partitioning could be built only on NUMBER or DATE columns.

Resources