Memigrasikan pengguna Oracle ke Cloud SQL untuk MySQL: Kueri, prosedur tersimpan, fungsi, dan pemicu

Dokumen ini adalah bagian dari rangkaian yang menyajikan informasi dan panduan penting terkait perencanaan dan migrasi database Oracle® 11g/12c ke Cloud SQL untuk MySQL versi 5.7, instance generasi kedua. Seri ini mencakup bagian-bagian berikut:

Kueri

Oracle dan Cloud SQL untuk MySQL mendukung standar ANSI SQL. Secara umum sangat mudah memigrasikan pernyataan SQL hanya dengan menggunakan elemen sintaksis dasar (misalnya, tidak menentukan fungsi skalar atau fitur diperluas Oracle lainnya). Bagian berikut membahas elemen kueri Oracle umum beserta ekuivalen Cloud SQL for MySQL yang sesuai.

Sintaksis SELECT dan FROM dasar

Nama fitur atau nama sintaksis Oracle Ringkasan atau implementasi Oracle Dukungan MySQL Solusi alternatif atau yang sesuai MySQL
Sintaksis dasar SQL untuk pengambilan data
SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
Ya
SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
SELECT untuk cetak output
SELECT 1 FROM DUAL
Ya
SELECT 1
OR
SELECT 1 FROM DUAL
Alias kolom
SELECT COL1 AS C1
Ya
SELECT COL1 AS C1
OR
SELECT COL1 C1
Nama tabel
Kepekaan huruf besar/kecil
Tidak ada kepekaan huruf besar/kecil
(misalnya, nama tabel dapat berupa orders dan/atau ORDERS).
Tidak Peka huruf besar/kecil sesuai dengan nama tabel yang ditentukan (misalnya, nama tabel hanya boleh orders atau ORDERS).

Anda dapat membaca detail selengkapnya tentang sintaksis SELECT MySQL.

  • Tampilan inline
    • Tampilan inline (juga dikenal sebagai tabel turunan) adalah pernyataan SELECT, yang terletak di klausa FROM dan digunakan sebagai subkueri.
    • Tampilan inline dapat membantu menyederhanakan kueri yang kompleks dengan menghapus penghitungan gabungan atau menghilangkan operasi join, sekaligus meringkas beberapa kueri terpisah menjadi satu kueri yang disederhanakan.
    • Catatan konversi: Tampilan inline Oracle tidak memerlukan penggunaan alias, sedangkan MySQL memerlukan alias khusus untuk setiap tampilan inline.

Tabel berikut menampilkan contoh konversi dari Oracle ke MySQL, sebagai tampilan inline.

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

Outputnya mirip dengan berikut ini:
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 untuk MySQL 5.7
Tanpa alias untuk tampilan inline:
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

Menambahkan alias ke tampilan inline:
mysql> SELECT FIRST_NAME,
              DEPARTMENT_ID,
              SALARY,
              DATE_COL
       FROM EMPLOYEES, (SELECT SYSDATE() AS DATE_COL FROM DUAL) AS A1;

Outputnya mirip dengan berikut ini:
+-------------+---------------+----------+---------------------+
| 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 |

Pernyataan JOIN

Pernyataan JOIN Oracle didukung oleh pernyataan MySQL JOIN, kecuali untuk klausa FULL JOIN. Selain itu, pernyataan JOIN MySQL mendukung penggunaan sintaksis alternatif, seperti klausa USING, klausa WHERE sebagai ganti klausa ON, dan menggunakan SUBQUERY di pernyataan JOIN.

Tabel berikut menampilkan contoh konversi JOIN.

Jenis JOIN Oracle Didukung oleh MySQL Sintaksis JOIN MySQL
INNER JOIN
Ya
SELECT E.FIRST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
CROSS JOIN
Ya
SELECT E.FIRST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E CROSS JOIN DEPARTMENTS D
FULL JOIN
Tidak Sebagai solusi, pertimbangkan untuk menggunakan UNION dengan pernyataan LEFT dan RIGHT JOIN.
LEFT JOIN
[ OUTER ]
Ya
SELECT E.FIRST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E LEFT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
RIGHT JOIN
[ OUTER ]
Ya
SELECT E.FIRST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E RIGHT JOIN DEPARTMENTS D
ON E.DEPARTMENT_ID = D.DEPARTMENT_ID;
SUBQUERY
Ya
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, INTERSECT, dan MINUS

MySQL tidak mendukung fungsi INTERSECT dan MINUS Oracle kecuali untuk fungsi UNION dan UNION ALL:

  • UNION: Melampirkan kumpulan hasil yang berisi dua pernyataan SELECT atau lebih dan menghapus data duplikat.
  • UNION ALL: Melampirkan kumpulan hasil dari dua pernyataan SELECT atau lebih tanpa menghapus data duplikat.
  • INTERSECT: Menampilkan perpotongan dari dua pernyataan SELECT atau lebih hanya jika data ada di kedua set data.
  • MINUS: Membandingkan dua atau beberapa pernyataan SELECT, hanya menampilkan baris yang berbeda dari kueri pertama yang tidak ditampilkan oleh pernyataan lainnya.

Catatan konversi

Saat melakukan konversi dari fungsi INTERSECT dan MINUS Oracle ke MySQL, gunakan pernyataan JOIN serta IN dan EXISTS sebagai solusi alternatif.

Contoh

