Invalid Column after Renaming - sql

I have a nested SQL statement. In the inner SQL statement I rename a column like this: b."MANDT" b_MANDT. In the outer statement I try something similar: a."b_MANDT" a_b_MANDT.
But I'm getting the error message that this is an invalid column name, why?
SAP DBTech JDBC: [260]: invalid column name: A.b_MANDT: line 1 col 43 (at pos 42)
Original SQL Statement:
SELECT a."MANDT", a."VBELN", a."POSNR", a."b_MANDT" a_b_MANDT, a."b_VBELN" a_b_VBELN, a."VPOSN" a_VPOSN, b."MANDT" b_MANDT, b."VBELN" b_VBELN, b."VPOSN"
FROM (
SELECT a."MANDT", a."VBELN", a."POSNR", b."MANDT" b_MANDT, b."VBELN" b_VBELN, b."VPOSN"
FROM "SAP_ECC".VBAP a
LEFT JOIN "SAP_ECC".VEDA b ON a.MANDT = b.MANDT AND a.VBELN = b.VBELN AND a.POSNR = b.VPOSN
) a
LEFT JOIN "SAP_ECC".VEDA b ON a.MANDT = b.MANDT AND a.VBELN = b.VBELN AND a.VPOSN = b.VPOSN

Try changing b."MANDT" b_MANDT to b."MANDT" "b_MANDT".
Not sure what DB you are using, but typically, unless quoted, the alias defaults to upper-case yet you are trying to reference it as mixed-case.

Related

Oracle database column ambiguously defined / invalid identifier

I've tried to write a SQL statement to select from some tables. But when I run it, I get an error, and I don't know how to fix it.
When I just select from vertrag and join pgrdat, abrkreis, mandant and komm_dat, everything works fine.
However, when I try to add literal into the joins, I get the following error:
ORA-00904: "VERTRAG"."MAN" invalid identifier
on (left join literal on literal.lit_kzl = pgrdat.beruftit and literal.man = vertrag.man)
or
ORA-00918: column ambiguously defined
on (left join Literal on Literal.LIT_KZL=pgrdat.BERUFTIT and Literal.man=man)
literal.man and vertrag.man both exist.
Here's my SQL:
SELECT man,
ak,
pnr,
vertrag.vertnr,
vertrag.eintrt2,
vertrag.ma_ab,
vertrag.verbegin,
vertrag.ver_ab,
vertrag.ver_bis,
vertrag.verende,
vertrag.enlogru,
pgrdat.spr,
pgrdat.anrede,
pgrdat.auswnr,
pgrdat.beruftit,
pgrdat.daschudat,
pgrdat.fax,
pgrdat.gebdat,
pgrdat.gebname,
pgrdat.gebort,
pgrdat.geschl,
pgrdat.lnd,
pgrdat.miname,
pgrdat.namevor,
pgrdat.namezus,
pgrdat.naname,
pgrdat.ort,
pgrdat.plz,
pgrdat.plzfach,
pgrdat.postfach,
pgrdat.pst_ab,
pgrdat.pst_bis,
pgrdat.staat,
pgrdat.staat2,
pgrdat.strasse,
pgrdat.telgesch,
pgrdat.telprivat,
pgrdat.titel,
pgrdat.vorname,
pgrdat.empfaenger,
pgrdat.taetint,
pgrdat.zimmer,
pgrdat.sachbegrp,
pgrdat.logasach,
pgrdat.stellung,
pgrdat.logasach2,
pgrdat.sachbegrp2,
abrkreis.ak_bez,
abrkreis.ak_kurz,
abrkreis.ak_ort,
abrkreis.ak_plz,
abrkreis.ak_fax,
abrkreis.ak_plzfach,
abrkreis.ak_postfach,
abrkreis.ak_strasse,
abrkreis.ak_telefon,
abrkreis.ak_text,
mandant.man_bez,
mandant.man_fax,
mandant.man_firma,
mandant.man_kurz,
mandant.man_ort,
mandant.man_plzfach,
mandant.man_plzstr,
mandant.man_postfach,
mandant.man_st_nr,
mandant.man_strasse,
mandant.man_telefon,
komm_dat.km_art,
komm_dat.km_ab,
komm_dat.km_bis,
komm_dat.km_bem,
literal.lit_txt
FROM vertrag
JOIN pgrdat
USING (man, ak, pnr)
JOIN abrkreis
USING (man, ak)
JOIN mandant
USING (man)
LEFT JOIN komm_dat
USING (man, ak, pnr)
LEFT JOIN literal
ON literal.lit_kzl = pgrdat.beruftit
AND literal.man = man
WHERE superman IN ('41900', '41901', '41902', '41903')
AND literal.lit_art = 'BERUFTIT'
AND ver_ab <= trunc(SYSDATE)
AND pgrdat.pst_ab <= trunc(SYSDATE)
AND ((ver_bis >= trunc(SYSDATE) AND pgrdat.pst_bis >= trunc(SYSDATE)) OR (ver_bis IS NULL AND pgrdat.pst_bis IS NULL));
The problem is with mixing using and on join syntax. There is a third variant you didn't try:
left join Literal on Literal.LIT_KZL=pgrdat.BERUFTIT and Literal.man=komm_dat.man
which gets
ORA-25154: column part of USING clause cannot have qualifier
You can't use the unqualified man because it's ambiguous (appearing in several tables); you can't use a qualifier because it's been used in earlier using() clauses.
If it was an inner join you could change that Literal join to using (man) and move the lit_kzl check to the where clause, but as it's an outer join that won't work (or at least, would force it back to being an inner join).
You probably need to change all the other using clauses to on, unfortunately:
...
from vertrag
join pgrdat on pgrdat.man = vertrag.man and pgrdat.ak = vertrag.ak and pgrdat.pnr = vertrag.pnr
join abrkreis on abrkreis.man = vertrag.man and abrkreis.ak = vertrag.ak
join mandant on mandant.man = vertrag.man
left join komm_dat on komm_dat.man = vertrag.man and komm_dat.ak = vertrag.ak and komm_dat.pnr = vertrag.pnr
left join Literal on Literal.LIT_KZL=pgrdat.BERUFTIT and Literal.man=vertrag.man
and Literal.LIT_ART='BERUFTIT'
where ...
I've moved and Literal.LIT_ART='BERUFTIT' from the where clause into the join condition, as that would also have forced that outer join to become an inner join again.

