=====Oracle 12c RAC Real Application Cluster Datenbank über einen Datenbank Link mit einer MS SQL 2017 Datenbank verbinden - Oracle Database Gateway unter Oracle Linux 7 einsetzen ===== **Aufgabe:** Über einen Datenbank Link soll aus einer Oracle 12c Datenbank (läuft in einem Oracle 12c Real Application Cluster) auf eine Microsoft SQL Server DB 2017 zugegriffen werden. Oracle Database Gateway (auch Heterogeneous Services) ist eine Bridge zwischen einem ODBC Treiber und der Oracle Datenbank. Aus der Datenbank wird über einen DB Link mit einem hinterlegten TNS Connect String auf den lokalen Listener zugegriffen. Dieser erkennt an der gewünschen SID, das er einen Gateway Prozess unter dem DB Owner starten soll. Dieser Gateway Prozess baut dann mit Hilfe des vom Hersteller gelieferten ODBC Treibers einen Connect auf die gewünschte Datenbank auf. Übersicht: {{ :dba:oracle_gateway_linux_to_mssql.png | Oracle Database Gateway unter Oracle Linux 7 }} ==Aufbau der Testumgebung== Die Testumgebung ist in folgender weise aufgebaut => [[dba:install_rac_linux_12c|Anmerkungen zu Installation des Oracle Real Application Cluster 12c R1 auf einem Oracle Linux 7]] Zusätzlich wird eine MS SQL Express DB 2017 auf einem 2016 Server installiert. ==Ablauf== * Lizenz pürfen * Treiber organiseren * Oracle DG4ODBC Gateway einrichten ---- ====Lizenz Oracle Database Gateway === Laut "https://docs.oracle.com/cd/E11882_01/license.112/e47877.pdf" der 11g R2 bzw. https://docs.oracle.com/cd/E80920_01/DBLIC/Licensing-Information.htm#DBLIC-GUID-B6113390-9586-46D7-9008-DCC9EDA45AB4 der Release 12c R2 : Oracle Database Gateway for ODBC Oracle Database Gateway for ODBC can be installed and used on a machine different from the machine where the Oracle Database is installed and used. It is not necessary to obtain a separate license for the machine running Oracle Gateway for ODBC => Sehr gut, nur die RDBMS Lizenz ist dafür notwendig. ---- ==== Einschränkungen beachten ! ==== Bei Problemen wie "ORA-02070: Datenbank xxxx unterstützt Subqueries in diesem Zusammenhang nicht" die Doku unter https://docs.oracle.com/cd/E11882_01/gateways.112/e12069/ch3.htm#GMSWN200 prüfen, was für Einschränkungen wir mit so einen Gateway haben. Nicht alle Varianten von SQL Befehlen werden 100% unterstütz. Treten solche Fehler auf kann mit dem Pakage „DBMS_HS_PASSTHROUGH“ ( Siehe => https://docs.oracle.com/cd/E18283_01/appdev.112/e16760/d_hspass.htm ) versucht werden, "nativ" auf der anderen Seite zu arbeiten. ---- ==== ODBC Treiber für die Microsoft Datenbank bereitstellen==== Im ersten Test wird der Treiber von Microsoft untersucht, alternativ gibt es auch Treiber zum kaufen z.b. der von EasySoft. ODBC Treiber für Linux: * EasySoft - https://www.easysoft.com/products/data_access/odbc_oracle_driver/index.html * Microsoft - https://docs.microsoft.com/de-de/sql/connect/odbc/linux-mac/system-requirements ---- ---- ===== Test Case implementieren ===== ==== MS SQL 2017 DB auf Test Server installieren ==== Über https://www.microsoft.com/en-us/sql-server/sql-server-downloads die "Express Edition" heruntergeladen und auf einem 2016 Server installiert. Der 2016 Server muss in das Internet zugreifen können, um das Setup herunterladen zu können. * Datei "SQLServer2017-SSEI-Expr.exe" als Administrator starten * Basic Installation ausgewählt, Lizenz bestätigt, Speicherort ausgewählt in meinen Fall D: * Installation läuft, Setup Files werden nachgeladen * Vom letzen Screen einen Screenshot anfertigen * Auf Connect Now klicken und diesen String merken "sqlcmd -S 12CWIN2016REP01\SQLEXPRESS -E" * Install SSSMS anklicken und auf der folgenden Website SQL Server Management Studio 17.5 herunterladen (802 MB) * Heruntergeladene Datei als Administrator starten und Install wählen * Mit "Close" die Express Installation schließen * Server neu starten Microsoft SQL Server Management Studio öffnen und eine Datenbank ORATST anlegen, ein Schema mit dem Namen "ORATAB" anlegen, unter Security/Logins ein Login ORALOGIN mit Password, unter Security/User einen User "orauser" für das ORALOGIN mit Schema ORATAB anlegen. Alternativ den User "SA" aktivieren. Dann in der Datenbank ORATST eine Tabelle DUAL anlegen. ---- ====Unter Linux eine ODBC Verbindung zu dieser Maschine herstellen==== Der Download der msodbcsql.msi Treiber von Microsoft® ODBC Driver 13.1 for SQL Server® - Windows, Linux, & macOS kann für Windows von https://www.microsoft.com/en-us/download/details.aspx?id=53339 erfolgen. Aber wie erfolgt das für Linux? === Driver auf beiden Knoten des Clusters installieren === Die Treiber für Linux lassen sich über ein RPM Package mit dem Microsoft Linux Repository installieren. Ablauf siehe => https://docs.microsoft.com/de-de/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server#microsoft-odbc-driver-131-for-sql-server Repository Definition anlegen: curl https://packages.microsoft.com/config/rhel/7/prod.repo > /etc/yum.repos.d/mssql-release.repo Vorbereitung - Unix ODBC UTF16 entfernen yum remove unixODBC-utf16 unixODBC-utf16-devel #to avoid conflicts Treiber installieren: ACCEPT_EULA=Y yum install msodbcsql # optional: for unixODBC development headers yum install unixODBC-devel # optional: for bcp and sqlcmd ACCEPT_EULA=Y yum install mssql-tools === IP Zugriff sicherstellen === Prüfen ob der Name des Datenbank Hosts aufgelößt werden kann, evlt. in der "hosts" Server aufnehmen. Bei mir heist der Server 12cWIN2016REP01 mit der IP 10.10.10.111 vi /etc/hosts 10.10.10.111 12cWIN2016REP01 12cWIN2016REP01.pipper.local # nun pürfen ob der Server ereichbar ist ping 12cWIN2016REP01.pipper.local Falls es nicht funktioniert, erstmal probehalber die FW auf Windows ausschalten. === Test von einer Windows Maschine (Win10 VM) === Nun erstmal **sqlcmd** in einer Windows 10 VM installieren, ob überhaupt ein Connect mit dem Server in der Windows Welt funktioniert. Dort auch den Server in der Host Datei hinterlegt. sqlcmd installieren über diese beiden MSI Packages, herunterladen und installieren * https://www.microsoft.com/en-us/download/details.aspx?id=53591 * https://www.microsoft.com/en-us/download/details.aspx?id=53339 == Prüfen ob die Datenbank überhaupt über TCP angesprochen werden kann== Mit dieser Beschreibung alle Einstellungen checken => https://blogs.msdn.microsoft.com/walzenbach/2010/04/14/how-to-enable-remote-connections-in-sql-server-2008/ Bei mir war TCP/IP als Protocol abgeschaltet, siehe auch https://docs.microsoft.com/en-us/sql/tools/configuration-manager/tcp-ip-properties-ip-addresses-tab Als nächstes FW Thema prüfen => siehe https://docs.microsoft.com/en-us/sql/sql-server/install/configure-the-windows-firewall-to-allow-sql-server-access SA User aktiveren auf dem Server (ist ja hier nur ein Test, Produktiv je nach Bedarf einrichten) Daran denken, überhaupt MS SQL Server Logins zu aktiveren => https://support.microsoft.com/en-us/help/555332/login-failed-for-user-error-message-when-you-log-on-to-sql-server ==Test mit der Windows 10VM== Test mit sqlcmd: PS C:> sqlcmd -S 12CWIN2016REP01\SQLEXPRESS -U sa -P ora123Login 1> use oratst 2> go Changed database context to 'ORATST'. 1> select * from dual; 2> go FROM_X -------------------------------------------------- (0 rows affected) 1> insert into dual (from_x) values ("X"); 2> go (1 rows affected) 1> select * from dual; 2> go FROM_X -------------------------------------------------- X (1 rows affected) 1> Das funktioniert also prinzipell === Nun das ganze über die Linux Maschine testen === === Problem CP Provider: Error code 0x2AF9== Der ersten Test schlägt fehl mit **TCP Provider: Error code 0x2AF9.** [root@racdb01 ~]# /opt/mssql-tools/bin/sqlcmd -S 12CWIN2016REP01\SQLEXPRESS -U sa -P ora123Login Sqlcmd: Error: Microsoft ODBC Driver 13 for SQL Server : Login timeout expired. Sqlcmd: Error: Microsoft ODBC Driver 13 for SQL Server : TCP Provider: Error code 0x2AF9. Sqlcmd: Error: Microsoft ODBC Driver 13 for SQL Server : A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online.. # Prüfen ob der Port auch erreichbar ist telnet 12CWIN2016REP01 1433 Trying 10.10.10.111... Connected to 12CWIN2016REP01. Escape character is '^]'. # Port ist erreichbar! # Test mit strace strace -tt /opt/mssql-tools/bin/sqlcmd -S 12CWIN2016REP01\SQLEXPRESS -U sa -P ora123Login 02:54:10.673532 execve("/opt/mssql-tools/bin/sqlcmd", ["/opt/mssql-tools/bin/sqlcmd", "-S", "12CWIN2016REP01SQLEXPRESS", "-U", "oralogin", .. 02:54:10.264688 write(2, "Sqlcmd: Error: Microsoft ODBC Dr"..., 517Sqlcmd: Error: Microsoft ODBC Driver 13 for SQL Server : Login timeout expired. .. # Hier fällt auf das der \ im -S Parameter verschwunden ist! # Könnte das der Fehler sein??? Lösung : Fehler mit der -S Option, wahrscheinlich stört hier der \, oh was für ein ... : Test nur mit dem Servernamen: [root@racdb01 ~]# /opt/mssql-tools/bin/sqlcmd -S 12CWIN2016REP01 -U sa -P ora123Login 1> use oraTST 2> go Changed database context to 'ORATST'. 1> select * from dual; 2> go FROM_X -------------------------------------------------- X (1 rows affected) 1> SELECT NAME FROM sys.sysdatabases; 2> go 1> exit Damit können wir nun über die Linux Maschine auf den MS SQL Server zugreifen, damit ist die halbe Aufgabe gelößt. ---- ==== Datenbank DNS in der ODBC ini hinterlegen ==== vi /etc/odbc.ini [MSSQL01_ODBC_DSN] Driver = ODBC Driver 13 for SQL Server Server = 12CWIN2016REP01 Database = oratst Description = MS SQL Server 01 TST Trace = No Username und Password muss nicht hinterlegt werden, das wird später beim DB Link hinterlegt. Testen: isql -v MSSQL01_ODBC_DSN [IM002][unixODBC][Driver Manager]Data source name not found, and no default driver specified [ISQL]ERROR: Could not SQLConnect # hmmm strace isql -v MSSQL01_ODBC_DSN close(3) = 0 open("/etc/odbcinst.ini", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=521, ...}) = unmap(0x7fd5f91e4000, 4096) = 0 open("/etc/odbc.ini", O_RDONLY) = 3 close(3) = 0 open("/etc/odbc.ini", O_RDONLY) = 3 # Als nochmals die etc/odbc.ini überprüfen, darauf achten das die Treiber Schreibweise genau dem Wert in der /etc/odbcinst.ini entspricht! #Korregieren und erneut testen isql -v MSSQL01_ODBC_DSN [28000][unixODBC][Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Login failed for user ''. [ISQL]ERROR: Could not SQLConnect # Mit Angabe des Users geht es isql -v MSSQL01_ODBC_DSN sa ora123Login +---------------------------------------+ | Connected! | | | | sql-statement | | help [tablename] | | quit | | | +---------------------------------------+ SQL> OK!, in den nächsten Schritten sehen wir dann ob wir mit dem User/Password ein Problem bekommen. ---- ---- ===== Oracle Gateway einrichten ===== Nach dem der ODBC Treiber auf dem System ist und wir uns an der Ziel Datenbank anmelden können, können wir nun den Oracle Part einrichten. Problem: Wir sind ja hier mit einem Oracle Cluster unterwegs, im Cluster laufen die Listener unter dem Scope des Grid User! Der Gateway wird über das Oracle Home der Datenbank (und den User der DB) gestartet! Der Listener aber über das Cluster Home und dessen Eigentümer! Das Scan Listener Konzept nicht unterstützt, diese Gateway Prozesse können ja auch nur lokal von der Datenbank angesprochen werden, das bedeutet der Gatway wird über den localen Listener konfiguriert. Dazu wird dieser auf einen freien Port, wie 2011, betrieben um die anderen Listener nicht zu stören. Ablauf: * Den Gateway Initialization Parameter File einrichten * Oracle Net für das Gateway konfigurieren * Die Datenbank für für den Gateway Access konfigurieren * Den Database Link anlegen * Encrypt Gateway Initialization Parameter Values siehe auch https://docs.oracle.com/database/121/OTGIS/configodbc.htm#OTGIS110 ===Gateway Initialization Parameter File einrichten=== Für das Gateway wird eine Art Instance vom Listener gestartet, der Name muss pro ODBC Verbindung eindeutig sein. Die Beispiel Datei liegt unter dem Oracle Home der Datenbank Installation und muss dort bearbeitet werden ( $ORACLE_HOME/hs/admin , Template Name initdg4odbc.ora ). In unseren Fall wählen wir : MSSQL01 für die ersten MSSQL DB => Name der Datei initMSSQL01.ora Für die Konfiguration brauchen wir die Library hinter dem MS ODBC Treiber, daher analysieren wir was hier installiert wurde: rpm -ql msodbcsql ... /opt/microsoft/msodbcsql/lib64/libmsodbcsql-13.1.so.9.2 ... Wir benötigen diese Information "/opt/microsoft/msodbcsql/lib64/libmsodbcsql-13.1.so.9.2" Datei initMSSQL01.ora bearbeiten (user oracle bzw. DB Eigentümer!): cd $ORACLE_HOME/hs/admin cp initdg4odbc.ora initMSSQL01.ora vi initMSSQL01.ora # # HS init parameters # HS_FDS_CONNECT_INFO = MSSQL01_ODBC_DSN HS_FDS_SHAREABLE_NAME = /opt/microsoft/msodbcsql/lib64/libmsodbcsql-13.1.so.9.2 # SQL Server NLS HS_NLS_NCHAR=UCS2 # Oracle NLS settings HS_LANGUAGE=AMERICAN_AMERICA.AL32UTF8 # # ODBC specific environment variables # set ODBCINI=/etc/odbc.ini ===Oracle Net für das Gateway konfigurieren=== Das Gateway liegt ja in Home der DBInstallation , daher in der Listener Konfiguration das Oracle Home von der DB verwenden! Listener.ora anpassen als user "grid": # User grid! su - grid cd $TNS_ADMIN pwd /opt/12.1.0.2/grid/network/admin vi listener.ora # Zusätzlich Eintrag (ADDRESS = (PROTOCOL = TCP)(port = 2011)) # diesen Port gewählt damit dieser Locale Listener nicht mit den vom Cluster verwalteten Listener ins gehege kommt! LISTENER = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = IPC)(KEY = LISTENER)) (ADDRESS = (PROTOCOL = TCP)(port = 2011)) ) ) # Gateway in die SID List aufgenommen SID_LIST_LISTENER = (SID_LIST = (SID_DESC= (SID_NAME=MSSQL01) (ORACLE_HOME=/opt/oracle/product/12.1.0.2/dbhome_1) (PROGRAM=dg4odbc) (ENVS=LD_LIBRARY_PATH = /opt/microsoft/msodbcsql/lib64/:/opt/oracle/product/12.1.0.2/dbhome_1/lib) ) ) #Listner neu starten lsnrctl stop LISTENER lsnrctl start LISTENER ... Services Summary... Service "MSSQL01" has 1 instance(s). Instance "MSSQL01", status UNKNOWN, has 1 handler(s) for this service... ... === Die Datenbank für für den Gateway Access konfigurieren === ==Tnsnames.ora im Cluster UND in der DB anpassen== # als user grid cd $TNS_ADMIN vi tnsnames.ora MSSQL01= (DESCRIPTION= (ADDRESS=(PROTOCOL=TCP)(HOST=racdb01)(PORT=2011)) (CONNECT_DATA= (SID=MSSQL01)) (HS=OK) ) # als user oracle cd $TNS_ADMIN vi tnsnames.ora MSSQL01= (DESCRIPTION= (ADDRESS=(PROTOCOL=TCP)(HOST=racdb01)(PORT=2011)) (CONNECT_DATA= (SID=MSSQL01)) (HS=OK) ) ==DB Link in der DB anlegen== CREATE DATABASE LINK MSSQL01 CONNECT TO "sa" IDENTIFIED BY "ora123Login" using 'MSSQL01'; Nun kann der DB Link getest werden mit: -- meine Testtabelle abfragen select * from dual@MSSQL01; -- wenn genug rechte auch testen mit um alle DB's anzuzeigen select * from sys.sysdatabases@INTERFACESQL; SELECT * FROM sys.tables@INTERFACESQL; Falls das zu Beginn nicht funktioniert, siehe den folgenden Abschnitt. ---- ==== Cluster Verhalten testen ==== === Zweiten Knoten auch konfigurieren === Auch auf dem zweiten Knoten die ODBC Treiber mit yum wie oben beschrieben installieren. Als root die odbc.ini kopieren [root@racdb01 etc]# scp odbc.ini racdb02:/etc/odbc.ini Nun die Einträge vom Knoten 1 in der Listener.ora auf den Knoten 2 übernehmen und dort ebenfalls den Listener neu starten. Nicht kopieren! Listner Konfiguration: # als user grid ssh racdb02 cd $TNS_ADMIN [grid@racdb02:admin ]$ pwd /opt/12.1.0.2/grid/network/admin vi listener.ora LISTENER = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = IPC)(KEY = LISTENER)) (ADDRESS = (PROTOCOL = TCP)(port = 2011)) ) ) SID_LIST_LISTENER= (SID_LIST = (SID_DESC= (SID_NAME=MSSQL01) (ORACLE_HOME=/opt/oracle/product/12.1.0.2/dbhome_1) (PROGRAM=dg4odbc) (ENVS=LD_LIBRARY_PATH = /opt/microsoft/msodbcsql/lib64/:/opt/oracle/product/12.1.0.2/dbhome_1/lib) ) ) Gateway Konfiguration kopieren # als user oracle cd /opt/oracle/product/12.1.0.2/dbhome_1/hs/admin scp initMSSQL01.ora racdb02:/opt/oracle/product/12.1.0.2/dbhome_1/hs/admin/initMSSQL01.ora tnsnames.ora eintrag auf zweiten Knoten anlegen, je nach Umgbung darauf achten das hier der richtige Port verwendet wird, hier in diesem Beispiel läuft der Listener auf 2011! cd $TNS_ADMIN vi tnsnames MSSQL01= (DESCRIPTION= (ADDRESS=(PROTOCOL=TCP)(HOST=racdb02)(PORT=2011)) (CONNECT_DATA= (SID=MSSQL01)) (HS=OK) ) === Kleiner Last Test mit SQL*Plus sessions von jeder DB === Testcode 1: declare v_result varchar2(200); begin for i in 1 .. 300 loop SELECT FROM_X into v_result FROM dual@MSSQL01; end loop; end; / Nun auf jeden Knoten SQL*Plus starten und gleichzeitig testen ob Fehler auftauchen. Dazu den Test als Script ablegen, in meine Fall auf dem ACFS, das können bei mir beide DB Knoten auslesen: vi /opt/oracle/diag_acfs/runTest.sql declare v_result varchar2(200); begin for i in 1 .. 300 loop SELECT FROM_X into v_result FROM dual@MSSQL01; dbms_output.put_line('-- Info :: get Result :: ' || v_result); UPDATE dual@MSSQL01 set FROM_X ='Y'; end loop; end; / exit Das ganze nun ein paar mal auf jeden Knoten parallel starten um zu sehen was passiert for i in `seq 1 50`; do echo start sqlplus $i sqlplus / as sysdba @/opt/oracle/diag_acfs/runTest.sql & done ps uafx | grep sqlplus | wc -l # Auswerten: tail -f /tmp/sqlplus_error.log # nach Fehlern suchen grep ORA /tmp/sqlplus_error.log Keine Auffälligkeiten im Clusterbetrieb zu sehen, auf beiden Seiten gleichzeitig 50 Connections auf die MSSQL gestartet die selectieren und Updaten. ---- ==== Test und Debug bei Fehlern ===== == Trace aktivieren == ON OFF DEBUG Trace wird eigentlich über "HS_FDS_TRACE_LEVEL=Debug" eingeschaltet, mal sehen was wir nun unter $ORACLE_HOME/hs/log/odbc_agt_pid.trc finden, leider erstmal nix... == Listener Log auswerten== Listener Log auswerten ob überhaupt eine Anfrage angekommen ist: lsnrctl status LISTENER .. Listener Log File /opt/oracle/diag/tnslsnr/racdb01/listener/alert/log.xml ... tail -f /opt/oracle/diag/tnslsnr/racdb01/listener/alert/log.xml # erneut testen und sehen ob was ankommt: 27-FEB-2018 05:55:11 * (CONNECT_DATA=(SID=MSSQL01)(CID=(PROGRAM=)(HOST=racdb01.pipperr.local)(USER=oracle))) * (ADDRESS=(PROTOCOL=tcp)(HOST=10.10.10.190)(PORT=29645)) * establish * MSSQL01 * 0 OK, Listener wird angesprochen ===Fehler - Unable to retrieve text of NETWORK/NCR message 65535=== Problem: SYS@GPIDB1-racdb01>select * from dual@MSSQL01; select * from dual@MSSQL01 * ERROR at line 1: ORA-28545: error diagnosed by Net8 when connecting to an agent Unable to retrieve text of NETWORK/NCR message 65535 ORA-02063: preceding 2 lines from MSSQL01 Die init Datei wurde nicht gefunden ! Muss im Oracle Home der DB liegen und auch init.ora heißen! Bei mir fälschlicherweise im Grid Home angelegt: # als User Oracle: cp /opt/12.1.0.2/grid/hs/admin/initMSSQL01.ora /opt/oracle/product/12.1.0.2/dbhome_1/hs/admin/initMSSQL01.ora ODER ! Hier wird die Installation auf einem Cluster mit Cluster Listenern beschrieben, in einer normalen Umgebung in der TNSNames.ora auf den richtigen Port (1521!) achten! ==Fehler - ORA-28541: Error in HS init file on line 20.=== SYS@GPIDB1-racdb01>select * from dual@MSSQL01; select * from dual@MSSQL01 * ERROR at line 1: ORA-28500: connection from ORACLE to a non-Oracle system returned this message: ORA-28541: Error in HS init file on line 20. ORA-02063: preceding 2 lines from MSSQL01 Datei $ORACLE_HOME/hs/admin/initMSSQL01.ora fixen, schaunen wir mal was an Line 20 steht, dort war noch ein Setting nicht auskommentiert! ==Fehler - ORA-28500: connection from ORACLE to a non-Oracle system returned this message oder ORA-02063: preceding line from MSSQL01== SYS@GPIDB1-racdb01>select * from dual@MSSQL01; select * from dual@MSSQL01 * ERROR at line 1: ORA-28500: connection from ORACLE to a non-Oracle system returned this message: [ Spracheinstellungen müssen nun auf den richtigen Wert gesetzt werden. Erster Test mit ein paar Defaults vi initMSSQL01.ora HS_NLS_NCHAR = AMERICAN_AMERICA.US7ASCII HS_LANGUAGE = AMERICAN_AMERICA.US7ASCII sqlplus / as sysdba SYS@GPIDB1-racdb01>select * from dual@MSSQL01; select * from dual@MSSQL01 * ERROR at line 1: ORA-28513: internal error in heterogeneous remote agent ORA-02063: preceding line from MSSQL01 So geht das nicht! Prüfen welchen Zeichensatz wir denn auf der MSSQL haben: /opt/mssql-tools/bin/sqlcmd -S 12CWIN2016REP01 -U sa -P ora123Login 1> use oraTST 2> go 1> SELECT databasepropertyex('oraTST', 'Collation') 2> go SQL_Latin1_General_CP1_CI_AS 1> SELECT COLLATIONPROPERTY('SQL_Latin1_General_CP1_CI_AS', 'CodePage'); 2> go 1252 das heißt: * latin1 makes the server treat strings using charset latin 1, basically ascii * CP1 stands for Code Page 1252 * CI case insensitive comparisons so 'ABC' would equal 'abc' * AS accent sensitive, so 'ü' does not equal 'u' => Das wäre unter Oracle wohl ein WE8MSWIN1252 , ABER! Allerdings muss der Parameter HS_LANGUAGE auf den Einstellung der DB gesetzt werden! sqlplus / as sysdba select PARAMETER , Value from nls_database_parameters where parameter in ('NLS_CHARACTERSET') order by 2 / NLS DB Character Set Setting ------------------------ ----------- NLS_CHARACTERSET AL32UTF8 vi initMSSQL01.ora # SQL Server NLS HS_NLS_NCHAR=UCS2 # Oracle NLS settings HS_LANGUAGE=AMERICAN_AMERICA.AL32UTF8 sqlplus / as sysdba SYS@GPIDB1-racdb01>select * from dual@MSSQL01; select * from dual@MSSQL01 * FROM_X ------------- X siehe auch: * ORA-28513 Connecting From Oracle To SQL*Server Using DG4ODBC (Doc ID 1928926.1) * NLS Guide for Generic Connectivity and Gateways (Doc ID 230239.1) === {01S00}[Microsoft][ODBC Driver 13 for SQL Server]Connecting to a mirrored SQL Server MultiSubnetFailover connection option is not supported. {IMH01} === SYS@GPIDB2-racdb02>SELECT * FROM dual@MSSQL01; SELECT * FROM dual@MSSQL01 * ERROR at line 1: ORA-28500: connection from ORACLE to a non-Oracle system returned this message: [Microsoft][ODBC Driver 13 for SQL Server]Invalid attribute value {HY024}[Microsoft][ODBC Driver 13 for SQL Server]Invalid connection string attribute {01S00}[Microsoft][ODBC Driver 13 for SQL Server]Connecting to a mirrored SQL Server instance using the MultiSubnetFailover connection option is not supported. {IMH01} ORA-02063: preceding 2 lines from MSSQL01 Lösung: odbc.ini auf zweiten Knoten nicht hinterlegt! ---- ---- ===== Anmerkungen zu PostgreSQL ODBC Connect unter Windows 64 ===== Aufgaben: Die PostgreSQL DB von https://netbox.readthedocs.io/en/latest/ in eine Oracle 12c R2 Apex Umgebung einbinden. Unter Windows kann das gleiche Konzept eingesetzt werden, es ist sogar etwas leichter, da hier die ODBC Funktionalität zum Betriebsystem gehört. Ablauf: * Download PostgreSQL ODBC Treiber von https://www.postgresql.org/ftp/odbc/versions/msi/ * Installation der PostgreSQL 64 Bit Treiber für die 12c R2 64 bit * * Falls der Install error code 2503 auftritt, darauf achten das der Install User auch ein vollständiger Admin ist, bzw. das MSI über eine DOS Box mit Admin Rechten starten! siehe auch https://www.urtech.ca/2016/02/solved-how-to-fix-error-2503-2502-on-windows-10-when-installing-software/ * Einrichten einer passenden SYSTEM DNS ( Database Name , Server, Port, User, Password ) * Konfiguation der System Dateien der Oracle DB wie oben unter Linux beschrieben * DB Link anlegen create database link dg4Netbox connect to "dbuser" identified by "dbuser_pwd" using 'dg4NetBoxTNS'; auf die " " achten!!! == Testen== Problem: ORA-28500: connection from ORACLE to a non-Oracle system returned this message: ERROR: relation "DCIM_SITE" does not exist Ursache: Tabellen Namen in PostgreSQL in **kleinbuchstaben**, Oracle sendet aber per default alles in **GROSSBUCHSTABEN** => Alles in "" einbauen! SQL> select * from dcim_site@dgNetbox ; select * from ds_site@PG_LINK * ERROR at line 1: ORA-28500: connection from ORACLE to a non-Oracle system returned this message: ERROR: relation "DCIM_SITE" does not exist; No query has been executed with that handle {42P01,NativeErr = 1} ORA-02063: preceding 3 lines from PG_LINK SQL> select * from "dcim_site"@dg4Netbox ; Site -------- ----------- ---------- ------ homesite Siehe auch => * https://dbaspot.wordpress.com/2013/05/29/how-to-access-postgresql-from-oracle-database/ * http://oracle-help.com/oracle-database/oracle-database-gateway-postgresql/ === Probleme ORA-28500 / ORA-060 mit Datentyp TEXT im Postgres === Bei einer Afragen auf eine Tabelle in der Postgres Datenbank mit Datentyp TEXT => ORA-28500 ODBC Postgres Treiber auf die 13.01 hochgerüstet => ORA-060 Problem: * Datentyp TEXT im Postgres wird in Oracle als LONG behandelt. * Es geht nur eine Long Spalte pro Tabelle. Lösung: * View in Postgres auf die Tabelle anlegen und die TEXT Spalte konvertieren mit SPALTENNAME::varchar(4000) * Im ODBC die CheckBox "Text as LongVarChar" entfernen ---- ---- =====Quellen ===== ODBC Treiber für Linux: * https://www.easysoft.com/products/data_access/odbc_oracle_driver/index.html * https://docs.microsoft.com/de-de/sql/connect/odbc/linux-mac/system-requirements * https://docs.microsoft.com/de-de/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server#microsoft-odbc-driver-131-for-sql-server Oracle: * Database Gateway Installation and Configuration Guide 12c => https://docs.oracle.com/database/121/OTGIS/newoverview.htm#OTGIS100 * Einschränkungen https://docs.oracle.com/cd/E11882_01/gateways.112/e12069/ch3.htm#GMSWN200 * „DBMS_HS_PASSTHROUGH“ zu umgehen => https://docs.oracle.com/cd/E18283_01/appdev.112/e16760/d_hspass.htm Web: * https://www.easysoft.com/applications/oracle/database-gateway-dg4odbc.html * https://github.com/mkleehammer/pyodbc/wiki/Connecting-to-SQL-Server-from-RHEL-or-Centos Web MSSQL * https://stackoverflow.com/questions/7321159/determining-the-character-set-of-a-table-database