Migrazione degli utenti Oracle a Cloud SQL per MySQL: query, stored procedure, funzioni e trigger

Questo documento fa parte di una serie che fornisce informazioni e indicazioni chiave relative alla pianificazione ed esecuzione delle migrazioni dei database Oracle® 11g/12c a Cloud SQL per MySQL versione 5.7, istanze di seconda generazione. La serie include le seguenti parti:

Query

Oracle e Cloud SQL per MySQL supportano lo standard ANSI SQL. È in genere è semplice eseguire la migrazione delle istruzioni SQL usando solo la sintassi di base (ad esempio, non specificare alcuna funzione scalare o qualsiasi altra funzione funzionalità estesa). La sezione seguente illustra gli elementi comuni delle query di Oracle e i relativi equivalenti di Cloud SQL per MySQL.

Sintassi di base di SELECT e FROM

Nome della funzionalità o nome sintassi Oracle Panoramica o implementazione di Oracle Supporto MySQL Soluzione MySQL corrispondente o alternativa
Sintassi di base di SQL per il recupero dei dati
SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
SELECT per la stampa di output
SELECT 1 FROM DUAL
SELECT 1
OR
SELECT 1 FROM DUAL
Alias di colonna
SELECT COL1 AS C1
SELECT COL1 AS C1
OR
SELECT COL1 C1
Nome tabella
distingue maiuscole e minuscole
Nessuna distinzione tra maiuscole e minuscole
(ad esempio, il nome della tabella può essere orders e/o ORDERS).
No Sensibile alle maiuscole in base al nome della tabella definito (ad esempio, il nome della tabella può essere solo orders o ORDERS).

Per maggiori dettagli, puoi consultare Sintassi SELECT.

  • Visualizzazioni in linea
    • Le visualizzazioni in linea (note anche come tabelle derivate) sono SELECT disponibili nella clausola FROM e utilizzate come sottoquery.
    • Le visualizzazioni in linea possono contribuire a semplificare le query complesse rimuovendo i calcoli composti o eliminando le operazioni di join, nonché comprimendo più query distinte in un'unica query semplificata.
    • Nota sulla conversione: le viste in linea di Oracle non richiedono l'utilizzo di alias, mentre MySQL richiede alias specifici per ogni vista in linea.

La tabella seguente presenta un esempio di conversione da Oracle a MySQL come visualizzazione in linea.

Oracle 11g/12c
SQL> SELECT FIRST_NAME,
            DEPARTMENT_ID,
            SALARY,
            DATE_COL
     FROM EMPLOYEES,
          (SELECT SYSDATE AS DATE_COL FROM DUAL);

L'output è simile al seguente:
FIRST_NAME           DEPARTMENT_ID     SALARY DATE_COL
-------------------- ------------- ---------- ---------
Steven                          90      24000 30-JUL-19
Neena                           90      17000 30-JUL-19
Lex                             90      17000 30-JUL-19
Cloud SQL per MySQL 5.7
Senza alias per la visualizzazione in linea:
mysql> SELECT FIRST_NAME,
              DEPARTMENT_ID,
              SALARY,
              DATE_COL
       FROM EMPLOYEES, (SELECT SYSDATE() AS DATE_COL FROM DUAL);

ERROR 1248 (42000): Every derived table must have its own alias

Aggiunta di un alias alla visualizzazione in linea:
mysql> SELECT FIRST_NAME,
              DEPARTMENT_ID,
              SALARY,
              DATE_COL
       FROM EMPLOYEES, (SELECT SYSDATE() AS DATE_COL FROM DUAL) AS A1;

L'output è simile al seguente:
+-------------+---------------+----------+---------------------+
| FIRST_NAME  | DEPARTMENT_ID | SALARY   | DATE_COL            |
+-------------+---------------+----------+---------------------+
| Steven      |            90 | 23996.00 | 2019-07-30 09:28:00 |
| Neena       |            90 | 22627.00 | 2019-07-30 09:28:00 |
| Lex         |            90 | 22627.00 | 2019-07-30 09:28:00 |

Istruzioni JOIN

Le istruzioni JOIN di Oracle sono supportate dalle istruzioni MySQL JOIN , tranne per la clausola FULL JOIN. Inoltre, MySQL JOIN supportano l'utilizzo di una sintassi alternativa, come la clausola USING, il WHERE anziché ON e utilizzare SUBQUERY nella clausola JOIN l'Informativa.

La seguente tabella mostra un esempio di conversione JOIN.

Tipo di JOIN Oracle Supportato da MySQL Sintassi JOIN MySQL
INNER JOIN
SELECT E.FIRST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
CROSS JOIN
SELECT E.FIRST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E CROSS JOIN DEPARTMENTS D
FULL JOIN
No Per una soluzione alternativa, valuta la possibilità di utilizzare UNION con LEFT e RIGHT JOIN.
LEFT JOIN
[ OUTER ]
SELECT E.FIRST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E LEFT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
RIGHT JOIN
[ OUTER ]
SELECT E.FIRST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E RIGHT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
SUBQUERY
SELECT E.FIRST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E JOIN (SELECT * FROM DEPARTMENTS)D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;

UNION, UNION ALL, INTERSETT e MENO

MySQL non supporta le funzioni INTERSECT e MINUS di Oracle, ad eccezione delle funzioni UNION e UNION ALL:

  • UNION: allega gli insiemi di risultati di due o più istruzioni SELECT ed eliminare i record duplicati.
  • UNION ALL: collega i set di risultati di due o più istruzioni SELECT senza eliminare i record duplicati.
  • INTERSECT: restituisce l'intersezione di due o più istruzioni SELECT solo se esiste un record in entrambi i set di dati.
  • MINUS: confronta due o più istruzioni SELECT, restituendo solo le righe distinte della prima query che non vengono restituite dalle altre istruzioni.

Note sulle conversioni