Fungsi Oracle Implementasi Oracle Dukungan MySQL Solusi alternatif atau yang sesuai MySQL
UNION
SELECT COL1 FROM TBL1
UNION
SELECT COL1 FROM TBL2
Ya
SELECT COL1 FROM TBL1
UNION
SELECT COL1 FROM TBL2
UNION ALL
SELECT COL1 FROM TBL1
UNION ALL
SELECT COL1 FROM TBL2
Ya
SELECT COL1 FROM TBL1
UNION ALL
SELECT COL1 FROM TBL2
INTERSECT
SELECT COL1 FROM TBL1
INTERSECT
SELECT COL1 FROM TBL2
Tidak
SELECT COL1 FROM TBL1
WHERE COL1 IN
(SELECT COL1 FROM TBL2)
MINUS
SELECT COL1 FROM TBL1
MINUS
SELECT COL1 FROM TBL2
Tidak
SELECT A.COL1
FROM TBL1 A LEFT JOIN TBL2 B
ON USING(COL1)
WHERE B.COL1 IS NULL

Fungsi skalar (baris tunggal) dan grup

MySQL menyediakan daftar lengkap fungsi skalar (baris tunggal) dan agregasi. Beberapa fungsi MySQL mirip dengan fungsi Oracle (berdasarkan nama dan fungsi, atau dengan nama yang berbeda tetapi dengan fungsi yang mirip). Meskipun fungsi MySQL dapat memiliki nama yang identik dengan fungsi Oracle, keduanya dapat menunjukkan fungsionalitas yang berbeda.

Tabel berikut menjelaskan di mana Oracle dan MySQL setara berdasarkan nama dan fungsionalitas (ditentukan oleh "Yes") dan tempat konversi direkomendasikan (semua kasus selain "Yes").

Fungsi karakter
Fungsi Oracle Spesifikasi atau implementasi fungsi Oracle Setara MySQL Fungsi yang sesuai MySQL Spesifikasi atau implementasi fungsi MySQL
CONCAT(str1,str2)
Menampilkan str1 yang disambungkan dengan str2:
CONCAT('A', 1) = A1
Ya
CONCAT
Setara dengan Oracle:
CONCAT('A', 1) = A1
LOWER/UPPER
Menampilkan karakter, dengan semua huruf kecil atau huruf besar:
LOWER('SQL') = sql
Ya
LOWER/UPPER
Setara dengan Oracle:
LOWER('SQL') = sql
LPAD/RPAD(expr1,n,expr2)
Menampilkan expr1, dengan padding kiri atau kanan hingga panjang karakter n dengan urutan karakter dalam expr2:
LPAD('A',3,'*') = **A
Ya
LPAD/RPAD
Setara dengan Oracle:
LPAD('A',3,'*') = **A
SUBSTR(char,p,n)
Menampilkan sebagian char, dimulai pada posisi karakter p, panjang substring n karakter:
SUBSTR('MySQL', 3, 3)
= SQL
Ya
SUBSTR(char,p,n)
Setara dengan Oracle:
SUBSTR('MySQL', 3, 3)
= SQL
INSTR(index,str)
Menampilkan posisi (indeks) string str:
INSTR('MySQL', 'y')
= 2
Ya
INSTR
Setara dengan Oracle:
INSTR('MySQL', 'y')
= 2
REPLACE(char,str1,str2)
Menampilkan karakter dengan setiap kemunculan string penelusuran yang diganti dengan string pengganti:
REPLACE('ORADB', 'ORA', 'MySQL')

= MySQLDB
Ya
REPLACE(char,str1,str2)
Setara dengan Oracle:
REPLACE('ORADB', 'ORA', 'MySQL')

= MySQLDB
TRIM(str)
Pangkas karakter di awal atau akhir (atau keduanya) dari string:
TRIM(both '-' FROM '-MySQL-')
= MySQL

TRIM(' MySQL ') = MySQL
Ya
TRIM(str)
Setara dengan Oracle:
TRIM(both '-' FROM '-MySQL-')
= MySQL

TRIM(' MySQL ') = MySQL
LTRIM/RTRIM(str)
Menghapus semua karakter yang muncul dalam penelusuran dari ujung kiri atau kanan string:
LTRIM('   MySQL', ' ')
= MySQL
Sebagian
LTRIM/RTRIM(str)
Fungsi R/LTRIM Oracle kecuali pengganti parameter (spasi kosong atau string). R/LTRIM MySQL hanya menghilangkan spasi kosong, sehingga hanya menerima string input:
LTRIM('   MySQL')
= MySQL
ASCII(char)
Menampilkan representasi desimal dalam himpunan karakter database dari karakter pertama char:
ASCII('A') = 65
Ya
ASCII(char)
Setara dengan Oracle:
ASCII('A') = 65
CHR(char)
Menampilkan nilai kode ASCII, yang merupakan nilai numerik antara 0 dan 225, ke karakter:
CHR(65) = A
Sebagian dengan nama fungsi yang berbeda
CHAR(char)
MySQL menggunakan fungsi CHAR untuk fungsi yang sama; oleh karena itu, Anda harus mengubah nama fungsi:
CHAR(65) = A
LENGTH(str)
Menampilkan panjang string tertentu:

