• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:SQL Server(MSDE2000) : ALTER TABLE)

SQL Server(MSDE2000)でのALTER TABLEでの列追加とUPDATEの問題

jamshid6の回答

  • ベストアンサー
  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.1

SQL文を実行するときには、まずコンパイルして、実行プランを立て、それから実行するというステップがあるという点をご理解ください。 私の理解ではその時点でTEST_TABLEが存在しないかぎり、CREATE~INSERT~ALTER~UPDATEはエラーにならないはずです。 ただし、"既にTEST_TABLE(ALTER前)がある状態"で4行一緒に実行すると、 列名 'TEST_FIELD3' は無効です。 と返されますので、それと混同されているのではないかなと推測します。 (CREATE TABLE文は既にテーブルが存在していても、コンパイル時にはエラーにはならず、実行時にエラーになるため。 一方、UPDATE文は後述の通り、コンパイル時にエラーになります) CREATE~INSERTが成功したあとで、ALTER~UPDATEが失敗するのは、実行に失敗しているのではなく、コンパイルに失敗しているということです。 (「実行して失敗し、ロールバックされた」わけではありません) 既にそのテーブルが存在する場合、SQL Serverはコンパイル時にテーブルのカラムをチェックします。 この時点のテーブルにはTEST_FIELD3はありませんので、コンパイルエラーになります。 一方、実行時にそのテーブルが存在しない場合は、遅延解決と言ってコンパイル時にはカラムがチェックされません。 (実行時に条件がそろっていなければエラーとなります) 従って、CREATE~INSERT~ALTER~UPDATEと一気に実行すると、チェックすべきテーブルがまだ存在していないため、エラーにはなりません。 もう一つ注意すべきなのは、キャッシュの存在です。 一度「UPDATE TEST_TABLE SET TEST_FIELD3 = 3」が成功すると、このクエリはプランキャッシュというところにキャッシュされ、必要に応じて再利用されます。 その状態でテーブルをDROPし、CREATE~INSERTを行い、ALTER~UPDATEを行うと、キャッシュされた情報を参照してTEST_FIELD3は存在すると判断され、コンパイルが通りますので、今度はエラーになりません。 ご参考までに。

hachiban022
質問者

お礼

早速の回答、ありがとうございました。 頂いた回答の中の「コンパイル→実行プラン立て→実行」というステップのお話からヒントを得て、問題を解決する方法が見つかりました。 まず、プランキャッシュの存在の事が全く頭に無かったため、UPDATE を実行する時点で、オプティマイザがまだ「TEST_FIELD3」の存在に気が付いていないため(直前で ALTER TABLE で追加される事なんて、コンパイル時点でオプティマイザが知る由もありませんよね)、当たり前のようにエラーになる事に気が付いていませんでした。 しかも、完全に DROP TABLE した状態からでは、提示した4行の実行ではエラーが発生せず、コンパイルが通ってしまう事も、当方のテスト不足で、気が付いていませんでした。 ご指摘を頂いたポイントを参考にし、解決方法を模索した結果、以下のような方法で、当方の問題が解決できた事をご報告します。 まず、 -------- CREATE TABLE TEST_TABLE ( TEST_FIELD1 SMALLINT, TEST_FIELD2 SMALLINT) INSERT INTO TEST_TABLE VALUES( 1, 2 ) -------- を先に実行しておいた状態で、 -------- DECLARE @SQLSTR VARCHAR(64) SET @SQLSTR = 'UPDATE TEST_TABLE SET TEST_FIELD3 = 3' ALTER TABLE TEST_TABLE ADD TEST_FIELD3 SMALLINT EXEC (@SQLSTR) -------- というSQL文を実行します。 もうお気付きかと思いますが、コンパイル時にエラーとなってしまっていた UPDATE 文を、文中で動的に組み立てた事にしてしまい、EXECで実行した訳です。 「動的に組み立てられたSQLを実行する際は、実行時にコンパイルされる」という特性を利用してみました。 これによって、当方の問題を解決する事ができました。 ご回答頂いた内容が、かなりのヒントになりました。非常に助かりました。 それと、今回の指摘を受けて思った事は、プランキャッシュの影響を受けるようなSQL文をデバッグする際には、実行毎に、SQLServerのサービスを停止・再開させて強制的にプランキャッシュを破棄した方が、実行結果がプランキャッシュの影響を受けずに済むという点です。ここについては、今後も注意したいと思います。 当然ながら、ベストアンサーとさせて頂きます。 ありがとうございました!

