今回は、Silverの「S3 開発/SQL - S3.1 SQL コマンド(INSERT文)」からの出題です。
複数行のデータを挿入する場合、2番目の方法でないと正常に実行できない。
列のデータ型が変更された時、2番目の方法でないと正常に実行できない。
テーブルに列が追加された時、2番目の方法でないと正常に実行できない。
テーブルの列の順序が変更された時、2番目の方法でないと正常に実行できない。
テーブルに制約が追加された時、2番目の方法でないと正常に実行できない。
※この例題は実際のOSS-DB技術者認定試験とは異なります。
例題公開日:2017年6月5日
INSERT文で通常使われる形式は
INSERT INTO テーブル名 [(列1, 列2…)] VALUES (値1, 値2…);
INSERT INTO テーブル名 [(列1, 列2…)] SELECT …;
の2つがあります。いずれの場合も、テーブル名の後の列リストは省略可能で、省略した場合はテーブルのすべての列を宣言時の順番に並べたものがデフォルトとして使用されます。
従って、例題のテーブルでは INSERT INTO test … としても、INSERT INTO test(id, vali, vals) … としても結果は同じです。
しかし、テーブルの定義は不変であるとは限らず、ALTER TABLEによって列が追加・削除されたり、列の名前や定義が変わったりすることもあります。
例えば、valxという列が追加された場合、1番目のINSERT文は
INSERT INTO test(id, vali, vals, valx) VALUES (1, 10, 'XXX');
と同等になってしまいます。これは列の数とデータの数がマッチしないため、エラーになります(注)。一方で2番目のINSERT文であれば正常にデータが挿入され、valxにはデフォルト値が割り当てられます。
PostgreSQLではテーブルの再作成をするなどしなければ、列の順序を変更することができませんが、一部のデータベースでは列の順序を変更することができます。1つ目のINSERT文はテーブルの最初の列がid、2つ目の列がvali、3つ目の列がvalsであることに依存しており、例えばvaliとvalsの順序が逆になるとエラーになってしまいますが、2番目のINSERT文のように列名を指定すれば、テーブル定義における列の順序が変わってもデータを挿入できます。
あるいは、valiという列を削除し、新たにvalxという列を追加する、ということもあるかもしれません。この場合、2番目のINSERT文はvali列が存在しないためエラーになりますが、1番目のINSERT文は
INSERT INTO test (id, vals, valx) VALUES (1, 10, 'XXX');
と同等になるので、valx のデータ型によっては、エラーにならないかもしれません。これは、エラーが発生しないから良いというものではなく、文字列型のvalsに整数の10を文字列に変換したデータが入ってしまうなど、予想外のデータが作られてしまうので、むしろ望ましくない状況であることが多いでしょう。
このように、データを挿入しようとする列について明確に意識する一方で、それらの列の物理的な順序や、それ以外の列の存在について意識しないで済むやり方が、一般的には望ましいと考えられています。
なお、複数行のデータを挿入する場合はどちらのINSERT文でも動作は同じです。列のデータ型が変わった場合、VALUES句で指定した値によってはエラーになりますが、これも列指定の有無とは関係ありません。テーブル制約もINSERTでの列指定の有無とは関係ありません。
従って、正解はCとDです。
(注) testテーブルにid, vali, vals, valxの4つの列がある場合、PostgreSQLでは1番目のINSERT文はエラーにならず、id, vali, valsにVALUES句で指定した値、valxにはデフォルト値が入ります。ただし、この動作はPostgreSQLの拡張で、他の多くのデータベースではエラーになります。
今回の解説について、理解できないポイントがあればどんどん質問をお寄せ下さい。
採用になった方にはLPI-Japanオリジナルの記念品を贈呈します。
※試験問題に関わるお問い合わせにつきましては、LPI-Japan事務局ではお応えできませんのでご了解ください。
© EDUCO All Rights Reserved.