LENGTH ('MySQL') = 5
Ya
LENGTH(str)
Setara dengan Oracle:
LENGTH('MySQL') = 5
REGEXP_REPLACE(str1,expr,str2)
Telusuri string untuk pola ekspresi reguler:
REGEXP_REPLACE('John', '[hn].', '1') = Jo1
Tidak T/A Hanya didukung dari MySQL versi 8. Sebagai solusinya, gunakan fungsi REPLACE jika memungkinkan atau konversikan ke lapisan aplikasi
REGEXP_SUBSTR(str,expr)
Memperluas fungsi dari fungsi SUBSTR dengan menelusuri string untuk pola ekspresi reguler:
REGEXP_SUBSTR('https://console.cloud.google.com/sql/instances','https://([[:alnum:]]+\.?){3,4}/?')
= https://console.cloud.google.com/
Tidak T/A Hanya didukung dari MySQL versi 8. Sebagai solusinya, gunakan fungsi SUBSTR jika memungkinkan, atau konversikan fungsi tersebut ke lapisan aplikasi.
REGEXP_COUNT(str,expr)
Menampilkan frekuensi terjadinya pola di string sumber. Tidak T/A Untuk solusi alternatif, konversikan fungsi ke lapisan aplikasi.
REGEXP_INSTR(index,expr)
Telusuri posisi string (indeks) untuk pola ekspresi reguler. Tidak T/A Hanya didukung dari MySQL versi 8.
REVERSE(str)
Tampilkan string terbalik
REVERSE('MySQL')
= LQSyM
Ya
REVERSE
Setara dengan Oracle:
REVERSE('MySQL')
= LQSyM
Fungsi numerik
Fungsi Oracle Spesifikasi atau implementasi fungsi Oracle Setara MySQL Fungsi yang sesuai MySQL Spesifikasi atau implementasi fungsi MySQL
ABS(n)
Nilai absolut n:
ABS(-4.6) = 4.6
Ya
ABS
Setara dengan Oracle:
ABS(-4.6) = 4.6
CEIL(n)
Menampilkan bilangan bulat terkecil yang lebih besar dari atau sama dengan n:
CEIL(21.4) = 22
Ya
CEIL
Setara dengan Oracle:
CEIL(21.4) = 22
FLOOR(n)
Menampilkan bilangan bulat terbesar yang sama dengan atau kurang dari n:
FLOOR(-23.7) = -24
Ya
FLOOR
Setara dengan Oracle:
FLOOR(-23.7) = -24
MOD(m,n)
Menampilkan sisa m yang dibagi n:
MOD(10, 3) = 1
Ya
MOD(m,n)
Setara dengan Oracle:
MOD(10,3) = 1
ROUND(m,n)
Menampilkan m yang dibulatkan ke n tempat bilangan bulat di sebelah kanan titik desimal:
ROUND(1.39,1) = 1.4
Ya
ROUND
Setara dengan Oracle:
ROUND(1.39,1) = 1.4
TRUNC(n1, n2)
Menampilkan n1 yang dipotong menjadi n2 di belakang koma:
TRUNC(99.999) = 99
TRUNC(99.999,0) = 99
Sebagian dengan nama fungsi yang berbeda
TRUNCATE(n1, n2)
Fungsi TRUNCATE MySQL harus menerima angka input dan bilangan bulat untuk menentukan jumlah akurasi di sebelah kanan titik desimal:
TRUNCATE(99.999,0) = 99
Fungsi tanggal dan waktu
Fungsi Oracle Spesifikasi atau implementasi fungsi Oracle Setara MySQL Fungsi yang sesuai MySQL Spesifikasi atau implementasi fungsi MySQL
SYSDATE
Menampilkan tanggal dan waktu yang ditetapkan saat ini untuk sistem operasi tempat server database berada:
SELECT SYSDATE
FROM DUAL
= 31-JUL-2019
Sebagian
SYSDATE()
SYSDATE() MySQL harus menyertakan tanda kurung dan menampilkan format tanggal/waktu yang berbeda dari fungsi SYSDATE Oracle:
SELECT SYSDATE()
FROM DUAL;
= 2019-01-31 10:01:01.0

Perhatikan bahwa format tanggal/waktu dapat diubah pada tingkat sesi
SYSTIMESTAMP
Menampilkan tanggal sistem, termasuk detik pecahan dan zona waktu:
SELECT SYSTIMESTAMP FROM DUAL
= 01-JAN-19 07.37.11.622187000 AM +00:00
Sebagian dengan nama fungsi yang berbeda
CURRENT_TIMESTAMP
MySQL menampilkan format tanggal/waktu yang berbeda dari Oracle. Format tanggal diperlukan (atau fungsi tanggal yang berbeda) agar cocok dengan format tanggal/waktu asli:
SELECT CURRENT_TIMESTAMP
FROM DUAL
= 2019-01-31 06:55:07
LOCAL_TIMESTAMP
Menampilkan tanggal dan waktu saat ini dalam zona waktu sesi dalam nilai jenis data TIMESTAMP:
SELECT LOCAL_TIMESTAMP
FROM DUAL
= 01-JAN-19 10.01.10.123456 PM
Sebagian dengan format tanggal/waktu yang berbeda.
LOCAL_TIMESTAMP
MySQL menampilkan format tanggal/waktu yang berbeda dari Oracle. Format tanggal/waktu diperlukan (atau fungsi tanggal yang berbeda) agar cocok dengan format tanggal/waktu asli:
SELECT LOCAL_TIMESTAMP
FROM DUAL
= 2019-01-01 10:01:01.0
CURRENT_DATE
Menampilkan tanggal saat ini dalam zona waktu sesi:
SELECT CURRENT_DATE
FROM DUAL
= 31-JAN-19
Sebagian dengan format tanggal/waktu yang berbeda
CURRENT_DATE
MySQL menampilkan format tanggal/waktu yang berbeda dari Oracle. Format tanggal/waktu diperlukan (atau fungsi tanggal yang berbeda) agar cocok dengan format tanggal/waktu asli:
SELECT CURRENT_DATE
FROM DUAL
= 2019-01-31
CURRENT_TIMESTAMP
Menampilkan tanggal dan waktu saat ini dalam zona waktu sesi:
SELECT CURRENT_TIMESTAMP
FROM DUAL
= 31-JAN-19 06.54.35.543146 AM +00:00
Sebagian dengan format tanggal/waktu yang berbeda
CURRENT_TIMESTAMP
MySQL menampilkan format tanggal/waktu yang berbeda dari Oracle. Format tanggal/waktu diperlukan (atau menggunakan fungsi tanggal yang berbeda) agar cocok dengan format tanggal/waktu asli:
SELECT CURRENT_TIMESTAMP
FROM DUAL
= 2019-01-31 06:55:07
ADD_MONTHS
Menampilkan tanggal plus bulan bilangan bulat:
ADD_MONTHS(SYSDATE, 1)
= 31-JAN-19
Sebagian dengan nama fungsi yang berbeda
ADDDATE
Untuk mencapai fungsi yang sama, MySQL menggunakan fungsi ADDDATE:
ADDDATE(SYSDATE(), 1)
= 2019-08-01 06:42:49.0

