solution for ORA-00933 - sql

I'm tring to use join but facing this issue. I've pasted my query
select count(*) from table_a inner
join table_b on table_a.number = table_b.number
left outer join table_c on table_a.id = table_c.id
and table_a.number = table_c.number
order by number;
pls let me know what is wrong in the query...
-Vinod

Are you executing this query as part of an INSERT or DELETE?
If so, remove the ORDER BY. It's not needed anyway.
Error: ORA-00933: SQL command not
properly ended
Cause: You tried to
execute an SQL statement with an
inappropriate clause.
Action: The
options to resolve this Oracle error
are:
You may have executed an INSERT
statement with an ORDER BY Clause. To
resolve this, remove the ORDER BY
clause and re-execute the INSERT
statement. For example, you tried to
execute the following INSERT
statement:
INSERT INTO supplier (supplier_id,
supplier_name) VALUES (24553, 'IBM')
ORDER BY supplier_id;
You can correct the INSERT statement
by removing the ORDER BY clause as
follows:
INSERT INTO supplier (supplier_id,
supplier_name) VALUES (24553, 'IBM');
You may have tried to execute a DELETE
statement with an ORDER BY Clause. To
resolve this, remove the ORDER BY
clause and re-execute the DELETE
statement. For example, you tried to
execute the following DELETE
statement:
DELETE FROM supplier WHERE
supplier_name = 'IBM' ORDER BY
supplier_id;
You can correct the DELETE statement
by removing the ORDER BY clause as
follows:
DELETE FROM supplier WHERE
supplier_name = 'IBM';

How did you execute this query?
In Oracle SQL, there's no such thing as a statement separator like ";". That one is only used in PL/SQL and some tools allow you to put more than one statement in a file/editor, when you separate them with ";". Only so that they can execute them separately.
Long story short: remove the ";" and try again.
Oh and next time, tell us how you ran the query. We have to check our crystal balls to guess what your problem is.

You cannot order by a value which cannot be included in the result set. your result set aggregates multiple rows, each with its own value of NUMBER, into a single row. therefore the order by does not make logical sense. In this case your query only returns one row so ORDER BY is irrelevant.

When you transcribed your query to the anodyne test case you present here you inadvertently corrected it. Well, you introduced an ORA-00918 bug but once that is fixed the code runs fine...
SQL> create table table_a (col_1 number, id number)
2 /
Table created.
SQL> create table table_b (col_1 number)
2 /
Table created.
SQL> create table table_c (col_1 number, id number)
2 /
Table created.
SQL>
SQL>
SQL> select count(*) from
2 table_a inner join table_b on table_a.col_1 = table_b.col_1
3 left outer join table_c on table_a.id = table_c.id
4 and table_a.col_1 = table_c.col_1
5 order by col_1
6 /
order by col_1
*
ERROR at line 5:
ORA-00918: column ambiguously defined
SQL> select count(*) from
2 table_a inner join table_b on table_a.col_1 = table_b.col_1
3 left outer join table_c on table_a.id = table_c.id
4 and table_a.col_1 = table_c.col_1
5 order by table_a.col_1
6 /
COUNT(*)
----------
0
SQL>
Note: I have subsituted COL_1 for NUMBER as a column name. I don't think that's your problem, because using NUMBER unescaped in the query would hurl ORA-1747 not ORA-00933.
So, let's rule out the obvious: are you running on an ancient version of Oracle which doesn't support the ANSI join syntax, that is 8i or older?

Related

Is the GROUP BY needed to insert

INSERT INTO NEWTABLE
(Street,
Number,
NuDate,
XValue)
SELECT
a1.Street,
a2.Number,
a2.NuDate,
a2.XValue
FROM
ABC.dbo.Faculty a1 INNER JOIN
ABC.dbo.Faculty2 a2
ON a1.NameID = a2.NameID
WHERE
a1.Bologna = 'True'
GROUP BY
a1.Street,
a2.Number,
a2.NuDate,
a2.XValue
In this completely fictitious SQL statement, is the GROUP by needed to insert properly into NEWTABLE? and/or does the group by need to match up perfectly with the INSERT INTO for this statement to work properly?
EDIT: Sorry, I realized I had the wrong values for the GROUP BY statement, they're supposed to match the INSERT INTO
In this completely fictitious SQL statement, is the GROUP by needed to insert properly into NEWTABLE?
It's not necessary if you don't mind duplicates
If you don't want duplicate rows then yes, you'll need to use GROUP BY (or DISTINCT):
SELECT DISTINCT
a1.Street,
a2.Number,
a2.NuDate,
a2.XValue
does the group by need to match up perfectly with the INSERT INTO for this statement to work properly?
Yes, the selected columns must match.
There are cases when what you group by doesn't match what you select but that's when you aggregating:
SELECT
column1, -- no aggregation, must match
sum(column2) -- aggregation, so does not need to match
FROM a
GROUP BY column1

