MySQL saklı yordam vs işlevi, ne zaman kullanacağım?


160

MySQL saklı yordamlar ve işlev bakıyorum. Gerçek fark nedir?

Benzer görünüyorlar, ancak bir işlevin daha fazla sınırlaması var.

Muhtemelen yanılıyorum, ancak saklı bir yordam her şeyi yapabilir ve daha fazla saklı işlevi yapabilirsiniz. Neden / ne zaman bir fonksiyona karşı bir fonksiyon kullanmalıyım?

Yanıtlar:


101

Saklı yordamları sıradan SQL ile karıştıramazken, saklı işlevle yapabilirsiniz.

örn. bir yordam SELECT get_foo(myColumn) FROM mytablegeçerli değilse get_foo(), ancak bir işlevse bunu yapabilirsiniz get_foo(). Fiyat, fonksiyonların bir prosedürden daha fazla sınırlamaya sahip olmasıdır.


18
İşlevlerin ne tür sınırlamaları vardır?
Fantius

11
Ah, burada bazı iyi bilgiler buldum: dev.mysql.com/doc/refman/5.0/en/…
Fantius

262

Prosedürler ve fonksiyonlar arasındaki en genel fark, farklı ve farklı amaçlarla çağrılmasıdır:

  1. Yordam bir değer döndürmez. Bunun yerine, bir tabloyu değiştirmek veya alınan kayıtları işlemek gibi bir işlemi gerçekleştirmek için bir CALL deyimi ile çağrılır.
  2. Bir işlev bir ifade içinde çağrılır ve tek bir değeri doğrudan ifadede kullanılacak arayana döndürür.
  3. CALL deyimiyle bir işlevi çağıramazsınız veya bir ifadede yordam çağıramazsınız.

Rutin oluşturma sözdizimi, prosedürler ve işlevler için biraz farklıdır:

  1. Yordam parametreleri yalnızca girdi, yalnızca çıktı veya her ikisi olarak tanımlanabilir. Bu, bir prosedürün çıkış parametrelerini kullanarak değerleri arayana geri aktarabileceği anlamına gelir. Bu değerlere CALL deyimini izleyen ifadelerde erişilebilir. Fonksiyonların yalnızca giriş parametreleri vardır. Sonuç olarak, hem yordamların hem de işlevlerin parametreleri olabilse de, yordam parametre bildirimi işlevlerden farklıdır.
  2. İşlevler dönüş değeri; bu nedenle, dönüş değerinin veri türünü belirtmek için işlev tanımında bir RETURNS yan tümcesi olmalıdır. Ayrıca, çağırana bir değer döndürmek için işlev gövdesinde en az bir RETURN deyimi olmalıdır. RETURNS ve RETURN prosedür tanımlarında görünmez.

    • Saklı bir yordamı çağırmak için CALL statement. Saklanan bir işlevi çağırmak için, bir ifadede bu işleve başvurun. İşlev, ifade değerlendirmesi sırasında bir değer döndürür.

    • Bir yordam bir CALL deyimi kullanılarak çağrılır ve değerleri yalnızca çıktı değişkenlerini kullanarak geri verebilir. Bir işlev, herhangi bir işlev gibi bir ifadenin içinden çağrılabilir (yani, işlevin adını çağırarak) ve skaler bir değer döndürebilir.

    • Bir parametrenin IN, OUT veya INOUT olarak belirtilmesi yalnızca PROSEDÜR için geçerlidir. FUNCTION için parametreler her zaman IN parametreleri olarak kabul edilir.

    Parametre adından önce anahtar sözcük verilmezse, varsayılan olarak bir IN parametresidir. Saklanan işlevler için parametrelerin önünde IN, OUT veya INOUT yoktur. Tüm fonksiyon parametreleri IN parametreleri olarak kabul edilir.

Saklı bir yordamı veya işlevi tanımlamak için, sırasıyla CREATE PROCEDURE veya CREATE FUNCTION kullanın:

CREATE PROCEDURE proc_name ([parameters])
 [characteristics]
 routine_body


CREATE FUNCTION func_name ([parameters])
 RETURNS data_type       // diffrent
 [characteristics]
 routine_body

Saklı yordam (işlevler değil) için bir MySQL uzantısı, bir yordamın bir sonuç kümesi veya hatta birden çok sonuç kümesi oluşturabilmesidir, bu da çağıranın bir SELECT deyiminin sonucuyla aynı şekilde işlenmesidir. Bununla birlikte, bu tür sonuç kümelerinin içerikleri doğrudan ifadede kullanılamaz.

Depolanan yordamlar (hem depolanan yordamlara hem de depolanan işlevlere atıfta bulunur) tıpkı tablolar veya görünümler gibi belirli bir veritabanıyla ilişkilendirilir. Bir veritabanını bıraktığınızda, veritabanında depolanan yordamlar da bırakılır.

Saklı yordamlar ve işlevler aynı ad alanını paylaşmaz. Veritabanında aynı ada sahip bir yordam ve işlev olması mümkündür.

Saklı yordamlarda dinamik SQL kullanılabilir, ancak işlevlerde veya tetikleyicilerde kullanılamaz.

SQL tarafından hazırlanan ifadeler (PREPARE, EXECUTE, DEALLOCATE PREPARE) saklı yordamlarda kullanılabilir, ancak saklanan işlevler veya tetikleyiciler kullanılamaz. Bu nedenle, depolanan işlevler ve tetikleyiciler Dinamik SQL'i kullanamaz (burada ifadeleri dize olarak oluşturup çalıştırırsınız). (MySQL saklı yordamlarında dinamik SQL)

