web-dev-qa-db-ja.com

sqlplusを使用してコマンドラインからOracleスクリプトを実行する際の問題

Sqlplusを使用してSQLスクリプトをOracleに実行しようとすると問題が発生します。スクリプトは、いくつかのダミーデータを入力するだけです。

DECLARE 
  role1Id NUMBER;
  user1Id NUMBER;
  role2Id NUMBER;
  user2Id NUMBER;
  role3Id NUMBER;
  user3Id NUMBER;
  perm1Id NUMBER;
  perm2Id NUMBER;
  perm3Id NUMBER;
  perm4Id NUMBER;
  perm5Id NUMBER;
BEGIN
  INSERT INTO PB_USER(USER_ID,USER_NAME, USER_EMAIL, USER_ACTIVEYN)
  VALUES(PB_USER_ID_SEQ.nextval, 'RoleDataManagerTests_Username', '[email protected]',' ');

  INSERT INTO ROLES(ROLE_ID, ROLE_NAME)
  VALUES(PB_ROLE_ID_SEQ.nextval, 'Test role 1');
  INSERT INTO ROLES(ROLE_ID, ROLE_NAME)
  VALUES(PB_ROLE_ID_SEQ.nextval, 'Test role 2');
  INSERT INTO ROLES(ROLE_ID, ROLE_NAME)
  VALUES(PB_ROLE_ID_SEQ.nextval, 'Test role 3');

  SELECT ROLE_ID INTO role1Id FROM ROLES WHERE ROLE_NAME = 'Test role 1';
  SELECT USER_ID INTO user1Id FROM PB_USER WHERE USER_NAME = 'RoleDataManagerTests_Username';
  INSERT INTO USERS_ROLES(USER_ID, ROLE_ID) VALUES(user1Id, role1Id);

  SELECT ROLE_ID INTO role2Id FROM ROLES WHERE ROLE_NAME = 'Test role 2';
  SELECT USER_ID INTO user2Id FROM PB_USER WHERE USER_NAME = 'RoleDataManagerTests_Username';
  INSERT INTO USERS_ROLES(USER_ID, ROLE_ID) VALUES(user2Id, role2Id);

  SELECT ROLE_ID INTO role3Id FROM ROLES WHERE ROLE_NAME = 'Test role 3';
  SELECT USER_ID INTO user3Id FROM PB_USER WHERE USER_NAME = 'RoleDataManagerTests_Username';
  INSERT INTO USERS_ROLES(USER_ID, ROLE_ID) VALUES(user3Id, role3Id);

  INSERT INTO PERMISSIONS(PERMISSION_ID, KEY, DESCRIPTION)
  VALUES (PB_PERMISSION_ID_SEQ.nextval, 'perm1', 'permission 1');
  INSERT INTO PERMISSIONS(PERMISSION_ID, KEY, DESCRIPTION)
  VALUES (PB_PERMISSION_ID_SEQ.nextval, 'perm2', 'permission 2');
  INSERT INTO PERMISSIONS(PERMISSION_ID, KEY, DESCRIPTION)
  VALUES (PB_PERMISSION_ID_SEQ.nextval, 'perm3', 'permission 3');
  INSERT INTO PERMISSIONS(PERMISSION_ID, KEY, DESCRIPTION)
  VALUES (PB_PERMISSION_ID_SEQ.nextval, 'perm4', 'permission 4');
  INSERT INTO PERMISSIONS(PERMISSION_ID, KEY, DESCRIPTION)
  VALUES (PB_PERMISSION_ID_SEQ.nextval, 'perm5', 'permission 5');

  SELECT PERMISSION_ID INTO perm1Id FROM PERMISSIONS WHERE KEY = 'perm1';
  SELECT PERMISSION_ID INTO perm2Id FROM PERMISSIONS WHERE KEY = 'perm2';
  SELECT PERMISSION_ID INTO perm3Id FROM PERMISSIONS WHERE KEY = 'perm3';
  SELECT PERMISSION_ID INTO perm4Id FROM PERMISSIONS WHERE KEY = 'perm4';
  SELECT PERMISSION_ID INTO perm5Id FROM PERMISSIONS WHERE KEY = 'perm5';

  INSERT INTO ROLES_PERMISSIONS(ROLE_ID, PERMISSION_ID)
  VALUES(role1Id, perm1Id);
  INSERT INTO ROLES_PERMISSIONS(ROLE_ID, PERMISSION_ID)
  VALUES(role1Id, perm2Id);
  INSERT INTO ROLES_PERMISSIONS(ROLE_ID, PERMISSION_ID)
  VALUES(role1Id, perm3Id);

  INSERT INTO ROLES_PERMISSIONS(ROLE_ID, PERMISSION_ID)
  VALUES(role2Id, perm3Id);

  INSERT INTO ROLES_PERMISSIONS(ROLE_ID, PERMISSION_ID)
  VALUES(role3Id, perm4Id);
  INSERT INTO ROLES_PERMISSIONS(ROLE_ID, PERMISSION_ID)
  VALUES(role3Id, perm5Id);
