missing parenthesis error - sql

So I created the following code:
Select c_id, c_name
From bk_CustWithOrders
where to_char(order_date,'MM-YYYY')=prevMonth(sysdate '2014-11-27', 4)
INTERSECT
Select c_id, c_name
From bk_CustWithOrders
where to_char(order_date,'MM-YYYY')=prevMonth(sysdate '2014-11-27', 3)
INTERSECT
Select c_id, c_name
From bk_CustWithOrders
where to_char(order_date,'MM-YYYY')=prevMonth(sysdate '2014-11-27', 2);
and I get the following error message:
ORA-00907: missing right parenthesis
00907. 00000 - "missing right parenthesis"
*Cause:
*Action:
Error at Line: 3 Column: 55
I've tried adding parenthesis but then I incur another error. Not sure what to do.

I dont know anyting about the function prevMonth.
But, What I noticed is there is no separator between sysdate and '2014-11-27'.
prevMonth(sysdate '2014-11-27', 2);
Use ',' between sysdate and '2014-11-27' and recheck:
prevMonth(sysdate, '2014-11-27', 2);
else you have to use any one of sysdate or '2014-11-27'
prevMonth(sysdate, 2);
prevMonth('2014-11-27', 2);

Line 3, column 55 is exactly at start of this part:
'2014-11-27', 4)
He's saying : I don't understand why you put a whitespace as separator.

sysdate '2014-11-27' is invalid.
If you only want to specify a date literal, it should be: date '2014-11-27'
sysdate is a function that returns the current date. If you just want to pass the current date to the function, then use only sysdate.

Related

Invalid number error in where clause

