Can't use column names in select query on sqlfiddle (oracle) - oracle

I'm not if am I using sqlfidle incorrectly or if this is missing functionality?
Steps to reproduce:
Select oracle option (top left)
create table and insert data:
CREATE TABLE products
("P_Id" int, "ProductName" varchar2(10), "UnitPrice" numeric, "UnitsInStock" int, "UnitsOnOrder" int)
//
INSERT ALL
INTO products ("P_Id", "ProductName", "UnitPrice", "UnitsInStock", "UnitsOnOrder")
VALUES (1, 'Jarlsberg', 10.45, 16, 15)
INTO products ("P_Id", "ProductName", "UnitPrice", "UnitsInStock", "UnitsOnOrder")
VALUES (2, 'Mascarpone', 32.56, 23, NULL)
INTO products ("P_Id", "ProductName", "UnitPrice", "UnitsInStock", "UnitsOnOrder")
VALUES (3, 'Gorgonzola', 15.67, 9, 20)
SELECT * FROM dual
//
Build schema
run query and verify result is correct
select * from products
Run query with column name (any) and get the error:
select ProductName from products
error given:
ORA-00904: "PRODUCTNAME": invalid identifier
Is my query wrong or isn't it possible on sqlfiddle to use the column names in the select query? Do I have any workarounds to keep testing my query?

[TL;DR] The simplest thing to do is to never use double quotes around object names and just let oracle manage the case-sensitivity in its default manner.
However, you can use double-quotes in SQLFiddle:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE products
("P_Id" int, "ProductName" varchar2(10), "UnitPrice" numeric, "UnitsInStock" int, "UnitsOnOrder" int)
//
INSERT ALL
INTO products ("P_Id", "ProductName", "UnitPrice", "UnitsInStock", "UnitsOnOrder")
VALUES (1, 'Jarlsberg', 10.45, 16, 15)
INTO products ("P_Id", "ProductName", "UnitPrice", "UnitsInStock", "UnitsOnOrder")
VALUES (2, 'Mascarpone', 32.56, 23, NULL)
INTO products ("P_Id", "ProductName", "UnitPrice", "UnitsInStock", "UnitsOnOrder")
VALUES (3, 'Gorgonzola', 15.67, 9, 20)
SELECT * FROM dual
//
Query 1:
SELECT "ProductName" FROM products
Results:
| ProductName |
|-------------|
| Jarlsberg |
| Mascarpone |
| Gorgonzola |
Run query with column name (any) and get the error:
select ProductName from products
error given:
ORA-00904: "PRODUCTNAME": invalid identifier
Oracle databases are, by default, case sensitive; however, they will also, by default, convert everything to upper-case so that the case sensitivity is abstracted from you, the user. It is only when you use double-quotes that Oracle will use the case you specify for the identifier.
Since you used quoted identifiers in the CREATE TABLE statement you will also need to use quoted identifiers in the SELECT statements with the exact case used in table creation.
So, the column name is not ProductName it is "ProductName" (with the double-quotes).
A better solution is to not use double quotes:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE products(
P_Id int,
ProductName varchar2(10),
UnitPrice numeric,
UnitsInStock int,
UnitsOnOrder int
)
//
INSERT INTO products ( P_Id, ProductName, UnitPrice, UnitsInStock, UnitsOnOrder )
SELECT 1, 'Jarlsberg', 10.45, 16, 15 FROM DUAL UNION ALL
SELECT 2, 'Mascarpone', 32.56, 23, NULL FROM DUAL UNION ALL
SELECT 3, 'Gorgonzola', 15.67, 9, 20 FROM DUAL
//
Query 1:
SELECT ProductName FROM products
Results:
| PRODUCTNAME |
|-------------|
| Jarlsberg |
| Mascarpone |
| Gorgonzola |

In Oracle when you use mixed case names, you must always use double quotes around them. It assumes that identifiers will be all upper case.
So to access a column called ProductName you should run:
select "ProductName" from products

I see your column names between double quotes " ".
This can use when you want to entitle your column names with special charecters.
So you can use :
select "ProductName" from products;

Related

i got a error ORA-01747 when insert data into table