Secara default, MySQL menampilkan tanggal/waktu dan rentang/format yang berbeda dari Oracle. Pemformatan tanggal/waktu diperlukan (atau fungsi tanggal yang berbeda) agar cocok dengan format tanggal/waktu asli.
EXTRACT(bagian tanggal) Menampilkan nilai kolom tanggal/waktu yang ditentukan dari tanggal/waktu atau ekspresi interval:
EXTRACT(YEAR FROM DATE '2019-01-31')
= 2019
Ya EXTRACT (bagian tanggal) Setara dengan Oracle:
EXTRACT(YEAR FROM DATE '2019-01-31')
= 2019
LAST_DAY
Menampilkan tanggal dari hari terakhir dalam sebulan:
LAST_DAY('01-JAN-2019')
= 31-JAN-19
Sebagian dengan format tanggal/waktu yang berbeda
LAST_DAY
MySQL menampilkan format tanggal/waktu yang berbeda dari Oracle. Format tanggal/waktu diperlukan (atau fungsi tanggal yang berbeda) agar cocok dengan format tanggal/waktu asli:
LAST_DAY('2019-01-01')
= 2019-01-31
MONTH_BETWEEN
Menampilkan jumlah bulan antara tanggal date1 dan date2:
MONTHS_BETWEEN(
SYSDATE, SYSDATE-60)
= 1.96
Sebagian dengan nama fungsi yang berbeda
PERIOD_DIFF(date1,date2)
Fungsi PERIOD_DIFF MySQL menampilkan perbedaan dalam bulan sebagai bilangan bulat antara dua titik (diformat sebagai YYMM atau YYYYMM):
PERIOD_DIFF(
'201903', '201901')
= 2

