1

テーブル my_table は次のとおりです。

CREATE TABLE MY_TABLE(
ID        NUMBER  NOT NULL,
MY_DATE   DATE    NOT NULL);

次のクエリを入力します。

select sysdate from dual

結果は次のとおりです。

10-MAG-12 21:22:32

mag = may であることに注意してください。

ここで、次のクエリを入力すると:

select *
from my_table
where my_date <= sysdate

結果は次のとおりです。

9918    10-MAG-12 20:00:00
9915    10-MAG-12 21:00:00
9952    10-MAG-12 22:00:00
9951    10-MAG-12 23:00:00

my_table には、これら 4 つのレコードしかないことに注意してください。最初と 2 番目のレコードだけではなく、すべてのレコードが表示されるのはなぜですか? ありがとう。

私はOracle SQL Developerを使用しています。

編集: PL/SQL でレコードを挿入するときは、次のように入力することに注意してください。

nCount NUMBER;
myDate DATE;
stringDate VARCHAR2(255);
BEGIN
nCount := 0;
stringDate := substr(to_char(trunc(sysdate)),0,9);
myDate := to_date(stringDate || ' 20:00:00','dd-mm-yyyy hh24:mi:ss');
for t in (a cursor) loop
   insert into MY_TABLE(ID,MY_DATE)
   values (9918,myDate+(nCount/1440));
   nCount := nCount + 60;
end loop;
END;
4

1 に答える 1

3

あなたのテーブルに保存されているデータの年は 2012 ではないと思われます。おそらく 0012 年 (2000 年前) です。

クエリを実行すると何が表示されますか

SELECT id, to_char( my_date, 'dd-mm-yyyy hh24:mi:ss' )
  FROM my_table

年は 2012 ではなく 0012 になると予想しています。その理由は、データを挿入するために使用しているコードが、明示的な書式マスクを使用せずに日付を文字列に誤って変換し、文字列を日付に戻すためです。セッションのNLS_DATE_FORMAT. 一般に、日付を文字列に変換して日付に戻す場合は、おそらく何か間違ったことをしている可能性があります。単純に日付操作を行うようにコードを変更すると、より効率的で堅牢になり、エラーが発生しにくくなります。

DECLARE
  nCount NUMBER;
  myDate DATE;
BEGIN
  nCount := 0;
  myDate := trunc(sysdate) + interval '20' hour;
  for t in (a cursor) loop
     insert into MY_TABLE(ID,MY_DATE)
       values (9918,myDate+(nCount/1440));
     nCount := nCount + 60;
  end loop;
END;

元のコードがうまくいかない理由を説明する

stringDate := substr(to_char(trunc(sysdate)),0,9);

これはSYSDATE、現在の日の午前 0 時に切り捨てられます。ここまでは順調ですね。次に、TO_CHAR明示的な書式マスクなしで呼び出します。これにより、Oracle はセッションのNLS_DATE_FORMAT. セッションがNLS_DATE_FORMATたまたま「dd-mon-rr hh24:mi:ss」である場合、投稿したクエリ結果に基づいて推測していますが、これは文字列に 2 桁の年があることを意味します。あなたSUBSTRは、出力の年が 2 桁であると想定しているようです (別の がある場合NLS_DATE_FORMATSUBSTR2012 年から 12 を切り取って 20 年だけにするなど、さまざまなバグが発生する可能性があります)。

myDate := to_date(stringDate || ' 20:00:00','dd-mm-yyyy hh24:mi:ss');

stringDateのようなものであると仮定すると10-MAG-12、この次の行は文字列10-MAG-12 20:00:00を生成し、書式マスクを使用して日付に変換しようとしますdd-mm-yyyy hh24:mi:ss。これは、文字列の年が 4 桁であると想定しているため、2 桁しか見つからない場合は、2012 年ではなく 12 年を意味していると想定します。

于 2012-05-10T17:25:51.647 に答える