Per la conversione dalle funzioni Oracle INTERSECT e MINUS a MySQL, utilizza Istruzioni JOIN e IN e EXISTS come soluzione alternativa.

Esempi

Funzione Oracle Implementazione di Oracle Supporto MySQL Soluzione MySQL corrispondente o alternativa
UNION
SELECT COL1 FROM TBL1
UNION
SELECT COL1 FROM TBL2
SELECT COL1 FROM TBL1
UNION
SELECT COL1 FROM TBL2
UNION ALL
SELECT COL1 FROM TBL1
UNION ALL
SELECT COL1 FROM TBL2
SELECT COL1 FROM TBL1
UNION ALL
SELECT COL1 FROM TBL2
INTERSECT
SELECT COL1 FROM TBL1
INTERSECT
SELECT COL1 FROM TBL2
No
SELECT COL1 FROM TBL1
WHERE COL1 IN
(SELECT COL1 FROM TBL2)
MINUS
SELECT COL1 FROM TBL1
MINUS
SELECT COL1 FROM TBL2
No
SELECT A.COL1
FROM TBL1 A LEFT JOIN TBL2 B
ON USING(COL1)
WHERE B.COL1 IS NULL

Funzioni scalari (riga singola) e di gruppo

MySQL offre un ampio elenco di scalari (riga singola) e aggregazione funzioni. Alcune funzioni MySQL sono simili alle controparti Oracle (per nome e funzionalità o con un nome diverso ma con elementi simili funzionalità). Sebbene le funzioni MySQL possano avere nomi identici Le controparti Oracle possono presentare funzionalità diverse.

Le tabelle seguenti descrivono i casi in cui Oracle e MySQL sono equivalenti per nome e funzionalità (specificato da "Sì") e in cui è consigliata una conversione (tutti i casi diversi da "Sì").

Funzioni di carattere
Funzione Oracle Specifica o implementazione della funzione Oracle Equivalente MySQL Funzione corrispondente MySQL Specifica o implementazione della funzione MySQL
CONCAT(str1,str2)
Restituisce str1 concatenato con str2:
CONCAT('A', 1) = A1
CONCAT
Equivalente a Oracle:
CONCAT('A', 1) = A1
LOWER/UPPER
Restituisce il carattere con tutte le lettere in minuscolo o in maiuscolo:
LOWER('SQL') = sql
LOWER/UPPER
Equivalente a Oracle:
LOWER('SQL') = sql
LPAD/RPAD(expr1,n,expr2)
Restituisce expr1, con spazi iniziali o finali per una lunghezza di n caratteri con la sequenza di caratteri in expr2:
LPAD('A',3,'*') = **A
LPAD/RPAD
Equivalente a Oracle:
LPAD('A',3,'*') = **A
SUBSTR(char,p,n)
Restituisce una parte di char, che inizia dalla posizione p, lunghezza sottostringa di n caratteri:
SUBSTR('MySQL', 3, 3)
= SQL
SUBSTR(char,p,n)
Equivalente a Oracle:
SUBSTR('MySQL', 3, 3)
= SQL
INSTR(index,str)
Restituisce la posizione (indice) della stringa str:
INSTR('MySQL', 'y')
= 2
INSTR
Equivalente a Oracle:
INSTR('MySQL', 'y')
= 2
REPLACE(char,str1,str2)
Restituisce un carattere quando ogni occorrenza di una stringa di ricerca viene sostituita con una stringa sostitutiva:
REPLACE('ORADB', 'ORA', 'MySQL')

= MySQLDB
REPLACE(char,str1,str2)
Equivalente a Oracle:
REPLACE('ORADB', 'ORA', 'MySQL')

= MySQLDB
TRIM(str)
Taglia i caratteri iniziali o finali (o entrambi) di una stringa:
TRIM(both '-' FROM '-MySQL-')
= MySQL

TRIM(' MySQL ') = MySQL
TRIM(str)
Equivalente a Oracle:
TRIM(both '-' FROM '-MySQL-')
= MySQL

TRIM(' MySQL ') = MySQL
LTRIM/RTRIM(str)
Rimuove dall'estremità sinistra o destra della stringa tutti i caratteri che compaiono nella ricerca:
LTRIM('   MySQL', ' ')
= MySQL
Parzialmente
LTRIM/RTRIM(str)
Funzione Oracle R/LTRIM tranne la sostituzione del parametro (spazio vuoto o stringa). MySQL R/LTRIM elimina solo gli spazi bianchi, accettando solo la stringa di input:
LTRIM('   MySQL')
= MySQL
ASCII(char)
Restituisce la rappresentazione decimale nel set di caratteri del database della primo carattere di char:
ASCII('A') = 65
ASCII(char)
Equivalente a Oracle:
ASCII('A') = 65
CHR(char)
Restituisce il valore del codice ASCII, che è un valore numerico compreso tra 0 e 225, in un carattere:
CHR(65) = A
Parzialmente con nome funzione diverso
CHAR(char)
MySQL utilizza la funzione CHAR per la stessa funzionalità, pertanto devi modificare il nome di una funzione:
CHAR(65) = A
LENGTH(str)
Restituisce la lunghezza di una determinata stringa:

