2011-10-31 11 views
8

vardır böyle çağrılarsysdate fark

iki sysdate çağrılar farklı değerlere vereceği ihtimali var olup olmadığını merak ediyorum
some_proc(sysdate, sysdate); 
select some_func(sysdate, sysdate) from dual 

? Sysdate sadece yürütme hızı nedeniyle değişmez mi?

+0

Eğer (değişken l_sysdate ile değiştirmek planlıyor musunuz yerine prosedür/işlev)? –

+0

Yapabilseydim bunu yapardım. Ancak, sysdate gerektiren yalnızca bir sql sorgum var. Sadece sysdate için yeni sorgu eklemek istemiyorum. Eğer bu (değişken bildirme, ona bir değişken atama, bir sql sorgu yürütme) mükemmel bir sorguda yapılabilir. –

+0

@nisha, cevabımı aşağıya ekledim. –

cevap

11

some_proc(sysdate, sysdate);- PL/SQL deyimi kullanıldığında sysdate hep aynı olmayacaktır

select some_func(sysdate, sysdate) from dual;- SQL deyimi (kullanıldığında bu SQL deyimi aradığını bile sysdate hep aynı olacaktır PL/SQL) Kavramlar kılavuzun Statement-Level Read Consistency bölümünden

:. "Oracle daima deyim düzey okuma tutarlılığı zorlar Bu sefer zamanlı olarak tek bir noktadan gelen tüm veriler tek bir sorgu tarafından döndürülen garanti olduğunu sorgu başladı. "

Bu sayfa, aynı durumun salt PL/SQL işlevi için geçerli olmadığını ima eder.

Bunu, çok sayıda zaman damgası parametresini kabul eden büyük bir işlev (SQL bağlamı) ve yordamı (PL/SQL bağlamı) oluşturarak gösterebiliriz, ardından herhangi bir farklılık için giriş parametrelerini karşılaştırın. Tarihler yerine zaman damgaları kullandım çünkü tutarlılıkla ilgili olarak aynı şekilde çalışmalılar, ancak zaman damgası (9) bir tarihin değişiminden milyarlarca kat daha fazladır. (Kabaca - yuvarlanması ve bunu habersiz olduğum iç saat birçok ayrıntı bu daha karmaşık hale muhtemelen vardır.) Eğer başında SysDate seçmek içine

--First, use functions like these to create long strings of variables. 
--PL/SQL can go to 64K parameters, but luckily differences appear much sooner. 

--Parameters for function and procedure 
select listagg('a'||level||' timestamp', ',') within group(order by level) 
from dual connect by level <= 100 order by level; 

--Columns for least/greatest 
select listagg('a'||level, ',') within group(order by level) 
from dual connect by level <= 100; 

--Systimestamps for select/exec 
select listagg('systimestamp',',') within group(order by 1) 
from dual connect by level <= 100; 




--FUNCTION - SQL context 
create or replace function function_test(
    a1 timestamp,a2 timestamp,a3 timestamp,a4 timestamp,a5 timestamp,a6 timestamp,a7 timestamp,a8 timestamp,a9 timestamp,a10 timestamp,a11 timestamp,a12 timestamp,a13 timestamp,a14 timestamp,a15 timestamp,a16 timestamp,a17 timestamp,a18 timestamp,a19 timestamp,a20 timestamp,a21 timestamp,a22 timestamp,a23 timestamp,a24 timestamp,a25 timestamp,a26 timestamp,a27 timestamp,a28 timestamp,a29 timestamp,a30 timestamp,a31 timestamp,a32 timestamp,a33 timestamp,a34 timestamp,a35 timestamp,a36 timestamp,a37 timestamp,a38 timestamp,a39 timestamp,a40 timestamp,a41 timestamp,a42 timestamp,a43 timestamp,a44 timestamp,a45 timestamp,a46 timestamp,a47 timestamp,a48 timestamp,a49 timestamp,a50 timestamp,a51 timestamp,a52 timestamp,a53 timestamp,a54 timestamp,a55 timestamp,a56 timestamp,a57 timestamp,a58 timestamp,a59 timestamp,a60 timestamp,a61 timestamp,a62 timestamp,a63 timestamp,a64 timestamp,a65 timestamp,a66 timestamp,a67 timestamp,a68 timestamp,a69 timestamp,a70 timestamp,a71 timestamp,a72 timestamp,a73 timestamp,a74 timestamp,a75 timestamp,a76 timestamp,a77 timestamp,a78 timestamp,a79 timestamp,a80 timestamp,a81 timestamp,a82 timestamp,a83 timestamp,a84 timestamp,a85 timestamp,a86 timestamp,a87 timestamp,a88 timestamp,a89 timestamp,a90 timestamp,a91 timestamp,a92 timestamp,a93 timestamp,a94 timestamp,a95 timestamp,a96 timestamp,a97 timestamp,a98 timestamp,a99 timestamp,a100 timestamp 
) return varchar2 is 
    v_min timestamp(9); 
    v_max timestamp(9); 