I am executing a query in Oracle database. The column and everything is correct but I am getting an Invalid Number error for below query:
select COUNT(*) AS "COUNT" from NE.STRUCT B
where B.STRUCT_TYPE in ('IDC')
and NET_ENTITY_ID is not null
and length(NET_ENTITY_ID) = 18
AND regexp_like(SUBSTR(NET_ENTITY_ID,15,1),'[^A-Z]')
and TO_NUMBER(SUBSTR(NET_ENTITY_ID,(length(NET_ENTITY_ID) -3), 4)) < 6000;
NET_ENTITY_ID field has only one data ABCDEFGHXXXXNB0001.
But not necessary that it will always be having one data. This is just for resolving the issue I am considering only this.
Error Message:
ORA-01722: invalid number
01722. 00000 - "invalid number"
*Cause: The specified number was invalid.
*Action: Specify a valid number.
The problem is that Oracle -- and any other database -- does not guarantee the order of evaluation of clauses in a WHERE. You can get around this using CASE:
where B.STRUCT_TYPE in ('IDC') and
NET_ENTITY_ID is not null and
length(NET_ENTITY_ID) = 18 AND
regexp_like(SUBSTR(NET_ENTITY_ID, 15, 1), '[^A-Z]') and
(CASE WHEN regexp_like(SUBSTR(NET_ENTITY_ID,(length(NET_ENTITY_ID) -3), 4), '^[0-9]{4}$'
THEN TO_NUMBER(SUBSTR(NET_ENTITY_ID,(length(NET_ENTITY_ID) -3), 4))
END) < 6000;
You need to ensure that the last 4 chars are numeric before using TO_NUMBER on them.
This will do it:
select COUNT(*) AS "COUNT" from
( SELECT * FROM NE.STRUCT B
where B.STRUCT_TYPE in ('IDC')
and NET_ENTITY_ID is not null
and length(NET_ENTITY_ID) = 18
AND regexp_like(SUBSTR(NET_ENTITY_ID,15,1),'[^A-Z]')
AND regexp_like(SUBSTR(NET_ENTITY_ID,-4),'[0-9]')
)
where TO_NUMBER(SUBSTR(NET_ENTITY_ID,-4)) < 6000;
NB I simplified your SUBSTR for obtaining the last 4 characters.

Complex SELECT IN doesn't work in Oracle 11

I have this query:
SELECT d.CREATION_DATE, r.RN5, s.rn1, s.PI1, r.KTR,
VERSION_NR, getTitle(r.RN5, VERSION_NR) AS TITLE
FROM DOI_SNAPSHOT d, RELATION r, SOURCE_ADDRESS s
WHERE r.RN1 NOT IN (8010,777)
AND d.RN5 = r.RN5
AND r.RN1 = s.RN1
AND r.RN5 IN (91010008,91010015)
AND r.RN5 not in (
SELECT RN5
FROM RELATION
WHERE DOI5 IS NOT NULL
AND DOI_DATE IS NULL
)
AND VERSION_NR = (
SELECT max(VERSION_NR)
FROM DOI_SNAPSHOT dmax
WHERE d.RN5 = dmax.RN5
);
and this query:
SELECT substr(w.message, 5, instr(w.message, 'KTR') - 5) AS RN5
FROM WEB_STATISTICS w
WHERE w.ACTION = 'DOI Display'
GROUP BY substr(w.message, 5, instr(w.message, 'KTR') - 5)
ORDER BY count(*) DESC;
both of them are working correctly.
Now if I replace the first query's line
AND r.RN5 IN (91010008, 91010015)
and put in the parenthesis the second query, I get an error
ORA-00907: missing right parenthesis
00907. 00000 - "missing right parenthesis"
I don't know what is happening, since both queries are working oracle should at least accept the syntax?
The problem is that you have an order by clause in your second query, and you've left that in when you turned it into a subquery. The clause isn't valid in that context and makes no sense anyway - you're looking for members of a set, the ordering of the elements within that set is irrelevant - so you should remove the order by count(*) desc part.
To demonstrate with a simple but very contrived example; with an order by clause:
select * from dual
where dummy in (select 'X' from dual order by 1 desc);
SQL Error: ORA-00907: missing right parenthesis
00907. 00000 - "missing right parenthesis"
And without:
select * from dual
where dummy in (select 'X' from dual);
DUMMY
-----
X
As a simplistic explanation of the error message, when the parser see the order by it thinks that applies to the main query, and therefore the subquery should have already been terminated a closing right parenthesis - which is missing.
This is a message that often doesn't mean what you might think it implies - it isn't that the query overall has unbalanced parentheses, just that it's found a syntax error that may have been caused by a missing or misplaced one.
Generally error ORA-00907 usually means "there is a syntax error somewhere before this point".
Let's try
SQL> select * from dual
2 where dummy in (select dummy from dual);
DUMMY
-----
X
SQL> select * from dual
2 where dummy in (select dummy from dual order by 1);
ORA-00907: missing right parenthesis
So you should remove ORDER BY clause from inner query.

Using COALESCE in oracle and getting ORA-00907: missing right parenthesis

I am trying to use COALESCE function in query but it throws an error ORA-00907: missing right parenthesis but the same query is running well in mysql i dont know how to write same query in orcale please help me out from this error.
SELECT DISTINCT sut.SERVICE_USER_TYPE , COUNT(er.ENFORCMENT_ID)
, SUM(er.FINE_AMOUNT),
COALESCE(er.CHECK_DATE>=('12-JAN-15'), er.CHECK_DATE<=('12-JAN-15''11.59.59.465000000 PM'))
from SERVICE_USER_TYPE sut
LEFT JOIN SERVICE_USERS su
ON su.SERVICE_USER_TYPE_ID = sut.SERVICE_USER_TYPE_ID
LEFT JOIN ENFORCEMENT_REPORT er ON su.SERVICE_USER_ID = er.SERVICE_USER_ID
group by sut.SERVICE_USER_TYPE ;
and the error
ORA-00907: missing right parenthesis
00907. 00000 - "missing right parenthesis"
*Cause:
*Action:
Error at Line: 4 Column: 23
please help me out..
You say this works in MySQL. Well, the COALESCE expression results in 0, 1 or NULL per record. Then you aggregate your rows, but there is no aggregate on your COALESCE expression. This gives you a random 0, 1 or NULL per SERVICE_USER_TYPE.
The COALESCE expression
COALESCE(er.CHECK_DATE>=('12-JAN-15'), er.CHECK_DATE<=('12-JAN-15''11.59.59.465000000 PM'))
does the following in MySQL (only obfuscated):
CASE
WHEN er.CHECK_DATE IS NULL THEN NULL
WHEN er.CHECK_DATE >= '12-JAN-15' THEN 1
WHEN er.CHECK_DATE < '12-JAN-15' THEN 0
END
or, with NULL being the default, shortly
CASE
WHEN er.CHECK_DATE >= '12-JAN-15' THEN 1
WHEN er.CHECK_DATE < '12-JAN-15' THEN 0
END
You can do the same in Oracle and any other DBMS, but think about what aggregate you want to see. (If you expect it to be the same within all records for a SERVICE_USER_TYPE, use MIN or MAX or AVG, whichever you like best.)
For instance:
MIN
(
CASE
WHEN er.CHECK_DATE >= DATE'2015-01-12' THEN 1
WHEN er.CHECK_DATE < DATE'2015-01-12' THEN 0
END
)

Removing leading zeros from varchar sql developer

How would I remove the leading zeros from a number which is in the form of varchar.
I have tried the following:
Option 1:
insert into example_table (columnName)
(SELECT
SUBSTR(columnName2, InStr('%[^0 ]%', columnName2 + ' '), 10)
from columnName2);
With this, the error I get is
SQL Error: ORA-01722: invalid number
ORA-02063: preceding line from xxxx
01722. 00000 - "invalid number"
Option 2:
insert into example_table (columnName)
(SELECT
SUBSTR(columnName2, InStr('%[^0 ]%', columnName2 + ' '),
LEN(columnName2))
from columnName2);
This time I get
Error at Command Line:23 Column:87
Error report:
SQL Error: ORA-00904: "LEN": invalid identifier
Option 3:
SUBSTRING
(columnName2, PATINDEX('%[^0 ]%', columnName2 + ' '), 10));
Similar to above, I get
Error at Command Line:23 Column:41
Error report:
SQL Error: ORA-00904: "PATINDEX": invalid identifier
00904. 00000 - "%s: invalid identifier"
EDIT
I think that the trim route might be my best option, however... I am uncertain how to use it in the case I have.
INSERT INTO temp_table
(columnNeedTrim, column2, column3, column4, column5)
SELECT * FROM
(SELECT(
SELECT TRIM(leading '0' from columnNeedTrim) FROM table),
table.column2,
table2.column3,
table.column4
table.column5
FROM
table
INNER JOIN
table2 ON
table1.columnNeedTrim=table2.columnNeedTrim)
WHERE NOT EXISTS (SELECT * FROM temp_table);
I now get an error because my trim function returns multiple row result.
Error report:
SQL Error: ORA-01427: single-row subquery returns more than one row
01427. 00000 - "single-row subquery returns more than one row"
I am not sure how to work a trim (or a cast) into the statement above. Any help on that?
Thanks for any help!
Oracle has built-in TRIM functions for strings. Assuming you have a string like '00012345' and you want to keep it as a string, not convert it to an actual NUMBER, you can use the LTRIM function with the optional second setparameter specifying that you're triming zeros:
select ltrim('000012345', '0') from dual;
LTRIM
-----
12345
If you might also have leading spaces you can trim both in one go:
select ltrim(' 00012345', '0 ') from dual;
LTRIM
-----
12345
You could also convert to a number and back, but that seems like a lot of work unless you have other formatting that you want to strip out:
select to_char(to_number('000012345')) from dual;
Incidentally, the immediate reason you get the ORA-01722 from your first attempt is that you're using the numeric + operator instead of Oracle's string concentenation operator ||. It's doing an implicit conversion of your string to a number, which it seems you're trying to avoid, and the implicit conversion of the single space - whatever that is for - is causing the error. (Possibly some of your values are not, in fact, numbers at all - another example of why numbers should be stored in NUMBER fields; and if that is the case then converting (or casting) to a number and back would still get the ORA-01722). You'd get the same thing in the second attempt if you were using LENGTH instead of LEN. Neither would work anyway as INSTR doesn't recognise regular expressions. You could use REGEXP_INSTR instead, but you'd be better off with #schurik's REGEXP_REPLACE version if you wanted to go down that route.
I'm not sure I understand your question edit. It looks like your insert can be simplified to:
INSERT INTO temp_table (columnNeedTrim, column2, column3, column4, column5)
SELECT LTRIM(table1.columnNeedTrim, '0 '),
table1.column2,
table1.column3,
table1.column4,
table1.column5
FROM table1
INNER JOIN table2 ON table2.columnNeedTrim = table1.columnNeedTrim
WHERE NOT EXISTS (
SELECT * FROM temp_table
WHERE columnNeedTrim = LTRIM(t42.columnNeedTrim, '0 '));
(I don't understand why you're doing a subquery in your version, or why you're getting the trimmed value from another subquery.)
You could also use MERGE:
MERGE INTO temp_table tt
USING (
SELECT LTRIM(t42.columnNeedTrim, '0 ') AS columnNeedTrim,
t42.column2,
t42.column3,
t42.column4,
t42.column5
FROM t42
INNER JOIN t43 ON t43.columnNeedTrim=t42.columnNeedTrim
) sr
ON (sr.columnNeedTrim = tt.columnNeedTrim)
WHEN NOT MATCHED THEN
INSERT (tt.columnNeedTrim, tt.column2, tt.column3, tt.column4, tt.column5)
VALUES (sr.columnNeedTrim, sr.column2, sr.column3, sr.column4, sr.column5);
SELECT '00012345' AS zeroWith, TRIM(LEADING 0 FROM '00012345') AS zeroWithOut
FROM dual;
Result : zeroWith > 00012345 & zeroWithOut > 12345
For SQL server, if you know the data is actually a number, you can just cast it twice. Casting to an int removes the leading zeroes, then back to a string for insertion. I'm assuming you can do something similar in Oracle.
DECLARE #vc varchar(100) = '0000000000000000000001234'
SELECT CAST(CAST(#vc as int) as varchar(100))
Returns:
1234
You do not have to replace it. It will be handled by Oracle.
SELECT TO_NUMBER(num)
FROM
(
SELECT '00000123' AS num FROM DUAL
);
-- Result:
-- 123
You can use the following methods:
Option 1: use the ltrim function as Alex said:
select ltrim('0005400', '0')
from dual;
Option 2: use the trim function:
select trim(leading '0' from '0005400')
from dual;
Oracle trim function has the leading, trailing and both options.
Option 3: use regular expressions:
select regexp_substr('0005400', '[^0].+')
from dual;

Encountered "ORA-00907: missing right parenthesis" using insrt function in oracle SQL

I am trying to test this sql query but I always encounter an error stating missing right parenthesis at row 1. I am guessing it has something to do with the INSTR function because my query just works fine if I replace INSTR function with a column name.
* row 1
SELECT INSTR(diary.entry, 'service', 1, 1 > 0)
FROM diary journal
WHERE journal.req_time >= '00:00:00'
AND journal.req_time <= '00:10:59';
Anyone care to help? Thanks
I think it is
SELECT INSTR(diary.entry, 'service', 1, 1) > 0
INSTR Function
INSTR Function Example