LENGTH ('MySQL') = 5
LENGTH(str)
Equivalente a Oracle:
LENGTH('MySQL') = 5
REGEXP_REPLACE(str1,expr,str2)
Cerca un pattern di espressioni regolari in una stringa:
REGEXP_REPLACE('John', '[hn].', '1') = Jo1
No N/D Supportata solo da MySQL versione 8. Come soluzione alternativa utilizza il Funzione REPLACE, se possibile, o convertila nell'applicazione livello
REGEXP_SUBSTR(str,expr)
Estende la funzionalità della funzione SUBSTR cercando un stringa per un pattern di espressioni regolari:
REGEXP_SUBSTR('https://console.cloud.google.com/sql/instances','https://([[:alnum:]]+\.?){3,4}/?')
= https://console.cloud.google.com/
No N/D Supportato solo dalla versione 8 di MySQL. Come soluzione alternativa, se possibile, utilizza la funzione SUBSTR o converti la funzionalità nel livello di applicazione.
REGEXP_COUNT(str,expr)
Restituisce il numero di volte in cui un pattern compare in una stringa di origine. No N/D Per una soluzione alternativa, converti la funzionalità nel livello di applicazione.
REGEXP_INSTR(index,expr)
Cerca una posizione della stringa (indice) per un pattern di espressioni regolari. No N/D Supportata solo da MySQL versione 8.
REVERSE(str)
Restituisce una stringa invertita
REVERSE('MySQL')
= LQSyM
REVERSE
Equivalente a Oracle:
REVERSE('MySQL')
= LQSyM
Funzioni numeriche
Funzione Oracle Specifica o implementazione della funzione Oracle Equivalente MySQL Funzione corrispondente MySQL Specifica o implementazione della funzione MySQL
ABS(n)
Valore assoluto di n:
ABS(-4.6) = 4.6
ABS
Equivalente a Oracle:
ABS(-4.6) = 4.6
CEIL(n)
Restituisce il numero intero più piccolo maggiore o uguale a n:
CEIL(21.4) = 22
CEIL
Equivalente a Oracle:
CEIL(21.4) = 22
FLOOR(n)
Restituisce il numero intero più grande uguale o minore di n:
FLOOR(-23.7) = -24
FLOOR
Equivalente a Oracle:
FLOOR(-23.7) = -24
MOD(m,n)
Restituisce il resto di m diviso per n:
MOD(10, 3) = 1
MOD(m,n)
Equivalente a Oracle:
MOD(10,3) = 1
ROUND(m,n)
Restituisce m arrotondato a n posizioni interi a destra di punto decimale:
ROUND(1.39,1) = 1.4
ROUND
Equivalente a Oracle:
ROUND(1.39,1) = 1.4
TRUNC(n1, n2)
Restituisce n1 troncato a n2 cifre decimali:
TRUNC(99.999) = 99
TRUNC(99.999,0) = 99
Parzialmente con nome funzione diverso
TRUNCATE(n1, n2)
La funzione MySQL TRUNCATE deve accettare un numero di input e un numero intero per specificare l'importo della precisione a destra del decimale punto:
TRUNCATE(99.999,0) = 99
Funzioni di data e ora
Funzione Oracle Specifica o implementazione della funzione Oracle Equivalente MySQL Funzione corrispondente MySQL Specifica o implementazione della funzione MySQL
SYSDATE
Restituisce la data e l'ora correnti impostate per il sistema operativo su cui risiede il server di database:
SELECT SYSDATE
FROM DUAL
= 31-JUL-2019
Parzialmente
SYSDATE()
MySQL SYSDATE() deve includere parentesi e restituisce un diverso da quello della funzione Oracle SYSDATE:
SELECT SYSDATE()
FROM DUAL;
= 2019-01-31 10:01:01.0

Tieni presente che la formattazione di data e ora può essere modificata a livello di sessione.
SYSTIMESTAMP
Restituisce la data di sistema, inclusi i secondi frazionari e il fuso orario:
SELECT SYSTIMESTAMP FROM DUAL
= 01-JAN-19 07.37.11.622187000 AM +00:00
Parzialmente con nome funzione diverso
CURRENT_TIMESTAMP
MySQL restituisce una formattazione di data e ora diversa da quella di Oracle. È necessaria una formattazione della data (o una funzione di data diversa) per corrispondere alla formattazione della data/dell'ora originale:
SELECT CURRENT_TIMESTAMP
FROM DUAL
= 2019-01-31 06:55:07
LOCAL_TIMESTAMP
Restituisce la data e l'ora correnti nel fuso orario della sessione in un valore del tipo di dati TIMESTAMP:
SELECT LOCAL_TIMESTAMP
FROM DUAL
= 01-JAN-19 10.01.10.123456 PM
Formato parzialmente diverso per data/ora.
LOCAL_TIMESTAMP
MySQL restituisce una formattazione della data/dell'ora diversa da quella di Oracle. È obbligatoria la formattazione della data/dell'ora (o una funzione data diversa) per far corrispondere la formattazione della data/dell'ora originale:
SELECT LOCAL_TIMESTAMP
FROM DUAL
= 2019-01-01 10:01:01.0
CURRENT_DATE
Restituisce la data corrente nel fuso orario della sessione:
SELECT CURRENT_DATE
FROM DUAL
= 31-JAN-19
Parzialmente con formattazione di data/ora diversa
CURRENT_DATE
MySQL restituisce una formattazione della data/dell'ora diversa da Oracle. È obbligatoria la formattazione della data/dell'ora (o una funzione data diversa) per far corrispondere la formattazione della data/dell'ora originale:
SELECT CURRENT_DATE
FROM DUAL
= 2019-01-31
CURRENT_TIMESTAMP
Restituisce la data e l'ora correnti nel fuso orario della sessione:
SELECT CURRENT_TIMESTAMP
FROM DUAL
= 31-JAN-19 06.54.35.543146 AM +00:00
Parzialmente con formattazione di data/ora diversa
CURRENT_TIMESTAMP
MySQL restituisce una formattazione della data/dell'ora diversa da quella di Oracle. Data/ora è necessaria la formattazione (o utilizzare una funzione di data diversa) affinché corrisponda la formattazione originale di data e ora:
SELECT CURRENT_TIMESTAMP
FROM DUAL
= 2019-01-31 06:55:07
ADD_MONTHS
Restituisce la data più i mesi interi:
ADD_MONTHS(SYSDATE, 1)
= 31-JAN-19
Parzialmente con nome funzione diverso
ADDDATE
Per ottenere la stessa funzionalità, MySQL utilizza ADDDATE funzione:
ADDDATE(SYSDATE(), 1)
= 2019-08-01 06:42:49.0

