powered by simpleCommunicator - 2.0.41     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Не могу решить элементарную задачу
6 сообщений из 6, страница 1 из 1
Не могу решить элементарную задачу
    #32036396
Volk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Hi All!

Ситуация следующая.
Передаю в хранимую процедуру значение. Как проверить содержит ли это значение некоторая таблица. И если содержит выпонить действие.

Но вообще надо решить следующую задачу. Есть старая элементарная база данных, у которой есть основная таблица MainTable, к ней по внешним ключам подключаются данные из других таблиц. Так как делал я базу первый раз в жизни, то не стал определять ссылочную целостность. Теперь хочу перегнать таблицу на другой сервер ессно по всем правилам. Но есть в таблице MainTable значения внешних ключей, которые не существуют во вспомогательных таблицах. И при перегоне со старого сервера на новый, новый начинает ругаться.

Вопрос как проверить существует ли значение внешнего ключа главной таблицы во вспомогательной и в зависимости от этого, например обнулить значение внешнего ключа?
...
Рейтинг: 0 / 0
Не могу решить элементарную задачу
    #32036437
Привет!
Судя по описанию задачи, могу предложить
Используй запрос вида, который выведет все внешние ключи из MainTable, которых нет в таблицах-справочниках (для каждой таблицы - свой запрос)

select MainTable.ВнешнийКлюч
from MainTable
where not exists(
select *
from <VspomogatTable>
where <VspomogatTable>.<ПервичныйКлюч> = MainTable.ВнешнийКлюч )

Совет на будущее - приводи скрипты таблиц (прямо копированием), а то очень трудно понять, о чем речь.

С уважением,
Алексей Ковязин,
первая книга в России по InterBase/FireBird/Yaffil,
www.interbase-world.com
...
Рейтинг: 0 / 0
Не могу решить элементарную задачу
    #32036677
Volk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо, новое, конечно я узнал. Но не могу понять как применить это к моей задаче.

Еще раз задача с учетом советов:

основная таблица
/* Table: MAIN, Owner: SYSDBA */

CREATE TABLE "MAIN"
(
"OLDNUM" VARCHAR(15) CHARACTER SET WIN1251,
"LOGICNUM" VARCHAR(15) CHARACTER SET WIN1251,
"SECTION" SMALLINT,
"KSTREET1" SMALLINT,
"DOM1" SMALLINT,
"KORP1" VARCHAR(3) CHARACTER SET WIN1251,
"KSTREET2" SMALLINT,
"LOCATION" VARCHAR(200) CHARACTER SET WIN1251,
"KTYPEOFSHELL" SMALLINT,
"TECHDATA" VARCHAR(200) CHARACTER SET WIN1251,
"KSTATE" SMALLINT,
"KDISTRICT" SMALLINT,
"KTYPEOFLEADIN" SMALLINT,
"LENGTHOFLEADIN" SMALLINT,
"KTYPETAX" SMALLINT,
"KTYPETARIFING" SMALLINT,
"PERMIT" SMALLINT,
"NOTE" VARCHAR(200) CHARACTER SET WIN1251,
"KOPERATOR" SMALLINT,
"CONTRACT" VARCHAR(20) CHARACTER SET WIN1251,
"ID" INTEGER NOT NULL,
CONSTRAINT "PK_MAIN" PRIMARY KEY ("ID")
);
ALTER TABLE "MAIN" ADD CONSTRAINT "FK_MAIN_" FOREIGN KEY ("KTYPEOFSHELL") REFERENCES SHELLS ("ID");
ALTER TABLE "MAIN" ADD CONSTRAINT "FK_MAIN_DISTRICT" FOREIGN KEY ("KDISTRICT") REFERENCES DISTRICTS ("ID");
ALTER TABLE "MAIN" ADD CONSTRAINT "FK_MAIN_LEADIN" FOREIGN KEY ("KTYPEOFLEADIN") REFERENCES LEADINS ("ID");
ALTER TABLE "MAIN" ADD CONSTRAINT "FK_MAIN_OPERATOR" FOREIGN KEY ("KOPERATOR") REFERENCES OPERATORS ("ID");
ALTER TABLE "MAIN" ADD CONSTRAINT "FK_MAIN_STATE" FOREIGN KEY ("KSTATE") REFERENCES STATES ("ID");
ALTER TABLE "MAIN" ADD CONSTRAINT "FK_MAIN_STREET1" FOREIGN KEY ("KSTREET1") REFERENCES STREETS ("ID");
ALTER TABLE "MAIN" ADD CONSTRAINT "FK_MAIN_STREET2" FOREIGN KEY ("KSTREET2") REFERENCES STREETS ("ID");
ALTER TABLE "MAIN" ADD CONSTRAINT "FK_MAIN_TYPETARIF" FOREIGN KEY ("KTYPETARIFING") REFERENCES TYPETARIFS ("ID");
ALTER TABLE "MAIN" ADD CONSTRAINT "FK_MAIN_TYPETAX" FOREIGN KEY ("KTYPETAX") REFERENCES TYPETAXES ("ID");



вспомогательная таблица.

/* Table: STREETS, Owner: SYSDBA */

CREATE TABLE "STREETS"
(
"ID" INTEGER NOT NULL,
"FULLSTR" VARCHAR(30) CHARACTER SET WIN1251,
"SHORTSTR" VARCHAR(30) CHARACTER SET WIN1251,
PRIMARY KEY ("ID")
);


У меня есть старая база, состоящая из тех же таблиц, которую надо перегнать на Interbase. Перегонять предполагаю хранимой процедурой, вызываемой из дельфи.

/* Stored procedures */