i got trouble when insert data using this query :
INSERT ALL
INTO obat ('id_obat','nama_obat','tanggal_kadarluarsa','stock','harga')
VALUES (1, 'Indomethacin', '2023-09-01', 50, 3000)
SELECT * FROM dual;
this is the table query :
CREATE TABLE obat (
id_obat INTEGER NOT NULL,
nama_obat VARCHAR2(255) NOT NULL,
tanggal_kadarluarsa DATE NOT NULL,
stock INTEGER NOT NULL,
harga NUMBER(20, 2) NOT NULL,
CONSTRAINT obat_pk PRIMARY KEY ( id_obat )
);
is somethin wrong with my code?
Single quotes are for string literals; identifiers (e.g. column names) should be in double quotes - but only have to be if they were created as quoted identifiers, and then the case of the name has to match the data dictionary name exactly. Yours are not quoted identifiers in the create statement, so you can just do:
INSERT ALL
INTO obat (id_obat,nama_obat,tanggal_kadarluarsa,stock,harga)
VALUES (1, 'Indomethacin', DATE '2023-09-01', 50, 3000)
SELECT * FROM dual;
If you really wanted to quote them then you would need to do (including the table name to demonstrate, as the same rules apply):
INSERT ALL
INTO "OBAT" ("ID_OBAT","NAMA_OBAT","TANGGAL_KADARLUARSA","STOCK,HARGA")
VALUES (1, 'Indomethacin', DATE '2023-09-01', 50, 3000)
SELECT * FROM dual;
but that's just more typing and arguably maybe harder to read, and easier to get wrong.
You can read more about quoted and non-quoted identifiers in the documentation.
With a single row you don't really need ALL, you can also do:
INSERT INTO obat (id_obat,nama_obat,tanggal_kadarluarsa,stock,harga)
VALUES (1, 'Indomethacin', DATE '2023-09-01', 50, 3000)
Note that I've added the DATE keyword to these statements; '2023-09-01' is not a date, it's a string literal, so you're relying on Oracle implicitly converting that to an actual date, based on your current session NLS settings. With DATE '2023-09-01' that is now a date literal. Again, there is more in the documentation.

query object attributs (as data in a column) Oracle SQL

I imported a dataset that has a object in the column GENRES and I'm wondering if there is a (beginner's) way to query the data inside each entry.
[{"id": 12, "name": "Adventure"}, {"id": 10751, "name": "Family"}, {"id": 14, "name": "Fantasy"}]
For example, if I would want to query all the movies having the "id": 12.
The dataset comes from here
If you store the data with an IS JSON constraint, then you can use JSON_TABLE to expand the JSON into columns.
--Create a table.
create table tmdb(movie_id number, genres clob check (genres is json));
--Insert a test row.
insert into tmdb
values(1, '[{"id": 12, "name": "Adventure"}, {"id": 10751, "name": "Family"}, {"id": 14, "name": "Fantasy"}]');
--Use JSON_TABLE to convert JSON to relational data.
select movie_id, id, name
from tmdb,
json_table
(
genres, '$[*]'
columns
(
id number path '$.id',
name varchar2(4000) path '$.name'
)
) as jt;
--Results:
MOVIE_ID ID NAME
-------- ----- ---------
1 12 Adventure
1 10751 Family
1 14 Fantasy

The data model cannot be executed because of an error, please contact the administrator

I have a data sets that contains a columns which the parameters is by name, date and number. But everytime I view the data there's a error said The data model cannot be executed because of an error, please contact the administrator. But it only show the message but didn't show the details of the error. I also have a list of values because I set the parameter type of my parameters for name and number as a menu which is the result
that will return for the number is based on the name because if I didn't base it on the name it will return a 100+ values which is not okay to my user.
My query for my data set for example is,
select a.name, a.date, a.type_name, b.number, c.address
from details1 a, details2 b, details3 c
where
a.id = b.id
and b.id = c.id
and a.name = :name
and a.date between :start_date and :end_date
and b.number = :number
Query of List of Values for name
select a.name from details1 a
where a.type_name = 'person'
Query of List of Values for num
select b.number
from details1 a, details2 b
where 1=1
and a.id = b.id
and a.name = :name
I don't know BI Publisher, but - as far as Oracle is concerned, column name can not be number. It is reserved word for a datatype:
SQL> create table test (number number);
create table test (number number)
*
ERROR at line 1:
ORA-00904: : invalid identifier
Your query uses such a column:
select b.number ...
which can't work, unless someone created such a table by enclosing column name into double quotes, e.g.
SQL> create table test ("number" number);
Table created.
SQL> desc test
Name Null? Type
----------------------------------------- -------- ---------------
number NUMBER
SQL>
However, you'll have to specify such a column name using double quotes every time, paying attention to letter case (meaning: if column was created as "NumBER", you have to reference it exactly that way. "numBER" or "NUMber" or "nUmBeR" or "number" or "NUMBER" won't work). A few examples:
SQL> insert into test (number) values (1);
insert into test (number) values (1)
*
ERROR at line 1:
ORA-00928: missing SELECT keyword
SQL> insert into test ("NUMber") values (1);
insert into test ("NUMber") values (1)
*
ERROR at line 1:
ORA-00904: "NUMber": invalid identifier
SQL> insert into test ("NUMBER") values (1);
insert into test ("NUMBER") values (1)
*
ERROR at line 1:
ORA-00904: "NUMBER": invalid identifier
SQL> insert into test ("number") values (1);
1 row created.
SQL> select t."number" from test t;
number
----------
1
SQL>
Therefore, I'd suggest you to check table description and try with what you see; maybe it is as simple as
select b."number" ...
If that's the case, it is more than obvious that doing something because you can do it doesn't mean that you should do it. Avoid such things, never enclose Oracle object names into double quotes, use defaults.

How to insert a value into a nested table without losing data in that table?

