Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Delphi: Базы данных и репортинг > Не выполняется SQL - запрос в связной таблице |
Автор: ivanfr 7.8.2012, 12:14 | ||||
При формировании запроса(Access) к таблице Table_of_key_media с TempDataFromMemory[3] содержимым, выводит пустой результат, хотя данные в таблице есть.
Помогите разобраться, почему не работает вышеприведенный код? таблицы связаны след. образом образом ![]() В делфи таблицы тоже связаны и ДБгрид1,2,3 при переключении выводит корректные данные. Если, например, обращаюсь так -
то все работает. |
Автор: kami 7.8.2012, 12:53 |
Нет строк, удовлетворяющих условию Like ? |
Автор: ivanfr 7.8.2012, 13:37 |
Ага. А в базе смотрю они есть. |
Автор: kami 7.8.2012, 14:03 |
Чудес не бывает ![]() ![]() Прямой запрос в Access-е, с подстановкой вместо TempDataFromMemory[3] его значения, выдаст результат? Добавлено через 4 минуты и 57 секунд И кстати, может не ADOQuery1, а ADOQuery2 ? Чтобы не нарушать связи по полям? |
Автор: baldina 7.8.2012, 14:10 |
БД mssql или access? во втором случае спец-символом "любой" является * а не % |
Автор: Данкинг 7.8.2012, 14:35 |
Кто сказал? |
Автор: baldina 7.8.2012, 15:15 |
http://office.microsoft.com/ru-ru/access-help/HP001032253.aspx Добавлено через 54 секунды недоверчивые могут проверить опытным путем ![]() |
Автор: kami 7.8.2012, 15:27 | ||
Проверяли ![]()
http://office.microsoft.com/ru-ru/access-help/HP001032284.aspx?CTT=5&origin=HP001032253 К сожалению не описано, но верно и обратное - символ '*' действует только в Access, а при работе через ADO считается литералом. |
Автор: Данкинг 7.8.2012, 19:26 | ||
Вот у меня работающий код:
|
Автор: ivanfr 8.8.2012, 09:06 | ||
Попробовал по серийному номеру ключ
Результат, пустой. Поля рисунка соответсвуют таблице бд после запроса, но данных в ней нет. ![]() Данные в БД access ![]() Все равно не работает |
Автор: baldina 8.8.2012, 09:27 |
для надежности? моя твоя понимайтен судя по скриншоту ему лайк Serial_Number... |
Автор: ivanfr 8.8.2012, 09:41 | ||||||
or - Так делать нельзя. Запрос делаю по 7 полям, если они совпадают, то я считаю, что в БД уже есть такая запись, следовательно, вносить ее повторно не нужно.
Не сообразил, что хочешь сказать?
|
Автор: baldina 8.8.2012, 09:49 |
на скриншоте вижу кусочек данных в поле Serial_Number - 'e00...', в поле Type_Carrier - 'eToken RPC' а в твоем запросе Type_Carrier сравнивается с e00630FGE ЗЫ:ты бы нормально показал свои данные |
Автор: ivanfr 8.8.2012, 09:52 | ||
Ответить там в коде ошибка.
Данные не там искал. Сейчас поправил заработало, а вот основном коде, который приведен выше не фурычит. Смотрю в Watch list данные соответсвют, тому что находится в таблице в столбцах. |
Автор: Данкинг 8.8.2012, 10:34 |
Гы, вероятно. Я даже не заметил сейчас, а что я тогда имел в виду - кто меня знает. |
Автор: kami 8.8.2012, 10:53 | ||||
Зачем так?
И дублирующаяся строка не сможет вставиться. |
Автор: baldina 8.8.2012, 11:05 | ||
все-таки, как выглядит итоговая строка, которая передается в ADD()? как выглядит хотя бы одна запись в базе, соответствующая этому where? ошибка где-то рядом... кстати, если в этой строчке вообще убрать where, результаты будут? |
Автор: ivanfr 8.8.2012, 11:30 | ||||||||
Итоговая строка выглядит так:
Тут из базы. ![]() а тут после запроса выше приведенного кода. ![]() Вот так выводит запись работает.
Как будет реагировать бд если внее будут летететь пустые
|
Автор: baldina 8.8.2012, 11:38 |
это не итоговая. покажи что получается после подстановки TempDataFromMemory и соответствующую ей запись в БД |
Автор: ivanfr 8.8.2012, 12:02 |
Смотрите выше я отредактировал предыдущее сообщение. |
Автор: baldina 8.8.2012, 12:46 |
итоговую Вы так и не показали))) ну да ладно а в таблице 'eToken RPC...' в общем не морочьте нам голову, проверяйте свои входные данные. еще: у Вас все поля текстовые? и еще: зачем весь этот цирк со сравнением множества полей? идентификатором записи служит id, его и используйте. Добавлено через 3 минуты и 52 секунды если это эквивалентно любому значению, нормально будет реагировать. если отсутствию значения - ненормально. лучше так не делать. используйте в предложении where только те поля, по которым сравнение действительно нужно. |
Автор: ivanfr 8.8.2012, 13:54 | ||||||
Да там в столбце Type_Carrier содержится. вот рисунок из БД ![]()
Можно увидеть из этотого рисунка ![]() Весь этот цирк нужен, для того чтобы в таблицу не попали одинаковые ключевые носители. Как я программе объясню? только путём сравнения всех параметров если они совпадут, то это будет тот же ключевой носитель. особенность в том, что есть КНИ без номеров и в таблице не могу выбрать ключевое поле(уникальное). Любое из всех может повторяться, но не в совокупности вместе взятые. В бд данные попадают из xls где переодически обновляется инфа. |
Автор: baldina 8.8.2012, 14:43 |
если это ключ, вам требуется строгое сравнение, а не like. и почему вы сравниваете все как строки? сравнивайте числа как числа. отключайте все свои условия, включайте по одному и выполняйте запросы - так найдете то, которое не подходит. начните с полей где дата хранится. данные для сравнения полей datetime делайте в формате 'ГГГГ/ММ/ДД' |
Автор: kami 8.8.2012, 14:43 | ||||
Я уже ответил на этот вопрос.
|
Автор: kami 8.8.2012, 18:19 |
В дополнение (к исполнению обязательно): Заменить всё на параметры в запросе. Хотя бы даты. Ибо по умолчанию в Access стоит формат даты "мм.дд.гггг". Соответственно, в приведенном примере TempDataFromMemory[12] интерпретируется как "8 января 2012 года"; Однако, это только на тех компьютерах, которые мне встречались, так что не факт, что где-то не встретится какой-либо другой формат. Параметр же передается вне зависимости от строкового отображения даты. |
Автор: ivanfr 23.8.2012, 11:41 | ||
Заменил на запрос с параметрами теперь работает, как надо! Привожу код
Прошу рассмотреть на ошибки и внести замечания. |
Автор: ivanfr 24.8.2012, 11:14 | ||||
Помогите с ошибкой!
В чём может быть пробмема, убираю эти строки из кода и данные из БД выбираются. Если добавляю результат пустые значения. ставлю в ячейку БД значение "1", оставляю нижеприведенный код работает.
|
Автор: kami 24.8.2012, 23:27 |
Вам уже несколько раз сказали, что нужен http://www.gunsmoker.ru/2008/10/x-y-z.html А все эти многокилометровые запросы с кучей AND - лишняя нагрузка на СУБД. |
Автор: ivanfr 27.8.2012, 08:05 | ||
Хорошо. Объясните мне не компетентному, что это такое(нижеприведённый код SQL) и как это мне поможет в решении моей проблемы? Почему, ваше решение должно работать?
Как я программе объясню? только путём сравнения всех параметров если они совпадут, то это будет тот же ключевой носитель. особенность в том, что есть КНИ без номеров и в таблице не могу выбрать ключевое поле(уникальное). Любое из всех может повторяться, но не в совокупности вместе взятые. Я уже ответил на этот вопрос. |
Автор: kami 27.8.2012, 11:59 | ||||
Не нужно программе ничего объяснять. Приведенный мной SQL-код создает ограничение - СУБД не сможет добавить запись в таблицу, если в ней уже есть аналогичная. По каким полям производить сравнение - подставляется вместо (Поле1, Поле2). Можете хоть все поля таблицы перечислить через запятую. Таким образом, после добавления Constraint задача будет сведена к следующему:
И всё. Не нужно никаких формирований лишних запросов, выборок, сравнений с добавляемым и так далее и тому подобное. Всю эту нагрузку возьмет на себя СУБД. А вообще, уважаемый, за столько времени можно уже было почитать справку о том, что такое CONSTRAINT и с чем его едят. Потому что прежде чем писать его сюда, я просмотрел справку к Access, увидел нужный синтаксис, создал тестовую таблицу, ввел ограничение и попробовал добавить одинаковые записи. В отличие от вас. |
Автор: ivanfr 28.8.2012, 09:53 | ||||||||||
Буду учиться. Так как мне нет необходимости в создании таблицы, то я беру вот эту строку:
в Место: 1)"Таблица1" -" Table_of_key_media" 2)"myConstraint" - не понял что это такое. Смотрел в примерах стоит всегда другое значение нe связанное с таблицей, например,
3)"UNIQUE(Поле1, Поле2)" - UNIQUE(Type_Carrier, Serial_Number_Carrier, Issued_Keys, Name_Of_The_Holder_Of_The_Keys,+ 'Employee_Number_Key_Holder, Position_Or_Location_Key, Workstation_Installation_Inventory_Number,'+ 'Type_Key, Date_Of_Issue_Of_Key_Media, Date_of_delivery_of_key, Date_Of_Last_Inspection,'+ 'Integrity_Of_The_Sealing, Order_Of_The_Key_Storage_Medium, Comments )'; И должно получиться следующее: Параметры оставлять и использовать insert нужно?
![]() Не совсем понятно, как добавить в связную таблицу оставшиеся данные. По логике
Прошу Вас объяснить моменты, которые я не понимаю. |
Автор: kami 28.8.2012, 11:37 | ||||
да. А нужно смотреть не в примерах, а в описании самого оператора и особенно - в ремарках. Хелп пересказывать не буду. нет. Читаем. Смотрим еще раз на синтаксис ALTER TABLE. Думаем. Смотрим на выделенное жирным шрифтом. Опять думаем И понимаем, что этот SQL оператор нужно/можно выполнить непосредственно в Access ОДИН раз при создании БД. А потом пользоваться обычным INSERT INTO с его параметрами. Кстати, по поводу исключения могу ошибаться - возможно, ADOQuery.ExecSQL при добавлении записи в таблицу просто вернет 0 вместо 1. Но сути дела это не меняет.
Если добавление было успешно, то следующий запрос "SELECT @@IDENTITY" вернет ID добавленной записи в том случае, если ID поле - автоинкрементное. |
Автор: ivanfr 24.9.2012, 07:58 | ||||
Ура!!! наконце получилось! Как делал: 1)нашёл эту статью где все понятно написано ссылка:http://office.microsoft.com/ru-ru/access-help/HA010341600.aspx Выполнил по пунктно
Запускаю в Delphi следующий код:
БД не дает ввносить изменение если идентичная строка в базе сущестует, если изменить 1 или два поля то данные добавить можно. Благодарю всех кто помогал, отдельное спасибо kami kami Если б сразу сказал, что нужно выполнить SQL запрос в самом Access, что в итоге позволит создать ограничение на несколько полей уже бы сделал давно. |
Автор: kami 24.9.2012, 10:01 | ||||
то ли лыжи не едут,... но:
![]() |
Автор: ivanfr 25.9.2012, 13:51 | ||
На всякий случай добавляю вариант с INSERT INTO
|
Автор: ivanfr 26.9.2012, 09:12 | ||||||
Помогите довести данный вопрос до логического конца.
![]() Рисунок - Схема данных Сейчас данные добавляются, но не связываются, так как отсутсвуют индексы записи. Ранее я устанавливал в ДБ Гриде на запись с locate таблице persona_stor на нужную запись, а затем записывал данные. Сейчас же запись осуществляется с помощью INSERT INTO и ему нужно предоставить индекс для связи таблиц. Делаю следующим образом, передаю, пытаюсь записать данные о ключевом носителе информации. В БД сделал ограничение по 10 столбцам, если совпадают, то запись сделать не возможно. И далее обрабатывается исключительная ситуация, а именно except, - где я пытаюсь дописать информацию о ключе, если запись не совпадает - то записывается в БД. Тут возникает проблема, как узнать все ID нужных мне записей, по которым таблицы связываются друг с другом. Допустим, после записи я могу сразу получить ID текущей записи, следующим образом:
Запишу значение в следующую таблицу (в моём случае Таблица Key_User записи Id_Table_of_Key_Media), но как узнать ID записи вышестоящей таблицы, а именно таблицы persona_stor записи Id_persona_stor записав это значение в таблицу Table_of_key_media столбца Id_table_persona_stor? Есть предположение как это сделать, сформировать sql-запрос на поиск данных из него выбрать id. Есть еще вариант с помощью LOCETE установить на запись а затем извлеч ID только не пойму как. на запись перехожу так:
Помогите решить задачу. |
Автор: kami 27.9.2012, 10:42 | ||
После Locate:
Добавлено через 2 минуты и 56 секунд Ну и соответственно в этот гигантский Insert Into добавляем поле 'id_persona_stor' и значение id_persona_stor |
Автор: ivanfr 27.9.2012, 13:40 | ||||||||
Сам разобрался вчера, долго парился.. но все равно спасибо за ответ.
если так сделать, то он должен добавить индекс только в таблицу КНИ, а в таблицу КИ ничего не добавит и ключ не свяжется. я сделал так для таблицы КНИ
а для таблцы КИ след. образом
Привожу итоговый код:
|