web-dev-qa-db-fra.com

ORA-01747: spécification user.table.column, table.column ou column non valide

Obtient l'erreur ci-dessus lorsque l'exécuté immédiat est appelé dans une boucle

Update CustomersPriceGroups set  1AO00=:disc  Where cuno=:cuno
    Parameters:   disc=66 cuno=000974
Update CustomersPriceGroups set  1AP00=:disc  Where cuno=:cuno
    Parameters:   disc=70.5 cuno=000974
Update CustomersPriceGroups set  1AQ00=:disc  Where cuno=:cuno
    Parameters:   disc=66 cuno=000974
Update CustomersPriceGroups set  1ZA00=:disc  Where cuno=:cuno
    Parameters:   disc=60 cuno=000974

Qu'est-ce que ça veut dire ?

Voici le fragment de code

    c:=PriceWorx.frcPriceListCustomers('020','221');
LOOP
  fetch c into comno,cuno,nama,cpls;
  exit when c%notfound;
  dbms_output.put_Line(cuno);
   g:=priceWorx.frcPriceListItemGroups('020','221');
   d:=priceworx.frcCustomerDiscounts('020','221',cuno);
  loop
    fetch g into comno,cpgs,n;
    fetch d into comno,cpls,cuno,cpgs,stdt,tdat,qanp,disc,src;
    --dbms_output.put(chr(9)||cpgs);
    sQ:='Update saap.CustomersPriceGroups set "'|| trim(cpgs)||'"=:disc '
       || ' Where cuno=:cuno';
    execute immediate sQ using disc,cuno; 
    commit;
    dbms_output.put_line( sQ );
    dbms_output.put_line( chr(9)||'Parameters:   disc='|| disc||' cuno='||cuno);
    exit when g%notfound;
  end loop;
  close g;
  close d;
end loop;
10
TonyP

Les identificateurs non cités doivent commencer par un caractère alphabétique (voir règle 6 ici ). Vous essayez d'attribuer une valeur à une colonne dont le nom commence par un nombre 1AO00, 1AP00 etc.

Sans voir la définition de la table pour CustomersPriceGroups, nous ne savons pas si elle contient des colonnes avec ces noms. Si c'est le cas, ils doivent avoir été créés en tant qu'identificateurs cités. Si c'est le cas, vous devrez vous y reporter (partout) avec des guillemets, ce qui n'est pas idéal - rend le code un peu plus difficile à lire, facilite les erreurs et permet de repérer ce qui ne va pas. Même Oracle dit, sur la même page:

Remarque: Oracle ne recommande pas l'utilisation d'identificateurs entre guillemets pour la base de données noms d'objet. Ces identificateurs cités sont acceptés par SQL * Plus, mais ils peuvent ne pas être valides lorsque vous utilisez d'autres outils de gestion de base de données objets.

Dans votre code, vous semblez utiliser des guillemets lorsque vous affectez sQ, mais le résultat que vous affichez ne le fait pas; mais il n'a pas non plus l'identifiant de schéma saap.. C'est peut-être parce que vous n'exécutez pas la version du code que vous pensez, mais que vous avez peut-être simplement perdu Si vous avez ressaisi les données au lieu de les coller: vous ne présentez pas non plus la sortie précédente de c.cuno. Mais il est également possible que le cas du nom de colonne soit incorrect, par exemple.

Si la variable execute renvoie l'erreur, vous ne verrez pas la commande être exécutée cette fois-ci autour de la boucle car le débogage vient après, vous voyez les valeurs réussies, pas celles qui se cassent. Vous devez vérifier toutes les valeurs renvoyées par les fonctions. Je soupçonne que g renvoie une valeur pour cpgs qui n'est en réalité pas un nom de colonne valide.

Comme @ninesided le dit, le fait de montrer plus d'informations, en particulier le message d'exception complet, aidera à identifier ce qui ne va pas.

6
Alex Poole

vérifiez votre requête pour la double virgule. 

insert into TABLE_NAME (COLUMN1, COLUMN2,,COLUMN3) values(1,2,3);

(il y a une virgule supplémentaire après COLUMN2).


Mise à jour: récemment (certaines personnes ont des talents particuliers), j'ai réussi à obtenir la même exception avec une nouvelle approche: 

update TABLE_NAME set COLUMN1=7, set COLUMN2=8

(le deuxième SET est redondant)

23
yurin

Cela signifie que l'analyseur Oracle pense que l'une de vos colonnes n'est pas valide. Cela peut être dû au fait que vous avez incorrectement référencé une colonne, que le nom de la colonne est réservé à Word ou à une erreur de syntaxe dans l'instruction UPDATE qui fait penser à Oracle qu'un élément qui n'est pas une colonne est une colonne. Il serait vraiment utile de voir la déclaration complète en cours d’exécution, la définition de la table CustomersPriceGroups et le texte intégral de l’exception levée, car elle dira souvent à quelle colonne est en faute.

6
ninesided

Outre les raisons citées dans d'autres réponses, vous devrez peut-être également vérifier qu'aucun des noms de colonne de votre table n'a un nom considéré comme un mot spécial/réservé dans la base de données Oracle. 

Dans mon cas, j'avais un nom de colonne de table uid. uid est un mot réservé dans Oracle et c'est pourquoi cette erreur me causait.

Heureusement, ma table était une nouvelle table et je n'avais aucune donnée. J'étais capable d'utiliser la commande de table Oracle DROP pour supprimer la table et en créer une nouvelle avec un nom modifié pour la colonne posant problème.

J'ai également eu du mal à renommer la colonne du problème car Oracle ne me le permettait pas et je continuais à lancer des erreurs.

1
Abhi Rampal

Et j'écrivais une requête comme. J'ai dû supprimer [ et ]

UPDATE SN.TableName 
SET [EXPIRY_DATE] = systimestamp + INTERVAL '12' HOUR, 
WHERE [USER_ID] ='12345'

Nous avons récemment quitté SQL Server pour Oracle.

1
Jaikrat

si vous ajoutez un "," à la fin de l'instruction set au lieu d'une erreur de syntaxe, vous obtiendrez ORA-01747, qui est très très étrange de la part d'Oracle 

  update table1 
  set col1 = 'Y', --this odd 1
  where col2 = 123
  and col3 = 456 
0
Junchen Liu

La cause peut aussi être lorsque vous groupez par un ensemble de colonnes différent de celui de select par exemple

select tab.a, tab.b, count(*)
from ...
where...
group by tab.a, tab.c;
0
Rafał

Vous avez utilisé le mot clé Oracle dans votre instruction SQL

0
Alireza Alallah