在Oracle MySQL中,如何检查存储过程if块中是否存在行

时间:2018-12-03 16:28:36

标签: mysql stored-procedures innodb

我目前正在建立一个数据库并为Android应用程序编写存储过程。我是一名长期程序员,几年前创建了一些数据库,但直到现在才真正使用存储过程。我目前遇到的问题是,我找不到正确的方法来检查给定的字符串(由stringId指定)和给定的语言(由languageId指定)是否不存在,以及在继续之前是否已存在翻译后的字符串并将新的翻译后的字符串插入表 TranslatedStrings 中。我查找了许多类似的问题以及许多其他网站,尽管有些问题似乎完全相同,但他们的解决方案确实对他们有用,但对我却没有。

这是我当前的“创建过程”脚本:

create procedure `InsertTranslatedString`(in stringId int(10) unsigned, in translationSource tinyint(3) unsigned, in translationLanguageId int(10) unsigned, 
    in translatedString mediumtext, out insertedTranslatedStringId int(10) unsigned, out returnValue int(10))
reads sql data
modifies sql data
begin
    -- if the string id does not exists
    if (select count(1) from `Strings` where `stringId` = stringId) = 0
    then
        -- return error code
        set returnValue = -1;
        set insertedTranslatedStringId = 0;

    -- if the language id does not exists
    elseif (select count(1) from `Languages` where `languageId` = translationLanguageId) = 0
    then
        -- return error code
        set returnValue = -2;
        set insertedTranslatedStringId = 0;

    -- if the translated string already exists
    elseif (select count(1) from `TranslatedStrings` where `stringId` = stringId and `languageId` = translationLanguageId) > 0
    then
        -- return error code
        set returnValue = -3;
        set insertedTranslatedStringId = 0;

    -- if we are ready to go
    else
        -- insert the actual translated string
        insert into TranslatedStrings (`stringId`, `languageId`, `value`, `translationSource`, `createdDateTime`)
        values (stringId, translationLanguageId, translatedString, translationSource, now());
        select @newTranslatedStringId := last_insert_id();

        -- give back output parameters
        set insertedTranslatedStringId = @newTranslatedStringId;
        set returnValue = 0;
    end if;
end $$

过程的创建就像魅力一样。

我用call InsertTranslatedString(76, 0, 1, 'German (Germany)', @insertedTranslatedStringId, @returnValue);调用该过程,stringId 76和languageId 1都不存在。

当我打电话时,我注意到if-elseif-elseif-else块跳过了第一个if(stringId检查),即使它应该进入其then块。但是,该过程将输入第一个elseif(语言ID检查),它可以正常工作。

我也尝试了如下的if-check:if not exists (select 1 from 'Strings' where 'stringId' = stringId),但是exists()函数似乎总是返回true,无论select返回一行还是没有一行都没有关系。然后该过程将直接跳到第二个elseif,因为我在那里使用了elseif exists (select...。但是,如果我单独运行实际的select,则不会返回任何行。非常令人困惑。

以下是三个引用的表:

CREATE TABLE `Languages` (
`languageId` int(10) unsigned NOT NULL,
`nameStringId` int(10) unsigned NOT NULL,
`languageCode` varchar(5) DEFAULT NULL,
`hiddenInSettings` tinyint(1) DEFAULT '0',
PRIMARY KEY (`languageId`),
KEY `FK_Languages_nameStringId` (`nameStringId`),
CONSTRAINT `FK_Languages_nameStringId` FOREIGN KEY (`nameStringId`) REFERENCES `Strings` (`stringId`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='contains all supported and automatically translated languages'


CREATE TABLE `Strings` (
`stringId` int(10) unsigned NOT NULL AUTO_INCREMENT,
`originalValue` mediumtext NOT NULL,
`originalLanguageId` int(10) unsigned NOT NULL,
PRIMARY KEY (`stringId`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='contains all language-independent strings instances'


CREATE TABLE `TranslatedStrings` (
`stringId` int(10) unsigned NOT NULL,
`languageId` int(10) unsigned NOT NULL,
`value` mediumtext NOT NULL,
`translationSource` tinyint(3) unsigned DEFAULT '0',
`createdDateTime` datetime DEFAULT NULL,
`lastModifiedDateTime` datetime DEFAULT NULL,
`incorrectTranslationState` tinyint(3) unsigned DEFAULT '0',
`incorrectTranslationReporterId` int(10) unsigned DEFAULT NULL,
`incorrectTranslationReportedDateTime` datetime DEFAULT NULL,
PRIMARY KEY (`stringId`,`languageId`),
KEY `FK_TranslatedStrings_languageId` (`languageId`),
KEY `FK_TranslatedStrings_incorrectTranslationReporterId` (`incorrectTranslationReporterId`),
CONSTRAINT `FK_TranslatedStrings_incorrectTranslationReporterId` FOREIGN KEY (`incorrectTranslationReporterId`) REFERENCES `Users` (`userId`) ON DELETE CASCADE,
CONSTRAINT `FK_TranslatedStrings_languageId` FOREIGN KEY (`languageId`) REFERENCES `Languages` (`languageId`) ON DELETE CASCADE,
CONSTRAINT `FK_TranslatedStrings_stringId` FOREIGN KEY (`stringId`) REFERENCES `Strings` (`stringId`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='contains all localized and automatically translated strings'

当我创建表时,我并没有创建这些KEY条目,它们是由MySQL Server创建的。奇怪的是,它们仅类似于某些CONSTRAINT条目,而并非全部。

由于字符串只有一个单列主键,没有外键,我很困惑,它的相应if语句没有被触发。我在做什么错了?

0 个答案:

没有答案