"ORA-01733: virtual column not allowed here" when inserting into a view - sql

I created a view called "view_employee" like this:
CREATE VIEW view_employee AS
SELECT employee.surname || ', ' || employee.name AS comp_name, employee.sex, sections.name AS section_name, employee_age
FROM sections, employee WHERE employee.section = sections.sect_code;
And I would like to insert data into the table using the view, like this:
INSERT INTO view_employee VALUES ('Doe, John', 'm', 'Marketing', 34);
Here are the tables' columns and constraints:
create table sections(
sect_code number(2),
name varchar2(20),
income number(5,2)
constraint CK_sections_income check (income>=0),
constraint PK_sections primary key (sect_code)
);
create table staff(
ident number(5),
document char(8),
sex char(1)
constraint CK_staff_sex check (sex in ('f','m')),
surname varchar2(20),
name varchar2(20),
address varchar2(30),
section number(2) not null,
age number(2)
constraint CK_staff_age check (age>=0),
marital_status char(10)
constraint CK_employee_marital_status check (marital_status in
('married','divorced','single','widower')),
joindate date,
constraint PK_employee primary key (ident),
constraint FK_employee_section
foreign key (section)
references sections(sect_code),
constraint UQ_staff_document
unique(document)
);
The error message I get when attempting to insert is the following:
Error starting at Command Line: 1 Column : 1
Error report -
SQL Error: ORA-01733: virtual column not allowed here
01733. 00000 - "virtual column not allowed here"
*Cause:
*Action:
How could I insert those values into the table using the view? Thanks in advance.

A view must not contain any of the following constructs. So, it can be updateable.
A set operator
A DISTINCT operator
An aggregate or analytic function
A GROUP BY, ORDER BY, MODEL, CONNECT BY, or START WITH clause
A collection expression in a SELECT list
A subquery in a SELECT list
A subquery designated WITH READ ONLY
Joins, with some exceptions, as documented in Oracle Database
Administrator's Guide.

Related

SQL add a new column and its values only can be in several fixed options

I want to add a new column with SQL in my data table as below,
CREATE TABLE brands (
Brand varchar(255),
Contact varchar(150),
Address varchar(255),
Location varchar(50),
)
:
I wish to add a new column called country, and the value only can be selected from the following values: "Japan", "New Zealand", "US", "France"
I can add the new column but I don't know how to set the limited optional values for the column. Please help if you have ideas. Many thanks
You could use a check constraint, or a foreign key.
Check constraint:
alter table brands add country_name varchar(64) not null;
alter table brands add constraint ck_country_list
check (country_name in ('Japan', 'New Zealand', 'US', 'France'));
With a check constraint, the values that are allowed never change (unless you change the constraint code). With a foreign key, the allowed values are stored in another table. As long as the value exists in the other table, they are allowed in this table.
create table countries(country_name varchar(64) not null primary key);
insert countries (country_name)
values ('France'), ('New Zealand') -- etc
alter table brands add country_name varchar(64) not null;
alter table brands add constraint fk_brands_countries
foreign key (country_name) references countries (country_name);
But we can actually do even better that! Countries already have a well defined "thing" which uniquely identifies them: ISO3166 country codes. You can use the 2 char, 3 char, or int versions. Using well defined standards where you can is always a good idea for primary keys.
This is the next level up beyond what you are currently trying to learn. But here's what it might look like:
create table countries
(
country_code char(2) not null primary key clustered,
country_name varchar(64) not null
);
insert countries (country_code, country_name)
values ('FR', 'France'), ('NZ', 'New Zealand') -- etc etc;
alter table brands add country_code char(2) not null;
alter table brands add constraint fk_brands_countries
foreign key (country_code) references countries (country_code);
When you want to get the country name, you join the brands table to the countries table using the country_code column.
After you added the column you could add a check constraint
ALTER TABLE brands
ADD CONSTRAINT chk_country check (Country IN ('Japan', 'New Zealand', 'US', 'France'));

Missing Right Parenthesis in SQL