FONKSİYON ve KAYITLI PROSEDÜR arasındaki bazı ilginç farklılıklar:

  1. ( Bu nokta bir blog yazısından kopyalanır . ) Saklı yordam, işlevlerin olmadığı yerlerde önceden derlenmiş yürütme planıdır. İşlev Çalışma zamanında ayrıştırıldı ve derlendi. Saklı yordamlar, Veritabanında bir sahte kod olarak saklanır yani derlenmiş form.

  2. ( Bu nokta için emin değilim. )
    Saklı yordam güvenliği vardır ve ağ trafiğini azaltır ve ayrıca herhangi bir hayır saklı yordam çağırabiliriz. bir seferde uygulamaların sayısı. referans

  3. İşlevler normal olarak, iş mantığının yürütülmesi için prosedürlerin normal olarak kullanıldığı hesaplamalar için kullanılır.

  4. İşlevler Veritabanının durumunu etkileyemez (Açık veya kapalı kesinleştirme veya geri alma ifadeleri işlevde izin verilmez) Oysa Saklı yordamlar, kesinleştirme vb. Kullanarak veritabanının durumunu etkileyebilir.
    Referans: J.1. Kayıtlı Rutinler ve Tetikleyicilerle İlgili Kısıtlamalar

  5. Saklı yordamlar, işlevler FLUSH deyimlerini kullanamaz .

  6. Saklı yordamlar yinelemeli iken Saklı yordamlar olabilir. Not: Yinelenen saklı yordamlar varsayılan olarak devre dışıdır, ancak max_sp_recursion_depth sunucu sistemi değişkeni sıfır olmayan bir değere ayarlanarak sunucuda etkinleştirilebilir. Daha fazla bilgi için bkz. Bölüm 5.2.3, “Sistem Değişkenleri” .

  7. Depolanmış bir işlev veya tetikleyici içinde, işlevi veya tetikleyiciyi başlatan ifade tarafından zaten kullanılmakta olan (okuma veya yazma için) bir tablonun değiştirilmesine izin verilmez. İyi Örnek: MYSQL'de silme işleminde aynı tablo nasıl güncellenir?

Not : bazı kısıtlamalar normalde saklanan işlevler ve tetikleyiciler için geçerli olsa da saklı yordamlar için geçerli olmasa da, bu kısıtlamalar saklı bir işlev veya tetikleyiciden çağrıldıklarında saklı yordamlar için geçerlidir. Örneğin, FLUSH'u saklı bir yordamda kullanabilmenize rağmen, bu saklı yordam depolanmış bir işlev veya tetikleyiciden çağrılamaz.


2
@GrijeshChauhan, "İşlev çalışma zamanında ayrıştırıldı ve derlendi" derken ne demek istiyorsun ?
Pacerier

@Pacerier, MySQL'deki işlevlerin, derlenen ve çalıştırılan komut dosyaları gibi bir şey olduğu anlamına gelir. Bazı blog yayınlarından kopyaladım , ancak bu davranışları incelemek için pratik yapmadım.
Grijesh Chauhan

Prosedürleri size parametre olarak bir takım değişken geçirebilirsiniz, daha sonra bir select deyimi ile diyoruz
LTroya

1
Bu cevabın alt kısmında mermi noktası # 4, sanırım, prosedürler ve fonksiyonlar arasındaki farkın özüdür. yordamlar veritabanını değiştirebilir, işlevler değiştiremez. diğer tüm farklılıklar sadece bu amaca daha etkin bir şekilde hizmet etmek içindir.
Woodrow Barlow

51

Önemli bir fark, SQL sorgularınıza bir işlev ekleyebilmenizdir , ancak saklı yordamlar yalnızca CALLifadeyle çağrılabilir :

UDF Örneği:

CREATE FUNCTION hello (s CHAR(20))
   RETURNS CHAR(50) DETERMINISTIC
   RETURN CONCAT('Hello, ',s,'!');
Query OK, 0 rows affected (0.00 sec)

CREATE TABLE names (id int, name varchar(20));
INSERT INTO names VALUES (1, 'Bob');
INSERT INTO names VALUES (2, 'John');
INSERT INTO names VALUES (3, 'Paul');

SELECT hello(name) FROM names;
+--------------+
| hello(name)  |
+--------------+
| Hello, Bob!  |
| Hello, John! |
| Hello, Paul! |
+--------------+
3 rows in set (0.00 sec)

Sproc Örneği:

delimiter //

CREATE PROCEDURE simpleproc (IN s CHAR(100))
BEGIN
   SELECT CONCAT('Hello, ', s, '!');
END//
Query OK, 0 rows affected (0.00 sec)

delimiter ;

CALL simpleproc('World');
+---------------------------+
| CONCAT('Hello, ', s, '!') |
+---------------------------+
| Hello, World!             |
+---------------------------+
1 row in set (0.00 sec)

1
İşlevin iki dönüşü var mı? Yani bu çizgi nedir? RETURNS CHAR(50) DETERMINISTIC?
Martin AJ

RETURNS CHAR(50)Verilerin yazdıklarınızı devletler iade edilecektir. RETURN CONCAT(...İade edilen verilerdir. Her ikisi de gereklidir. DETERMINISTICTemel veri modifiye olmayacak durum için gereklidir.
lemming622

8

Saklanan bir işlev bir sorgu içinde kullanılabilir. Daha sonra her satıra veya bir WHERE deyimine uygulayabilirsiniz.

CALL sorgusu kullanılarak bir prosedür yürütülür.


0

Saklı yordam özyinelemeli olarak adlandırılabilir, ancak saklı işlev kullanılamaz

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.