Untuk mencapai nilai yang sama dengan fungsi MONTH_BETWEEN Oracle, diperlukan konversi yang lebih spesifik
TO_CHAR (tanggal/waktu) Mengonversi jenis data tanggal/waktu atau stempel waktu menjadi nilai jenis data VARCHAR2 dalam format yang ditentukan oleh format tanggal:
TO_CHAR(
SYSDATE,'DD-MM-YYYY HH24:MI:SS')
= 01-01-2019 10:01:01
Sebagian dengan nama fungsi yang berbeda
DATE_FORMAT
Fungsi DATE_FORMAT MySQL memformat tanggal seperti yang ditentukan oleh definisi format tanggal:
DATE_FORMAT(
SYSDATE(),'%d-%m-%Y %H:%i:%s')
= 01-01-2019 10:01:01
Fungsi encoding dan decoding
Fungsi Oracle Spesifikasi atau implementasi fungsi Oracle Setara MySQL Fungsi yang sesuai MySQL Spesifikasi atau implementasi fungsi MySQL
DECODE
Membandingkan ekspresi dengan setiap nilai penelusuran satu per satu menggunakan fungsi pernyataan IF-THEN-ELSE Tidak
CASE
Gunakan pernyataan CASE MySQL untuk mendapatkan fungsi yang serupa.
DUMP
Menampilkan nilai VARCHAR2 yang berisi kode jenis data, panjang dalam byte, dan representasi internal untuk ekspresi tertentu. Tidak T/A Tidak didukung.
ORA_HASH
Menghitung nilai hash untuk ekspresi tertentu. Tidak
MD5/SHA
Menggunakan MD5 MySQL untuk checksum 128-bit atau fungsi SHA untuk checksum 160-bit guna menghasilkan nilai hash
Fungsi konversi
Fungsi Oracle Spesifikasi atau implementasi fungsi Oracle Setara MySQL Fungsi yang sesuai MySQL Spesifikasi atau implementasi fungsi MySQL
CAST
Mengonversi satu jenis data bawaan atau nilai berjenis koleksi menjadi jenis data bawaan atau nilai berjenis koleksi lainnya:
CAST('1' as int) + 1
= 2
Sebagian
CAST
Fungsi CAST MySQL mirip dengan fungsi Oracle, tetapi dalam kasus tertentu, fungsi tersebut harus disesuaikan bergantung pada apakah konversi eksplisit atau implisit diperlukan:
CAST('1' AS SIGNED) + 1
= 2
CONVERT
Mengonversi string karakter dari satu himpunan karakter ke himpunan karakter lainnya:
CONVERT('Ä Ê Í Õ Ø A B C D E ', 'US7ASCII', 'WE8ISO8859P1')
= ?? ?? ?? A B C
Sebagian
CONVERT
Fungsi CONVERT MySQL memerlukan beberapa penyesuaian pada sintaksis dan parameter untuk menampilkan hasil yang tepat sebagai Oracle:
CONVERT('Ä Ê Í A B C ' USING utf8)
= Ä Ê Í A B C
TO_CHAR
(string/numerik)
Fungsi ini mengonversi angka atau tanggal menjadi string:
TO_CHAR(22.73,'$99.9')
= $22.7
Tidak
FORMAT
Fungsi FORMAT MySQL menjalankan format '#,###.##' dari angka, membulatkannya ke sejumlah desimal tertentu, lalu menampilkan hasilnya sebagai string, memiliki fungsi yang berbeda dengan Oracle:
CONCAT('$',
FORMAT(22.73, 1))
= $22.7
TO_DATE
Fungsi TO_DATE Oracle mengonversi string menjadi tanggal berdasarkan format tanggal/waktu tertentu sumber:
TO_DATE(
'2019/01/01', 'yyyy-mm-dd')
= 01-JAN-2019
Sebagian dengan nama fungsi dan format tanggal/waktu yang berbeda
STR_TO_DATE
Fungsi STR_TO_DATE MySQL mengambil string dan menampilkan tanggal yang ditentukan oleh format tanggal/waktu:
STR_TO_DATE(
'2019/01/01', '%Y/%m/%d')
= 2019-01-01
TO_NUMBER
Mengonversi ekspresi ke nilai jenis data NUMBER:
TO_NUMBER('01234')
= 1234
Tidak
CAST
Sebagai alternatif, gunakan fungsi CAST MySQL untuk menampilkan hasil yang sama dengan Oracle TO_NUMBER:
CAST('01234' as SIGNED)
= 1234
Fungsi SELECT bersyarat
Fungsi Oracle Spesifikasi atau implementasi fungsi Oracle Setara MySQL Fungsi yang sesuai MySQL Spesifikasi atau implementasi fungsi MySQL
CASE
Pernyataan CASE memilih dari urutan kondisi dan menjalankan pernyataan yang sesuai dengan sintaksis berikut:
CASE WHEN condition THEN result
[WHEN ...] [ELSE result]
END
Ya
CASE
Selain fungsi CASE, MySQL juga mendukung penggunaan penanganan kondisional IF/ELSE dalam pernyataan SELECT:
CASE WHEN condition THEN result
[WHEN ...] [ELSE result]
END
Fungsi null
Fungsi Oracle Spesifikasi atau implementasi fungsi Oracle Setara MySQL Fungsi yang sesuai MySQL Spesifikasi atau implementasi fungsi MySQL
COALESCE
Menampilkan ekspresi non-null pertama dalam daftar ekspresi:
COALESCE(
null, '1', 'a')
= a
Ya
COALESCE
Setara dengan Oracle:
COALESCE(
null, '1', 'a')
= 1
NULLIF
Bandingkan expr1 dan expr2m. Jika keduanya sama, fungsi akan menampilkan null. Jika kedua nilai tersebut tidak sama, fungsi akan menampilkan expr1:
NULLIF('1', '2')
= a
Ya
NULLIF
Setara dengan Oracle:
NULLIF('1', '2')
= a
NVL
Ganti null (ditampilkan sebagai kosong) dengan string dalam hasil kueri:
NVL(null, 'a')
= a
Tidak
IFNULL
Fungsi yang setara di MySQL adalah fungsi IFNULL , yang menggantikan nilai null dengan string tertentu:
IFNULL(null, 'a')
= a
NVL2
Tentukan nilai yang ditampilkan oleh kueri berdasarkan nilai ekspresi
tertentu, yakni null atau bukan null.
Tidak
CASE
Pernyataan CASE
memilih dari urutan kondisi dan menjalankan pernyataan yang sesuai:
CASE WHEN condition THEN result
[WHEN ...] [ELSE result]
END
Fungsi lingkungan dan ID
Fungsi Oracle Spesifikasi atau implementasi fungsi Oracle Setara MySQL Fungsi yang sesuai MySQL Spesifikasi atau implementasi fungsi MySQL
SYS_GUID
Menghasilkan dan menampilkan ID unik global (nilai RAW) yang terdiri dari 16 byte:
SELECT SYS_GUID()
FROM DUAL
= 8EFA4A31468B4C6DE05011AC0200009E
Tidak REPLACE dan UUID Sebagai solusinya, gunakan fungsi REPLACE dan UUID MySQL untuk menyimulasikan fungsi SYS_GUID Oracle:
REPLACE(
UUID(), '-', '')
UID
Menampilkan bilangan bulat yang mengidentifikasi pengguna sesi secara unik (pengguna
yang login):
SELECT UID FROM DUAL
= 43
Tidak T/A T/A
USER
Menampilkan nama dari nama pengguna sesi saat ini:
SELECT USER FROM DUAL
= UserName
Sebagian
USER + INSTR + SUBSTR
Fungsi USER MySQL menampilkan nama pengguna beserta server koneksi (root@IP). Untuk mengambil nama pengguna saja, gunakan fungsi pendukung tambahan:
SELECT
SUBSTR(USER(), 1, INSTR(USER(), '@') -1) FROM DUAL
= root
USERENV
Menampilkan informasi tentang sesi pengguna saat ini dengan konfigurasi parameter saat ini:
SELECT USERENV('LANGUAGE')
FROM DUAL
= ENGLISH_AMERICA.AL32UTF8
Tidak
SHOW SESSION
VARIABLES
Gunakan pernyataan SHOW SESSION
VARIABLES MySQL untuk melihat setelan untuk sesi saat ini:
SHOW SESSION VARIABLES LIKE '%collation%';
= utf8_general_ci
ROWID
Server Oracle menetapkan ROWID unik pada setiap baris di setiap tabel untuk mengidentifikasi baris dalam tabel. ROWID adalah alamat baris yang berisi nomor objek data, blok data baris, posisi baris, dan file data. Tidak T/A Jika memungkinkan, coba emulasikan fungsi yang sama dengan fungsi MySQL lainnya.
ROWNUM
Menampilkan angka yang mewakili urutan baris yang dipilih oleh Oracle dari tabel atau tabel gabungan. Tidak T/A Jika memungkinkan, coba emulasikan fungsi yang sama dengan fungsi MySQL atau variabel sesi lainnya.
Fungsi agregat (grup)
Fungsi Oracle Spesifikasi fungsi atau
implementasi Oracle
MySQL
setara
Fungsi yang sesuai MySQL Spesifikasi atau implementasi fungsi MySQL
AVG
Menampilkan nilai rata-rata kolom atau ekspresi. Ya
AVG
Setara dengan Oracle
COUNT
Menampilkan jumlah baris yang ditampilkan oleh kueri. Ya
COUNT
Setara dengan Oracle
COUNT
(DISTINCT)
Menampilkan jumlah nilai unik dalam kolom atau ekspresi. Ya
COUNT
(DISTINCT)
Setara dengan Oracle
MAX
Menampilkan nilai maksimum kolom atau ekspresi. Ya
MAX
Setara dengan Oracle
MIN
Menampilkan nilai minimum kolom atau ekspresi. Ya
MIN
Setara dengan Oracle
SUM
Menampilkan jumlah nilai kolom atau ekspresi. Ya
SUM
Setara dengan Oracle
LISTAGG
Menampilkan data dalam setiap grup berdasarkan satu baris yang ditentukan dalam klausa ORDER BY dengan menggabungkan nilai kolom ukuran:
SELECT LISTAGG(
DEPARTMENT_NAME, ', ')
WITHIN GROUP
(ORDER BY DEPARTMENT_NAME) DEPT
FROM DEPARTMENTS;