Merge with only 'when matched then update' In Oracle 9i

I am working at a company with Oracle 9i 9.2, and I am unable to upgrade.
A merge which only does an update on matched, not an insert on not-matched, seems not to work in this version.
I am trying to do:
MERGE INTO CDLREFWORK.pricing d --table to insert to
USING V_REC S --table source
ON ( D.item_id = S.item_id
and d.line_type = s.line_type
AND d.price_code =s.price_code )
WHEN MATCHED THEN UPDATE SET
d.APPLICATION_ID='CPMASI',
d.SYS_UPDATE_DATE=SYSDATE,
d.OPERATOR_ID=nvl(s.OPERATOR_ID, d.OPERATOR_ID),
d.LOCATION_ID=nvl(s.LOCATION_ID,d.LOCATION_ID),
d.ITEM_ID= nvl(s.ITEM_ID,d.ITEM_ID),
d.LINE_TYPE= nvl(s. LINE_TYPE, d.LINE_TYPE),
d.EXPIRATION_DATE=nvl(s.EXPIRATION_DATE,d.EXPIRATION_DATE),
d.PRICE_CODE= nvl(s.PRICE_CODE,d.PRICE_CODE),
d.TO_QTY=nvl(s.TO_QTY,d.TO_QTY),
d.PRICE= nvl(s.PRICE,d.PRICE),
d.CHARGE_CODE=nvl(s.CHARGE_CODE,d.CHARGE_CODE),
d.SOC=nvl(s.SOC,d.SOC),
d.COMMITMENT=nvl(s.COMMITMENT,d.COMMITMENT),
d.CAMBIAZO_CODE=nvl(s.CAMBIAZO_CODE,d.CAMBIAZO_CODE),
d.PPG_IND=nvl(s.PPG_IND,d.PPG_IND);
This gets:
SQL Error: ORA-00905: missing keyword
00905. 00000 - "missing keyword"
If this isn't possible in 9i, then how would I do an equivalent update instead?
The syntax diagram for 9i shows that you had to have both when matched and when not matched clauses. That changed in 10gR1 (and is mentioned in the new features list); but that doesn't really help you if you can't upgrade - it just explains why it doesn't work. You were also trying to update two of the three columns from the join clause, which isn't allowed.
You can do a correlated update instead:
UPDATE CDLREFWORK.pricing d
SET (d.APPLICATION_ID, d.SYS_UPDATE_DATE, d.OPERATOR_ID, d.LOCATION_ID,
d.EXPIRATION_DATE, d.PRICE_CODE, d.TO_QTY, d.PRICE, d.CHARGE_CODE, d.SOC,
d.COMMITMENT, d.CAMBIAZO_CODE, d.PPG_IND)
= (
SELECT 'CPMASI',
SYSDATE,
nvl(s.OPERATOR_ID, d.OPERATOR_ID),
nvl(s.LOCATION_ID,d.LOCATION_ID),
nvl(s.EXPIRATION_DATE,d.EXPIRATION_DATE),
nvl(s.PRICE_CODE,d.PRICE_CODE),
nvl(s.TO_QTY,d.TO_QTY),
nvl(s.PRICE,d.PRICE),
nvl(s.CHARGE_CODE,d.CHARGE_CODE),
nvl(s.SOC,d.SOC),
nvl(s.COMMITMENT,d.COMMITMENT),
nvl(s.CAMBIAZO_CODE,d.CAMBIAZO_CODE),
nvl(s.PPG_IND,d.PPG_IND)
FROM V_REC s
WHERE s.item_id =d.item_id
AND s.line_type = d.line_type
AND s.price_code = d.price_code
)
WHERE EXISTS (
SELECT null
FROM V_REC s
WHERE s.item_id =d.item_id
AND s.line_type = d.line_type
AND s.price_code = d.price_code
);
I've taken out the item_id and line_type columns as you already know they match. The where exists clause means only rows in pricing which actually have a matching row in v_rec are updated. That may mean the nvl() calls are redundant, and you just need to select the value from s, but without knowing your data it's hard to be sure.