How to fix PL/SQL: ORA-00918: column ambiguously defined in Oracle

I'm creating a package in Oracle, and when I've compiled the body of the package, i am getting the PL/SQL: ORA-00918: column ambiguously defined error.
I've gone through the code, and double checked the aliases, so am a bit stumped as to why I am receiving this error.
The error in question is on Line 10.
The PERSON_CODE, FUND_YEAR and UIO_ID in the WHERE clause are the arguments on the function that I am creating in the package.
SELECT CASE
WHEN LH.PROP_NOT_TAUGHT > 50 AND LA.DELIVERY_PROVIDER IS NOT NULL THEN TO_NUMBER(OU.UKPRN)
ELSE LA.UK_PROV_NO
END AS UKPRN_T
FROM FES.LEARNER_AIMS LA
JOIN FES.LEARNER_HE LH
ON LH.PERSON_CODE = LA.PERSON_CODE
AND LH.FUNDING_YEAR = LA.FUNDING_YEAR
LEFT JOIN FES.ORGANISATION_UNITS OU
ON OU.ORGANISATION_CODE = LA.DELIVERY_PROVIDER
WHERE LA.PERSON_CODE = PERSON_CODE
AND LA.FUNDING_YEAR = FUND_YEAR
AND LA.UIO_ID = UIO_ID;
Your function parameter name and the name of the field are clashing, creating a shadowing effect. You can prefix the name of the parameter with the function name to remove the ambiguity
AND LA.UIO_ID = MyfunctionName.UIO_ID;
Alternatively, rename the parameter to avoid such occurrences.
Its always good practice to use table alais with columns Names.
SELECT CASE
WHEN LH.PROP_NOT_TAUGHT > 50 AND LA.DELIVERY_PROVIDER IS NOT NULL THEN TO_NUMBER(OU.UKPRN)
ELSE LA.UK_PROV_NO
END AS UKPRN_T
FROM FES.LEARNER_AIMS LA
JOIN FES.LEARNER_HE LH
ON LH.PERSON_CODE = LA.PERSON_CODE
AND LH.FUNDING_YEAR = LA.FUNDING_YEAR
LEFT JOIN FES.ORGANISATION_UNITS OU
ON OU.ORGANISATION_CODE = LA.DELIVERY_PROVIDER
WHERE LA.PERSON_CODE = <tableAlaisForPersonCode>PERSON_CODE
AND LA.FUNDING_YEAR = <tableAlaisForFUND_YEAR>FUND_YEAR
AND LA.UIO_ID = <tableAlaisForUIO_ID>UIO_ID;
. The PERSON_CODE, FUND_YEAR and UIO_ID are the arguments on the function.
It is bad practice to use PL/SQL parameter names which are the same as column names. The compiler applies the nearest namespace check, which means in this case it tries to map PERSON_CODE to a table column. Aliasing is optional so it doesn't realise that you're trying to reference PL/SQL parameters.
Because you have more than one table with a column called PERSON_CODE you get the ORA-00918 error. Otherwise you would just have a query which returned all rows.
The better practice is to name parameters differently; the convention is to prefix them with p_:
WHERE LA.PERSON_CODE = P_PERSON_CODE
AND LA.FUNDING_YEAR = P_FUND_YEAR
AND LA.UIO_ID = P_UIO_ID;
Alias is missing for the column UIO_ID, just provide OU.UIO_ID
SELECT CASE
WHEN LH.PROP_NOT_TAUGHT > 50 AND LA.DELIVERY_PROVIDER IS NOT NULL THEN TO_NUMBER(OU.UKPRN)
ELSE LA.UK_PROV_NO
END AS UKPRN_T
FROM FES.LEARNER_AIMS LA
JOIN FES.LEARNER_HE LH
ON LH.PERSON_CODE = LA.PERSON_CODE
AND LH.FUNDING_YEAR = LA.FUNDING_YEAR
LEFT JOIN FES.ORGANISATION_UNITS OU
ON OU.ORGANISATION_CODE = LA.DELIVERY_PROVIDER
WHERE LA.PERSON_CODE = PERSON_CODE
AND LA.FUNDING_YEAR = FUND_YEAR
AND LA.UIO_ID = OU.UIO_ID;

