Skaler değerli fonksiyonların neden seçmek yerine yürütme iznine ihtiyacı vardır?


15

Neden skaler değerli fonksiyon için, ben sadece bir seçim yerine yürütmek için kullanıcıya vermek zorunda olduğunu merak ediyorum?

bu arada bir tablo değerli fonksiyonlar sadece seçili izin veya db_datareaderüyelik ile iyi çalışır .

burada daha açık olması için benim örnek: Ben veritabanına salt okunur izni olan bir kullanıcıya ihtiyacım var. bu yüzden adlı bir kullanıcı oluşturdum testUserve ona db_datareaderüyelik verdim . daha sonra adlandırılan bir tablo değerli fonksiyonu yarattım fn_InlineTable. Ve hepsi harika. testUserbu SQL'i gün boyu çalıştırır

select * from dbo.fn_InlineTable

o zaman bir skaler fonksiyona ihtiyacım var, bu yüzden denilen bir skaler fonksiyon oluşturdum fn_ScalarTest. testUserbu SQL çalıştırılamıyor

Select dbo.fn_ScalarTest(1) 

Anlaşılır bir şekilde: Ben "testUser" yürütmek için izin vermedi çünkü fn_ScalarTest.

Sorum şu: /programming/6150888/insert-update-delete-with-function-in-sql-server bu bağlantıya dayanarak FUNCTION, veritabanı durumunu değiştiren eylemleri gerçekleştirmek için kullanılamayacağını söyleyen bir bağlantı . Peki neden bir skaler fonksiyon izin yerine yürütmek yerine aynı "SELECT" izni ile kullanılmasına izin vermiyor?

Umarım sorum mantıklıdır. Teşekkür ederim.

Yanıtlar:


15

Büyük olasılıkla birincil neden, Tablo Değerli İşlevlerin, Tablolar ve Görünümler gibi bir Sonuç Kümesi döndürmesidir. Bunlar kullanılabilecek bu araçlar FROM(dahil madde JOINs ve APPLYbir s, vs.) SELECT, UPDATEve DELETEsorgular. Bununla birlikte, bu bağlamların hiçbirinde Skaler UDF kullanamazsınız.

İkinci olarak, EXECUTESkaler UDF de yapabilirsiniz . Bu sözdizimi, giriş parametreleri için varsayılan değerleriniz olduğunda oldukça kullanışlıdır. Aşağıdaki UDF'yi ele alalım, örneğin:

CREATE FUNCTION dbo.OptionalParameterTest (@Param1 INT = 1, @Param2 INT = 2)
RETURNS INT
AS
BEGIN
    RETURN @Param1 + @Param2;
END;

Giriş parametrelerinden herhangi birini "isteğe bağlı" olarak değerlendirmek istiyorsanız DEFAULT, imza düzeltildiğinden, bir işlev gibi çağırırken anahtar kelimeyi iletmeniz gerekir:

DECLARE @Bob1 INT;

SET @Bob1 = dbo.OptionalParameterTest(100, DEFAULT);

SELECT @Bob1;
-- Returns: 102

Öte yandan, eğer EXECUTEişlev varsa, varsayılan değeri olan herhangi bir parametreyi tıpkı Kayıtlı Prosedürlerde olduğu gibi gerçekten isteğe bağlı olarak ele alabilirsiniz. Parametre adlarını belirtmeden ilk n parametreyi iletebilirsiniz :

DECLARE @Bob2 INT;

EXEC @Bob2 = dbo.OptionalParameterTest 50;

SELECT @Bob2;
-- Returns: 52

Saklı Yordamlarda olduğu gibi, yine parametre adlarını belirterek ilk parametreyi atlayabilirsiniz:

DECLARE @Bob3 INT;

EXEC @Bob3 = dbo.OptionalParameterTest @Param2 = 50;

SELECT @Bob3;
-- Returns: 51

GÜNCELLEME

Neden EXECbir Saklı Yordam gibi skaler UDF'yi çağırmak için sözdizimini kullanmak isteyebilirsiniz ? Bazen bir sorguya eklenip döndürülen satırlar kümesi üzerinde çalışabildikleri için UDF'ler olarak harika olan UDF'ler vardır, oysa kod bir Saklı Yordamdaysa imlecin içine yerleştirilmesi gerekir. bir dizi satır üzerinde yineleme yapar. Ancak, bu işlevi tek bir değerde, muhtemelen başka bir UDF içinden çağırmak istediğiniz zamanlar vardır. Bir UDF'yi tek bir değer için çağırmak şu şekilde yapılabilir:

SELECT dbo.UDF('some value');

bu durumda sonuç kümesinde bir dönüş değeri alırsınız (sonuç kümesi çalışmaz). Veya şu şekilde yapılabilir:

DECLARE @Dummy INT;

SET @Dummy = dbo.UDF('some value');

bu durumda @Dummydeğişkeni bildirmeniz gerekir ;

Ancak EXECsözdizimi ile bu rahatsızlıkların her ikisinden de kaçınabilirsiniz:

EXEC dbo.UDF 'some value';

AYRICA, skaler UDF'lerin yürütme planları önbelleğe alınır. Bu, UDF'de yürütme planları olan sorgular varsa parametre koklama sorunlarıyla karşılaşmanın mümkün olduğu anlamına gelir. EXECSözdizimini kullanmanın mümkün olduğu senaryolar için, o yürütme içinWITH RECOMPILE planlanan derlenmiş değeri yok saymak seçeneğini de kullanmak mümkündür . Örneğin:

KURMAK:

GO
CREATE FUNCTION dbo.TestUDF (@Something INT)
RETURNS INT
AS 
BEGIN
   DECLARE @Ret INT;
   SELECT @Ret = COUNT(*)
   FROM   sys.indexes si
   WHERE  si.[index_id] = @Something;

   RETURN @Ret;
END;
GO

ÖLÇEK:

DECLARE @Val INT;

SET @Val = dbo.TestUDF(1);
SELECT @Val;

EXEC @Val = dbo.TestUDF 0 -- uses compiled value of (1)
SELECT @Val;

EXEC @Val = dbo.TestUDF 0 WITH RECOMPILE; -- uses compiled value of (0)
SELECT @Val;

EXEC @Val = dbo.TestUDF 3 -- uses compiled value of (1)
SELECT @Val;

4

İzinleri arasındaki fark aslında saklı yordamlar (kullanıcı tanımlı işlevleri tanıttı SQL Server 2000 Books Online içine kazana kadar fark etmemişti) gibi EXEC ile aslında skaler değerli kullanıcı tanımlı işlevleri çağırabilirsiniz çünkü ancak bunlardan bir tablo kaynağı olarak seçim yapamazsınız. Örneğin:

DECLARE @date datetime
EXEC @date = dbo.first_day_of_month '8/14/2015'
SELECT @date

Bu durumda, dbo.first_day_of_month kullanıcı tanımlı bir işlevdir. Neden böyle bir işlevi çağıracağınızı bilmiyorum, ancak tutarlılığı korumak için SELECT yerine EXECUTE izni istediklerini tahmin ediyorum. Günümüzde muhtemelen sadece uyumluluk bagajı olarak duruyor.

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.