CREATE TABLE failed ORA 00957 Duplicate column name

As I tried to create new table from existing 2 table with specific column name in oracle.
I tried below code
CREATE TABLE D_T1
AS
SELECT a.col1, a.col2, a.col3, a.col4, a.col5, b.col6, b.col7, b.col8
FROM db1.table1 a INNER JOIN db1.table2 b
ON (a.col1 = b.colNum AND a.col2 = b.colnum1)
But I get error
CREATE TABLE failed ORA 00957 Duplicate column name
Can anyone help?
Ignoring the other errors you seem to have introduced by retyping the code, you've shown that you do have a duplicate column, which is what the error is telling you:
a.VALIDFLAG, b.VALIDFLAG
You seem to be under the impression that the table (alias) prefix makes the column names in the projection unique. They do not. The table prefix tells Oracle which table to get the column value from (unless you're using the using join syntax, which you are not). If the column appears in two tables you have to prefix the column name with the table. If you want the value from both tables you have to prefix both of them.
With a simple query then referring to both table columns without column aliases is OK, but something trying to consume the result set might struggle. This is fine:
select a.dummy, b.dummy
from dual a
join dual b on b.dummy = a.dummy;
DUMMY DUMMY
------- -------
X X
But notice that both columns have the same heading. If you tried to create a table using that query:
create table x as
select a.dummy, b.dummy
from dual a
join dual b on b.dummy = a.dummy;
You'd get the error you see, ORA-00957: duplicate column name.
If you alias the duplicated columns then the problem goes away:
create table x as
select a.dummy as dummy_a, b.dummy as dummy_b
from dual a
join dual b on b.dummy = a.dummy;
So in your case you can alias those columns, if you need both:
..., a.VALIDFLAG AS validflag_a, b.VALIDFLAG AS validflag_b, ...
To be completely honest, that query is a mess. You've got several errors in your SQL statement:
CREATE TABLE AS SELECT
The table name is missing - this should be
CREATE TABLE my_new_table AS SELECT
to create a new table named my_new_table.
a.ALIDFLAG,b,VALIDFLAG,
I've got a suspicion that this should really be a.VALIDFLAG instead of a.ALIDFLAG. Also, you need to replace b,VALIDFLAG with b.VALIDFLAG.
SELECT a.BILLFREQ a.CDHRNUM,
You're missing a comma after a.BILLFREQ - this is a syntax error.
a.A‌​GNYCOY,a.AGNTCOY
There's the culprit - you're selecting the same column twice. Get rid of the second one.
EDIT Actually, the names are different, so this isn't the cause of the error (unless you've mistyped your query in the comment instead of copy& paste).
To debug this kind of errors, try to
format your SQL statement in a readable way
comment out everything but one column, run the statement and ensure it works
add one column
repeat until you find the error or you've added all columns
2ND UPDATE
With the updated query, the error is here:
a.VALIDFLAG,
b,
VALIDFLAG,
You have two columns named VALIDFLAG - use an alias for one of these, and it should work.
ORA-00957: duplicate column name
The only reason for that error in your CTAS statement is that you have similar column name in the SELECT statement. Though you might be referring to different table columns, but you did not use a column alias
Error reproduce:
Using the standard EMP and DEPT table.
SQL> CREATE TABLE D_T1 AS
2 SELECT a.deptno,
3 b.deptno
4 FROM emp A
5 INNER JOIN dept b
6 ON (a.deptno = b.deptno);
b.deptno
*
ERROR at line 3:
ORA-00957: duplicate column name
Workaround:
Use proper alias:
SQL> CREATE TABLE D_T1 AS
2 SELECT a.deptno e_deptno, --add column alias
3 b.deptno d_deptno --add column alias
4 FROM emp a
5 INNER JOIN dept b
6 ON (a.deptno = b.deptno);
Table created.
Edit as per new input from OP.
You have some syntax error in your query. Corrected those. I also checked for duplicate columns. There are none. Now run this and let me know if you still get same error.
CREATE TABLE D_T1 AS SELECT
a.B, a.C,a.C, a.C, a.C,a.J, a.O,
a.P,a.P,a.S,a.S,a.R,a.B,
a.S,a.S,b.A,b.C,b.C,b.I, b.M,
b.P,b.P,b.S,b.S,b.S,b.Z,b.Z,a.C,
a.CH‌​,a.G,b,V,b.T,a.C,a.C,a.C,
a.A,a.A‌​Ga.AG
FROM tbl1 a JOIN tbl2 b
ON (a.C= b.C AND a.C1= b.C1)