How can Inner join with where clause select's table with hexadecimal value?

Below code works fine:
$stmt = $DB_con->prepare("select tbl_items.*,tbl_basket.* from tbl_items INNER JOIN tbl_basket on tbl_basket.id_items = tbl_items.id
where tbl_basket.cookie_user = 100);
I get en error when I change it to this:
$stmt = $DB_con->prepare("select tbl_items.*,tbl_basket.* from tbl_items
INNER JOIN tbl_basket on tbl_basket.id_items = tbl_items.id
where tbl_basket.cookie_user = c2b32bbfd582389b7df8e89e5796aa27);
.
Error: Fatal error: Uncaught PDOException: SQLSTATE[42S22]: Column not
found: 1054 Unknown column 'c2b32bbfd582389b7df8e89e5796aa28' in 'where clause' in
I think the problem is with inner join, However it works perfectly without inner join.
any solution?
Your working query suggests, that cookie_user is of a numeric type. If so, prepend 0x to the hexadecimal representation. That should work.
...
tbl_basket.cookie_user = 0xc2b32bbfd582389b7df8e89e5796aa27
...

ORA-00904 on join

I am trying to create the following view:
CREATE OR REPLACE VIEW AlbumDistribution AS
SELECT Album.Album_ID,
Album.title,
HasTrack.tracked,
FinishedTrack.released_title,
SUBSTR(Album.Album_ID, -1) is_distributed_as
FROM Album A
JOIN HasTrack HT
ON HT.Album_ID = A.Album_ID
JOIN FinishedTrack FT
ON HasTrack.OriginatesFrom = FT.OriginatesFrom
AND HasTrack.tracked = FT.version;
but I get the ORA-00904 error:
ERROR at line 6:
ORA-00904: "HASTRACK"."TRACKED": invalid identifier
Which I find very confusing, as I reference HasTrack.tracked before and there's no error. If I change the order of the statements, putting HasTrack.OriginatesFrom = FT.OriginatesFrom last then I get the same error but for HasTrack.OriginatesFrom.
You define an alias for this and other tables. You need to use the alias throughout the query:
CREATE OR REPLACE VIEW AlbumDistribution AS
SELECT A.Album_ID, A.title, HT.tracked,
FT.released_title, SUBSTR(A.Album_ID, -1) is_distributed_as
FROM Album A JOIN
HasTrack HT
ON HT.Album_ID = A.Album_ID JOIN
FinishedTrack FT
ON HT.OriginatesFrom = FT.OriginatesFrom AND
HT.tracked = FT.version;

Why am I getting an "ambiguous column name" error in SQLite?

I can't quite figure out why I'm getting the error. The call worked fine until I added the second where clause.
ambiguous column name: nanoProd.name:
SELECT
nanoProd.name AS prodName,
nanoProd.intro AS prodIntro,
nanoProd.prodText AS nanoText,
nanoFiles.fileLoc AS nanoFile
FROM nanoProd
LEFT JOIN nanoRelFiles on nanoFiles.rid = nanoRelFiles.file_id
LEFT JOIN nanoProd on nanoProd.rid = nanoRelFiles.item_id
WHERE nanoRelFiles.scr_type = 'prod' AND nanoRelFiles.fileUse = 'list'