END;
/

Oracle SQL Developerを使用してスクリプトを実行するとスクリプトは正常に機能しますが、sqlplusコマンドラインツールを使用すると、これが出力され、ハングします。

SQL*Plus: Release 11.1.0.7.0 - Production on Tue May 11 09:49:34 2010

Copyright (c) 1982, 2008, Oracle.  All rights reserved.


Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP, Data Mining Scoring Engine
and Real Application Testing options

このコマンドラインを使用してツールを実行しています。これは他のスクリプトでも正常に機能します。

sqlplus username/password@server/dbname @Setup.sql

何か案は?ありがとう。

8
Charlie

TOADなどのクライアントで正常に実行される特定のスクリプトでもこの問題が発生していましたが、SQLPlusを介してハングする代わりに、@ scriptディレクティブを使用して実行すると、SQLPlusクライアントはに対応する番号を含むプロンプトを返します。実行されているスクリプトの行数(+1)。

たとえば、70行の「doit.sql」という名前のスクリプトを実行した場合、適切なコマンドでSQLPlusを起動し、次のように入力します。

> @doit.sql

次に、次のように表示されます。

71:

この時点でEnterキーを押すと、

72:

プロンプトで/と入力し、Enterキーを押すことで、これらのスクリプトを実行できました。

13
cwash

簡単な答え

必ず両方の「end;」を入れてください。そして最後の行に「/」を入れます

それは簡単に実行されます。

5
Viren

コマンドライン

sqlplus username/password@server/dbname @Setup.sql

上記は、sqlplusがスクリプトSetup.sqlを実行し、さらにコマンドを対話的に待機する必要があることを意味します(スクリプトがexitを明示的に実行しない場合)。これはsqlplusの正常な動作です。

sqlplusは、次の3つの場合に終了します。

  • 失敗(一部のエラーについては、終了するかどうかを変更できます。WHENEVERplsql-commandを参照してください)
  • 明示的なexit(インタラクティブとsriptの両方)
  • STDIN(EOF)の終わり

インタラクティブモードまたはスクリプトから、^Z文字を送信して、入力フローをソフトに終了できます。インタラクティブにCtrl+Z,Enterを押すだけです。

そしてもちろん、STDINをリダイレクトして、キーボードからではなくファイルから取得することもできます。これを行うには、2つの同様の方法があります。

1) sqlplus username/password@server/dbname<Setup.sql
2) echo @Setup.sql|sqlplus username/password@server/dbname

どちらの場合も、入力フローにsqlplusがあるため、スクリプトの実行後にEOFは終了します。

1
Naeel Maqsudov

問題は、SQLplusがOracleクライアントホームから実行されていて、startupupgradeコマンドの実行時にクラッシュしていたことが原因です。

クライアント以外のOracleホームからsqlplusを実行し、コマンドを試してみると、期待どおりに機能します。したがって、解決策は、Oracleクライアントホームではなく、メインのOracleホームからsqlplusを実行することです。

0
PranavF

プロンプトで/を使用する代わりに、doit.sqlのクエリがセミコロンで終わっていることを確認してください。

0
sandrows