Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > создание связи один ко многим


Автор: Teleport 15.11.2009, 07:02
Создаю бд с двумя таблицами.  Хочу сделать связь один ко многим. Хочу чтобы на id_q (таблица ta_1) можно было повесить много записей из таблицы ta_2  Вот мои запросы:
Код

ADOQ1.Active:= false;
ADOQ1.SQL.Clear;
ADOQ1.SQL.Add('CREATE TABLE ta_1 (id_q int NOT NULL PRIMARY KEY , questions MEMO NOT NULL);');
ADOQ1.ExecSQL;
ADOQ1.SQL.Clear;
ADOQ1.SQL.Add('CREATE TABLE ta_2 (id_a int NOT NULL, answers MEMO NOT NULL);');
ADOQ1.ExecSQL;
ADOQ1.SQL.Clear;
ADOQ1.SQL.Add('SELECT id_q FROM ta_1 INNER JOIN ta_2 ON ta_1.id_q = ta_2.id_a);');
ADOQ1.ExecSQL;



Не могу разобраться с последним запросом никак. Связь не создается. Ошибка пишет синтаксиса. 

Автор: ТоляМБА 15.11.2009, 10:02
F1

Цитата
Call ExecSQL to execute the SQL statement currently assigned to the SQL property. Use ExecSQL to execute queries that do not return a cursor to data (such as INSERT, UPDATE, DELETE, and CREATE TABLE).

ExecSQL returns an integer value reflecting the number of rows affected by the executed SQL statement.

Note:     For SELECT statements, call Open instead of ExecSQL or set the Active property to True.



Цитата(Teleport @  15.11.2009,  09:02 Найти цитируемый пост)
Не могу разобраться с последним запросом никак. Связь не создается
Потому что вы не создаете физически связь а делаете запрос на выборку. Читайте выше.

Автор: Teleport 15.11.2009, 13:13
Цитата

Потому что вы не создаете физически связь а делаете запрос на выборку. Читайте выше.


исходя из вышенаписанного переделываю последние строки:
Код

ADOQ1.SQL.Add('SELECT id_a, answers FROM ta_2 INNER JOIN ta_1 ON ta_1.id_q = ta_2.id_a);');
ADOQ1.Active:= true;


Где-то в запросе все равно ошибка. А как же создать связь физически?
Как я понимаю нужно создавать связь еще при запросе Create table?

Автор: ТоляМБА 15.11.2009, 13:57
Цитата(Teleport @  15.11.2009,  15:13 Найти цитируемый пост)
Где-то в запросе все равно ошибка.
Считаем количество открытых и закрытых скобок в строке с запросом, сравниваем, делаем выводы.

Цитата(Teleport @  15.11.2009,  15:13 Найти цитируемый пост)
А как же создать связь физически?
Зависит от СУБД, название которой я в сей теме не наблюдаю.

Автор: Teleport 15.11.2009, 14:02
Со скобками я понял. Косяк. Исправил. Запрос прокатил нормально. СУБД использую Access. Открываю бд через Access и связей не наблюдаю. Вопрос о создании связей физически - открыт.

Автор: Акимыч 17.11.2009, 14:45
Код

ADOQ1.Active:= false;
ADOQ1.SQL.Clear;
ADOQ1.SQL.Add('CREATE TABLE TA_1 (ID_Q INT NOT NULL PRIMARY KEY , QUESTIONS MEMO NOT NULL);');
ADOQ1.ExecSQL;
ADOQ1.SQL.Clear;
ADOQ1.SQL.Add('CREATE TABLE TA_2 (ID_A INT NOT NULL, ANSWERS MEMO NOT NULL, CONSTRAINT FKTA_1 FOREIGN KEY (ID_A) REFERENCES TA_1(ID_Q));');
ADOQ1.ExecSQL;


А выбирать из них
Код

ADOQ1.SQL.Clear;
ADOQ1.SQL.Add('SELECT * FROM ta_1 INNER JOIN ta_2 ON ta_1.id_q = ta_2.id_a);');
ADOQ1.ExecSQL;

Автор: ТоляМБА 17.11.2009, 15:53
Цитата(Акимыч @  17.11.2009,  16:45 Найти цитируемый пост)
ADOQ1.SQL.Add('SELECT * FROM ta_1 INNER JOIN ta_2 ON ta_1.id_q = ta_2.id_a);');
ADOQ1.ExecSQL;



Акимыч, я могу и второй раз повторить:

F1

Цитата
Call ExecSQL to execute the SQL statement currently assigned to the SQL property. Use ExecSQL to execute queries that do not return a cursor to data (such as INSERT, UPDATE, DELETE, and CREATE TABLE).

ExecSQL returns an integer value reflecting the number of rows affected by the executed SQL statement.

Note:     For SELECT statements, call Open instead of ExecSQL or set the Active property to True.





Автор: Teleport 17.11.2009, 19:12
2 Акимыч - попробую так. Возникнут вопросы к коду... 

Автор: Акимыч 18.11.2009, 11:15
ТоляМБА, каюсь, грешен, тупо скопипастил. Там конечно ADOQ1.Open;

Teleport, будут - задавай! А вообще в Access хелп очень хороший, там все написано (правда по англицки)

Автор: Teleport 4.12.2009, 01:37
2 ТоляМБА - спасибо за замечание.  smile 
2 Акимыч - спасибо, помог  smile  smile 

Остались такие вопросы:
1) а как при создании связи назначить каскадное удаление и каскадное обновление?
Допустим, я создал, как ты и показал. Теперь выполняю запрос:

Код

 ADOQ1.Active:= false;
 ADOQ1.SQL.Clear;
 ADOQ1.SQL.Add('DELETE FROM TA_1 WHERE ID_Q = 2;');
 ADOQ1.ExecSQL;


Не прокатывает - так как есть связанные записи в таблице TA_2.

2) Или мне никак не назначить каскадное удаление и обновление при создании таблиц, взамен же этого использовать удаление или обновление из этих таблиц при выполнении моего запроса DELETE или UPDATE?? Мм??

Автор: Teleport 4.12.2009, 12:47
Вроде, разобрался. И оно еще и работает даже  smile  smile 
Оно вот решение:
Код

'CREATE TABLE TA_1 (ID_Q INT NOT NULL PRIMARY KEY , QUESTIONS MEMO NOT NULL);'

'CREATE TABLE TA_2 (ID_A INT NOT NULL, ANSWERS MEMO NOT NULL, '+
 ' CONSTRAINT FKTA_1 FOREIGN KEY (ID_A) REFERENCES TA_1(ID_Q)' +
 ' ON UPDATE CASCADE ON DELETE CASCADE);'


Выслушаю замечания по коду, если будут  smile 

Автор: Акимыч 4.12.2009, 21:04
Цитата(Teleport @  4.12.2009,  12:47 Найти цитируемый пост)
Оно вот решение

Все правильно!!! smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)