![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вместо строки ссылка в мастере подстановок
Galiaf © (2007-04-29 18:33:00)База msAccess, 2 таблицы, вовторой таблице четвёртоеполе имеет тип мастер подстановок для того, что бы можно было выбрать точные строки из первой таблици, при этом код:
disk.Fields[3].AsString
возвращает ссылку на ячейку первой таблиы(наверное) а не саму строку.
Вопрос: как получиить именно строку?
ЗЫ
компонент tADOTable;
Galiaf (2007-05-17 08:58:00) [1]ХА-ХА-ХА! РАБОТАЕТ!
sniknik (2007-05-17 08:28:00) [2]второй on лишний. похоже опечатка в хелпе.
Galiaf (2007-05-17 08:20:00) [3]В следующем запросе получаю ошибку пропущен оператор.
SELECT d.id, d.box, d.disk, l.seson, d.ses, d.seria
FROM disc d inner join look l
on l.name=d.name and
on l.ses=d.ses
where d.name=33;
В справке это выглядит следующим образом:
Чтобы связать несколько предложений ON в инструкции JOIN, используйте следующий синтаксис:
SELECT поля
FROM таблица_1 INNER JOIN таблица_2
ON таблица_1.поле_1 оператор таблица_2.поле_1 AND
ON таблица_1.поле_2 оператор таблица_2.поле_2) OR
ON таблица_1.поле_3 оператор таблица_2.поле_3)];
Как исправить?
Galiaf (2007-05-10 20:09:00) [4]Мартин Грубер
Понимание SQL
Перевод Лебедева В.Н.
Под редакцией Булычева В.Н.
Москва, 1993
Я конечно всю книгу не просматривал но через поиск нашел только одно упоминание JOIN
Примечание. В СУБД Interbase "INNER" и "OUTER" являются ключевыми словами, описы-вающими тип объединения ( JOINTYPE) поэтому запрос должен быть изменен, например, так:
SELECT *
FROM Customers out
WHERE CAST('10/03/1990' AS DATE) IN (SELECT odate
FROM Orders inn
WHERE out.cnum = inn.cnum);
Johnmen (2007-05-09 12:47:00) [5]
> В моей книге по SQL про JOIN нифига нет
Я тебе НЕ ВЕРЮ!
Galiaf (2007-05-09 12:18:00) [6]В моей книге по SQL про JOIN нифига нет, для начала найду книгу в которой оно есть.
Johnmen (2007-05-07 23:34:00) [7]
> Я хочу получить запрашиваемые строки даже если d.seson пустая.
Читай ещё раз свою книгу по SQL на тему типов соединений (JOIN).
Galiaf (2007-05-07 21:18:00) [8]И чуть не забыл, для обновления таблицы использую
discs.Close;
discs.CommandText:='SELECT d.id, d.box, d.disk, l.seson, d.ses, d.seria FROM disc d inner join look l on l.id=d.seson where d.name='+DBGrid1.SelectedField.AsString;
discs.Active:=true;
компонент TADODataSet
Выглядит как неправильное решение(в смысле переоткрывание), как тогда правильно.
Galiaf (2007-05-07 21:09:00) [9]Извиняюсь но опять help! И всё та же тема;
SELECT d.id, d.box, d.disk, l.seson, d.ses, d.seria FROM disc d inner join look l on l.id=d.seson where d.name=3
Если в ячейке disc нет ссылки(пустая ячейка), то данный запрос вместо того чтобы показать пустоту только в поле l.seson показывает пустоту во всех запрошенных полях, я просто так подумал я конечно могу сделать ссылку на пустое поле и получить желаемый результат но очень скоро собираюсь сделать так, что это решение уже нельзя будет использовать. В книге по SQL было сказано, что в запросе нельзя прописать условие типа if...then, а как тогда выходит сделать возможность вывода других полей даже если d.seson без ссылки?
На случай если я неправильно излажил мысли:
верхний запрос работает только если d.seson имеет ссылку на l.id(фактически это правильно ведь если в подстановочном поле ссылка на несуществующее поле\нет ссылки то это должна быть ошибка). Я хочу получить запрашиваемые строки даже если d.seson пустая.
Galiaf (2007-05-06 20:14:00) [10]С таким запросом это стало похоже на полный вывод данных двух таблиц но в моём случае это решение будет лучшим т.к. структуру базы ещё не продумал, набросал только основные связи. Но в конце хотелось бы получить запрос только на необходимые поля, да и таблица ещё как минимум одна добавится и тоже с подстановкой только уже значений из обоих таблиц. Сейчас начну изучение JETSQL40.CHM, а он на русском(приятно удивлён)
sniknik (2007-05-06 19:07:00) [11]> Кроме того я пока не догадываюсь как в том же запросе добавить значения остальных полей
сделай так
SELECT * FROM ani a INNER JOIN disc d ON a.ID=d.name
и смотри что тебе надо из полного списка
Galiaf (2007-05-06 18:54:00) [12]Как я понял Discs dэто присвоение(что-то вроде), вроде как запрос
SELECT a.Name AS name, d.disk AS disc FROM ani a INNER JOIN disc d ON a.ID=d.name
выводит то, что надо но странно, что ни первые, ни вторые поля не выводятся в "своём" порядке, так первая запись полученная этим запросом это 40-я из 94-х запись в таблице ani и 143-я из 152-х в таблице disc. Кроме того я пока не догадываюсь как в том же запросе добавить значения остальных полей таблицы disc(это там где мастер подстановок).
sniknik (2007-05-06 18:54:00) [13]> но в первом предложенном тобой запросе ошибка не пропала
там ошибка, ляп, т.к. писал прям сдесь, таблица обьеденяется сама с собой а поле показывается из другой (пытается), надо исправить и делать обьеденение 2 таблиц...
вообще, см синтаксис в справке. сказали же где найти можно.
> отдельное использование d и f в запросе
это алиас таблицы в запроосе, сокращение, также как и для поля d. NameAS Disc, вообще полный синтаксис с AS, чтобы понятнее ...FROM Discs AS d INNER JOIN Films AS f...
Galiaf (2007-05-06 18:05:00) [14]Перевёл свою таблицу и поля на английский но в первом предложенном тобой запросе ошибка не пропала, а вот пример приведёный тобой в [6] работает но я пока не могу понять, что значит d.Name(f.Name) и отдельное использование d и f в запросе
SELECT d.Name AS Disc, f.Name AS Film FROM Discs d INNER JOIN Films f ON d.ID=f.DiscsID
очевидно, что это таблицы discs и films но откуда access знает, что это так, я точно неправильно понял ведь эти таблици создавал прямо в своей базе данных и там есть другие таблицы начинающиеся на d.
sniknik (2007-05-05 14:42:00) [15]p.p.s. да, еше забыл, я примере не использую поле подстановки аксесса вместо него у меня явное указание полей связи - DiscsID INT, DirsID INT и их значений, Name.
чего аксес в принципе и делает, только "пряча" поле связи, как бы объеденяя 2 поля в одно. именно поэтому его, как говорил, лучше не использовать... обман своего рода, а удобств как в использовании из самого аксесса нет.
sniknik (2007-05-05 14:33:00) [16]p.s. забыл. выполнять по одной команде, аксесс пакетов команд не поддерживает.
sniknik (2007-05-05 14:31:00) [17]> У аксеса свой, чуднОй, синтаксис SQL команд.
для одного объеденения синтаксис тотже, вот для нескольких отличается (типа того ... ;), обьеденения делаются вложенными, чего ни в других sql серверах не видел.
> Подробней - в доке.
+
доку можно найти, при установленном мсофисе, у себя же на машине, ищи JETSQL40.CHM.
еще +
таблицы/поля не надо называть по русски могут быть "неприятности" на что ты и "нарвался" скорее всего т.к. в общем синтаксис запроса верен... но вот русские буквы гдето напортачили (если конечно показан именно тот запрос на котором ошибка)
сделай для примера (структура не идеальная и может не совсем под задачу (которую я не понял из [4]) но как начало пойдет, понять смысл объеденения)
сначала создаем таблицы (выполнить можно непосредственно в аксесе, либо в ADOCommand)
CREATE TABLE Discs (ID INT Identity(1,1) PRIMARY KEY, Name VarChar(30), Decrip Text)
//ну эта у нас не участвует в запросе, но смысл имеет, если расширять, добавить еще директории к дискам... это для аналогии
CREATE TABLE Dirs (ID INT Identity(1,1) PRIMARY KEY, DiscsID INT, Name VarChar(200), Decrip Text)
CREATE INDEX DiscsID ON Dirs (DiscsID)
CREATE TABLE Films (ID INT Identity(1,1) PRIMARY KEY, DiscsID INT, DirsID INT, Name VarChar(200), Decrip Text)
CREATE INDEX DiscsID ON Films (DiscsID)
CREATE INDEX DirsID ON Films (DirsID)
//заполняем
INSERT INTO Discs (Name) VALUES ('C:\')
INSERT INTO Discs (Name) VALUES ('D:\')
INSERT INTO Films (DiscsID,Name) VALUES (1, 'Film 1')
INSERT INTO Films (DiscsID,Name) VALUES (1, 'Film 2')
INSERT INTO Films (DiscsID,Name) VALUES (2, 'Anime 1')
INSERT INTO Films (DiscsID,Name) VALUES (2, 'Anime 2')
//и собственно запрос объеденения
SELECT d.Name AS Disc, f.Name AS Film FROM Discs d INNER JOIN Films f ON d.ID=f.DiscsID
заметь, что внесли только 2 раза названия дисков, а в результате их 4, в плюсе то, что не надо хранить лишнего, повторяться в куче записей, обьеденение по числу выполняется быстрее и если вдруг захочется поменять название с 'D:\' на 'Крутые фильмы', это будет легко сделать, не меняя логику программы, запросы, и только в 1м месте.
Johnmen (2007-05-05 13:08:00) [18]У аксеса свой, чуднОй, синтаксис SQL команд.
Типа того SELECT * FROM (T1 LEFT JOIN T2 ON ...). Подробней - в доке.
Galiaf (2007-05-05 12:13:00) [19]Приношу свои извинения из-за того, что отисываюсь раз в неделю, нет у меня денег на интернет вот и приходится выбирать правильное время. После долгих размышлений решил продолжить использование(изучение) баз данных. Удалил с формы компоненты ADOTable, попытался сделать соединение с запросом в ADODataSet
SELECT Аниме.Название FROM Диски left JOIN Диски on диски.название=аниме.Ключ
На что при активации компоненты получил сообщение об ошибке синтаксиса оператора join, пролистал книгу по SQL, ничего не нашёл. Возможно я чего не допонял. На всякий случай изложу точнее структуру базы данных.
База состоит из 3-х таблиц(пока), каждая таблица имеет ключевое поле с названием "ключ". Таблица "аниме" имеет поле "название" значения которого вводятся от руки, таблица "диски" имеет поле "название" значения которого выбираются в выпадающем списке т.к. поле имеет тип Мастер подстановок со ссылкой на поле "аниме.название". При использовании ADOTable значения "диски.названия" были какими-то бессмысленными, на сколько помню длинна их была до 4-х символов, а в ADODataSet получил в этом поле точное значение ключевого поля таблицы "аниме".
Прошу ткнуть меня носом в то место где я прописал бред!
sniknik (2007-04-30 12:02:00) [20]> да и автор выдал, что ADO лучше всех для продуктов Micro-soft.
это верно. но tADOTable это не совсем ADO, это подгонка борланда адошного рекордсета под BDE-шную идеологию. работа с клиент серверной методами файл сервера... естественно получается из рук вон плохо. (есть очень маленький процент случаев в которых его использование ни на что не влияет (работает наравне с adodataset-ом), в остальных вредит)
также лучше не использовать ADOQuery и ADOStoredProc, их "вина" поменьше, но всетаки. (хотя еще как сказать. представь общаешься с двумя людьми, один врет постоянно и ты об этом знаеш, другой всегда говорит правду изредка вставляя лож и определить в чем она чаще всего не удается...)
тебе решать, но совет не используй ничего из упомянутого, все это борландовские замены, используй оставшиеся "родные" ADO компоненты. (пусть поначалу они и сложнее кажутся)
> проще уж загрузить их в память и работать с массивами чем с таблицами.
серьезно так думаешь? сделать обледенение массивов проще чем положить на форму ADODataSet с показанным выше запросом, и открыть его. ???
удачи. как тренировка в программировании это наверное будет замечательно, только без будущего... стоит увеличится обьему данных/добавиться сложности их структуре и в какойто момент без баз будет не обойтись... их не просто так придумали.