2009-02-23 9 views
9

既存の表に列を追加するとき、Oracleは常に列を表の最後に配置します。 Oracleに表のどこに表示されるべきかをOracleに伝えることは可能ですか?もしそうなら、どうですか?Oracleでは、テーブルに列を「挿入」することは可能ですか?

+2

「注文はなぜ問題なのですか?もちろん、誰かにその物を読もうとすることは重要です。注文すると分かりやすくなります。 – tdugan

+0

@tdugan - 物を読もうとする人は、好きなように列を並べ替えることができます。 –

+0

@JeffreyKemp:はい、彼らはそれを何度も見て、毎回注文することができます.... – maaartinus

答えて

1

私はそう信じられません - SQL Serverではこれらを許可していません。私はいつも使用する必要があります方法は次のとおりです。

  1. (追加の列を含む右に見える新しいテーブルを作成します
  2. トランザクションを開始
  3. は、古いテーブルからすべてのデータを選択し、新しいものへ
  4. ドロップ古いテーブル
  5. は、トランザクションをコミットし、新しいテーブル
  6. の名前を変更します。

ないエクサかなり美しいですが、仕事は終わります。

+1

SQL Serverでは、テーブルデザイナを使用するときに、テーブルに列を配置できます。これは、現在のテーブルにデータと行がある場合でも(Nullableに設定された列を持つか、デフォルト値を設定している限り)、 – TheTXI

+0

でも十分ですが、バックエンドではこの正確なスクリプトを実行します。表の最後に列を追加しても、これが行われます。そのため、デザイナーによる表の変更は、実際に実行するまでに時間がかかります。 – SqlRyan

+1

手順2.と6.は冗長です。スキーマを変更するすべてのDDL文は、新しい暗黙のトランザクションを強制します。構造を変更するときに、未処理のDML変更を行うことはできません。 – Khb

2

私は正常にやっていることは次のとおりです。

  1. は、古いテーブルの名前を変更します。
  2. 正しい順序で列を含む新しいテーブルを作成します。
  3. 新しいテーブルの制約を作成します。
  4. データを挿入する:new_tableに挿入する*名前を変更したテーブルから*を選択します。
2

これは、一時テーブルにデータを保存したり、テーブルを削除したり、再作成したりせずに行うことはできません。一方、列がどこにあるかは重要ではありません。 select文で取得する列を指定する限り、必要なときに並べ替えることができます。

0

いいえ、 "ALTER TABLE"ステートメントでは不可能です。ただし、別の名前を使用していても、現在のテーブルと同じ定義で新しいテーブルを作成することができます。データを新しいテーブルにコピーします。古いテーブルを削除します。新しいテーブルの名前を古いテーブル名と一致するように変更します。

トム・カイトが検討する「ページサイズ」がある場合を除き、テーブル内の列の位置は(重要でないあるべき、またはOracleが実際にデータを格納するために使用するものは何でもAskTom link text

8

でこの記事を持っています)。消費者にとってより重要なことは、結果がどのように呼び出されるか、すなわちSelectステートメントである。

5

YOUR_ORIGINAL_TABLEの名前をYOUR_NEW_TABLEに変更します。

列1、列2、NEW_COLUMN、YOUR_NEW_TABLEからCOLUMN3 を選択するようにテーブルYOUR_ORIGINAL_TABLE NOLOGGING/*または回復不能*/ を作成します。

ドロップテーブルYOUR_NEW_TABLE;

選択* From YOUR_ORIGINAL_TABLE; < < < < <これで、テーブルの中央に新しい列が表示されます。

しかし、なぜあなたはそれをしたいですか?それは不公平だと思われる。カラムの順序が重要である場合は、カラムの順序付けを想定して名前付きカラムリストを使用しないでください。

+1

それ以上の美しさがあります。格納されるデータは、データの途中でフィールドを追加した外部ソース(XML)からのものです。だから、私たちのテーブルはXML以外のすべての列のXMLと同じ順序になっています。 – larf311

2

なぜ列の順序が重要になるのですか? select文でいつでも変更できますか?

テーブルの最後に新しい列を追加することに利点があります。単純に "SELECT *"を実行してから順番にフィールドを解析するコードがある場合、最後に新しい列を追加することで古いコードを破ることはありません。テーブルの中央に新しい列を追加すると、古いコードが壊れている可能性があります。

ある職場では、「SELECT * 'をしないでください」というスーパーアナルのDBAがいました。彼はあなたが常に特定の分野を書き出すと主張しました。

+1

そしてあなたのdbaはそれをするのに間違いなく正しいです。 Select *は驚異的な量のものを壊すことがあります。結合があれば、必要以上に多くのデータフィールドが返されます(結合フィールドが複製される)ので、貴重なデータベースとネットワークリソースが浪費されます。 – HLGEM

2

テーブルの下には、テーブルレコードのすべてのデータが結合されていることに注意してください。テーブルの末尾にカラムを追加すると、テーブルのメタデータが変更されます。 途中に列を追加するには、その列に適切な値(またはマーカー)を追加するために、その表のすべてのレコードを書き直す必要があります。場合によっては、レコードがブロック上でより多くのスペースを占め、一部のレコードを移行する必要があるかもしれません。 要するに、実際のサイズのテーブルではVAST量のIOエフォートです。

あなたは常に優先順序で列を持つテーブルの上にビューを作成し、テーブル

-1

1)[OK]をので、あなたが直接それを行うことはできませんと同じようにDML文でそのビューを使用することができます。私たちは同じことを言ってポストの後にポストを必要としないのですか?

