Python 如何检测mysql存储过程中是否添加了外键?

Python 如何检测mysql存储过程中是否添加了外键?,python,mysql,stored-procedures,Python,Mysql,Stored Procedures,我尝试了以下方法,但由于某种原因,@check参数被设置为我试图检查的约束的值,即使该约束不存在 你知道为什么吗 CREATE PROCEDURE AddForeignKey( IN constraint_name varchar(64), IN foreign_key_column_name varchar(64), IN table_name varchar(64), IN database_name varchar(64), IN foreign_t

我尝试了以下方法,但由于某种原因,
@check
参数被设置为我试图检查的约束的值,即使该约束不存在

你知道为什么吗

CREATE PROCEDURE AddForeignKey(
    IN constraint_name varchar(64),
    IN foreign_key_column_name varchar(64),
    IN table_name varchar(64),
    IN database_name varchar(64),
    IN foreign_table_key_name varchar(64),
    IN foreign_table_name varchar(64))

BEGIN
    set @sql = CONCAT('ALTER TABLE ', database_name, '.', table_name,
            ' ADD CONSTRAINT ', constraint_name,
                ' FOREIGN KEY (', foreign_key_column_name, ')'
                ' REFERENCES ', foreign_table_name, ' (', foreign_table_key_name, ');' ) ;

    set @dbname = database_name;

    set @fkname = constraint_name;

    set @check = '';

    SELECT 
        CONSTRAINT_NAME
    INTO
        @check
    FROM 
        INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
    WHERE
       CONSTRAINT_SCHEMA = @dbname
    AND
       CONSTRAINT_NAME   = @fkname
    AND
       CONSTRAINT_TYPE   = 'FOREIGN KEY'
    LIMIT 1;

    IF @check != @fkname
    THEN
        prepare stmt from @sql;
        execute stmt;
    ELSE
        insert into errors(message) values (CONCAT ( 'Check: ', @check, ' DB:', @dbname, ' FK:', @fkname, ' Could not execute statement: ',  @sql));
    END IF;
END

您只能比较列
约束\u NAME
,这不足以防止创建外键重复

您必须添加
REFERENTIAL\u约束
表,并添加更多要比较的列

我还更改了变量名以避免不必要的变量名:

CREATE PROCEDURE AddForeignKey(
    IN p_constraint_name varchar(64),
    IN foreign_key_column_name varchar(64),
    IN p_table_name varchar(64),
    IN p_database_name varchar(64),
    IN foreign_table_key_name varchar(64),
    IN foreign_table_name varchar(64))

BEGIN
    set @sql = CONCAT('ALTER TABLE `', p_database_name, '`.`', p_table_name,
        '` ADD CONSTRAINT `', p_constraint_name,
            '` FOREIGN KEY (`', foreign_key_column_name, '`)'
            ' REFERENCES `', foreign_table_name, '` (`', foreign_table_key_name, '`);' ) ;

    set @check = '';

    SELECT 
        TABLE_CONSTRAINTS.CONSTRAINT_NAME
        INTO @check
    FROM 
    INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
            INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
            ON  TABLE_CONSTRAINTS.CONSTRAINT_SCHEMA = REFERENTIAL_CONSTRAINTS.CONSTRAINT_SCHEMA
              AND TABLE_CONSTRAINTS.CONSTRAINT_NAME = REFERENTIAL_CONSTRAINTS.CONSTRAINT_NAME
              AND TABLE_CONSTRAINTS.TABLE_NAME = REFERENTIAL_CONSTRAINTS.TABLE_NAME

    WHERE
    TABLE_CONSTRAINTS.CONSTRAINT_SCHEMA =  p_database_name
        AND TABLE_CONSTRAINTS.CONSTRAINT_NAME   =  p_constraint_name
        AND TABLE_CONSTRAINTS.CONSTRAINT_TYPE   = 'FOREIGN KEY'
    AND TABLE_CONSTRAINTS.TABLE_NAME = p_table_name
        and REFERENTIAL_CONSTRAINTS.REFERENCED_TABLE_NAME = foreign_table_name
    LIMIT 1;

    IF @check <> p_constraint_name
    THEN
        prepare stmt from @sql;
        execute stmt;
    ELSE
        insert into errors(message) values (CONCAT ( 'Check: ', @check, ' DB:', @dbname, ' FK:', 
        @fkname, ' Could not execute statement: ',  @sql));
    END IF;

END
创建过程AddForeignKey(
在p_constraint_name varchar(64)中,
在外键列中,名称为varchar(64),
在p_表_name varchar(64)中,
在p_数据库_name varchar(64)中,
在外文表中,键名为varchar(64),
在外文_表_name varchar(64))
开始
设置@sql=CONCAT('ALTER TABLE`',p_database_name',`.`',p_TABLE_name,
“`ADD CONSTRAINT`”,p_CONSTRAINT_name,
“`外键(`',外键列名称,`)”
“REFERENCES`',foreign_table_name',`(`',foreign_table_key_name,`);”;
设置@check='';
挑选
表_CONSTRAINTS.CONSTRAINT_名称
进入@检查
从…起
信息\u SCHEMA.TABLE\u约束
内部联接信息\u架构。引用\u约束
在表上\u CONSTRAINTS.CONSTRAINT\u SCHEMA=参考\u CONSTRAINTS.CONSTRAINT\u SCHEMA
表_CONSTRAINTS.CONSTRAINT_NAME=参考_CONSTRAINTS.CONSTRAINT_NAME
和TABLE_CONSTRAINTS.TABLE_NAME=参考_CONSTRAINTS.TABLE_NAME
哪里
表\u CONSTRAINTS.CONSTRAINT\u SCHEMA=p\u数据库\u名称
和表_CONSTRAINT.CONSTRAINT_NAME=p_CONSTRAINT_NAME
和表_CONSTRAINTS.CONSTRAINT_TYPE='FOREIGN KEY'
和TABLE_CONSTRAINTS.TABLE_NAME=p_TABLE_NAME
和引用约束。引用的表名=外来表名
限值1;
如果@check p_constraint_name
然后
从@sql准备stmt;
执行stmt;
其他的
插入到错误(消息)值中(CONCAT('Check:'、@Check、'DB:'、@dbname、'FK:'),
@fkname,'无法执行语句:',@sql));
如果结束;
结束

我无法重现该问题。请看,我没有使用MySQL作为根用户。我也在使用MySQL 5.6。我不相信你已经回答了我的问题。我会按照你的建议做些改变,看看有没有什么效果,但我对此表示怀疑。您对简洁的SQL和更彻底的检查提出了公平的观点,但这些不是我遇到的问题。另外,ELSE条件中的insert将失败。不确定如何失败,但这似乎已经修复了它。