Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL:如何检查外键是否真的更改了_Sql_Postgresql_Plpgsql - Fatal编程技术网

SQL:如何检查外键是否真的更改了

SQL:如何检查外键是否真的更改了,sql,postgresql,plpgsql,Sql,Postgresql,Plpgsql,我使用了错误约束的FK,我必须更改它: ALTER TABLE user_login_logout_fact DROP CONSTRAINT user_fk; ALTER TABLE user_login_logout_fact ADD CONSTRAINT user_fk FOREIGN KEY (user_id) REFERENCES uuser (id) MATCH SIMPLE ON UPDATE CASCADE ON DELETE CASCADE DEFE

我使用了错误约束的FK,我必须更改它:

ALTER TABLE user_login_logout_fact DROP CONSTRAINT user_fk;

ALTER TABLE user_login_logout_fact
  ADD CONSTRAINT user_fk FOREIGN KEY (user_id)
      REFERENCES uuser (id) MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
它没有问题,但我必须使用补丁文件应用它,并检查它是否已经应用。所以我必须创建如下函数:

CREATE FUNCTION tryUpgrade(patch varchar) RETURNS integer AS $$
    DECLARE testRecord RECORD;
    BEGIN
        RAISE NOTICE 'checking %', patch;
        SELECT INTO testRecord * FROM patchlog where basename = patch;
        IF FOUND THEN
            RAISE NOTICE 'patch % has already been applied', patch;
            RETURN 0;
        END IF;

    //check if constraints are ok
    IF ok THEN
        RAISE NOTICE 'upgraded but not noted';
        INSERT INTO patchlog VALUES (patch, now());
        RETURN 0;
    END IF;

    SELECT INTO testRecord upgrade(); //this function will alter table
    INSERT INTO patchlog VALUES (patch, now());
    RAISE NOTICE 'upgraded';
    RETURN 1;
END;
$$ LANGUAGE plpgsql;
所以,问题是-如何检查FK是否将用于删除级联而不是旧的无操作

如何检查FK是否将用于删除级联而不是旧的无操作

可以在系统目录表中检查confdeltype。手册:

外键删除操作代码:a=不操作,r=限制,c=级联,n=设置为空,d=设置为默认值

在PL/pgSQL代码中,使用它的方式如下:

如果存在 从pg_约束中选择 其中conname='user\u fk' 和conrelid='user\u login\u logout\u fact':regclass 而confdeltype='c' 然后 -全部完成 其他的 -运行ALTERTABLE。。。 如果结束; 表名可以是模式限定的。见:

信息模式与系统目录 正如您自己回答的那样,通过查询遵循SQL标准的,也可以实现同样的目的

然而:

并非所有主要的RDBMS都实现了它。例如,甲骨文没有

信息模式有时使用非常复杂的视图而不是表来实现,这使得查找比直接访问中的表慢得多。在真实的实时数据库中进行的快速测试显示,手边示例的系数为10。我似乎有1000倍甚至更多

使用信息模式的目的通常是保持实现的可移植性。但这从一开始就很难奏效。各种RDBMS在很多方面都离SQL标准太远了

不过,还有另一个好处:Postgres不会声明任何关于PGU目录中跨主要版本的表结构的内容。通过使用信息模式,可以在Postgres的主要版本中安全地使用。 然而,基本结构几乎没有变化。虽然有可能,但像这样的查询不太可能在将来的版本中中断

见:


另外,第二种解决方案似乎不太适合postgresql

关于引用约束表中外键存储的信息:


我在回答中增加了一章讨论信息模式与PGU目录。
SELECT * FROM information_schema.referential_constraints 
WHERE CAST(constraint_name AS TEXT) LIKE 'user_fk' 
    AND delete_rule LIKE 'CASCADE' 
    AND update_rule LIKE 'CASCADE';