Per impostazione predefinita, MySQL restituisce date/ora e intervallo/formato diversi rispetto a Oracle. È richiesta la formattazione di data/ora (o una data diversa ) per corrispondere alla formattazione originale di data e ora.
EXTRACT(parte data) Restituisce il valore di un campo data/ora specificato da una data/ora o espressione di intervallo:
EXTRACT(YEAR FROM DATE '2019-01-31')
= 2019
EXTRACT (parte data) Equivalente a Oracle:
EXTRACT(YEAR FROM DATE '2019-01-31')
= 2019
LAST_DAY
Restituisce la data dell'ultimo giorno del mese:
LAST_DAY('01-JAN-2019')
= 31-JAN-19
Parzialmente con formattazione di data/ora diversa
LAST_DAY
MySQL restituisce una formattazione della data/dell'ora diversa da quella di Oracle. È obbligatoria la formattazione della data/dell'ora (o una funzione di data diversa) per far corrispondere la formattazione della data/dell'ora originale:
LAST_DAY('2019-01-01')
= 2019-01-31
MONTH_BETWEEN
Restituisce il numero di mesi compresi tra le date date1 e date2:
MONTHS_BETWEEN(
SYSDATE, SYSDATE-60)
= 1.96
Parzialmente con nome funzione diverso
PERIOD_DIFF(date1,date2)
La funzione PERIOD_DIFF di MySQL restituisce la differenza in mesi come numero intero tra due periodi (formattata come YYMM o YYYYMM):
PERIOD_DIFF(
'201903', '201901')
= 2

