それが問題です。
OTNフォーラムの最近の投稿では、ステートメントターミネータとしてセミコロンとスラッシュを使用することについて質問されました。私はこのトピックについて4年以上前に開発チームのために書いた記事をちりばめました。この記事は良いレビューを受け、必要に応じてOTNフォーラムで利用できます。ブログにも投稿しようと思いました。記事は次のとおりです:
スラッシュまたはスラッシュなし
ブライアン・ピースランド
当社では、デプロイされるSQLスクリプトはOracleのSQL * Plusコマンドラインユーティリティで実行されますが、多くの開発者はPL /SQLDeveloperやSQLDeveloperなどのGUIツールを使用します。スラッシュは、PL /SQLDeveloperまたはSQLDeveloperでは必要のないSQL*Plusへの何かを意味します。そのため、SQLスクリプトにスラッシュを含める必要があるかどうかを知るのは混乱を招く可能性があります。うまくいけば、このセクションでは、スラッシュが何をするのか、いつ使用するのか、いつ使用しないのかが明らかになるでしょう。セミコロンターミネータほとんどのSQLステートメントでは、セミコロンがステートメントターミネータです。たとえば、SQL*Plusで実行される次の単純なSQLステートメントについて考えてみます。
SQL>デュアルからsysdateを選択します;
SYSDATE
———
2012年6月18日
SQL * Plusはセミコロンを認識すると、SQLステートメントの終わりに到達したことを認識し、コマンドを実行できるようになります。
SQL*Plusバッファ
SQL*Plusにコマンド用のバッファがあることに気付いていないかもしれません。 「list」の「l」キーを押すと、現在セッションのバッファにあるコマンドを確認できます。
SQL> l
1*デュアルからsysdateを選択
当然のことながら、実行したばかりのコマンドがあります。次に、別のSQLステートメントを実行しました。バッファは次のようになります。
SQL> l
1 sysdate、user
を選択します2*デュアルから
ご覧のとおり、セッションのSQL*Plusバッファに2行あります。
スラッシュ=バッファの実行
スラッシュについて理解するための最初のルールは、SQL * Plusにとって、スラッシュはバッファの内容を実行することを意味するということです。この概念を説明するために、SQLステートメントを実行し、数秒待ってから、同じSQLステートメントを再度実行しますが、バッファーを実行するだけです。
SQL>デュアルからto_char(sysdate、’MM / DD / YYYY HH24:MI:SS’)を選択します;
TO_CHAR(SYSDATE、’MM
——————-
2012年6月18日15:20:40
SQL> /
TO_CHAR(SYSDATE、’MM
——————-
2012年6月18日15:21:17
SQL> /
TO_CHAR(SYSDATE、’MM
——————-
2012年6月18日15:21:50
2回目と3回目に行ったのは、「/」と入力してEnterキーを押すだけで、SQL*Plusは毎回コマンドバッファの内容を実行したことがわかります。
PL/SQLブロック
セミコロンステートメントターミネータは、OracleがOracleバージョン7でPL / SQLを導入するまで、それ自体で問題なく機能していました。問題は、PL / SQLブロックに複数のセミコロンを付けて、そのブロックを構成する個々のステートメントを終了できることです。何もしないこの非常に単純なPL/SQLブロックについて考えてみます。
SQL>開始
2 null;
3 null;
4終了;
5
2行目と3行目には、それぞれセミコロンで終了する完全に有効なステートメントが含まれています。 4行目には、PL/SQLブロックの終わりを示すENDキーワードがあります。ネストされたBEGIN/ENDペアが許可されていない場合、SQL*Plusが「END;」を認識するたびにPL / SQLブロックの終わりに到達したことはわかりますが、ネストされたBEGIN / ENDペアが許可されているため、以下は完全に合法で有効です。
SQL>開始
2開始
3 null;
4終了;
5 null;
6終了;
7
上記から、「END」を探しているだけであることがわかります。 SQL * Plusは4行目以降のブロックを実行しようとしたため、十分ではありません。では、Oracleは、PL/SQLブロックを実行する準備ができたことをどのように示したのでしょうか。答えは、すでにご存知かもしれませんが、スラッシュを使用することです。理解すべき2番目のルールは、PL / SQLブロックを終了するためにスラッシュを使用するときにすべてのスラッシュが実行することは、SQL*Plusにバッファ内にあるものを実行するように指示することです。これは、Oracle7用にPL/SQLが作成される前から変更されていません。次のサンプルを検討してください。
SQL>開始
2 null;
3終了;
4 /
PL/SQLプロシージャが正常に完了しました。
SQL> l
1開始
2null;
3*終了;
4行目で、スラッシュを入力してPL/SQLブロックを実行しました。私のブロックが正常に完了したことがわかります。戻ってコマンドバッファの内容を見ると、スラッシュ以外のすべてが含まれていることがわかります。スラッシュはコマンドバッファの一部ではありません。そこで、別のPL/SQLブロックを実行します。
SQL>開始
2 dbms_output.put_line(‘今日は‘ || to_char(sysdate、’MM / DD / YYYY HH24:MI:SS’));
3終了;
4 /
今日は2012年6月18日15:39:32
PL/SQLプロシージャが正常に完了しました。
スラッシュはSQL*Plusに、そのバッファにあるものを実行するように指示し、結果が表示されます。次に、スラッシュだけをもう一度入力すると、PL/SQLブロックが再度実行されるのがわかります。
SQL> /
今日は2012年6月18日15:40:42
PL/SQLプロシージャが正常に完了しました。
PL / SQLブロックは現在コマンド・バッファにあるため、新たに入力する必要はありませんでした。
PL/SQLおよびSQLDeveloperとPL/SQLブロック
ほとんどの開発者にとっての最大の問題は、PL/SQL開発者とSQL開発者がスラッシュを使用する必要がないことです。なんで?実行(F8)またはスクリプトの実行(F5)を押して、PL/SQLブロックを実行できるためです。 PL / SQL Developerは、F8を押した瞬間に、実行するPL/SQLブロックを送信しようとしていることを認識しています。この場合、PL / SQL DeveloperのF8は、SQL*Plusのスラッシュと同じジョブを実行します。同様に、SQLDeveloperのF5の場合。
私の会社の問題は、コードを本番環境にデプロイするチームがPL /SQLDeveloperまたはSQLDeveloperでコードをデプロイしないことです。コマンドラインツールを使用すると複数の実行のスクリプトを作成する方が簡単なため、SQL*Plusを使用します。多くの開発者は、PL / SQLブロックのスラッシュを必要としないためにスクリプトに含めないという間違いを犯しますが、そのコードセクションをSQLスクリプトにデプロイする場合は、各PLの最後にスラッシュが必要です。 /SQLブロック。
スラッシュを使用しない場合
スラッシュを使用する時期と理由を見てきましたが、使用するのが悪いのはいつですか。知っておくべき3番目のルールは、特にそのスラッシュがDMLステートメント(INSERT、UPDATE、またはDELETE)の直後に続く場合は、単一のSQL文(PL / SQLブロック内ではない)の後にスラッシュを使用するのは悪いことです。スクリプトに次のものが含まれている場合:
デュアルからsysdateを選択します;
/
次に、スクリプトで通常行うことを意図していない「二重出力」を取得します。上記のスクリプトのように2行ではなく、実際には1行だけを返したいのです。
SQL>デュアルからsysdateを選択します;
SYSDATE
———
2012年6月18日
SQL>/
SYSDATE
———
2012年6月18日
DMLステートメントの後にスラッシュを使用すると、そのステートメントが2回実行されるため、さらに悪化します。次のスクリプトについて考えてみます。
test_tab値に挿入します(10);
/
上記の2行をスクリプトで実行すると、セミコロンステートメントターミネータが原因でSQL * Plusが1回実行し、次にスラッシュがSQL * Plusに、コマンドバッファ。上記の2行のスクリプトを実行すると、次の出力が得られます。
SQL> test_tab値に挿入(10);
1行作成されました。
SQL>
/
test_tab値に挿入(10)*
1行目のエラー:ORA-00001:一意性制約(PEASLAND.SYS_C00767176)に違反しています
おっと!最初の挿入は機能しましたが(1行が作成されました)、スラッシュを入力すると、SQL * Plusが同じデータを挿入しようとしたため、一意の制約違反に遭遇しました。
結論
うまくいけば、このページには、スラッシュが必要な理由、何が必要か、いつ使用しないかが示されています。要約するには:
- 各PL/SQLブロックの最後にスラッシュを含めます
- PL/SQLブロックにないSQL文の後にスラッシュを含めないでください。
- 単一のSQLステートメントの後にスラッシュを付けると、そのSQLコマンドが2回実行されます。