-- Single line results
= Accounting, Administration, Benefits, Construction
Tidak
GROUP_CONCAT
Gunakan fungsi GROUP_CONCAT MySQL untuk menampilkan hasil yang serupa dengan Oracle, antisipasi perbedaan sintaksis dengan kasus tertentu:
SELECT GROUP_CONCAT(
DEPARTMENT_NAME ORDER BY DEPARTMENT_NAME SEPARATOR ', ') DEPT
FROM DEPARTMENTS;

-- Single line results
= Accounting, Administration, Benefits, Construction
Pengambilan Oracle 12c
Fungsi Oracle Spesifikasi fungsi atau
implementasi Oracle
MySQL
setara
Fungsi yang sesuai MySQL Spesifikasi atau implementasi fungsi MySQL
FETCH
Mengambil baris data dari kumpulan hasil kueri multi-baris:
SELECT * FROM
EMPLOYEES
FETCH FIRST 10 ROWS ONLY;
Tidak LIMIT Gunakan klausa LIMIT MySQL untuk mengambil kumpulan data tertentu saja:
SELECT * FROM
EMPLOYEES
LIMIT 10;

Pemfilteran dasar, operator, dan subkueri

Selama konversi, pemfilteran dasar, fungsi operator, dan subkueri relatif mudah, sehingga hanya memerlukan sedikit atau tanpa upaya tambahan.

Catatan konversi

Periksa dan tangani format tanggal karena format Oracle dan MySQL menampilkan hasil default yang berbeda:

  • Fungsi SYSDATE Oracle secara default menampilkan 01-AUG-19.
  • Fungsi SYSDATE() MySQL secara default menampilkan 2019-08-01 12:04:05.
  • Format tanggal dan waktu dapat disetel menggunakan fungsi [DATE_FORMAT](https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-format) atau [STR_TO_DATE](https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_str-to-date) MySQL.
Fungsi atau subkueri Oracle Setara MySQL Fungsi atau sub-kueri yang sesuai MySQL Spesifikasi atau implementasi fungsi MySQL
EXISTS/NOT EXISTS
Ya
EXISTS/NOT EXISTS
SELECT * FROM DEPARTMENTS D
WHERE EXISTS (SELECT 1
              FROM EMPLOYEES E
              WHERE
              E.DEPARTMENT_ID =
              D.DEPARTMENT_ID);
IN/NOT IN
Ya
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
Ya
LIKE/NOT LIKE
SELECT * FROM EMPLOYEES
WHERE FIRST_NAME LIKE '_e_n%';
BETWEEN/NOT BETWEEN
Ya
BETWEEN/NOT BETWEEN
SELECT * FROM EMPLOYEES
WHERE EXTRACT(YEAR FROM HIRE_DATE)
NOT BETWEEN 2001 and 2004;
AND/OR
Ya
AND/OR
SELECT * FROM EMPLOYEES
WHERE DEPARTMENT_ID IN(100, 101)
AND (SALARY >= 1000 OR HIRE_DATE <= '2006-02-05');
SubQuery
Ya
SubQuery
MySQL mendukung subkueri di level SELECT, untuk pernyataan JOIN dan untuk pemfilteran dalam klausa WHERE/AND:
-- 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);
Operator Ya Operator MySQL mendukung semua operator dasar:
> | >= | < | <= | = | <> | !=

Fungsi analisis (atau fungsi jendela dan peringkat)

Fungsi analisis Oracle memperluas fungsionalitas dari fungsi analisis SQL standar dengan menyediakan kemampuan untuk menghitung nilai agregat berdasarkan sekumpulan baris. Fungsi ini dapat diterapkan ke kumpulan hasil yang dipartisi secara logis dalam cakupan ekspresi kueri tunggal. Fungsi ini biasanya digunakan bersama dengan analisis dan laporan business intelligence, dengan potensi untuk meningkatkan performa kueri sebagai alternatif untuk mencapai hasil yang sama menggunakan kode SQL non-analitis yang lebih kompleks.