begin 
    v_min := least(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31,a32,a33,a34,a35,a36,a37,a38,a39,a40,a41,a42,a43,a44,a45,a46,a47,a48,a49,a50,a51,a52,a53,a54,a55,a56,a57,a58,a59,a60,a61,a62,a63,a64,a65,a66,a67,a68,a69,a70,a71,a72,a73,a74,a75,a76,a77,a78,a79,a80,a81,a82,a83,a84,a85,a86,a87,a88,a89,a90,a91,a92,a93,a94,a95,a96,a97,a98,a99,a100 
     ); 
    v_max := greatest(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31,a32,a33,a34,a35,a36,a37,a38,a39,a40,a41,a42,a43,a44,a45,a46,a47,a48,a49,a50,a51,a52,a53,a54,a55,a56,a57,a58,a59,a60,a61,a62,a63,a64,a65,a66,a67,a68,a69,a70,a71,a72,a73,a74,a75,a76,a77,a78,a79,a80,a81,a82,a83,a84,a85,a86,a87,a88,a89,a90,a91,a92,a93,a94,a95,a96,a97,a98,a99,a100 
     ); 
    if v_min <> v_max then 
     return 'different'; 
    else 
     return 'the same'; 
    end if; 
end; 
/

--No matter how many times you run this, you'll always get "the same". 
select function_test(systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp) 
from dual; 




--PROCEDURE - PL/SQL context 
set serveroutput on; 

create or replace procedure procedure_test(
     a1 timestamp,a2 timestamp,a3 timestamp,a4 timestamp,a5 timestamp,a6 timestamp,a7 timestamp,a8 timestamp,a9 timestamp,a10 timestamp,a11 timestamp,a12 timestamp,a13 timestamp,a14 timestamp,a15 timestamp,a16 timestamp,a17 timestamp,a18 timestamp,a19 timestamp,a20 timestamp,a21 timestamp,a22 timestamp,a23 timestamp,a24 timestamp,a25 timestamp,a26 timestamp,a27 timestamp,a28 timestamp,a29 timestamp,a30 timestamp,a31 timestamp,a32 timestamp,a33 timestamp,a34 timestamp,a35 timestamp,a36 timestamp,a37 timestamp,a38 timestamp,a39 timestamp,a40 timestamp,a41 timestamp,a42 timestamp,a43 timestamp,a44 timestamp,a45 timestamp,a46 timestamp,a47 timestamp,a48 timestamp,a49 timestamp,a50 timestamp,a51 timestamp,a52 timestamp,a53 timestamp,a54 timestamp,a55 timestamp,a56 timestamp,a57 timestamp,a58 timestamp,a59 timestamp,a60 timestamp,a61 timestamp,a62 timestamp,a63 timestamp,a64 timestamp,a65 timestamp,a66 timestamp,a67 timestamp,a68 timestamp,a69 timestamp,a70 timestamp,a71 timestamp,a72 timestamp,a73 timestamp,a74 timestamp,a75 timestamp,a76 timestamp,a77 timestamp,a78 timestamp,a79 timestamp,a80 timestamp,a81 timestamp,a82 timestamp,a83 timestamp,a84 timestamp,a85 timestamp,a86 timestamp,a87 timestamp,a88 timestamp,a89 timestamp,a90 timestamp,a91 timestamp,a92 timestamp,a93 timestamp,a94 timestamp,a95 timestamp,a96 timestamp,a97 timestamp,a98 timestamp,a99 timestamp,a100 timestamp 
) is 
    v_min timestamp(9); 
    v_max timestamp(9); 
begin 
    v_min := least(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31,a32,a33,a34,a35,a36,a37,a38,a39,a40,a41,a42,a43,a44,a45,a46,a47,a48,a49,a50,a51,a52,a53,a54,a55,a56,a57,a58,a59,a60,a61,a62,a63,a64,a65,a66,a67,a68,a69,a70,a71,a72,a73,a74,a75,a76,a77,a78,a79,a80,a81,a82,a83,a84,a85,a86,a87,a88,a89,a90,a91,a92,a93,a94,a95,a96,a97,a98,a99,a100 
     ); 
    v_max := greatest(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31,a32,a33,a34,a35,a36,a37,a38,a39,a40,a41,a42,a43,a44,a45,a46,a47,a48,a49,a50,a51,a52,a53,a54,a55,a56,a57,a58,a59,a60,a61,a62,a63,a64,a65,a66,a67,a68,a69,a70,a71,a72,a73,a74,a75,a76,a77,a78,a79,a80,a81,a82,a83,a84,a85,a86,a87,a88,a89,a90,a91,a92,a93,a94,a95,a96,a97,a98,a99,a100 
     ); 
    if v_min <> v_max then 
     dbms_output.put_line('different'); 
    else 
     dbms_output.put_line('the same'); 
    end if; 
end; 
/

--I see "different" about 50% of the time. 
--The ratio of differences decreases as you decrease the number of parameters. 

exec procedure_test(systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp,systimestamp); 
0

Oracle, deyim ayrıştırılıp yürütüldüğünde, tüm SYSDATE örnekleri için geçerli sistem tarihini ve saatini kullanır. Yürütme öncesinde değer değiştirme gerçekleştiği için yürütme hızı bir faktör değildir.

+0

Tawman - sysdate değeri çalışma zamanında hesaplanır ve ayrıştırma zamanı değil. Oracle, yalnızca ayrıştırma sırasında geçerli bir sysdate (veya sysdate geçerli bir anahtar sözcük/komut ise) olup olmadığını kontrol eder. –

+0

Semantikleri, ancak sorunun SYSDATE'in değerlendirilmesi sırasında eşzamanlı yürütme olduğu ima edildi. Oracle, SYSDATE'nin tüm değerlerini aynı anda değiştirecek ve uzun bir alt seçimden önce değil, diğerinden vb. – tawman