Как проверить, существует ли строка в хранимой процедуре if-block в Oracle MySQL - PullRequest
0 голосов
/ 03 декабря 2018

В настоящее время я создаю базу данных и пишу хранимые процедуры для приложения 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 $$

Создание процедуры работает как charm.

Я вызываю процедуру с call InsertTranslatedString(76, 0, 1, 'German (Germany)', @insertedTranslatedStringId, @returnValue); И stringId 76, и languageId 1. не существуют.

Когда я делаю этот вызовЯ заметил, что блок if-elseif-elseif-else пропускает первый if (проверка stringId), даже если он должен войти в свой блок then.Однако процедура входит в первую elseif (проверку languageId), которая работает нормально.

Я также опробовал if-проверки следующим образом: 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 записей, а не на все.

Поскольку Strings имеет только первичный ключ, состоящий из одного столбца, и никаких внешних ключей, я озадачен тем, что соответствующий ему оператор if не сработал,Что я делаю не так?

...