Can't find the cause of a 'missing right parenthesis' error - oracle

I am having problems with a line of code. I am trying to create a count function for a view that I created. I have done this a bunch of different ways but below is the format that I have most recently used.
CREATE VIEW ERP_REPORT(EVENTNAME, DESCRIPTION, COUNT(RIDERS) AS
SELECT EVENTNAME, RACES.DESCRIPTION,
RIDERS_FIRSTNAME||' '||RTRIM(RIDERS_LASTNAME)
FROM EVENTS, RACES, PARTICIPATION, RIDERS
WHERE EVENTS.EVENTID = RACES.EVENTID
AND RACES.RACEID = PARTICIPATION.RACEID
AND RIDERS.RIDERID = PARTICIPATION.RIDERID
ORDER BY RIDERS.RIDERS_LASTNAME, EVENTNAME;
The error I am getting is ORA-00907: missing right parenthesis. The error is at the (COUNT(RIDERS) part of the code. Any ideas how I should tackle this?

The list of names in parentheses on line 1 should be the names of the view columns:
CREATE VIEW ERP_REPORT(EVENTNAME, DESCRIPTION, COUNT(RIDERS) AS ...
You can't create a column called "COUNT(RIDERS" or even "COUNT(RIDERS)" since a column name may not contain ( or ). This would work:
CREATE VIEW ERP_REPORT(EVENTNAME, DESCRIPTION, RIDER_FULL_NAME) AS ...
However it appears that you really do want a count of something, though I'm not sure of what. To do that the view definition would have to be something like:
CREATE VIEW ERP_REPORT(EVENTNAME, DESCRIPTION, RIDER_COUNT) AS
SELECT EVENTNAME, RACES.DESCRIPTION, COUNT(*)
FROM EVENTS, RACES, PARTICIPATION, RIDERS
WHERE EVENTS.EVENTID = RACES.EVENTID
AND RACES.RACEID = PARTICIPATION.RACEID
AND RIDERS.RIDERID = PARTICIPATION.RIDERID
GROUP BY EVENTNAME, DESCRIPTION;
(i.e. the COUNT function goes in the SELECT part, not in the list of column names).
As an aside, since you are presumably new to Oracle, I would suggest you start using the more modern ANSI join syntax to make your queries clearer:
...
FROM EVENTS
JOIN RACES ON RACES.EVENTID = EVENTS.EVENTID
JOIN PARTICIPATION ON PARTICIPATION.RACEID = RACES.RACEID
JOIN RIDERS ON RIDERS.RIDERID = PARTICIPATION.RIDERID

CREATE VIEW ERP_REPORT(EVENTNAME, DESCRIPTION, COUNT(RIDERS) AS
....
Should not it be:
CREATE VIEW ERP_REPORT(EVENTNAME, DESCRIPTION, COUNT(RIDERS)) AS

As the error message points out you are missing a closing bracket ). The bracket is opened here : 'ERP_REPORT(EVENTNAME' and is never closed.

you can't have brackets in column names unless you put quotation marks around. Try this:
CREATE VIEW ERP_REPORT(EVENTNAME, DESCRIPTION, "COUNT(RIDERS)") AS ...
or
CREATE VIEW ERP_REPORT(EVENTNAME, DESCRIPTION, COUNT_RIDERS) AS ...
For example:
SQL> CREATE OR REPLACE VIEW foo ("count(*)") AS SELECT COUNT(*) FROM dual;
View created
SQL> CREATE OR REPLACE VIEW foo (count_all) AS SELECT COUNT(*) FROM dual;
View created

As Tony points out there are actually several syntax errors in your statement. The missing bracket is just the first.
I find it useful to have an IDE which supports bracket matching, because it can be hard to walk back through the code and find which bracket lacks a mate. As it happens my choice is TextPad but just about anything which is more advanced than NotePad ought to be able to do this.

Related

Getting invalid identifier SQL query

I am trying to execute next query:
MERGE INTO NOTIFICATION_OBJS p
USING (SELECT
:fcsNotif_id as doc_id,
:OKPD2_code as OKPD2_code,
:OKPD2_name as OKPD2_name,
:quantity_value as quantity,
:purchaseObject_price as price
FROM DUAL
) v
ON (p.doc_id=v.doc_id)
WHEN MATCHED THEN
UPDATE SET
p.OKPD2_code = v.OKPD2_code,
p.OKPD2_name = v.OKPD2_name,
p.quantity_value = v.quantity_value,
p.price = v.price
WHEN NOT MATCHED THEN
INSERT (p.doc_id, p.OKPD2_code, p.OKPD2_name, p.quantity_value, p.price)
VALUES(v.doc_id, v.OKPD2_code, v.OKPD2_name, v.quantity_value, v.price)
I am sending to bind method next dictionary:
{'OKPD2_code': '62.02.30.000', 'OKPD2_name': 'some text', 'purchaseObject_price': '20466982.25', 'quantity_value': '1', 'fcsNotif_id': '18941152'}
But I am getting error:
ORA-00904: "P"."OKPD2_NAME": invalid identifier
All other query with binding are working. Please help me to find error.
There's no OKPD2_NAME column in NOTIFICATION_OBJS table.
If you used double quotes while creating that table (and its columns), you should
recreate the table without double quotes, or
reference the table (and its columns that use mixed case) using double quotes again, specifying case EXACTLY as it was while creating the table
[EDIT, after the screenshot has been uploaded]
Column name really is created using mixed case, so you'll have to reference it exactly like that: "OKPD2_name" paying attention to double quotes and mixed case.
If you use "okpd2_name" or "okPD2_NAME" or anything but "OKPD2_name", it won't work. Once again: get rid of double quotes.

Partial select of left joined table with doctrine query builder

When querying one table using the doctrine query builder a partial select can be written like this:
$queryBuilder = $this->createQueryBuilder('person');
$queryBuilder->addSelect('partial person.{id, name}');
How can one write a partial select be written for a left joined table? I tried something like this, but can't figure out the correct syntax:
$queryBuilder = $this->createQueryBuilder('person');
$queryBuilder->join('person.address');
$queryBuilder->addSelect('partial person.{id, name} person.address.city'); // ???
My goal would be to select only parts of the Person and the Address object when executing the query to be more memory efficient.
Your syntax is off for your join operation. You have to give an alias when using join. From there, you can just use the same syntax to query your partial Address object:
// In a method of PersonRepository
$qb = $this->createQueryBuilder('person')
->select(['partial person.{id, name}', 'partial address.{id, city}'])
->join('person.address', 'address');
Notice that I added id to the fields retrieved for Address. If you don't, Doctrine will give you the following error:
Error: The partial field selection of class Path\To\Entity\Address must contain the identifier
As a side note, you said you wanted to write this select for a left joined table. If you want to perform a LEFT JOIN, you need to use leftJoin instead of join (the signature of both methods is the same).

ActiveRecord 4 cannot retrieve "select AS" field

Ok, I feel really stupid for asking this, but it's driving me nuts and I can't figure it out. The docs say I should be able to use select AS in a Rails/ActiveRecord query. So:
d = Dvd.where(id: 1).select("title AS my_title")
Is a valid query and if I do a to_sql on it, it produces the expected SQL:
SELECT title AS my_title FROM `dvd` WHERE `dvd`.`id` = 1
However, d.my_title will give an error:
NoMethodError: undefined method `my_title' for #<ActiveRecord::Relation
I need to be able to use AS since the columns I want to retrieve from different joins have the same name so I can't access them the "regular" way and have to resort to using AS.
I also don't want to resort to using find_by_sql for future compatibility and a possible switch form Mysql to PostGresql.
Just to clarify, what I'm really trying to do is write this SQL in a Railsy way:
SELECT tracks.name AS track_name, artists.name AS artist_name, composers.name AS composer_name, duration
FROM `tracks_cds`
INNER JOIN `tracks` ON `tracks`.`id` = `tracks_cds`.`track_id`
INNER JOIN `artists` ON `artists`.`id` = `tracks_cds`.`artist_id`
INNER JOIN `composers` ON `composers`.`id` = `tracks_cds`.`composer_id`
WHERE cd_id = cd.id
The top example was just a simplification of the fact that SELECT AS will not give you an easy way to refer to custom fields which I find hard to believe.
ActiveRecord automatically creates getter and setter methods for attributes based on the column names in the database, so there will be none defined for my_title.
Regarding the same common names, why not just do this:
d = Dvd.where(id: 1).select("dvds.title")
You can write your sql query and then just pass into ActiveRecord's execute method
query = "SELECT title AS my_title FROM `dvd` WHERE `dvd`.`id` = 1"
result = ActiveRecord::Base.connection.execute(query)

Oracle: Invalid identifier

Can anyone explain to me why I get a 00904 error when I run the following
SELECT "OASM"."DT_GROUPEPG".GROUPEPGID,
"OASM"."DT_GROUPEPG".GROUPID,
"OASM"."DT_GROUPEPG".EPGID,
"OASM"."DT_GROUPEPG".ZAPID,
"OASM"."LU_EPG".LASTREADTIME,
"OASM"."LU_EPG".SERVICE_NAME,
"OASM"."LU_EPG".SOURCE_ID,
"OASM"."LU_EPG".ONID,
"OASM"."LU_EPG".TSID,
"OASM"."LU_EPG".SID,
"OASM"."LU_EPG".TYPE_ID,
"OASM"."LU_EPG".OPERATOR_ID,
"OASM"."LU_EPG".URL
FROM "OASM"."DT_GROUPEPG"
INNER JOIN "OASM"."LU_EPG"
ON "OASM"."DT_GROUPEPG".EPGID = "OASM"."LU_EPG".EPGID
ORDER BY LastReadTime;
I'm still new to Oracle, and was of the impression that, because Oracle executes blocks of statements, and not line by line, that doing this kind of query would be valid? The error currently fires at the OPERATOR_ID line, but removing/commenting it out just moves the erro up a line, until all the LU_EPG table references are removed
You can't (and don't need to) specify the schema name when referring to the columns. Also, I recommend you use table aliases (e.g. a and b in the example below):
SELECT a.GROUPEPGID,
a.GROUPID,
a.EPGID,
a.ZAPID,
b.LASTREADTIME,
b.SERVICE_NAME,
b.SOURCE_ID,
b.ONID,
b.TSID,
b.SID,
b.TYPE_ID,
b.OPERATOR_ID,
b.URL
FROM "OASM"."DT_GROUPEPG" a
INNER JOIN "OASM"."LU_EPG" b
ON a.EPGID = b.EPGID
ORDER BY b.LastReadTime;

With the use of Apex code, how can I select all ''OpportunityProducts' objects which are belongs to particular 'Opportunity Id'

I am way to customizing 'Sales' application that belongs to 'salesforce.com' platform.
Is there any way to select all the 'OpportunityProducts' objects which are belongs to particular 'Opportunity Id' ?
[SELECT Id FROM OpportunityProduct WHERE Opportunity =:opportunitId];
When I execute above code for select those 'OpportunityProduct', I got following error. If any one have some idea please update me. Thanks.
Save error: sObject type 'OpportunityProduct' is not supported. If you are attempting to use a custom object, be sure to append the '__c' after the entity name. Please reference your WSDL or the describe call for the appropriate names.
Another way to get this done when you need the actual products, not just the line items, is as follows. First get your opportunities:
List<Opportunity> opps = [SELECT Id, Name FROM Opportunity LIMIT 1000];
Then loop through to create a list of opportunity Ids
List<Id> oppIds = new List<Id>();
for(Opportunity o : opps)
{
oppIds.add(o.Id);
}
Now get your actual products that belong to your opportunities...
List<OpportunityLineItem> oppProds = [SELECT Id, PricebookEntry.Product2.Name, PricebookEntry.Product2.Family
FROM OpportunityLineItem
WHERE OpportunityId IN :oppIds];
Hope that helps.

Resources