感謝馬克,我再次嘗試,並最終以某種方式改變了所有視圖「選擇1作爲測試從rdb $數據庫」工作,然後可以刪除它們。
由於我在現場有很多不同版本的模式,我不確定我會遇到哪些依賴關係。所以我寫了這個PSQL塊,它遍歷所有這些對象,忽略錯誤,直到一切都清理完畢。因此,如果這些對象中的任何一個都不可刪除,那麼一旦它運行了100次以避免掛起,我就會跳出迭代。之後,我檢查是否存在任何程序,視圖,觸發器和功能。如果是這樣,我招來一個例外。
我知道這是一種「骯髒」的解決方案(忽略異常通常是NoGo),但我沒有更好的主意,因爲無論是循環還是未檢測到的錯誤都不會發生,我會用這種方式。
EXECUTE BLOCK
as
declare x integer;
declare y integer;
declare z integer;
declare s varchar(100);
declare s1 varchar(100);
begin
x=1;
y=0;
while (x>0 and y<100) do
-- we break out of the loop if we have more than 100 rounds as this indicates
-- at least one object could not be deleted.
begin
y=y+1;
for SELECT distinct RDB$VIEW_NAME from RDB$VIEW_RELATIONS into :s do
begin
in autonomous transaction do
execute statement 'alter view ' || s || ' as select 1 as test from rdb$database';
-- Ignore errors here for now
in autonomous transaction do
execute statement 'drop view ' || s;
-- Ignore errors here for now
when any do begin end
end
for SELECT RDB$PROCEDURE_NAME from RDB$PROCEDURES into :s do
begin
in autonomous transaction do
execute statement 'drop procedure ' || s;
-- Ignore errors here for now
when any do begin end
end
for select RDB$TRIGGER_NAME from RDB$TRIGGERS where RDB$SYSTEM_FLAG=0 into :s do
begin
in autonomous transaction do
execute statement 'drop trigger ' || s;
-- Ignore errors here for now
when any do begin end
end
for select RDB$FUNCTION_NAME from RDB$FUNCTIONS into :s do
begin
in autonomous transaction do
execute statement 'drop function ' || s;
-- Ignore errors here for now
when any do begin end
end
for select rdb$constraint_name,rdb$relation_name from RDB$RELATION_CONSTRAINTS where not rdb$relation_name containing ('$') into :s,:s1 do
begin
in autonomous transaction do
execute statement 'alter table ' || s1 || ' drop constraint ' || s;
-- Ignore errors here for now
when any do begin end
end
for select rdb$index_name from rdb$indices where rdb$system_flag=0 into :s do
begin
in autonomous transaction do
execute statement 'drop index ' || s;
-- Ignore errors here for now
when any do begin end
end
x = 0;
SELECT count(*) from RDB$PROCEDURES into :z;
x = x + z;
SELECT count(distinct RDB$VIEW_NAME) from RDB$VIEW_RELATIONS into :z;
x = x + z;
select count(*) from RDB$TRIGGERS where RDB$SYSTEM_FLAG=0 into :z;
x = x + z;
select count(*) from RDB$FUNCTIONS into :z;
x = x + z;
select count(*) from RDB$RELATION_CONSTRAINTS where not rdb$relation_name containing ('$') into :z;
x = x + z;
select count(*) from rdb$indices where rdb$system_flag=0 into :z;
x = x + z;
end
if (x>0) then
-- Raise an exception showing that the block failed
y=x/0;
end
更新:我添加了代碼以刪除所有約束和索引。
更新2:保留「非空」約束可能是個好主意,因爲它們只能通過域進行重新調整。這樣做只是改變約束select語句:
for select rdb$constraint_name,rdb$relation_name from RDB$RELATION_CONSTRAINTS
where rdb$constraint_type<>'NOT NULL' and not rdb$relation_name containing ('$') into :s,:s1 do
您是否嘗試過使用['創建或更改VIEW'(http://www.firebirdsql.org/file/documentation/reference_manuals/fblangref25-en /html/fblangref25-ddl-view.html#fblangref25-ddl-view-crtoralter)?或者,您可以使用Firebird 3下的這些UDF進行遷移。 –
對使用這些udfs的視圖執行任何刪除或修改命令會失敗,並顯示無效的blr。不幸的是,如上所述,udfs不適用於FB3。我很想替換它們,但因爲它們被使用,所以沒有用。 – MichaSchumann
據我所知,你應該可以使用Firebird 1.5中使用的現有UDF。 –