Почему «insert (...) values ​​(...)» не может вставить новую строку? - PullRequest
1 голос
/ 07 июня 2010

У меня есть простой оператор вставки SQL в виде:

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

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

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

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

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

Есть ли какие-либо известные ошибки ADO (поставщик = SQLOLEDB.1)?

Есть ли другие объяснения этому поведению?

Спасибо, Нанг.

Ответы [ 4 ]

2 голосов
/ 07 июня 2010

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

2 голосов
/ 07 июня 2010

Если у вас нет никаких исключений, то:

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

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

1 голос
/ 07 июня 2010

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

1 голос
/ 07 июня 2010

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

  • ограничение CHECK
  • ИНОСТРАННЫЙ КЛЮЧ
  • ограничение NOT NULL
  • УНИКАЛЬНОЕ ограничение

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

...