Per ottenere gli stessi valori della funzione MONTH_BETWEEN di Oracle, sarà necessaria una conversione più specifica
TO_CHAR (data/ora) Converte un tipo di dati data/ora o timestamp in un valore del tipo di dati VARCHAR2 nel formato specificato dal formato della data:
TO_CHAR(
SYSDATE,'DD-MM-YYYY HH24:MI:SS')
= 01-01-2019 10:01:01
Parzialmente con nome funzione diverso
DATE_FORMAT
La funzione MySQL DATE_FORMAT formatta una data come specificato da una definizione del formato data:
DATE_FORMAT(
SYSDATE(),'%d-%m-%Y %H:%i:%s')
= 01-01-2019 10:01:01
Funzioni di codifica e decodifica
Funzione Oracle Specifica o implementazione della funzione Oracle Equivalente MySQL Funzione corrispondente MySQL Specifica o implementazione della funzione MySQL
DECODE
Confronta l'espressione con ogni valore di ricerca una alla volta utilizzando la funzionalità di un'istruzione IF-THEN-ELSE No
CASE
Utilizza l'istruzione CASE di MySQL per ottenere funzionalità simili.
DUMP
Restituisce un valore VARCHAR2 contenente il codice del tipo di dati, length in byte e una rappresentazione interna per una determinata espressione. No N/D Non supportati.
ORA_HASH
Calcola un valore hash per una determinata espressione. No
MD5/SHA
Utilizza MySQL MD5 per il checksum a 128 bit o il SHA funzione per checksum a 160 bit per generare valori hash
Funzioni di conversione
Funzione Oracle Specifica o implementazione della funzione Oracle Equivalente MySQL Funzione corrispondente MySQL Specifica o implementazione della funzione MySQL
CAST
Converte un tipo di dati incorporato o un valore con tipo di raccolta in un altro tipo di dati incorporato o un valore con tipo di raccolta:
CAST('1' as int) + 1
= 2
Parzialmente
CAST
La funzione CAST di MySQL è simile alla funzionalità di Oracle, ma in alcuni casi deve essere modificata a seconda che sia richiesta una conversione esplicita o implicita:
CAST('1' AS SIGNED) + 1
= 2
CONVERT
Converte una stringa di caratteri da un set di caratteri a un altro:
CONVERT('Ä Ê Í Õ Ø A B C D E ', 'US7ASCII', 'WE8ISO8859P1')
= ?? ?? ?? A B C
Parzialmente
CONVERT
La funzione CONVERT di MySQL richiede alcuni aggiustamenti alla sintassi e ai parametri per restituire i risultati esatti come Oracle:
CONVERT('Ä Ê Í A B C ' USING utf8)
= Ä Ê Í A B C
TO_CHAR e
(stringa/numerica)
La funzione converte un numero o una data in una stringa:
TO_CHAR(22.73,'$99.9')
= $22.7
No
FORMAT
La funzione MySQL FORMAT esegue i formati "#,###.##" da un numero, arrotondandolo a un certo numero di cifre decimali e quindi restituisce il risultato come stringa, ha funzionalità diverse rispetto Oracle:
CONCAT('$',
FORMAT(22.73, 1))
= $22.7
TO_DATE
La funzione TO_DATE di Oracle converte una stringa in una data in base al formato data/ora specifico dell'origine:
TO_DATE(
'2019/01/01', 'yyyy-mm-dd')
= 01-JAN-2019
Parzialmente con nome della funzione e formattazione di data/ora diversi
STR_TO_DATE
La funzione MySQL STR_TO_DATE accetta una stringa e restituisce un data specificata dal formato data/ora:
STR_TO_DATE(
'2019/01/01', '%Y/%m/%d')
= 2019-01-01
TO_NUMBER
Converte l'espressione in un valore di un tipo di dati NUMBER:
TO_NUMBER('01234')
= 1234
No
CAST
In alternativa, utilizza la funzione CAST di MySQL per restituire lo stesso risultato di TO_NUMBER di Oracle:
CAST('01234' as SIGNED)
= 1234
Funzioni SELECT condizionali
Funzione Oracle Specifica o implementazione della funzione Oracle Equivalente MySQL Funzione corrispondente MySQL Specifica o implementazione della funzione MySQL
CASE
L'istruzione CASE sceglie tra una sequenza di condizioni e esegue un'istruzione corrispondente con la seguente sintassi:
CASE WHEN condition THEN result
[WHEN ...] [ELSE result]
END
CASE
Oltre alla funzione CASE, MySQL supporta anche utilizzo di IF/ELSE gestione condizionale all'interno dell'istruzione SELECT:
CASE WHEN condition THEN result
[WHEN ...] [ELSE result]
END
Funzioni null
Funzione Oracle Specifica o implementazione della funzione Oracle Equivalente MySQL Funzione corrispondente MySQL Specifica o implementazione della funzione MySQL
COALESCE
Restituisce la prima espressione non null nell'elenco di espressioni:
COALESCE(
null, '1', 'a')
= a
COALESCE
Equivalente a Oracle:
COALESCE(
null, '1', 'a')
= 1
NULLIF
Confronta expr1 ed expr2m. Se sono uguali, la funzione restituisce null. Se non sono uguali, la funzione restituisce expr1:
NULLIF('1', '2')
= a
NULLIF
Equivalente a Oracle:
NULLIF('1', '2')
= a
NVL
Sostituisci null (restituito come vuoto) con una stringa nei risultati di una query:
NVL(null, 'a')
= a
No
IFNULL
La funzione equivalente di MySQL è la funzione IFNULL , che sostituisce i valori null con una determinata stringa:
IFNULL(null, 'a')
= a
NVL2
Determina il valore restituito da una query in base al fatto che un'espressione
specificata sia null o non null.
No
CASE
L'istruzione CASE
sceglie da una sequenza di condizioni ed esegue un'istruzione corrispondente:
CASE WHEN condition THEN result
[WHEN ...] [ELSE result]
END
Funzioni di ambiente e identificatori
Funzione Oracle Specifica o implementazione della funzione Oracle Equivalente MySQL Funzione corrispondente MySQL Specifica o implementazione della funzione MySQL
SYS_GUID
Genera e restituisce un identificatore univoco globale (valore RAW) costituito da 16 byte:
SELECT SYS_GUID()
FROM DUAL
= 8EFA4A31468B4C6DE05011AC0200009E
No REPLACE e UUID Come soluzione alternativa, utilizza le funzioni REPLACE e UUID di MySQL per simulare la funzione SYS_GUID di Oracle:
REPLACE(
UUID(), '-', '')
UID
Restituisce un numero intero che identifica in modo univoco l'utente della sessione (l'utente
che ha eseguito l'accesso):
SELECT UID FROM DUAL
= 43
No N/D N/D
USER
Restituisce il nome del nome utente della sessione corrente:
SELECT USER FROM DUAL
= UserName
Parzialmente
USER + INSTR + SUBSTR
La funzione MySQL USER restituisce il nome utente insieme al server di connessione (root@IP). Per recuperare solo il nome utente, utilizza funzioni di supporto aggiuntive:
SELECT
SUBSTR(USER(), 1, INSTR(USER(), '@') -1) FROM DUAL
= root
USERENV
Restituisce informazioni sulla sessione utente corrente con la configurazione del parametro corrente:
SELECT USERENV('LANGUAGE')
FROM DUAL
= ENGLISH_AMERICA.AL32UTF8
No
SHOW SESSION
VARIABLES
Utilizza l'istruzione MySQL SHOW SESSION
VARIABLES per visualizzare le impostazioni per la sessione corrente:
SHOW SESSION VARIABLES LIKE '%collation%';
= utf8_general_ci
ROWID
Il server Oracle assegna a ogni riga di ogni tabella un valore ROWID univoco per identificarla. ROWID è l'indirizzo della riga che contiene il numero dell'oggetto dati, i dati blocco della riga, la posizione della riga e il file di dati. No N/D Se possibile, prova a emulare la stessa funzionalità con altri database MySQL funzioni.
ROWNUM
Restituisce un numero che rappresenta l'ordine con cui una riga viene selezionata da Oracle da una tabella o tabelle unite. No N/D Se possibile, prova a emulare la stessa funzionalità con altre funzioni o variabili di sessione MySQL.
Funzioni di aggregazione (di gruppo)
Funzione Oracle Specifica della funzione Oracle o
implementazione
MySQL
equivalente
Funzione corrispondente di MySQL Specifica o implementazione della funzione MySQL
AVG
Restituisce il valore medio della colonna o dell'espressione.
AVG
Equivalente a Oracle
COUNT
Restituisce il numero di righe restituite da una query.
COUNT
Equivalente a Oracle
COUNT
(DISTINCT)
Restituisce il numero di valori univoci nella colonna o nell'espressione.
COUNT
(DISTINCT)
Equivalente a Oracle
MAX
Restituisce il valore massimo della colonna o dell'espressione.
MAX
Equivalente a Oracle
MIN
Restituisce il valore minimo della colonna o dell'espressione.
MIN
Equivalente a Oracle
SUM
Restituisce la somma del valore di una colonna o di un'espressione.
SUM
Equivalente a Oracle
LISTAGG
Visualizza i dati all'interno di ciascun gruppo in base a una singola riga specificata nella clausolaORDER BY concatenando i valori della colonna della misura:
SELECT LISTAGG(
DEPARTMENT_NAME, ', ')
WITHIN GROUP
(ORDER BY DEPARTMENT_NAME) DEPT
FROM DEPARTMENTS;

-- Single line results
= Accounting, Administration, Benefits, Construction
No
GROUP_CONCAT
Usa la funzione MySQL GROUP_CONCAT per restituire risultati simili a quelli di Oracle, aspettati differenze di sintassi in alcuni casi:
SELECT GROUP_CONCAT(
DEPARTMENT_NAME ORDER BY DEPARTMENT_NAME SEPARATOR ', ') DEPT
FROM DEPARTMENTS;

