2

一度に最大1人のユーザーがすべての行を編集できるようにしたいFirebirdデータベースがあります。OWNERそのために、該当するすべてのテーブルに列 を配置したいと思います。すべてのテーブルに対してこれを手作業で行うのは少し面倒なので、自動化する方法を書いてみました。まず、更新が必要なすべてのテーブルを提供するビューを作成します。

CREATE VIEW OWNABLE_TABLES_V
(
  NAME
)
AS
SELECT tables.RDB$RELATION_NAME 
FROM RDB$RELATIONS tables
WHERE (tables.RDB$SYSTEM_FLAG=0) and (tables.rdb$view_source is null)
  and not exists (
    --table containing names of tables that are exceptions to the rule
    select name from META_NOT_OWNABLE 
    where name = tables.RDB$RELATION_NAME)
  and not exists (
    select * from RDB$RELATION_FIELDS fields
    where (fields.RDB$RELATION_NAME = tables.RDB$RELATION_NAME)
    and (fields.RDB$FIELD_NAME = 'OWNER'))
order by tables.RDB$RELATION_NAME;

これは正常に機能します。

次に、メンテナンスを行うためのプロシージャを作成します。

CREATE PROCEDURE PREPARE_OWNERSHIP
AS 
declare variable name varchar(31); 
BEGIN
   for select NAME from OWNABLE_TABLES_V into :name do
   BEGIN
      execute statement replace('ALTER TABLE %T ADD OWNER INTEGER', '%T', :name)
        with autonomous transaction;
      execute statement replace('ALTER TABLE %T ADD OWNER_TIMEOUT TIMESTAMP', '%T', :name)
        with autonomous transaction;
      execute statement replace('ALTER TABLE %T ADD CONSTRAINT FK_%T_OWNER foreign key (OWNER) references USERS', '%T', :name)
        with autonomous transaction;
   END
END

しかし、これを実行しても何も起こりません。エラーは報告されませんが、新しい簿記で更新されるテーブルはありません。Firebird用のHopperprocデバッガーでprocを実行すると、エラーは発生しません。

何がうまくいかないのか、そしてこれを正しく行う方法はありますか?

4

1 に答える 1

1

問題を見つけました。それをステートメントとして実行しようとした後EXECUTE BLOCK、私は実際に有用なエラーメッセージ「不明なトークン:_OWNER」を受け取りました。

どうやらこれは、Hopperデバッガーでprocを実行すると表示されませんが、テーブル名を含むメタデータ選択の結果には末尾にスペースがあります。したがって、次の行:

replace('ALTER TABLE %T ADD CONSTRAINT FK_%T_OWNER foreign key (OWNER) references USERS', '%T', :name)

次のようなものに解決されます:

ALTER TABLE TABLENAME ADD CONSTRAINT FK_TABLENAME      _OWNER foreign key (OWNER) references USERS

これは明らかに無効です。ループ内のname = trim(name);直後に行を追加すると修正されました。BEGINfor

于 2012-11-17T19:18:43.423 に答える