如何创建存储过程以确保每个表包含某些列?

时间:2012-11-16 00:23:26

标签: sql firebird

我有一个Firebird数据库I want to ensure that every row can be edited by at most one user at a time.为此,我想在每个适用的表上放置一个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;

这很好用。

然后,创建一个proc来进行维护:

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的Hopper proc调试器下运行proc时,我再也没有出现任何错误。

知道出了什么问题,以及如何做到这一点?

1 个答案:

答案 0 :(得分:1)

我发现了问题。在尝试将其作为EXECUTE BLOCK语句运行后,我实际上收到了一条有用的错误消息:“Unknown token:_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);循环中的BEGIN之后立即添加行for修复了该行。