The result of a scalar fullselect, SELECT INTO statement, or VALUES INTO statement is more than one row

I have a problem about my query and i dont know what to do about it.Here is my query.and error i take.
select prd.product_id,prd.prd_name ,prd.prd_longname ,prd.prd_brand ,prd.prd_picture ,prd.market_comment ,prd.categ ,prd.status_id ,prd.status ,prd.active_stock ,prd.slot_date ,prd.currency ,prd.selling_price ,prd.old_price ,prd.type_of_sell ,prd.catalog_id ,prd.catalog_name ,prd.demo ,prd.demo_id,
(select coalesce(count(prd_attribute_id),0) from PRD_ATTRIBUTE where status_id = 1 and product_id = prd.product_id and batch_code <> '0000') as ATTR_CNT ,
(select prd_attribute_id from PRD_ATTRIBUTE where product_id = prd.product_id and batch_code = '0000' and status_id = 1),
(select categ_url from DBNAME.PRD_CATEGORY
where parameter_id = prd.categ_id)||'/'|| (select prd_url from DBNAME.PRODUCT_URL where product_id = prd.product_id) as CATEG_URL
from TEMP_WEB_PRD prd
order by slotdate desc
fetch first 12 rows only
Error:
[IBM][CLI Driver][DB2/AIX64] SQL0811N The result of a scalar fullselect, SELECT INTO statement, or VALUES INTO statement is more than one row. SQLSTATE=21000
The error message is pretty self-explanatory. One of your sub-selects is returning more than one row back, and the database doesn't know how to handle that. I'm guessing your database is DB2 on Linux/Unix/Windows, based on the error message, so here's the Info Center article on your error.
Yes in short it's due to you are using "=" but duplicate rows returned from sub-select statement.
Suppose you have a simple table:
create table T1 (ID int not null primary key, FID int);
The following statement may return SQL0811N if FID column references the same ID values multiple times.
db2 "select id from T1 where ID=(select fid from T1)"
ID
SQL0811N The result of a scalar fullselect, SELECT INTO statement, or VALUES
INTO statement is more than one row. SQLSTATE=21000
The following statement will run successfully:
db2 "select id from T1 where ID IN (select fid from T1)"
Maybe one of your tables has duplicate data, make sure you've checked it. I have the same problem too, it is caused by duplicate rows and it makes subquery return more than one row.

Delete all rows from a table that are present in a View

The queries I would like to perform:
BEGIN TRANSACTION
INSERT INTO TABLE_B SELECT * FROM TABLE_A WHERE SOME_COLUMN = 'something'
DELETE FROM TABLE_A WHERE COLUMN IN (
SELECT * FROM TABLE_A WHERE SOME_COLUMN = 'something'
)
END TRANSACTION
As you can see, there is a redundant SELECT statement in the DELETE query that I would like to replace (if possible), thus improving efficiency.
I was thinking to create a View with the rows in the first query and then scan the View with the rows in the second table. If some condition matches, then delete the row from the second table.
Could I get some pointers on how this could be done? If there is anything wrong I am doing, please criticize.
This is what you want, I think:
delete from table_a
where some_column = 'something'
As written, your query would probably generate a syntax error. The "SELECT *" would return all columns in table_a, and it presumably has more than one column.
Generally, you should be able to do joins in the delete statement, but you'd need to specify the table from which you're deleting rows:
delete table_a
from table_a left join table_b on (table_a.column_a = table_b.column_b)
where table_b.column_b = 'some_value'