Создание новой записи, содержащей значения на основе запросов других таблиц в MS-Access - PullRequest
1 голос
/ 01 февраля 2011

Я хочу создать новую запись в таблице почтовых программ, где три поля будут содержать значения: contacts_first_filter_id, mailer_states_id, creation_at.И два из этих значений основаны на запросах из других таблиц, а последнее - только текущее время.

Я пробовал несколько способов добиться этого, но ни один из них не сработал.Сначала я попытался создать запрос непосредственно в sql design:

INSERT INTO mailers ( contacts_first_filter_id, mailer_states_id, created_at )
VALUES (DLookup("id","update_mailer_step_two"), DLookup("id","mailer_states" & "mailer_state = 'sent'"), Now());

Это выдает ошибку 'unknown'.

Я также попытался поместить это в редактор VBA и вызвать его нажатием кнопки:

Private Sub Command6_Click()


        Dim CFF_ID As String, MS_ID As String, strSQL As String

        CFF_ID = "SELECT update_mailer_step_two.id FROM update_mailer_step_two"

        MS_ID = "SELECT mailer_states.id FROM mailer_states WHERE mailer_states.mailer_state = 'sent'"

        strSQL = "INSERT INTO mailers ( contacts_first_filter_id, mailer_states_id, created_at )VALUES ((" & CFF_ID & "),(" & MS_ID & "),NOW())"

        DoCmd.RunSQL strSQL

End Sub

Это приводит к ошибке: «Ввод запроса должен содержать хотя бы одну таблицу или запрос».

Я испробовал приведенную ниже рекомендацию, используя INNER JOIN, но, хотя это не приводит к ошибке, он добавляет 0 строк, предположительно потому, что между update_mailer_step_two и mailer_states нет ссылки:

INSERT INTO mailers ( contacts_first_filter_id, mailer_states_id, created_at )
SELECT update_mailer_step_two.id, mailer_states.id, Now()
FROM update_mailer_step_two INNER JOIN mailer_states ON update_mailer_step_two.id = mailer_states.ID
WHERE mailer_states.mailer_state = 'sent';

mailer_states tableэто просто таблица, которая содержит поле mailer_state с текстом.Это просто таблица поиска, которая никогда не меняется.

update_mailer_step_2 содержит одно поле с именем id, которое содержит набор идентификаторов, связанных с контактами в базе данных.Следовательно, вообще нет никакой связи между mailer_states и update_mailer_step_2.

** То, что я думал, что смогу сделать, это когда я создаю update_mailer_step_two, добавлю новый столбец и по умолчанию его со значением, соответствующим mailer_states, так чтоВНУТРЕННЕЕ СОЕДИНЕНИЕ будет работать.К сожалению, кажется, что вы не можете сделать это в Access!

В другом сообщении, посвященном стеке, вы можете:

SQL для добавления столбца со значением по умолчанию - Access 2003

Но это не работает для меня.

У меня закончились идеи о том, как разместить запрос на основе другой таблицы в качестве значения для запроса, который предназначен для создания новой записи в таблице.

Спасибо за ответ.

Ответы [ 4 ]

3 голосов
/ 01 февраля 2011

Попробуйте свои 2 оператора DLookup в Immediate Window (Ctrl + g).

? DLookup("id","update_mailer_step_two")
? DLookup("id","mailer_states", "mailer_state = 'sent'")

Если они работают (не выбрасывают ошибки) и возвращают то, что вы хотите, попробуйте включить их в свою подпрограмму.

Private Sub Command6_Click()
    Dim CFF_ID As Long, MS_ID As Long, strSQL As String
    Dim db As DAO.Database
    CFF_ID = DLookup("id","update_mailer_step_two")
    MS_ID = DLookup("id","mailer_states", "mailer_state = 'sent'")
    strSQL = "INSERT INTO mailers (contacts_first_filter_id, mailer_states_id, created_at) " & _
        "VALUES (" & CFF_ID & ", " & MS_ID & ", NOW())"
    'DoCmd.RunSQL strSQL '
    Debug.Print strSQL 'look in Immediate Window to see the completed INSERT statement '
    Set db = CurrentDb
    db.Execute strSQL, dbFailOnError
    Set db = Nothing
End Sub

Этот непроверенный код принимает числовые типы данных для полей CFF_ID, MS_ID, contacts_first_filter_id и mailer_states_id в почтовых программах и полей id в таблицах update_mailer_step_two и mailer_states.Если какой-либо из них на самом деле является текстовым, вам придется внести изменения в код или сообщить нам, какой именно.

Редактировать: Цель строки Debug.Print - позволить вам просмотреть завершенную вставкузаявление, которое вы просите БД выполнить.Если это не удается, вы можете скопировать текст оператора и вставить его в представление SQL нового запроса.Там вы можете настроить его так, чтобы Access его принял.Затем настройте код так, чтобы он выполнял ту же рабочую инструкцию INSERT.

3 голосов
/ 01 февраля 2011

Ваш первый подход (с использованием запроса, содержащего вызовы DLookup) в принципе должен работать, но он имеет синтаксическую ошибку. Предложение @HansUp о том, чтобы каждый DLookup запускался отдельно, поможет вам определить это (в редакторе Visual Basic нажмите Ctrl-G, чтобы отобразить промежуточное окно; знак вопроса перед каждым выражением в примере @ HansUp - это требуется).

В частности, амперсанд во втором вызове DLookup является символом конкатенации строк, что означает, что ваш текущий вызов эквивалентен:

DLookup("id","mailer_statesmailer_state = 'sent'")

Вместо этого измените его на:

DLookup("id","mailer_states", "mailer_state = 'sent'")


EXTRA

Чтобы вставить одну новую строку для каждой строки в update_mailer_step_two, попробуйте следующее:

INSERT INTO mailers ( contacts_first_filter_id, mailer_states_id, created_at )
SELECT update_mailer_step_two.id,
       DLookup("id","mailer_states", "mailer_state = 'sent'"),
       Now()
FROM update_mailer_step_two
0 голосов
/ 01 февраля 2011

Я думаю, что ваш пример нажатия кнопки также имеет синтаксические ошибки при построении строки.Это должно работать (с остальной частью кода, при условии, что ваши DLoookups работают правильно, как отмечено HansUp):

strSql = "INSERT INTO mailers (contacts_first_filter_id,  mailer_states_id," & _
       " created_at) VALUES (" & CFF_ID & ", " & MS_ID & ", #" & Now() & "#)"

Я не уверен, есть ли дополнительные пареныто, что я удалил, будет иметь какой-либо эффект, и разница между белым пробелом не будет без разницы, но моя версия позволяет VBA оценить Now() и встроить значение в строку.Access использует # для цитирования дат.

0 голосов
/ 01 февраля 2011

Вы пытаетесь вставить результаты оператора select в таблицу.Тем не менее, оператор выбора независимо выбирает из двух разных таблиц.

Я не думаю, что это будет работать.

Главным образом потому, как он обрабатывает два независимых результата.Создает ли он список с крестиком, внутренним соединением и т. Д.

Я бы создал запрос, который выбирает оба, и затем вставил бы этот запрос в вашу таблицу.Или вы можете внутренне объединить выборки и переслать, которые присоединяются к вашим значениям.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...