How can I insert new data into an existing row's nested table? For example, I have defined
CREATE OR REPLACE TYPE businessTableForCategories AS TABLE OF VARCHAR(128);
/
CREATE TABLE Category (
name VARCHAR(128) PRIMARY KEY,
businesses businessTableForCategories
) NESTED TABLE businesses STORE AS categoryBusinessTable;
Say in Category there is an entry with name = 'Restaurant' and businesses = businessTableForCategories('xzqpehc234ajdpa8').
How can I insert new data into that nested table for that entry in Category without removing the entry, or losing the data stored in the nested table?
I ask because one of the entries I am trying to insert requires an insert statement that is 25137 characters long, which is way past Oracle's limit for a single command. This is because there are many businesses in the category. I would like to create the category, and then insert the businesses one by one (or maybe small groupings) into the nested table "businesses".
Use the MULTISET UNION [ALL|DISTINCT] operator:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE OR REPLACE TYPE businessTableForCategories AS TABLE OF VARCHAR(128);
/
CREATE TABLE Category (
name VARCHAR(128) PRIMARY KEY,
businesses businessTableForCategories
) NESTED TABLE businesses STORE AS categoryBusinessTable
/
INSERT INTO Category VALUES (
'Restaurant',
businessTableForCategories('xzqpehc234ajdpa8')
)
/
UPDATE Category
SET businesses = businesses
MULTISET UNION ALL
businessTableForCategories('other_value')
WHERE name = 'Restaurant'
/
Query 1:
SELECT *
FROM category
Results:
| NAME | BUSINESSES |
|------------|------------------------------|
| Restaurant | xzqpehc234ajdpa8,other_value |
Query 2:
Or use a bind variable to include the collection in the query:
DECLARE
businesses businessTableForCategories := businessTableForCategories();
BEGIN
businesses.EXTEND( 10000 );
FOR i IN 1 .. 10000 LOOP
businesses(i) := DBMS_RANDOM.STRING( 'x', 128 );
END LOOP;
INSERT INTO Category VALUES ( 'lots of data', businesses );
END;
Query 3:
SELECT name, CARDINALITY( businesses )
FROM Category
Results:
| NAME | CARDINALITY(BUSINESSES) |
|--------------|-------------------------|
| lots of data | 10000 |
| Restaurant | 2 |

How to use stuff function in Oracle

I asked the stuff function in Oralce question several months ago and would like to revisit this question. The problem was when using the WM_CONCAT function (in Oracle), the result included the (,) in the front or before the field I wanted to stuff.
I googled to find a solution for this but had no success so far. What should I need to include in the WM_CONCAT function in order to remove the extra empty string for the field I'd like to stuff?
I have some sample records below
CREATE TABLE #TEMP
(
COMPANY VARCHAR (50),
ID INT,
PRODUCT VARCHAR(50)
)
INSERT INTO #TEMP VALUES ('APPLES', '123', 'IPHONE4')
INSERT INTO #TEMP VALUES ('APPLES', '123', 'IPHONE4S')
INSERT INTO #TEMP VALUES ('APPLES', '123', 'IPHONE5')
INSERT INTO #TEMP VALUES ('SAMSUNG', '124', 'GALAXY S2')
INSERT INTO #TEMP VALUES ('SAMSUNG', '124', 'GALAXY S3')
INSERT INTO #TEMP VALUES ('SAMSUNG', '124', 'GALAXY S4')
INSERT INTO #TEMP VALUES ('NOKIA', '125', 'C5-02')
INSERT INTO #TEMP VALUES ('NOKIA', '125', 'C5-03')
INSERT INTO #TEMP VALUES ('NOKIA', '125', 'C5-04')
When running this query it produces as
SELECT
COMPANY,
ID,
WM_CONCAT(PRODUCT) AS PRODUCT, --STUFF PRODUCT COLUMN
FROM
(
SELECT
COMPANY,
ID,
PRODUCT
FROM #TEMP
)
GROUP BY COMPANY, ID
COMPANY ID PRODUCT
APPLES 123 IPHONE4, IPHONE4S, IPHONE5
SAMSUNG 124 ,GALAXY S2, GALAXY S3, GALAXY S4
NOKIA 125 ,C5-02, C5-03, C5-04
Just replace the:
WM_CONCAT(PRODUCT)
with:
LTRIM(WM_CONCAT(PRODUCT),',')
This will remove any leading commas from your column.
Try with the following query
SELECT
COMPANY,
ID,
WM_CONCAT(PRODUCT) AS PRODUCT
FROM
(
SELECT
COMPANY,
ID,
PRODUCT
FROM TEMP
)
GROUP BY COMPANY, ID
Is this the output you are looking for?
NOKIA 125 C5-02,C5-04,C5-03
APPLES 123 IPHONE4,IPHONE5,IPHONE4S
SAMSUNG 124 GALAXY S2,GALAXY S4,GALAXY S3
Query can be this way as well
SELECT
COMPANY,
ID,
WM_CONCAT(PRODUCT) AS PRODUCT
FROM TEMP
--(
-- SELECT
-- COMPANY,
-- ID,
-- PRODUCT
-- FROM TEMP
-- )
GROUP BY COMPANY, ID
In Oracle PL/SQL, at least in the version 19c that I'm using, there is a LISTAGG() function that is the equivalent of Stuff(). There is no WM_CONCAT in that implementation.

Resources