助け合いフォーラム

Oracle DB

Oracle Master Silver SQL 2019(1Z0-071)
問題ID : 26745
問題を開く
PROD表の構造を確認して下さい。



PROD表にデータを追加するSQL文として、誤っているものはどれですか。

正解

INSERT INTO prod(prodid, name, category, startdate) VALUES (30, 'Pokemon', TO_DATE('05-03-25', 'RR-MM-DD'), SYSDATE);

解説

INSERT文のVALUES句では、関数を使用することもできます。関数を使用する場合は、列のデータ型と関数が返す値の型が一致しなければなりません。

選択肢のSQL文では、SYSDATE、TO_DATE、TO_NUMBERなどの関数を使用してデータを追加しています。
そのうち、TO_DATE関数の結果をCATEGORY列に登録するSQL文がありますが、CATEGORY列はNUMBER型の列であるため、DATE型の値を登録できません。そのためエラーとなります。

以上より、
・INSERT INTO prod(prodid, name, category, startdate) VALUES (30, 'Pokemon', TO_DATE('05-03-25', 'RR-MM-DD'), SYSDATE);
が正解となります。

正解のSQL文の実行結果は次のようになります。



ちなみに、次のSQL文ではVARCHAR2型のNAME列にTO_NUMBER関数の結果(NUMBER型)を登録していますが、暗黙的データ変換により、NUMBER型がVARCHAR2型に変換されて登録されるため、エラーとはなりません。


 
SQLを表示
INSERT INTO prod(prodid, name, category, startdate)
 VALUES (30, TO_NUMBER('$500,000', '$999,999'), 50, SYSDATE);

参考

表にデータを追加するにはINSERT文を使用します。

 INSERT INTO 表名[(列名1 [, 列名2 ...])] VALUES (値1 [, 値2 ...]);

 
 
SQLを表示
INSERT INTO prod(prodid, name, category, startdate, enddate)
 VALUES (20, 'SuperMan', 20, '2001-02-15', '2010-10-30');


列名と値は1対1で指定します。VALUES句の値1が列名1の列に格納されます。指定した列名の個数と値の個数が一致しない場合はエラーとなります。また、追加する値は列に定義されているデータ型と一致していなければなりません。
なお、列名を省略する場合は、表に定義されている全ての列の値を指定しなければならず、省略はできません。VALUES句には、表内の列の構成と同じ順序で値を指定します。

[列名を明示的に指定]
 列名を指定する場合は、指定する列の個数とVALUES句に指定する値の個数を同数にしなければなりません。また、表に定義されていない列名を指定するとエラーとなります。


 
SQLを表示
INSERT INTO prod(prodid, name, category, startdate, enddate)
 VALUES (20, 'SuperMan', 20, '2001-02-15', '2010-10-30');


 列名を明示的に指定する場合、列名の並びは任意です(表内の列の構成と同じ並びにする必要はありません)。
 また、NOT NULL制約が定義されている列以外の列名は省略できます。省略された列の値にはデフォルトでNULL値が入ります。

 
 
SQLを表示
INSERT INTO prod(category, name, prodid)
 VALUES (20, 'SuperMan', 20);


[列名の指定を省略]
 列名の指定を省略した場合は、表内の列の構成と同じ順序で値を指定しなければなりません。表内の列の構成はDESCコマンドで確認できます。

 
 
SQLを表示
DESC prod;


 
 
SQLを表示
INSERT INTO prod
 VALUES (20, 'SuperMan', 20, '2001-02-15', '2010-10-30');


また、副問合せを使用してデータの追加も行えます。
副問合せを使用してデータを追加するには、次のように記述します。

 INSERT INTO 表名1 [(列名 [, 列名...])]
  (SELECT 列名 [, 列名...] FROM 表名2 [WHERE 条件]);

なお、副問合せの部分を囲む()は必須ではありません。以下の実行例では省略しています。

 
 
SQLを表示
INSERT INTO prod2 (prodid, name, category, startdate, enddate)
 SELECT prodid, name, category, startdate, enddate
 FROM prod
 WHERE category < 50;


副問合せを使用したINSERT文では、VALUES句は使用できません。
※1つの列の1行のみ返す副問合せは、INSERT文のVALUES句の中でも使用できます。この後に解説します。
INSERT句に指定する列のリストと、副問合せのSELECT句に指定する列のリストは同数かつ同じ順番で指定します。
また、INSERT句の列のリストは省略可能ですが、省略する場合、副問合せのSELECT句の列のリストには、データを追加する表のすべての列を表の列構成の順番で指定しなければなりません(表の列構成はDESCコマンドで確認できます)。


 
SQLを表示
DESC prod2;



 
SQLを表示
INSERT INTO prod2
 SELECT name, category, prodid, startdate, enddate
 FROM prod;


1つの列の1行のみ返す副問合せであれば、INSERT文のVALUES句の中でも使用できます。
次のSQL文では2列目と3列目にそれぞれ1つの値を返す副問合せを使用しているため正常に実行できます。副問合せが複数の行や列を返す場合はエラーとなります。


SQLを表示
INSERT INTO prod2
VALUES (1, (SELECT name FROM prod WHERE prodid = 1),
(SELECT category FROM prod WHERE prodid = 1), SYSDATE, NULL);
上に戻る

VATCHAR2型にNUMBER型を追加できるのでしょうか

投稿日 2023/01/14

初歩的な質問になります。
解説を読んで、INSERT INTO prod(prodid, name, category, startdate) VALUES (30, 'Pokemon', TO_DATE('05-03-25', 'RR-MM-DD'), SYSDATE); が誤りなのは理解できましたが、
INSERT INTO prod(prodid, name, category, startdate) VALUES (30, TO_NUMBER('$500,000', '$999,999'), 50, SYSDATE);は、name(VATCHAR2型)に対して、TO_NUMBER('$500,000', '$999,999') を追加しています。
これは可能なのでしょうか。
理由を教えてください。

2023/01/17 09:46

解説にあるように暗黙的なデータ変換がされているためです。

ちなみに、次のSQL文ではVARCHAR2型のNAME列にTO_NUMBER関数の結果(NUMBER型)を登録していますが、暗黙的データ変換により、NUMBER型がVARCHAR2型に変換されて登録されるため、エラーとはなりません。

暗黙的なデータ変換については問題ID:26474の参考に書いてあります。


コメント

j jyochan

2023/01/21 10:16

ご回答ありがとうございます。 調べましたところ、そもそも暗黙的な型変換に規則があることを理解できていませんでした。 ありがとうございます。

この返信に対して
コメントを記入できます

この投稿に対して返信しませんか?