2010-06-07 1 views
1

У меня есть простой оператор SQL для вставки формы:Почему «вставить (...) значения (...)» не вставить новую строку?

insert into MyTable (...) values (...) 

Он используется несколько раз для вставки строк и обычно работает, как ожидалось. Он вставляет ровно одну строку в MyTable, которая также является значением, возвращаемым оператором Delphi AffectedRows: = myInsertADOQuery.ExecSQL.

Через некоторое время возникла временная проблема подключения к сети. В результате другие потоки того же приложения воспринимаются EOleExceptions (Ошибка соединения, -2147467259 = неуказанная ошибка). Позже сетевое соединение было восстановлено, эти потоки снова подключены и были в порядке.

Нить, ответственная за выполнение инструкции вставки, описанную выше, однако, не воспринимала проблемы с подключением (без исключений) - возможно, она просто не выполнялась, когда сеть была отключена. Но после проблем с подключением к сети myInsertADOQuery.ExecSQL всегда возвращал 0, и никакие строки больше не были добавлены в MyTable. После перезапуска приложения оператор insert снова работал, как ожидалось.

Для SQL Server существует ли какой-либо определенный случай, когда элемент вставки, подобный приведенному выше, не должен вставлять строку и возвращать 0 в качестве числа затронутых строк? Первичный ключ - это автогенерированный GUID. Нет никаких уникальных ограничений или ограничений проверки (это должно привести к исключению в любом случае, а не к вставке строки).

Существуют ли известные ошибки ADO (Provider = SQLOLEDB.1)?

Любые другие объяснения этого поведения?

Thanks, Nang.

+0

Вы проследили результат с помощью инструмента профилирования SQL, который поставляется с SQL Server? В первом ответе на этот вопрос есть видео, объясняющее, как это сделать: http://stackoverflow.com/questions/504326/trace-file-how-to-use-it –

+0

Нет, я этого не делал. Спасибо за подсказку. Если это произойдет снова, я попробую. – nang

ответ

1

Если значения, которые вы пытаетесь вставить нарушаете

  • проверочное ограничение
  • качестве внешнего ключа отношения
  • не нулевое ограничение
  • ограничение уникальности

или любые другие ограничения, то строки (строки) не будут вставлены.

+0

Спасибо! Правда. Но тогда я ожидал бы исключения, вместо того, чтобы молча вставлять строку. Но кроме того, таких ограничений нет. – nang

1

Вы используете транзакции? Возможно, ваше приложение не имеет autocommit? Некоторые драйверы не фиксируют данные, если в транзакции произошла ошибка.

+0

Спасибо. Никаких явных транзакций не используется, но автокомментировать. Если я использовал транзакции, ExecSQL должен возвращать 1 для количества затронутых строк, не так ли? – nang

2

Если вы не имеете каких-либо исключений, то:

  1. Если таблица содержит триггеры без SET NOCOUNT ON, то на самом деле операцию (INSERT/UPDATE/DELETE) может быть успешно завершена, но ряд постраничные записи могут быть возвращены как 0.
  2. В зависимости от активности транзакции в текущем сеансе другие сеансы могут не видеть изменений, сделанных текущим сеансом. Но текущая сессия увидит собственные изменения, и число затронутых записей будет (может быть) не 0.

Таким образом, точный ответ может зависеть от вашей таблицы DDL (+ триггеры, если есть) и от того, как вы находитесь проверка вставленных строк.

+0

Спасибо. 1. Триггеры не используются. 2. Ни текущий сеанс не замечает вставленные строки, ни внешние сеансы. Я проверяю количество вставленных строк на возвращаемое значение MyQuery.ExecSQL. Кроме того, я проверил таблицу для новых строк через SQL Management Studio - никаких новых строк. Кроме того, в нормальных условиях все работает нормально. Поэтому я предполагаю, что на уровне ADO/провайдера происходит что-то странное, а не на уровне SQL/SQL Server. – nang

+0

Можете ли вы воспроизвести свою проблему? –

+0

В начале все работало нормально. Тогда проблема возникла впервые. С тех пор он был постоянным, пока я не перезапустил приложение. С тех пор я не могу воспроизвести его. – nang

2

Похоже, что ваш Вставить нить потеряла молча подключение и не проверяет его, чтобы сделать автоново-соединение, если это необходимо, но продолжает ставить в очередь вставки без фактической отправки.
Я бы выделил этот код в небольшом автономном приложении, чтобы его отладить и посмотреть, как он себя ведет, когда вы добровольно отключите сеть, а затем снова подключите ее.
Я бы не удивился, если бы вы либо нашли «проглоченное» исключение, либо какой-то код, не указавший на успех/неудачу.
Надеюсь, это поможет ...

+0

Звучит разумно. Что я еще не описал: когда я закрыл приложение, сообщалось о некоторых утечках памяти, включая ~ 45 экземпляров TADOCommand и ~ 45 TADOQuery. Мне просто интересно, где исключение могло быть проглочено, определенно не в моем коде пользователя. В нормальных условиях, как только соединение сломается, все последующие аттестаты выполняют результат запроса в исключении. – nang