Catatan konversi

  • MySQL versi 5.7 tidak menyediakan fungsi analisis untuk mendukung konversi pernyataan SQL yang mudah. Namun, fungsi ini ditambahkan sebagian di MySQL versi 8, sehingga menjadikan konversi fungsi analisis sebagai hal yang perlu dipertimbangkan, yang mungkin memerlukan upaya manual dalam proses migrasi.
  • Solusi opsional adalah menulis ulang kode untuk menghapus penggunaan fungsi analisis, kembali ke solusi kode SQL yang lebih tradisional, atau memindahkan logika ini ke lapisan aplikasi.

Tabel berikut mencantumkan fungsi analisis umum Oracle.

Kelompok fungsi Fungsi terkait Didukung oleh MySQL 5.7
Analitis dan peringkat
RANK
AVERAGE_RANK
DENSE_RANK
RANK ROW_NUMBER
PERCENT_RANK
CUME_DIST
NTILE
FIRST_VALUE
LAST_VALUE
OVER (PARTITION BY...)
Tidak
Hierarkis
CONNECT BY
HIER_ANCESTOR
HIER_CHILD_COUNT
HIER_DEPTH
HIER_LEVEL
HIER_ORDER
HIER_PARENT
HIER_TOP
Tidak
Jeda
LAG
LAG_VARIANCE LAG_VARIANCE_PERCENT LEAD
LEAD_VARIANCE LEAD_VARIANCE_PERCENT
Tidak

Ekspresi tabel umum (CTE)

CTE menyediakan cara untuk menerapkan logika kode berurutan untuk menggunakan kembali kode SQL yang mungkin terlalu kompleks atau tidak efisien untuk beberapa penggunaan. CTE dapat diberi nama dan digunakan beberapa kali di berbagai bagian pernyataan SQL menggunakan klausul WITH.

Catatan konversi

  • MySQL versi 5.7 tidak mendukung CTE, tetapi MySQL versi 8 mendukungnya.
  • Untuk solusi alternatif, gunakan tabel turunan atau SubKueri atau tulis ulang pernyataan SQL untuk menghilangkan fungsi CTE.

Contoh

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;

Pernyataan MERGE

Pernyataan MERGE (atau UPSERT) menyediakan cara untuk menentukan satu pernyataan SQL yang secara kondisional melakukan operasi DML dalam satu operasi MERGE, bukan satu operasi DML, yang berjalan terpisah. Fungsi ini memilih data dari tabel sumber, kemudian, dengan menentukan struktur logis, secara otomatis melakukan beberapa operasi DML pada tabel target. Fitur ini membantu Anda menghindari penggunaan beberapa penyisipan, update, atau penghapusan. Perhatikan bahwa MERGE adalah pernyataan deterministik, yang berarti bahwa setelah sebuah baris diproses oleh pernyataan MERGE, baris tersebut tidak dapat diproses lagi menggunakan pernyataan MERGE yang sama.

Catatan konversi

MySQL versi 5.7 tidak mendukung fungsi MERGE, tidak seperti Oracle. Untuk menyimulasikan sebagian fungsi MERGE, MySQL menyediakan pernyataan REPLACE dan INSERT… ON DUPLICATE KEY UPDATE:

  • REPLACE: Berfungsi dengan cara yang sama seperti pernyataan INSERT, kecuali jika baris lama dalam tabel memiliki nilai yang sama dengan baris baru untuk PRIMARY KEY atau UNIQUE, baris lama akan dihapus sebelum baris baru disisipkan.

  • INSERT… ON DUPLICATE KEY UPDATE: Jika baris yang disisipkan akan menyebabkan nilai duplikat dalam indeks PRIMARY KEY atau UNIQUE, UPDATE dari baris lama akan muncul untuk menghilangkan pengecualian kunci duplikat, misalnya:

    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;
    

Solusi lainnya adalah mengonversi fungsi MERGE menjadi prosedur tersimpan untuk mengelola operasi DML, menggunakan perintah INSERT, UPDATE, dan DELETE dengan penanganan pengecualian serta duplikasi.

Petunjuk pernyataan SQL

Oracle menyediakan banyak petunjuk kueri SQL yang memungkinkan pengguna memengaruhi perilaku Optimizer dan pengambilan keputusannya, yang bertujuan untuk menghasilkan rencana eksekusi kueri yang lebih efisien. Oracle mendukung lebih dari 60 petunjuk database yang berbeda. MySQL menyediakan kumpulan petunjuk kueri yang terbatas.

Secara umum, MySQL versi 5.7 mendukung dua jenis petunjuk kueri: OPTIMIZER HINTS dan INDEX HINTS. Petunjuk MySQL Optimizer memberikan kemampuan untuk mengontrol perilaku Pengoptimal dalam setiap pernyataan SQL—misalnya:

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

Petunjuk Pengoptimal Tersedia pada MySQL versi 5.7

Nama petunjuk Ringkasan petunjuk Cakupan yang berlaku
BKA, NO_BKA
Memengaruhi pemrosesan penggabungan akses kunci batch Blok kueri, tabel
BNL, NO_BNL
Memengaruhi pemrosesan join loop bertingkat blok Blok kueri, tabel
MAX_EXECUTION_TIME
Membatasi waktu eksekusi pernyataan Global
MRR, NO_MRR
Memengaruhi pengoptimalan operasi baca multi-rentang [TABLE] INDEX
NO_ICP
Memengaruhi pengoptimalan bentang bawah kondisi indeks [TABLE] INDEX
NO_RANGE_OPTIMIZATION
Memengaruhi pengoptimalan rentang [TABLE] INDEX
QB_NAME
Menetapkan nama ke blok kueri Pemblokiran kueri
SEMIJOIN, NO_SEMIJOIN
Memengaruhi strategi semi-gabungan Pemblokiran kueri
SUBQUERY
Memengaruhi strategi SubQuery IN-ke-EXISTS materialisasi. Pemblokiran kueri

