Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
806 views
in Technique[技术] by (71.8m points)

oracle - sysdate difference

There are such calls

some_proc(sysdate, sysdate);
select some_func(sysdate, sysdate) from dual

I wonder if there are any possibility that two sysdate calls will give different values? Does sysdate not change only due to speed of execution?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

some_proc(sysdate, sysdate); - sysdate will NOT always be the same when used in a PL/SQL statement

select some_func(sysdate, sysdate) from dual; - sysdate will always be the same when used in a SQL statement (even if that SQL statement is calling PL/SQL)

From the Statement-Level Read Consistency section of the Concepts guide: "Oracle always enforces statement-level read consistency. This guarantees that all the data returned by a single query comes from a single point in time—the time that the query began."

That page kind of implies that the same is not true of a pure PL/SQL function.

We can demonstrate this by creating a large function (SQL context) and procedure (PL/SQL context) that accept many timestamp parameters, then compare the input parameters for any differences. I used timestamps instead of dates because they should work the same way with regards to consistency, but timestamp(9) is a billion times more likely to change than a date. (Roughly - there are probably lots of rounding and internal clock details I'm unaware of that make this more complicated.)

--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);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...