ORA-00905: missing keyword error in case after where clause - sql

I have the following query which is giving error ORA-00905: missing keyword. I've not been able to find the syntax despite continuous efforts for last few hours. Please help.
SELECT a.DOCUMENT_CATEGORY,
a.template_id,
a.category_id,
a.REVIEW_CATEGORY,
a.WITH_BIDS,
a.WITH_FINAL_DOCUMENTS,
b.divn_id,
b.deptt_id,
a.vdr_id,
C.DEPARTMENT,
a.TEMPLATE_TITLE
FROM DCTM_VDR_REF_DTLS a, DCTM_VDR_REF_MASTER b, VW_DIVN_DIR c
WHERE b.DIVN_ID = c.DIVN_CODE
AND b.DEPTT_ID = c.SECTN_CODE
AND a.vdr_id = b.vdr_id
AND (b.REFERENCE_NUMBER, b.APPROVED_ON) IN
( SELECT MAX (REFERENCE_NUMBER), MAX (APPROVED_ON)
FROM DCTM_VDR_REF_MASTER
WHERE REFERENCE_NUMBER =
(SELECT DISTINCT
NVL (TRIM (MR_NUMBER), TRIM (TENDER_NO))
FROM EILEDMS.EIL_DOCUMENT_SV#EDMS_DBLINK
WHERE object_name =
'A307-0IC-JA-MR-7960-1030-157-FOA'
AND r_object_type =
'eil_foa_order_pr_doc'
AND ( title = 'FOA'
OR title = 'DRAFT FOA'))
AND APPROVED_ON IS NOT NULL
GROUP BY DIVN_ID, DEPTT_ID)
AND REVIEW_CATEGORY <> 'Delete Category'
AND (CASE (SELECT IS_SCHEDULE_LOCKED
FROM DCTM_VENDOR_SCHEDULE
WHERE SCH_ID = 359)
WHEN 0
THEN
1
WHEN 1
THEN
(a.template_id || '-' || a.category_id) IN
(SELECT template_id || '-' || category_id
FROM DCTM_VENDOR_SCH_UNLOCK_DTLS
WHERE APPROVAL = 'Y'
AND APPROVAL_UPTO >= SYSDATE
AND CONSUMED = 0
AND sch_ID = 359)
END) = 1
ORDER BY c.DEPARTMENT ASC,
a.TEMPLATE_ID,
a.SORT_ORDER,
a.DOCUMENT_CATEGORY ASC
Can't we use IN clause inside a THEN statement?

Now that you've edited your question, it looks like you are simply trying to look up category_id and template_id in DCTM_VENDOR_SCH_UNLOCK_DTLS. Does the following work for you?
then
(
SELECT COUNT(*) -- 1 if found, 0 otherwise
FROM DCTM_VENDOR_SCH_UNLOCK_DTLS
WHERE APPROVAL = 'Y'
AND APPROVAL_UPTO >= SYSDATE
AND CONSUMED = 0
AND sch_ID = 359
AND template_id = a.template_id
AND category_id = a.category_id
AND rownum = 1
)

This is not actually about an IN clause after WHERE being allowed or not. The expression
a.category_id IN (SELECT ...)
evaluates to TRUE or FALSE. Your statement
a.template_id || '-' || a.category_id IN (SELECT ...)
tries to concatenate that TRUE or FALSE with a.template_id and a minus sign. This is not possible, as there is no boolean type in Oracle SQL. Think it over what you actually want to concatenate.
EDIT: Now that you set parentheses, you compare a string with another string resulting from a select statement. Fine so far. But still: All this evaluates to a boolean, not a number. Your first then results in a number (1), your second in a boolean (TRUE or FALSE). Oracle SQL has no boolean type, so your expression makes no sense to the parser and you get a syntax error.

Related

COALESCE function in OVER statement not working

Can someone please tell me why the COALESCE is working on the first SELECT here and not the other two? I'm still getting NULL values on the second two statements.
(SELECT COALESCE(DEFax, NULL, '') FROM Debtor d WHERE d.DEIsPrimary = 1 AND d.CApKey = c.CApKey) AS FaxNumberOne,
(SELECT COALESCE(DEFax, NULL, '') FROM (SELECT ROW_NUMBER() OVER (ORDER BY DEpKey ASC)
AS rownumber, DEFax FROM Debtor d WHERE d.CApKey = c.CApKey AND d.DEIsPrimary <> 1)
AS foo WHERE rownumber = 1) AS FaxNumberTwo,
(SELECT COALESCE(DEFax, NULL, '') FROM (SELECT ROW_NUMBER() OVER (ORDER BY DEpKey ASC)
AS rownumber, DEFax FROM Debtor d WHERE d.CApKey = c.CApKey AND d.DEIsPrimary <> 1)
AS foo WHERE rownumber = 2) AS FaxNumberThree
Thanks!
Sample data and desired results would really help.
But a scalar subquery is a subquery that returns one column and zero or one rows. If it returns zero rows, then the value is NULL regardless of the expression in the SELECT. In other words, the COALESCE() needs to go outside, something like this:
coalesce( (select . . . . ),
''
)
Including NULL in the coalesce() list is not a good practice. It is unnecessary and misleading -- and always ignored.