Petunjuk Indeks MySQL memberi Pengoptimal informasi tentang cara memilih indeks selama pemrosesan kueri. Kata kunci USE, FORCE, atau IGNORE digunakan untuk mengontrol proses penggunaan indeks Optimizer—misalnya:

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

Catatan konversi

Karena ada perbedaan mendasar antara Oracle dan MySQL Optimizer, dan karena ada tumpang-tindih terbatas atau tidak sama sekali antara petunjuk kueri Oracle dan MySQL, sebaiknya Anda mengonversi pernyataan Oracle SQL yang menyimpan petunjuk kueri yang tidak ditentukan ke target database MySQL.

Lakukan penyesuaian performa MySQL melalui alat MySQL (misalnya, Workbench MySQL untuk dasbor performa real-time) dan fitur seperti memeriksa kueri menggunakan rencana eksekusi dan menyesuaikan instance atau parameter sesi sesuai dengan kasus penggunaan.

Rencana eksekusi

Tujuan utama dari rencana eksekusi adalah untuk memberikan gambaran mendalam mengenai pilihan yang dibuat oleh pengoptimal kueri untuk mengakses data database. Pengoptimal kueri akan menghasilkan rencana eksekusi untuk pernyataan SELECT, INSERT, UPDATE, dan DELETE untuk pengguna database, yang juga memungkinkan administrator memiliki pandangan yang lebih baik mengenai kueri tertentu dan operasi DML. Parameter ini sangat berguna saat Anda perlu melakukan penyesuaian performa kueri—misalnya, untuk menentukan performa indeks atau untuk menentukan apakah ada indeks yang hilang yang perlu dibuat.

Rencana eksekusi dapat dipengaruhi oleh volume data, statistik data, dan parameter instance (parameter global atau sesi).

Pertimbangan konversi

Rencana eksekusi bukanlah objek database yang perlu dimigrasikan; melainkan alat untuk menganalisis perbedaan performa antara Oracle dan MySQL yang menjalankan pernyataan yang sama pada set data yang identik.

MySQL tidak mendukung sintaksis, fungsi, atau output rencana eksekusi yang sama dengan Oracle.

Contoh

Rencana eksekusi 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 | ---------------------------------------------------------------------------------------------
Rencana eksekusi 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 | +----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+

Prosedur, fungsi, dan pemicu yang tersimpan

PL/SQL adalah bahasa prosedural Oracle yang diperluas yang digunakan untuk membuat, menyimpan, dan menerapkan solusi berbasis kode dalam database. Secara umum, prosedur dan fungsi database yang tersimpan adalah elemen kode yang terdiri dari bahasa prosedural ANSI SQL dan SQL yang diperluas—misalnya, PL/SQL untuk Oracle, PL/pgSQL untuk PostgreSQL, dan bahasa prosedur MySQL untuk MySQL. MySQL menggunakan nama yang sama dengan database untuk bahasa prosedurnya sendiri yang diperluas.

Tujuan dari prosedur dan fungsi yang tersimpan ini adalah memberikan solusi untuk persyaratan yang lebih cocok dijalankan dari dalam database, bukan dari aplikasi (misalnya, performa, kompatibilitas, dan keamanan). Meskipun prosedur dan fungsi tersimpan menggunakan PL/SQL, prosedur tersimpan digunakan terutama untuk melakukan operasi DDL/DML, dan fungsi terutama digunakan untuk melakukan penghitungan guna menampilkan hasil tertentu.

Bahasa prosedur PL/SQL ke MySQL

Dari perspektif migrasi kode Oracle PL/SQL ke MySQL, implementasi prosedural MySQL berbeda dengan Oracle. Oleh karena itu, migrasi kode diperlukan untuk mengonversi fungsi PL/SQL dari Oracle ke prosedur dan fungsi yang tersimpan di MySQL. Selain itu, Paket Oracle dan Isi Paket tidak didukung oleh MySQL, jadi saat Anda melakukan konversi kode, konversikan elemen ini (atau uraikan elemen tersebut) menjadi satu unit kode MySQL. Perhatikan bahwa prosedur dan fungsi yang tersimpan di MySQL jua disebut sebagai rutin.g

Pemilik objek kode

Di Oracle, pemilik prosedur atau fungsi yang tersimpan adalah pengguna tertentu. Di MySQL, pemilik adalah skema spesifik (yang dibuat dalam database oleh pengguna database).

Hak istimewa dan keamanan objek kode

Di Oracle, untuk membuat prosedur atau fungsi tersimpan, pengguna harus memiliki hak istimewa sistem CREATE PROCEDURE (untuk membuat prosedur atau fungsi di bawah pengguna lain, pengguna database harus memiliki hak istimewa CREATE ANY PROCEDURE). Untuk menjalankan prosedur tersimpan atau fungsi, pengguna database harus memiliki hak istimewa EXECUTE.

Di MySQL, untuk membuat elemen kode, pengguna harus memiliki hak istimewa CREATE ROUTINE dan hak istimewa EXECUTE agar dapat berjalan. Klausa DEFINER MySQL menentukan pembuat pengguna untuk objek kode, dan pengguna harus memiliki hak istimewa yang sesuai seperti CREATE ROUTINE.

Prosedur dan sintaksis fungsi tersimpan MySQL

Contoh berikut menunjukkan prosedur dan fungsi yang tersimpan di MySQL sintaksis .

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