1

最初のプロシージャで 2 つの列を持つテーブルを動的に作成し、2 番目のプロシージャでそのテーブルに値を挿入するネストされたプロシージャを作成したいと考えています。

以下は私が使用しようとしているコードです。私は何を間違っていますか?

CREATE  or replace PROCEDURE mytable (tname varchar2)
is
stmt varchar2(1000);
begin
stmt := 'CREATE TABLE '||tname || '(sname varchar2(20) ,sage number (4))';
execute immediate stmt;
end;
create PROCEDURE mytable1 (emp_name varchar2,emp_age number,tname varchar2)
is
stmt1 varchar2(1000);
begin
stmt1 := 'insert into '||tname||' values ('Gaurav' ,27)';
execute immediate stmt1;
end;
4

1 に答える 1

3

ここでネストされたプロシージャを作成する必要はありません。すべてを 1 回の手順で実行できます。

ステートメントでのバインド変数の使用に注意してくださいexecute immediate

create or replace procedure mytable (
    Ptable_name in varchar2
  , Pemp_name in varchar2
  , Pemp_age in number
     ) is

begin

   execute immediate 'create table ' || Ptable_name 
                      || ' (sname varchar2(20), sage number (4))';
   execute immediate 'insert into ' || Ptable_name 
                      || ' values (:emp_name, :emp_age)'
         using Pemp_name, Pemp_age;

end;

より一般的には、使用する必要はまったくありませんexecute immediate。その場でテーブルを作成することは、データベースの設計が不十分であることを示しています。可能な限り、これを行わないでください。事前にテーブルを作成し、必要に応じてデータを挿入する簡単な手順を用意します。

create or replace procedure mytable (
  , Pemp_name in varchar2
  , Pemp_age in number
     ) is

begin

   insert into my_table 
   values (Pemp_name, Pemp_age);

end;

Oracle のGuarding Against SQL Injectionに関する章を読むことを強くお勧めします。


ネストされたプロシージャとしてこれを行う必要があると本当に感じている場合は、次のようになります。ネストされたプロシージャは最初のスコープの外では見えないため、メインのプロシージャでネストされたプロシージャを呼び出すことを忘れないでください。

create or replace procedure mytable (
    Ptable_name in varchar2
  , Pemp_name in varchar2
  , Pemp_age in number
     ) is

  procedure myvalues (
       Pemp_name in varchar2
     , Pemp_age in number
       ) is
  begin
     execute immediate 'insert into ' || Ptable_name
                    || ' values (:emp_name, :emp_age)'
       using Pemp_name, Pemp_age;
  end;

begin

   execute immediate 'create table ' || Ptable_name
                      || ' (sname varchar2(20), sage number (4))';

   myvalues ( Pemp_name, Pemp_age);

end;

PL/SQL サブプログラムに関する Oracle のドキュメントを参照してください。

于 2013-07-23T07:19:39.090 に答える