Missing expression error when creating a view

I have the following oracle query to create a view :
CREATE VIEW uvw_Dashboard_Templates
AS
SELECT LL.ID
,LL.LoadDate
,LL.FileName
,LL.TemplateType
,LL.AnalystName
,LL.RecDate
,LL.CompanyID
,LL.CompanyName
,LL.Recommendation
,LL.Loaded
,LL.ErrorText
,CASE
WHEN LL.NewCompany = 1 AND LL.Loaded = 0 THEN 0
ELSE LL.NewCompany END NewCompany
,RH.rec_date LastRecDate
,RH.rec_code LastRecCode
,CONVERT(NUMBER(1), CASE
WHEN LL.Loaded = 1 AND NVL(LL.Recommendation, 'Rec') <>
NVL(RH.rec_code,'LastRec') THEN 1
ELSE 0 END) RecChanged
FROM tblTemplates_LoadLog LL
LEFT JOIN (
SELECT company_id, rec_date, rec_code
FROM (
SELECT company_id
, rec_date
, UPPER(rec_code) rec_code
, ROW_NUMBER() OVER(PARTITION BY company_id ORDER BY rec_date DESC) RowNumber
FROM tblRecHist
) OrderedList
WHERE RowNumber = 2) RH
ON LL.CompanyID = RH.company_id
which is throwing a
ORA-00936: missing expression error on running.
What is the possible cause of this?
change this:
,CONVERT('1', CASE
The Oracle/PLSQL CONVERT function converts a string from one character set to another.
CONVERT( string1, char_set_to [, char_set_from] )
you gotta give in string there
It looks like you're trying to use the SQL Server convert() function. Oracle does have its own convert() function, but it's not related at all:
CONVERT converts a character string from one character set to another.
The closest equivalent I can see to the SQL Server function would be to cast it:
,CAST(CASE
WHEN LL.Loaded = 1 AND NVL(LL.Recommendation, 'Rec') <>
NVL(RH.rec_code,'LastRec') THEN 1
ELSE 0 END AS NUMBER(1)) RecChanged
Describing the view would show the column as NUMBER(1), which I assume is the point of converting/casting it in the first place, since you know it conforms to the scale/precision constraint already.

Oracle SQL Developer - Error: "FROM keyword not found where expected"

Sorry for my noob question but I'm trying to figure out why my Oracle-SQL indicates the error
"FROM keyword not found where expected" as the picture below:
The code I'm trying to run is the following:
select
PCKCOO AS 'COMPANHIA_DO_PEDIDO_NUMERO_DO_PEDIDO',
PCDOCO AS 'DOCUMENTO_NUMERO_DA_OS_FATURA',
PCDCTO AS 'TIPO_DE_ORDEM',
PCSFXO AS 'SUFIXO_DO_PEDIDO',
rpad(HORDT,'0',6) AS 'HORARIO_DE_LIBERACAO',
FX_PARA_GREGORIANA(HORDJ, 'DD/MM/YYYY')||' '||rpad(HORDT,6,'0') "APROVACAO",
rank() over (partition by pckcoo, pcdoco, pcdcto, pclnid order by FX_PARA_GREGORIANA(HORDJ, 'DD/MM/YYYY')||' '||rpad(HORDT,6,'0') desc) as rank,
FROM PRODDTA.F5543170 a,
proddta.f4209 b,
proddta.f4301 c,
WHERE
PCKCOO = '52171' AND
PCDCTO In ('OP','C1','C2','FZ','OF') AND
((PCTRDJ >= '117060' AND PCTRDJ <= '117090')
or (PCTRDJ >= '116061' AND PCTRDJ <= '116091')
) and
( b.hokcoo = a.pckcoo and
b.hodoco = a.pcdoco and
b.hodcto = a.pcdcto and
B.HOASTS = '2A') and
(c.phkcoo (+)= a.pckcoo and
c.phdoco (+)= COALESCE(TO_NUMBER(REGEXP_SUBSTR(PCOORN, '^(-|+)?d+(.|,)?(d+)?$')), 0) AND
c.phdcto (+)= 'OR')
The code was a lot bigger but I cut it into pieces in order to find out why this is happening (specially regarding the
Line: 3
and
Column: 25
as the error message indicated, which for me makes no sense).
Additionally, when I erase some lines in order to get closer towards the error, the red line (as indicated in the picture) keeps in the first line.
Do you have a guess of why this is happening? (sorry for the basic question again).
You have a trailing comma in the last table (proddta.f4301 c) of FROM clause and should become
...
FROM PRODDTA.F5543170 a,
proddta.f4209 b,
proddta.f4301 c
...
which should be removed.
You also have a trailing comma in your select statement that should also be removed.
...
rank() over (partition by pckcoo, pcdoco, pcdcto, pclnid order by FX_PARA_GREGORIANA(HORDJ, 'DD/MM/YYYY')||' '||rpad(HORDT,6,'0') desc) as rank
...
Finally, for table alias you need to use double instead of single quotes:
select
PCKCOO AS "COMPANHIA_DO_PEDIDO_NUMERO_DO_PEDIDO",
PCDOCO AS "DOCUMENTO_NUMERO_DA_OS_FATURA",
PCDCTO AS "TIPO_DE_ORDEM",
PCSFXO AS "SUFIXO_DO_PEDIDO",
rpad(HORDT,'0',6) AS "HORARIO_DE_LIBERACAO",
...
You have some trailing commas after AS RANK and after proddta.f4301 c.
Also, you can not use single quotes for column aliases, but you need double quotes;
this should work:
SELECT PCKCOO AS "COMPANHIA_DO_PEDIDO_NUMERO_DO_PEDIDO",
PCDOCO AS "DOCUMENTO_NUMERO_DA_OS_FATURA",
PCDCTO AS "TIPO_DE_ORDEM",
PCSFXO AS "SUFIXO_DO_PEDIDO",
RPAD(
HORDT,
'0',
6
)
AS "HORARIO_DE_LIBERACAO",
FX_PARA_GREGORIANA(HORDJ, 'DD/MM/YYYY')
|| ' '
|| RPAD(
HORDT,
6,
'0'
)
"APROVACAO",
RANK()
OVER(
PARTITION BY pckcoo,
pcdoco,
pcdcto,
pclnid
ORDER BY
FX_PARA_GREGORIANA(HORDJ, 'DD/MM/YYYY')
|| ' '
|| RPAD(
HORDT,
6,
'0'
) DESC
)
AS RANK
FROM PRODDTA.F5543170 a,
proddta.f4209 b,
proddta.f4301 c
WHERE PCKCOO = '52171'
AND PCDCTO IN ('OP',
'C1',
'C2',
'FZ',
'OF')
AND ( ( PCTRDJ >= '117060'
AND PCTRDJ <= '117090')
OR ( PCTRDJ >= '116061'
AND PCTRDJ <= '116091'))
AND ( b.hokcoo = a.pckcoo
AND b.hodoco = a.pcdoco
AND b.hodcto = a.pcdcto
AND B.HOASTS = '2A')
AND ( c.phkcoo(+) = a.pckcoo
AND c.phdoco(+) = COALESCE(TO_NUMBER(REGEXP_SUBSTR(PCOORN, '^(-|+)?d+(.|,)?(d+)?$')), 0)
AND c.phdcto(+) = 'OR')
As an aside, you should better switch to ANSI JOIN syntax.

SQL LEFT() not working as expected when used with GROUP BY and Partition

I have codes that are like 1231231A, 1231231A, 3453454B etc
I need to group them by their number (ignoring the char which is a version) and just get one of each. I also need to drop the last char. My code works in grouping them and returning one of each, but it returns the last char.
Why is it returning the last char when i chop it off?
Expected output is
1231231
3453454
What I'm getting is
1231231A
3453454B
SELECT * FROM (
SELECT *, ROW_NUMBER() OVER(PARTITION BY T.fldProductDescrip
ORDER BY T.fldEffectiveDate DESC) AS rn
FROM (
-- Insert statements for procedure here
SELECT JST.flduid
,JST.fldEffectiveDate
,(CASE
WHEN RIGHT(fldProductDescrip, 1) LIKE '[0-9]'
THEN fldProductDescrip
ELSE LEFT(fldProductDescrip, DATALENGTH(fldProductDescrip) - 1)
END) as fldProductDescrip
,(
CASE
WHEN PE.fldLogoutDateTime IS NULL
THEN PE.fldESigUser
ELSE ''
END
) AS LoggedIn
,(
CASE
WHEN PE.fldLogoutDateTime IS NULL
THEN PE.fldLoginDateTime
ELSE ''
END
) AS LoggedInDateTime
FROM tblJSJobSheetTemplates JST
INNER JOIN tblJSProducts JP ON JST.fldProductUID = JP.fldUID
INNER JOIN tblJSProductEsig PE ON JP.fldProductDescrip = PE.fldProduct
) AS T
WHERE LoggedIn <> ''
)AS G WHERE rn = 1

Oracle SQL syntax error (missing right parenthesis)

I don't understand why this provokes a syntax error (missing right parenthesis):
UPDATE table
SET doc =
(SELECT 'table-2844-doc' || SUBSTR(doc_file, INSTR(doc_file, '.', -1))
FROM docvers
WHERE (docvers.table_name = 'other_table'
AND docvers.field_name = 'doc')
AND ROWNUM = 1
ORDER BY VERSION DESC)
WHERE table_id = 2844
This looks right to me, does get executed correctly in SQL Server, and is similar to requests found, for example, in Oracle SQL: Update a table with data from another table.
Any tip?
Do it like this:
UPDATE table
SET doc = (
select r.myval
from (
SELECT 'table-2844-doc' || SUBSTR(doc_file, INSTR(doc_file, '.', -1)) myval, ROWNUM RN
FROM docvers
WHERE docvers.table_name = 'other_table'
AND docvers.field_name = 'doc'
ORDER BY VERSION DESC
) r
where r.RN = 1
)
WHERE table_id = 2844
Select the data set first including the ROWNUM, then select from that data set the first row.