CREATE PROCEDURE "MAIN_I_OLD"
(
"IOLDNUM" VARCHAR(15) CHARACTER SET WIN1251,
"ILOGICNUM" VARCHAR(15) CHARACTER SET WIN1251,
"ISECTION" SMALLINT,
"IKSTREET1" SMALLINT,
"IDOM1" SMALLINT,
"IKORP1" VARCHAR(3) CHARACTER SET WIN1251,
"IKSTREET2" SMALLINT,
"ILOCATION" VARCHAR(200) CHARACTER SET WIN1251,
"IKTYPEOFSHELL" SMALLINT,
"ITECHDATA" VARCHAR(200) CHARACTER SET WIN1251,
"IKSTATE" SMALLINT,
"IKDISTRICT" SMALLINT,
"IKTYPETAX" SMALLINT,
"IKTYPETARIFING" SMALLINT,
"INOTE" VARCHAR(200) CHARACTER SET WIN1251,
"IKOPERATOR" SMALLINT
)
AS
BEGIN EXIT; END ^


ALTER PROCEDURE "MAIN_I_OLD"
(
"IOLDNUM" VARCHAR(15) CHARACTER SET WIN1251,
"ILOGICNUM" VARCHAR(15) CHARACTER SET WIN1251,
"ISECTION" SMALLINT,
"IKSTREET1" SMALLINT,
"IDOM1" SMALLINT,
"IKORP1" VARCHAR(3) CHARACTER SET WIN1251,
"IKSTREET2" SMALLINT,
"ILOCATION" VARCHAR(200) CHARACTER SET WIN1251,
"IKTYPEOFSHELL" SMALLINT,
"ITECHDATA" VARCHAR(200) CHARACTER SET WIN1251,
"IKSTATE" SMALLINT,
"IKDISTRICT" SMALLINT,
"IKTYPETAX" SMALLINT,
"IKTYPETARIFING" SMALLINT,
"INOTE" VARCHAR(200) CHARACTER SET WIN1251,
"IKOPERATOR" SMALLINT
)
AS
declare variable ID integer;
BEGIN

IF(??????!!!!!!!!!!!!!!! ) then

id = gen_id(gen_ID_main,1);
INSERT INTO MAIN (
ID,
OLDNUM,
LOGICNUM,
SECTION,
KSTREET1,
DOM1,
KORP1,
KSTREET2,
LOCATION,
KTYPEOFSHELL,
TECHDATA,
KSTATE,
KDISTRICT,
KTYPETAX,
KTYPETARIFING,
NOTE,
KOPERATOR)
VALUES (
:ID,
:iOLDNUM,
:iLOGICNUM,
:iSECTION,
:iKSTREET1,
:iDOM1,
:iKORP1,
:iKSTREET2,
:iLOCATION,
:iKTYPEOFSHELL,
:iTECHDATA,
:iKSTATE,
:iKDISTRICT,
:iKTYPETAX,
:iKTYPETARIFING,
:iNOTE,
:iKOPERATOR);
END


В процедуре есть IF (?????). Как мне оформить это условие. Я хочу, чтобы если например в поле Kstreet1 содержится значение, которое не находит отображения в таблице STREETS то оно заменилось на NULL как не несущее никакой информации. А если значение ключа в поле KSTREET1 отображается в таблице STREETS то перейти к проверке следующего ключа.

Я привильно решаю задачу переноса базы или я выбрал не тот путь?
...
Рейтинг: 0 / 0
Не могу решить элементарную задачу
    #32036751
Привет!

Теперь гораздо лучше стало.
Насчет правильно-не правильно - главное, чтобы работало, вопрос лишь в том, сколько сил на это потратишь. Я обычно пишу такие конвертеры в Дельфи, но это дело вкуса.

Насчет ветвления:

IF exists(
select *
from "STREETS"
where "STREETS"."ID" = :"IKSTREET1")
) then
Begin
INSERT .....
End
else /*если надо*/
begin
...
end;

Что касается "перейти к следующей записи", то, как я понял, ты будешь вызывать эту процедуру из Дельфи для каждой строки исходной таблицы (из другой базы), поэтому FOR SELECT не нужен, так?

И еще один бесполезный совет - ну зачем тебе эти имена в кавычках? Да полюнь на них, замучаешься - пиши просто всегда ПРОПИСНЫМИ буквами и все будет ОК.
С уважением,
Алексей Ковязин,
www.interbase-world.com
...
Рейтинг: 0 / 0
Не могу решить элементарную задачу
    #32036835
Volk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо! Вот оно слово EXIST. Без него ничего не получалось. А я его не знал. Теперь знаю.

А какие имена в кавычках и что кавычки означают?

Вообще-то я их не пишу при написании процедуры. Но что они значат было бы интересно узнать.
...
Рейтинг: 0 / 0
Не могу решить элементарную задачу
    #32036910
Привет!

Имена объектов в кавычках - функция, появившееся начиная с версии InterBase 6.0.x
Все современные версии и клоны IB (IB6.5, Firebird 1.0, Yaffil) позволяют работать как в 1-м диалекте, где соблюдается режим некоторой совместимости с IB 4-5, так и в 3-м диалекте (2-й диалект бывает только у клиента и предназанчен для проверки совместимости и облегчения процесса миграции БД с 1-го на 3-й диалект).
В 3-м диалекте можно писать имена в кавычках, причем большие и маленькие буквы различаются - то есть "My TaBle" <> "MY TABLE".
Обычно рекомендуют писать все объекты в любом диалекте ПРОПИСНЫМИ буквами (кавычки тогда не нужны).
А иначе запутаться легко.
Подробности - "InterBase 6 Migration Guide", а также на сайтах interbase-world.com и ibase.ru

С уважением,
Алексей Ковязин,
www.interbase-world.com
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Не могу решить элементарную задачу
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]