I'm new to learning SQL. When I create this table, it has an Asterix (*) under the first parenthesis of the "(dbClassID)" and says "missing right parenthesis"
Does anyone know why it does that and how I can fix it?
CREATE TABLE vod_classification (
dbClassId CHAR(4) NOT NULL,
dbDescription VARCHAR2(100)
CONSTRAINT vod_classification_PK PRIMARY KEY (dbClassId)
);
CONSTRAINT is part of table creation and need to be comma delimited as other column:
CREATE TABLE zz_classification (
dbClassId CHAR(4) NOT NULL,
dbDescription VARCHAR2(100),
CONSTRAINT vod_classification_PK PRIMARY KEY( dbClassId)
);
Tables contain columns and constraints
you are missing , here try this VARCHAR2(100),
For a single-column constraint, it's neater to define it inline as part of the column:
create table vod_classification
( dbclassid varchar2(4) not null constraint vod_classification_pk primary key
, dbdescription varchar2(100) not null constraint vod_classification_uk unique
);
I have corrected the CHAR column to the standard string type which is VARCHAR2 in Oracle.
(PK columns will be not null automatically, but I've left it in for completeness and in case you later create table as select.)
When using the "Create" code, you must use a comma in the line where you define each column of the table. Except the last column. You can read the oracle sql syntax link as follows: https://docs.oracle.com/cd/E11882_01/server.112/e41085/sqlqr01001.htm#SQLQR110

How to use soft order with JOIN

I want to use table JOIN with soft order for these tables:
CREATE TABLE ACCOUNT(
ID INTEGER NOT NULL,
USER_NAME TEXT NOT NULL,
PASSWD TEXT,
FIRST_NAME TEXT,
LAST_NAME TEXT,
E_MAIL TEXT NOT NULL,
COUNTRY TEXT,
STATE TEXT,
CITY TEXT,
ADDRESS TEXT,
STATUS INTEGER,
SECURITY_QUESTION TEXT,
SECURITY_ANSWER TEXT,
LAST_PASSWD_RESET DATE,
DESCRIPTION TEXT,
LAST_UPDATED DATE,
CREATED DATE
)
;
-- ADD KEYS FOR TABLE ACCOUNT
ALTER TABLE ACCOUNT ADD CONSTRAINT KEY1 PRIMARY KEY (ID)
;
ALTER TABLE ACCOUNT ADD CONSTRAINT USER_NAME UNIQUE (USER_NAME)
;
ALTER TABLE ACCOUNT ADD CONSTRAINT E_MAIL UNIQUE (E_MAIL)
;
-- TABLE ACCOUNT_ROLE
CREATE TABLE ACCOUNT_ROLE(
ID INTEGER NOT NULL,
USER_NAME TEXT NOT NULL,
ROLE INTEGER,
PERMISSION TEXT,
LAST_UPDATED DATE,
CREATED DATE
)
;
-- CREATE INDEXES FOR TABLE ACCOUNT_ROLE
CREATE INDEX IX_RELATIONSHIP19 ON ACCOUNT_ROLE (ID)
;
-- ADD KEYS FOR TABLE ACCOUNT_ROLE
ALTER TABLE ACCOUNT_ROLE ADD CONSTRAINT KEY26 PRIMARY KEY (ID)
;
ALTER TABLE ACCOUNT_ROLE ADD CONSTRAINT RELATIONSHIP19 FOREIGN KEY (ID) REFERENCES ACCOUNT (ID) ON DELETE CASCADE ON UPDATE CASCADE
;
Working query:
SELECT * FROM ACCOUNT ORDER BY %S %S offset ? limit ?
I tried this SQL query:
SELECT *
FROM ACCOUNT_ROLE
INNER JOIN ACCOUNT ON ACCOUNT.ID = ACCOUNT_ROLE.ID
ORDER BY Account.%S Account.%S offset ? limit ?
But I get this error message:
Caused by: org.postgresql.util.PSQLException: ERROR: syntax error at or near "Account"
Position: 99
How I can fix this query? I would like to get the data from two tables and sort it based in value.
It is not entirely clear what you are asking so instead I am proposing a few troubleshooting steps:
It looks like you are trying to do some query preprocessing. Please log the query after this is done and troubleshoot based on that. Failing that, check the PostgreSQL logs for the failing query text string (the logged query is better because of how placeholders are handled).
Once you are looking at the query itself, then look at it for syntax errors.
The problems are almost certainly in portions of your code you have not shown us. Knowing how to get the troubleshooting process started however can be worth mentioning.

Insert fails due to "column not allowed here" error

I am a beginner with SQL. I have created 4 tables and added data to my SHIP table. I am having some issues with inserting data into the CRUISE table. I get the error message at the bottom.
I have researched and can not figure out what i am doing wrong. Is there an issue with my sequence and/or trigger that is not allowing me to do this or is my syntax in the CREATE TABLE CRUISE causing the error? Everything i have done has been successful up until trying to insert the first column into the CRUISE table.
The tables:
CREATE TABLE SHIP
( Ship_Name VARCHAR2(100) PRIMARY KEY,
Ship_Size INTEGER,
Ship_Registry VARCHAR2(50),
Ship_ServEntryDate INTEGER,
Ship_PassCapacity INTEGER,
Ship_CrewCapacity INTEGER,
Ship_Lifestyle VARCHAR2(40),
CONSTRAINT Size_ck CHECK (Ship_Size > 0),
CONSTRAINT Registry_ck CHECK (Ship_Registry IN ('Norway','Liberia','The Netherlands','Bahamas'))
)
CREATE TABLE CRUISE (
Cruise_ID INTEGER Primary Key,
Ship_Name VARCHAR(100),
Cruise_DeptDate DATE NOT NULL,
Cruise_DeptCity VARCHAR(80) NOT NULL,
Cruise_Duration INTEGER,
FOREIGN KEY (Ship_Name) REFERENCES SHIP(Ship_Name)
)
CREATE TABLE PASSENGERS (
Pass_ID INTEGER PRIMARY KEY,
Pass_Name VARCHAR(100) NOT NULL,
Pass_City VARCHAR(80),
Pass_Telephone VARCHAR(15),
Pass_NextOfKin VARCHAR(100)
)
CREATE TABLE RESERVATIONS (
Pass_ID INTEGER NOT NULL,
Cruise_ID INTEGER NOT NULL,
Res_TotalCost NUMERIC(9,2),
Res_BalanceDue NUMERIC(9,2),
Res_SpecialRequest VARCHAR(30),
Res_Room VARCHAR(10),
FOREIGN KEY (Pass_ID) REFERENCES PASSENGERS(Pass_ID),
FOREIGN KEY (Cruise_ID) REFERENCES CRUISE(Cruise_ID),
CONSTRAINT Cost_ck CHECK (Res_TotalCost >= 0),
CONSTRAINT BalanceDue_ck CHECK (Res_BalanceDue >= 0),
CONSTRAINT SpecialRequest_ck CHECK (Res_SpecialRequest IN ('Vegetarian','Vegan','Low salt','Gluten free','Kosher','Other'))
)
The sequence/trigger is an attempt to auto number Cruise_ID.
Create SEQUENCE cruise_id_sq
START WITH 1
INCREMENT BY 1;
CREATE OR REPLACE TRIGGER cruise_id_t
BEFORE INSERT
ON CRUISE
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
if(:new.Cruise_ID is null) then
SELECT cruise_id_sq.nextval
INTO :new.Cruise_ID
FROM dual;
end if;
END;
ALTER TRIGGER cruise_id_t ENABLE;
Inserting into SHIP is okay....
INSERT INTO SHIP
(Ship_Name, Ship_Size, Ship_Registry,Ship_ServEntryDate, Ship_PassCapacity,Ship_CrewCapacity,Ship_Lifestyle)
Values ('Carribean Princess',142000,'Liberia',1000,3100,1181,'Contemporary');
INSERT INTO SHIP
(Ship_Name, Ship_Size, Ship_Registry,Ship_ServEntryDate, Ship_PassCapacity,Ship_CrewCapacity,Ship_Lifestyle)
Values ('Carribean Sunshine',74000,'Norway',1992,1950,760,'Premium');
INSERT INTO SHIP
(Ship_Name, Ship_Size, Ship_Registry,Ship_ServEntryDate, Ship_PassCapacity,Ship_CrewCapacity,Ship_Lifestyle)
Values ('Ship of Dreams',70000,'Liberia',2004,1804,735,'Contemporary');
INSERT INTO SHIP
(Ship_Name, Ship_Size, Ship_Registry,Ship_ServEntryDate, Ship_PassCapacity,Ship_CrewCapacity,Ship_Lifestyle)
Values ('Sunshine of the Seas',74000,'The Netherlands',1990,2354,822,'Luxury');
Inserting into CRUISE fails...
INSERT INTO Cruise
(Ship_Name, Cruise_DeptDate,Cruise_DeptCity,CruiseDuration)
Values ('Sunshine of the Seas',25-may-15,'Miami',10);
Error starting at line : 1 in command - INSERT INTO Cruise (Ship_Name,
Cruise_DeptDate,Cruise_DeptCity,CruiseDuration) Values ('Sunshine of
the Seas',25-may-15,'Miami',10) Error at Command Line : 3 Column : 35
Error report - SQL Error: ORA-00984: column not allowed here
00984. 00000 - "column not allowed here"
*Cause:
*Action:
Oracle thinks that 25-may-15 is the expression 25 minus may minus 15. In looking up the value for may Oracle finds that there is nothing there. Thus the error.
You can, but probably don't want to, quote it like so, '25-may-15'. This will make a string that may or may not be implicitly converted to a date, depending on the settings of NLS_DATE_FORMAT and or NLS_TERRITORY.
To form a date independent of session setting one can use the TO_DATE function with explicit date format, to_date('25-may-15', 'DD-Mon-YY'). Another option is a date literal, date '2015-05-25', which is always YYYY-MM-DD no matter the session settings..

Can't serialize transient record type postgres

I am trying to make my calculation dynamic based on certain criteria as below, but when I try to send the fields dynamically in to my calculation logic, it fails with the error " Can't serialize transient record type":
Create table statement :
create table calculation_t(
Id serial,
product_id integer not null,
metric_id integer not null,
start_date date,
end_date date,
calculation_logic varchar(50),
insert_timestamp timestamp default current_timestamp,
CONSTRAINT calculation_pk PRIMARY KEY(Id),
CONSTRAINT calculation_pid_fk FOREIGN KEY(product_id) REFERENCES Product_T(Product_id),
CONSTRAINT calc_mid_fk FOREIGN KEY(metric_id) REFERENCES metric_T(metric_id)
);
Insert statement :
insert into calculation_t(product_id,metric_id,calculation_logic)
select a.product_id,b.metric_id,
(case when b.metric_id=2 then
('$1-$2') else
'$1/$2' end) calc
from product_t a,metric_t b
Select statement which throws the mentioned error :
select *,(1,2,calculation_logic) from calculation_t
Note : I am using Greenplum database.
Try to remove parenthesis form your query:
select *,1,2,calculation_logic from calculation_t
It worked for me.
Thanx,