2)表内の列の順序は技術的に重要ではありません。しかし、それはポイントではない、元の質問は単にあなたができるかどうかを尋ねた。他の人の必要条件をすべて知っているとは思わないでください。おそらく、100個の列を持つテーブルがあります。現在、「SELECT * ...」を使用して照会されていますが、「*」を100個の列名に置き換えるだけで、あるいは、SQL Developerを使用してスキーマをブラウズするときに、関連するフィールドを隣り合わせに持つことができます。おそらく彼らは論理的に、最初の近くのどこかにあるべきであるときに100列のリストの終わりを見ることを知らない非技術的なスタッフを扱っているでしょう。

正直な質問をして「それをしてはいけない」という答えを得るよりも、刺激的なことはありません。それは私の仕事であり、あなたのものではありません!私の仕事のやり方を教えてください。できるだけ手伝ってください。ありがとう!

[OK] ...おっとりして申し訳ありません。今、www.orafaq.comでこの回避策を提案しています。

まず、あなたがすでに実行したとします

を、表tab1(COL1 NUMBER)を作成します。

ここで、「col2」という名前の列を追加したいとしますが、「SELECT * FROM tbl1;」を実行するときには「col2」、「col1」を並べる必要があります。

提案が実行される:

ALTER表TAB1のADD(COL2 DATE)。 名前変更tab1 TO tab1_old; テーブルの作成tab1 AS SELECT 0 AS col1、col1 AS col2 FROM tab1_old;

私はこれが信じられないほど誤解を招くものであることを発見しました。まず、 "col1"に0を書き込んでいます。もしデータがあれば、それを失うことになります。次に、実際には「col1」の名前を「col2」に変更していますが、これについては言及していません。だから、ここに私の例では、うまくいけば、それは少し明確だ、だ:

では、次のステートメントで作成されたテーブルがあるとします。

はTABLEユーザー(FIRST_NAMEのVARCHAR(25)、LAST_NAMEのVARCHAR(25))を作成します。

ここで、first_nameとlast_nameの間にmiddle_nameを挿入するとします。ここには1つの方法があります:

ALTER TABLEユーザーADD middle_name varchar(25); ユーザーをRENAMEからusers_tmpに変更します。 CREATE TABLEのユーザーAS SELECT first_name、middle_name、last_name FROM users_tmp; /*そしてよい測定のために... */ DROP TABLE testusers_tmp;

middle_nameは、デフォルトでNULL(ALTER TABLEステートメントによって暗示されます)になります。別の方法として、CREATE TABLE文で次のように別のデフォルト値を設定することもできます。

CREATE TABLEユーザAS SELECT first_name、 'some default value' AS middle_name、last_name FROM users_tmp;

デフォルトのsysdateを持つ日付フィールドを追加する場合、このトリックは便利ですが、すべての既存のレコードに他の(たとえばそれより前の)日付値を追加すると便利です。

関連する問題