-- Single line results
= Accounting, Administration, Benefits, Construction
Oracle 12c Fetch
Funzione Oracle Specifica della funzione Oracle o
implementazione
MySQL
equivalente
Funzione corrispondente di MySQL Specifica o implementazione della funzione MySQL
FETCH
Recupera le righe di dati dal set di risultati di una query con più righe:
SELECT * FROM
EMPLOYEES
FETCH FIRST 10 ROWS ONLY;
No LIMIT Utilizza la clausola MySQL LIMIT per recuperare solo un insieme specifico di record:
SELECT * FROM
EMPLOYEES
LIMIT 10;

Filtri, operatori e sottoquery di base

Durante la conversione, i filtri di base, le funzioni degli operatori e le sottoquery sono relativamente semplici e richiedono uno sforzo minimo o nullo.

Note sulle conversioni

Esamina e gestisci i formati delle date perché i formati Oracle e MySQL restituiscono risultati predefiniti diversi:

  • Per impostazione predefinita, la funzione SYSDATE di Oracle restituisce 01-AUG-19.
  • Per impostazione predefinita, la funzione SYSDATE() di MySQL restituisce 2019-08-01 12:04:05.
  • I formati di data e ora possono essere impostati utilizzando le funzioni MySQL [DATE_FORMAT](https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-format) o [STR_TO_DATE](https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_str-to-date).
Funzione o sottoquery Oracle Equivalente MySQL Funzione o sottoquery corrispondente di MySQL Specifica o implementazione della funzione MySQL
EXISTS/NOT EXISTS
EXISTS/NOT EXISTS
SELECT * FROM DEPARTMENTS D
WHERE EXISTS (SELECT 1
              FROM EMPLOYEES E
              WHERE
              E.DEPARTMENT_ID =
              D.DEPARTMENT_ID);
IN/NOT IN
IN/NOT IN
SELECT * FROM DEPARTMENTS D
WHERE DEPARTMENT_ID IN
            (SELECT DEPARTMENT_ID
             FROM EMPLOYEES E);

-- OR
SELECT * FROM EMPLOYEES WHERE (EMPLOYEE_ID, DEPARTMENT_ID) IN((100, 90));
LIKE/NOT LIKE
LIKE/NOT LIKE
SELECT * FROM EMPLOYEES
WHERE FIRST_NAME LIKE '_e_n%';
BETWEEN/NOT BETWEEN
BETWEEN/NOT BETWEEN
SELECT * FROM EMPLOYEES
WHERE EXTRACT(YEAR FROM HIRE_DATE)
NOT BETWEEN 2001 and 2004;
AND/OR
AND/OR
SELECT * FROM EMPLOYEES
WHERE DEPARTMENT_ID IN(100, 101)
AND (SALARY >= 1000 OR HIRE_DATE <= '2006-02-05');
SubQuery
SubQuery
MySQL supporta le sottoquery a livello SELECT, per JOIN e per l'applicazione di filtri nel WHERE/AND clausole:
-- SELECT SubQuery
SELECT D.DEPARTMENT_NAME,
       (SELECT AVG(SALARY) AS AVG_SAL
        FROM EMPLOYEES E
        WHERE E.DEPARTMENT_ID =
              D.DEPARTMENT_ID) AVG_SAL
FROM DEPARTMENTS D;

-- JOIN SubQuery SELECT FIRST_NAME, LAST_NAME, SALARY FROM EMPLOYEES E JOIN (SELECT * FROM DEPARTMENTS WHERE LOCATION_ID = 2700) D ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
-- Filtering Subquery SELECT FIRST_NAME, LAST_NAME, SALARY FROM EMPLOYEES WHERE SALARY < (SELECT AVG(SALARY) FROM EMPLOYEES);
Operatori Operatori MySQL supporta tutti gli operatori di base:
> | >= | < | <= | = | <> | !=

Funzioni di analisi (o funzioni finestra e ranking)

Le funzioni di analisi Oracle estendono la funzionalità dell'analisi SQL standard offrendo funzionalità per calcolare valori aggregati in base a un gruppo di righe. Queste funzioni possono essere applicate a insiemi di risultati suddivisi in modo logico nel contesto di una singola espressione di query. Di solito vengono utilizzati in combinazione con report e analisi di business intelligence, con il potenziale di migliorare le prestazioni delle query come alternativa per ottenere lo stesso risultato utilizzando un codice SQL non analitico più complesso.

Note sulle conversioni

  • MySQL versione 5.7 non fornisce funzioni analitiche per supportare una una semplice conversione delle istruzioni SQL. Tuttavia, questa funzionalità è stata aggiunta parzialmente nella versione 8 di MySQL, rendendo la conversione delle funzioni analitiche un punto da considerare, probabilmente richiedono un intervento manuale nel processo di migrazione.
  • Una soluzione facoltativa è riscrivere il codice per rimuovere l'utilizzo di funzioni analitiche, ripristinare soluzioni di codice SQL più tradizionali o spostare questa logica in un livello di applicazione.

La tabella seguente elenca le funzioni analitiche comuni di Oracle.

Famiglia di funzioni Funzioni correlate Supportato da MySQL 5.7
Analisi e ranking
RANK
AVERAGE_RANK
DENSE_RANK
RANK ROW_NUMBER
PERCENT_RANK
CUME_DIST
NTILE
FIRST_VALUE
LAST_VALUE
OVER (PARTITION BY...)
No
Gerarchico
CONNECT BY
HIER_ANCESTOR
HIER_CHILD_COUNT
HIER_DEPTH
HIER_LEVEL
HIER_ORDER
HIER_PARENT
HIER_TOP
No
Ritardo
LAG
LAG_VARIANCE LAG_VARIANCE_PERCENT LEAD
LEAD_VARIANCE LEAD_VARIANCE_PERCENT
No

Espressione di tabella comune (CTE)

I CTE forniscono un modo per implementare la logica del codice sequenziale per riutilizzare il codice SQL troppo complessi o non efficienti per un uso multiplo. I CTE possono essere denominati e poi utilizzata più volte in parti diverse di un'istruzione SQL utilizzando WITH.