関連するQ&A

  • SQLServer2000:SQL文の記述について

    いつもお世話になっております。 SQLServer2000でSQL文で素朴な疑問なのですが、 質問が3点ございます。 1:列の追加 ALTER TABLE 文で、フィールドを追加する際に、 "]"(かぎ括弧閉じ) がフィールド名に存在する場合、どのように記述すればよいのでしょうか。 2:レコードの追加 INSERT 文で追加するレコードの文字列中に "'" (シングルクオテーション) が値に存在する場合、どのように記述すればよいのでしょうか。 3:列の削除 ALTER TABLE でフィールドを削除する際に、 "#"(シャープ) がフィールド名の先頭に存在する場合、どのように記述すればよいのでしょうか。 ご存知の方がいらっしゃいましたら、 ご回答をよろしくお願いいたします。

  • SQLでフィールドの順番を変更したい

    お世話になっております。 ORACLEを使用しております。 既存のテーブルに新しいフィールドをSQL文にて ALTER TABLE TEST_MST ADD TEST_CD VARCHAR2(2); と言う風に、SQL*PLUSにて追加いたしました。 これを参照しますと、 追加したフィールドがテーブルの一番最後のフィールドに 追加されているのですが、 フィールドの順番を変更したいと考えております。 SQL文にて何か方法はございませんでしょうか。 ご返答を宜しくお願い致します。

  • alter tableすると、処理が止まってしまい困っています

    表題の件で質問させて下さい。 以前までは特に問題なく、alter tableなどで列を追加出来ていたのですが、ここ最近、データ量が増えてきたためか、列追加にすごく時間がかかってしまっています。 それが原因なのかはわからないのですが、alter tableで列を追加すると、処理が止まってしまい、プロセスをkillして、とりあえず対処する・・・ と言うような対応が続いています。 調べたところ、alter table はテーブルロックがかかってしまうらしいのですが、これは begin でトランザクションを開始させても特に意味はないのでしょうか? いろいろと調べてはいるのですが、基本的な事は見つかるのですが、運用する時にどういった注意点があるか等が今いち、調べ切れませんでしたので、どんな運用をしていけばいいのかご教授して頂けると助かります。 宜しくお願いいたします。

  • mysqlのalter table中のロックについてです。

    mysqlのalter table中のロックについてです。 下記のように、alterでテーブルを再構築中に同じテーブルにinsertが実行された場合、 接続Bのinsertはブロックされるかと思うのですが、テーブルが大きくalterに時間がかかる場合、 タイムアウトなどは発生するのでしょうか。 またもし発生する場合、タイムアウト値の設定などの確認方法はあるのでしょうか。 1.接続A  alter table table1 add columnB int(11) ; 2.接続B(接続Aのalter実行中)  insert into table1(columnA) values('aaa');

    • ベストアンサー
    • MySQL
  • AccessのテーブルをSQL文にしたい

    urizakaです。 さて、今回質問したいのは、Accessで作ったテーブルをSQL文にする方法です。 具体的には、ACCESSで作ったテーブルを、 CREATE TABLE ××× (              ) INSERT… というSQL文にしたいのですが、これはどうすれば良いのでしょうか? すみませんが、教えてください。            

  • Oracle テーブルの列削除

    タイトルの通りテーブル(test)の列(retu)を削除したいのですが・・・ Sql*pLUS画面 SQL> alter table test drop(retu); ←この用に入力 alter table test drop(retu) * エラー行: 1: エラーが発生しました。 ORA-00905: キーワードがありません。 となってしまい列を削除できません。 なにか構文の間違いでしょうか?

  • SQL Server 2005 Express で CDate()関数の代替?

    SQL Server 2005 Expressで Create table Test( date_test datetime ); に追記する場合cdateを使いたいのですが Insert文で 「insert into test(date_test) values(CDate('1999/09/14 23:23:00'))」 とすると 「'CDate' は 組み込み関数名 として認識されません。」っと出てしまいます 他の関数名に変わっているのでしょうか??

  • SQL*Plusの実行結果にSQL文も残したいです

    SQL*Plusをスクリプトファイルを使って実行した際、実行SQLの出力はできないものでしょうか? 以下のようにスクリプトファイルを使ってSQL*Plusを実行し、その結果をログファイルへ 残しています。この時ログファイルには、実行結果は出力されるのですが、実行SQLは 出力されないようです。なんとかして実行SQLと、実行結果を作業ログとして残したいと 考えているのですが、何かよい方法はないものでしょうか? [ama@rh01 test]$ sqlplus scott/tiger@orcl @test01.sql > test01.log ■環境 Red Hat Linux 4 Oracle10g ■以下test01.sqlの中身です。 ---ここから-------------- create table ex01 ( c1 number, c2 varchar2(10), c3 varchar2(40) ); insert into ex01(c1,c2,c3) values(1,'AA1','BBB1'); select * from ex01; update ex01 set c2='aa1' where c1 =1; select * from ex01; exit; ---ここまで-------------- ■以下ログファイルの中身です。 ---ここから------------------ [ama@rh01 test]$ cat test01.log 省略 With the Partitioning, OLAP and Data Mining options に接続されました。                       ←ここにcreate文を出力したいです。 表が作成されました。                       ←ここにinsert文を出力したいです。 1行が作成されました。                       ←ここにselect文を出力したいです。 C1       C2   C3 ---------- ---------- ---------------------------------------- 1        AA1   BBB1                       ←ここにupdate文を出力したいです。 1行が更新されました。                       ←ここにselect文を出力したいです。 C1      C2 C3 ---------- ---------- ---------------------------------------- 1 aa1 BBB1 Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production With the Partitioning, OLAP and Data Mining optionsとの接続が切断されました。 [ama@rh01 test]$ -------------------ここまで--------------- どなたか良いアドバイスいただけたらと思います。 どうぞよろしくお願いします。

  • MSDEについて

    お世話になります。MSDE初心者です。 MSDE(ACCESS)を使用しています。 テーブルを作成するのに、バッチファイルで 作成する必要があるのですが、 作り方がわかりません。 コマンドプロンプトでバッチファイルを実行すると MSDEにログインをして「1>」まで表示されるのですが、 CREATE文まで発動しません。 内容としては以下のとおりになってます。 [ファイル名] db.bat [ファイルの内容] cd c:\ osql -U id -P pass use sampledb CREATE TABLE T_ORDER( 以下クリエイト文) 以上となってます。 また、クリエイト文を外部ファイル(create.sql)として cd c:\ osql -U id -P pass -Q C:\create.sqlで実行すると 「行1:'\'の近くに無効な構文があります」 と表示され、実行できません。 なにぶん初心者なので、ご説明に至らない点もあると思いますが、よろしくお願いします。

  • Access2003_ALTER TABLE構文

    Accessのテーブルにフィールドを追加したくSQLで命令文を書いています。 1.[T_テーブル1]というテーブルに[フィールドA]というフィールドを データ型:数値型 フィールドサイズ:単精度浮動小数点型 小数点以下表示桁数:2位まで表示 で追加したいです。 →ALTER TABLE T_テーブル1 ADD COLUMN フィールドA FLOAT4 これに少数点以下桁数を設定するにはどう書けばよろしいでしょうか? 2.[T_テーブル1]というテーブルに[フィールドB]というフィールドを データ型:数値型 フィールドサイズ:長整数型 で追加しました。 →ALTER TABLE T_テーブル1 ADD COLUMN フィールドA INT 「説明」の箇所に説明書きも入れたいのですがここでの設定は可能でしょうか? 以上2点につきましてご指導頂きたくよろしくお願い致します。