SQL*Plus Problem mit EZConnect

Will man sich mit SQL*Plus mit der Datenbank verbinden, kann man dies über die TNS-Alias oder die Easy Connect Methode (EZConnect) tun. Die Syntax ist: 

sqlplus <username>[/<password>][@<connect_identifier>

Also bspw.:

C:\Users>sqlplus scott/tiger@orcl
C:\Users>sqlplus scott/tiger@oracle.server.local:1521/myservice

Möchte man das Passwort nicht im Klartext mit übergeben, sondern es gesondert im Passwort-Prompt eingeben, lässt man den optionalen Passwort-Teil einschließlich des Schrägstriches weg.

C:\Users>sqlplus scott@orcl
C:\Users>sqlplus scott@oracle.server.local:1521/myservice

Problem

Im ersten Fall (Verbindung über den TNS-Alias) fragt SQL*Plus erwartungsgemäß nach dem Passwort. Im zweiten Fall (EZConnect) antwortet SQL*Plus bzw. der Listener mit der Fehlermeldung:

ERROR:
ORA-12504: TNS: Listener was not given the SERVICE_NAME in CONNECT_DATA
ORA-12504: TNS: Listener hat SERVICE_NAME in CONNECT_DATA nicht erhalten.

Schaut man sich dazu das Listener Log an sieht man auch, warum der Listener sich beschwert - die Angabe zum Servicenamen fehlt tatsächlich:

Listener Log bei erfolgreicher Verbindung über den TNS-Alias:

23-FEB-2023 09:10:44 * (CONNECT_DATA=(SERVICE_NAME=myservice)(CID=(PROGRAM=C:\Oracle\Client\bin\sqlplus.exe)(HOST=MYPC)(USER=myosuser))) * (ADDRESS=(PROTOCOL=tcp)(HOST=MY-PC)(PORT=61161)) * establish * myservice * 0

Listener Log bei fehlgeschlagener Verbindung über EZConnect:

23-FEB-2023 09:07:32 * (CONNECT_DATA=(SERVICE_NAME=)(CID=(PROGRAM=C:\Oracle\Client\bin\sqlplus.exe)(HOST=MY-PC)(USER=myosuser))) * establish * 12504
TNS-12504: TNS:listener was not given the SERVICE_NAME in CONNECT_DATA
TNS-12504: TNS:listener was not given the SERVICE_NAME in CONNECT_DATA

Lösung

SQL*Plus kommt bei der Verwendung von EZConnect ohne Passwortangabe mit der Verarbeitung der Parameter durcheinander (und interpretiert wahrscheinlich den Servicenamen als Passwort). Die Verbindung zum Listener kommt zustande, allerdings schickt SQL*Plus den Servicenamen nicht mit. Umgibt man die EZConnect-Verbindungsparameter mit maskierten Anführungszeichen, wird alles richtig verarbeitet.

C:\Users>sqlplus scott@\"oracle.server.local:1521/myservice\"

Achtung: Die Anführungszeichen sind mit einem Backslash maskiert, damit die Verarbeitung über die Shell richtig funktioniert (betrifft sowohl Windows als auch Linux). Erfolgt der Aufruf aus einem bereits gestarten SQL*Plus via CONNECT Kommando, müssen die Anführungszeichen nicht maskiert werden. 

SQL>connect scott@"oracle.server.local:1521/myservice"

Das Thema wird auch in folgenden Oracle Support Notes behandelt (Oracle Support Zugang benötigt):