Note sulle conversioni

  • MySQL versione 5.7 non supporta le CTE, ma MySQL versione 8 encoder-decoder.
  • Per una soluzione alternativa, utilizza tabelle derivate o sottoquery o riscrivi l'istruzione SQL per eliminare la funzionalità CTE.

Esempi

Oracle
WITH DEPT_COUNT
(DEPARTMENT_ID, DEPT_COUNT) AS
(SELECT DEPARTMENT_ID,
        COUNT(*)
 FROM EMPLOYEES
 GROUP BY DEPARTMENT_ID)

SELECT E.FIRST_NAME ||' '|| E.LAST_NAME AS EMP_NAME, D.DEPT_COUNT AS EMP_DEPT_COUNT FROM EMPLOYEES E JOIN DEPT_COUNT D USING (DEPARTMENT_ID) ORDER BY 2 DESC;
MySQL
SELECT * FROM (
SELECT CONCAT(E.FIRST_NAME, ' ', E.LAST_NAME) AS EMP_NAME,
       (SELECT COUNT(*)
        FROM EMPLOYEES D
        WHERE E.DEPARTMENT_ID = D.DEPARTMENT_ID
        GROUP BY DEPARTMENT_ID) AS EMP_DEPT_COUNT
FROM EMPLOYEES E
ORDER BY 2 DESC) TBL
WHERE EMP_DEPT_COUNT IS NOT NULL;

Istruzione MERGE

L'istruzione MERGE (o UPSERT) fornisce un mezzo per specificare singole istruzioni SQL che eseguono condizionatamente operazioni DML in un'operazione MERGE, diversamente da una singola operazione DML, in esecuzione separatamente. Seleziona i record dalla tabella di origine e quindi, specificando una struttura logica, esegue più operazioni DML sulla tabella di destinazione. Questa funzionalità ti aiuta evitare di usare più inserimenti, aggiornamenti o eliminazioni. Tieni presente che MERGE è un l'istruzione deterministica, il che significa che una volta che una riga è stata elaborata MERGE, non è possibile elaborarla nuovamente utilizzando la stessa istruzione MERGE l'Informativa.

Note sulle conversioni

A differenza di Oracle, la versione 5.7 di MySQL non supporta la funzionalità MERGE. Per simulare parzialmente la funzionalità MERGE, MySQL fornisce le istruzioni REPLACE e INSERT… ON DUPLICATE KEY UPDATE:

  • REPLACE: funziona come un'istruzione INSERT, ad eccezione che se una vecchia riga nella tabella ha lo stesso valore di una nuova riga per un PRIMARY KEY o un indice UNIQUE, la vecchia riga viene eliminata prima della nuova è stata inserita.

  • INSERT… ON DUPLICATE KEY UPDATE: se una riga inserita causa un valore duplicato in un indice PRIMARY KEY o UNIQUE, viene eseguita un'operazione UPDATE della riga precedente per eliminare l'eccezione di chiave duplicata, ad esempio:

    INSERT INTO tbl (a,b,c) VALUES (1,2,3)
      ON DUPLICATE KEY UPDATE c=c+1;
    
    UPDATE tbl SET c=c+1 WHERE a=1;
    

Un'altra soluzione consiste nel convertire la funzionalità MERGE in un stored procedure per gestire le operazioni DML, utilizzando INSERT, UPDATE e Comandi DELETE con gestione di eccezioni e duplicati.

Suggerimenti per le istruzioni SQL

Oracle offre un'ampia raccolta di suggerimenti per le query SQL che consentono agli utenti di influenzare Il comportamento dell'ottimizzatore e il suo processo decisionale, allo scopo di produrre risultati piani di esecuzione delle query. Oracle supporta oltre 60 diversi hint di database. MySQL fornisce un insieme limitato di suggerimenti per le query.

In generale, MySQL versione 5.7 supporta due tipi di suggerimenti di query: OPTIMIZER HINTS e INDEX HINTS. Gli suggerimenti per l'ottimizzatore di MySQL offrono la possibilità di controllare il comportamento dell'ottimizzatore all'interno di singole istruzioni SQL, ad esempio:

SELECT /*+ NO_RANGE_OPTIMIZATION(tbl PRIMARY, col1_idx) */ col1 FROM tbl;

Suggerimenti per l'ottimizzatore disponibili per MySQL versione 5.7

Nome del suggerimento Panoramica dei suggerimenti Ambiti applicabili
BKA, NO_BKA
Interessa l'elaborazione del join di accesso alle chiavi in batch Blocco query, tabella
BNL, NO_BNL
Influisce sull'elaborazione del join con ciclo nidificato dei blocchi Blocco di query, tabella
MAX_EXECUTION_TIME
Limita il tempo di esecuzione dell'istruzione Globale
MRR, NO_MRR
Ha effetto sull'ottimizzazione della lettura multiintervallo Tabella, indice
NO_ICP
Ha effetto sull'ottimizzazione pushdown delle condizioni dell'indice Tabella, indice
NO_RANGE_OPTIMIZATION
Interessa l'ottimizzazione dell'intervallo Tabella, indice
QB_NAME
Assegna un nome al blocco di query Blocco di query
SEMIJOIN, NO_SEMIJOIN
Interessa le strategie di semi-join Blocco di query
SUBQUERY
Interessa la materializzazione, una query secondaria da IN a EXISTS strategie. Blocco di query

Suggerimenti per indice MySQL fornire all'ottimizzatore informazioni su come scegliere gli indici durante la query e l'elaborazione dei dati. Le parole chiave USE, FORCE o IGNORE vengono utilizzate per controllare la procedura di utilizzo dell'indice di Optimizer, ad esempio:

SELECT * FROM tbl USE INDEX (col1_index, col2_index);
-- OR
SELECT * FROM tbl IGNORE INDEX (col1_index, col2_index);

Note sulle conversioni

