Проблемы с обновлением SQL в MS Access-операция должна использовать обновляемый запрос

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

если моя первая таблица если у меня есть поле типа "J1/2", он ищет идентификатор записи в другой таблице с J1 и J2 в соответствующих полях.

это все хорошо работает.

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

какие идеи?

мое заявление SELECT:

SELECT DISTINCT
t1.DD,
t1.TN,
t1.DD & " J" & MID(t1.TN,2,1) AS CalculatedStart,
t1.DD & " J" & MID(t1.TN,4,1) AS CalculatedEnd,
t2.ID
FROM t1 INNER JOIN t2
ON (t1.DD & " J" & MID(t1.TN,2,1)=t2.StartLink)
AND (t1.DD & " J" & MID(t1.TN,4,1)=t2.EndLink)
WHERE t1.TN Like "J?/?"
AND t1.DD Like "M*";

напомним-это отлично работает, и я получаю необходимый t2.Идентифицировать другой конец.

так я хочу сделать что-то вроде:

UPDATE t1 SET t2ID = (
    SELECT Query1.ID
    FROM Query1
    WHERE t1.DD=Query1.DD
    AND t1.TN=Query1.TN
    )
WHERE t1.TN Like "J?/?"
AND t1.DD Like "M*";

только это не удается. Это в самом MS Access, поэтому я не могу представить себе фактическую проблему с разрешениями, как и большинство проблем "операция должна использовать обновляемый запрос". быть.

EDIT: попытка упростить случай, который не работает.

этот запрос обновления в порядке:

UPDATE t1
SET t2ID="Unknown"
WHERE TN LIKE "J?/?"
AND DD LIKE "M*";

это не удается (спасибо Goedke-этот пример, очевидно, терпит неудачу, потому что подзапрос возвращает более 1 результата. Я упростил, чтобы попытаться найти мою проблему)

UPDATE t1
SET t2ID=(SELECT ID FROM t2)
WHERE TN LIKE "J?/?"
AND DD LIKE "M*";

Итак, у меня просто синтаксис подзапроса в некотором роде неправильный?

EDIT: эта инструкция SELECT тоже прекрасна:

SELECT t1.OA, t1.DD, t1.TN, t1.HATRIS,
    query1.DD, query1.TN, query1.ID
FROM t1 INNER JOIN query1
ON t1.DD=query1.DD
AND t1.TN=query1.TN

Furthermore, используя отсчет в инструкции select выше показано,что на комбинацию (DD, TN) возвращается ровно 1 ID

EDIT:

самый простой случай, который я теперь должен-используя различные операторы SELECT у меня теперь есть таблица всего с 2 столбцами-первичный ключ t1 и значение, которое я хочу вставить в t1.

Я все еще не могу писать

UPDATE t1 SET t1.f2 = (SELECT t2.f2 FROM t2 WHERE t2.f1 = t1.f1)

где первичным ключом t1 является f1. Даже добавляя, где t1.f1 IN (выберите f1 из t2) не помогает. (Добавлено для устранения вероятность того, что подзапрос возвращает 0 результатов)

7 ответов


подзапрос (выберите ID из t2) не может работать, если в t2 нет только одной записи. Какой ID вы ожидаете использовать?

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

факт вы используете DISTINCT, это заставит меня заподозрить, что суб-запрос возвращает более одной строки в вашем более сложном примере. Это, вероятно, самая распространенная проблема с назначением результата подзапроса: недостаточное ограничение предложения where.

еще одна проблема, которую я видел с назначением из подзапроса, - это если синтаксис внутреннего запроса неверен. По крайней мере, с SQL 2000 и 2005 back ends процессор запросов будет молча сбой и возврат NULL в таких случаях. (Это, насколько я могу судить, ошибка: Я не вижу причин, почему что-то, что вернет ошибку на верхнем уровне, будет молча разрешено в подзапросе... но это так.)

изменить: Чтобы убедиться, что ни пол, ни я не сходим с ума, я создал следующие таблицы:

t1 | ID, FK, Data
t2 | ID2, Data2

Я не поместите любые ограничения, кроме первичного ключа на ID и ID2. Все поля были текстовыми, что отличается от того, что я обычно используйте для идентификаторов, но не имеет значения.

t1:

ID  FK  Data
Key1        Data1
Key2        Data2
Key3        Data3

t2:

ID2 Data2
Key1    DataA
Key2    DataB
Key3    DataC

запрос вида:

UPDATE t1 SET t1.FK = (select ID2 from t2 where t2.ID2 = t1.ID);

не удалось с тем же сообщением, которое получил Пол.

select *, (select ID2 from t2 where t2.ID2 = t1.ID) as foreign from t1, 

работает, как ожидалось, поэтому мы знаем, что синтаксис подзапроса не виноват.

UPDATE t1 SET t1.FK = 'Key1'

также работает, как ожидалось, поэтому у нас нет поврежденного или не обновляемого назначения.

Примечание: если я изменю бэкэнд базы данных с собственного на SQL 2005, обновление работает! Немного погуглить, и я нахожу Access MVPs, предлагающий DLOOKUP заменить подзапрос:

http://www.eggheadcafe.com/software/aspnet/31849054/update-with-subquerycomp.aspx

по-видимому, это ошибка в Access SQL, которая избегается при использовании SQL Express 2000 или выше. (Результаты google для подзапроса "обновление доступа" поддерживают эту теорию).

см. здесь, как использовать этот обходной путь: http://www.techonthenet.com/access/functions/domain/dlookup.php


Я должен взвесить комментарий Дэвида У. Фентона по поводу операции.

Это очень раздражает проблема с Jet / ACE. Но попробуйте либо:

  1. перейдите к свойствам запроса (нажмите фон панели, на которой таблицы отображаются) и set "Уникальные записи" на "Да"
  2. Вариант 1 эквивалентен добавлению несколько странный вид DISTINCTROW ключевое слово в SELECT предложения, например

:

UPDATE DISTINCTROW tblClient 
       INNER JOIN qryICMSClientCMFinite 
          ON tblClient.ClientID = qryICMSClientCMFinite.ClientID
   SET tblClient.ClientCMType = "F";

Это решает так много проблем, связанных с этим сообщением об ошибке, что это почти смешно.

Это MS Access в двух словах-если вы не знаете секретный обходной путь для проблемы x, вы можете занять несколько дней, пытаясь найти ответ. Знать 10 000 обходных путей - значит программировать доступ. Достаточно ли этого предупреждения для непосвященных ?

Бен


это сработало для меня (Access 2000)

UPDATE DISTINCTROW T1 inner join T2 on T2.f1 = T1.f1  SET f2 = f2;

Я не прочитал весь поток, но это решение, которое я использую:

update (select * from t1 inner join t2 on t1.key = t2.key) set t1.field1 = t2.field2

и это отлично работает в MS Access для меня.


моим решением было изменить мой sql таким образом.

  update (select o.pricein, g.pricein from operations o left join goods g on g.id = o.goodid where o.opertype = 4 and o.acct = 1) 
  set o.pricein = g.pricein

У меня была такая же ошибка ("операция должна использовать обновляемый запрос"), используя Access 2010, и я выполнял простой запрос обновления с внутренним соединением. Все, что я сделал, это добавил первичный ключ к таблице, к которой я присоединялся (у меня уже был один, конечно, на столе, который я обновлял), и все сработало.


для этого: обновление T1 SET t1.f2 = (выберите t2.f2 из t2, где t2.Ф1 = Т1.Ф1)

UPDATE t1 INNER JOIN t2 ON t1.f1 = t2.f1 SET t1.f2 = [t2].[f2];