Poiché esistono differenze fondamentali tra l'ottimizzatore di Oracle e quello di MySQL e poiché le sovrapposizioni tra gli hint di query di Oracle e MySQL sono limitate, se presenti, ti consigliamo di convertire qualsiasi dichiarazione SQL di Oracle contenente hint di query non specificati nel database MySQL di destinazione.

L'ottimizzazione delle prestazioni di MySQL tramite gli strumenti MySQL (ad esempio MySQL) Workbench per dashboard sul rendimento in tempo reale) e funzionalità come l'esame delle query utilizzando piani di esecuzione e regolando i parametri di istanza o sessione in base al caso d'uso.

Piani di esecuzione

Lo scopo principale dei piani di esecuzione è fornire un'analisi approfondita delle scelte fatte dall'ottimizzatore delle query per accedere ai dati del database. Strumento di ottimizzazione delle query genera piani di esecuzione per SELECT, INSERT, UPDATE e DELETE istruzioni per gli utenti di database, permettendo inoltre agli amministratori su query e operazioni DML specifiche. Sono particolarmente utili quando devi ottimizzare le prestazioni delle query, ad esempio per determinare il rendimento degli indici o per stabilire se sono presenti indici mancanti che devono essere creati.

I piani di esecuzione possono essere influenzati da volumi di dati, statistiche dei dati e istanze (parametri globali o di sessione).

Considerazioni sulle conversioni

I piani di esecuzione non sono oggetti di database di cui è necessaria la migrazione, ma sono uno strumento per analizzare le differenze di prestazioni tra Oracle e MySQL che eseguono la stessa istruzione su set di dati identici.

MySQL non supporta la stessa sintassi, funzionalità o output del piano di esecuzione di Oracle.

Esempi

Piano di esecuzione Oracle
SQL> EXPLAIN PLAN FOR
     SELECT * FROM EMPLOYEES WHERE EMPLOYEE_ID = 105;

SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY (FORMAT=>'ALL +OUTLINE'));
Plan hash value: 1833546154 --------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 69 | 1 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| EMPLOYEES | 1 | 69 | 1 (0)| 00:00:01 | |* 2 | INDEX UNIQUE SCAN | EMP_EMP_ID_PK | 1 | | 0 (0)| 00:00:01 | ---------------------------------------------------------------------------------------------
Piano di esecuzione MySQL
mysql> EXPLAIN SELECT * FROM EMPLOYEES WHERE EMPLOYEE_ID = 105;

+----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+ | 1 | SIMPLE | EMPLOYEES | NULL | const | PRIMARY | PRIMARY | 3 | const | 1 | 100.00 | NULL | +----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+

Stored procedure, funzioni e trigger

PL/SQL è il linguaggio procedurale esteso di Oracle utilizzato per creare, archiviare e applicare soluzioni basate su codice all'interno del database. In generale, i database archiviati Le procedure e le funzioni sono elementi di codice costituiti da ANSI SQL e SQL un linguaggio procedurale esteso, ad esempio PL/SQL per Oracle, PL/pgSQL per Linguaggio procedurale PostgreSQL e MySQL per MySQL. MySQL utilizza lo stesso nome del database per il proprio linguaggio procedurale esteso.

Lo scopo di queste stored procedure e funzioni è fornire soluzioni per requisiti più adatti a essere eseguiti dall'interno del database e non dall'applicazione (ad esempio prestazioni, compatibilità e sicurezza). Sebbene sia le procedure memorizzate sia le funzioni utilizzino PL/SQL, le procedure memorizzate vengono principalmente utilizzate per eseguire operazioni DDL/DML e le funzioni vengono principalmente utilizzate per eseguire calcoli al fine di restituire risultati specifici.

Linguaggio procedurale PL/SQL a MySQL

Dal punto di vista della migrazione del codice Oracle PL/SQL a MySQL, l'implementazione procedurale di MySQL è diversa da quella di Oracle. Di conseguenza, la migrazione del codice è obbligatoria per convertire la funzionalità PL/SQL da Oracle a stored procedure MySQL funzioni. Inoltre, il pacchetto Oracle e il corpo del pacchetto non sono supportati a MySQL. Quando effettui una conversione del codice, converti questi elementi (o analizza ) in singole unità di codice MySQL. Tieni presente che le funzioni e le stored procedure di MySQL sono chiamate anche routine.

Proprietario dell'oggetto di codice

In Oracle, il proprietario di una procedura o funzione memorizzata è un utente specifico. In MySQL, il proprietario è uno schema specifico (creato in un database da un utente del database).

Privilegi e sicurezza degli oggetti di codice

In Oracle, per creare una stored procedure o una funzione, l'utente deve disporre del privilegio di sistema CREATE PROCEDURE (per creare procedure sotto altri utenti, gli utenti del database devono avere il privilegio CREATE ANY PROCEDURE). Per eseguire una stored procedure o una funzione, gli utenti del database devono disporre del privilegio EXECUTE.

In MySQL, per creare un elemento di codice, l'utente deve disporre del privilegio CREATE ROUTINE e del privilegio EXECUTE per l'esecuzione. La clausola DEFINER MySQL definisce l'utente che ha creato l'oggetto codice e l'utente deve disporre dei privilegi appropriati, ad esempio CREATE ROUTINE.

Sintassi delle funzioni e delle stored procedure MySQL

L'esempio seguente mostra la stored procedure e la funzione MySQL sintassi:

CREATE
    [DEFINER = user]
    PROCEDURE sp_name ([proc_parameter[,...]])
    [characteristic ...] routine_body

CREATE
    [DEFINER = user]
    FUNCTION sp_name ([func_parameter[,...]])
    RETURNS type
    [characteristic ...] routine_body

proc_parameter:
    [ IN | OUT | INOUT ] param_name type

func_parameter:
    param_name type

type:
    Any valid MySQL data type

characteristic:
    COMMENT 'string'
  | LANGUAGE SQL
  | [NOT] DETERMINISTIC
  | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
  | SQL SECURITY { DEFINER | INVOKER }

routine_body:
    Valid SQL routine statement