Драйвер ODBC для SQL Server не вызывает ошибок

Этот вопрос является частью серии ошибок в драйвере Microsoft ODBC:

Драйвер ODBC не может вызвать ошибки; но вместо этого подавляет ихЧтение столбцов не по порядку возвращает неверные результатыНевозможно выполнить хранимую процедуру, которая является SYNONYM

Microsoft заявила, что они не будут исправлять эти ошибки в драйвере ODBC.

Фон

Если у меня есть образец таблицы:

CREATE TABLE Wallet (
    WalletID int NOT NULL,
    Name varchar(50) NOT NULL
)

я пытаюсь выдать SQL, который вставляет в таблицу, не указывая значение дляНЕНУЛЕВОЙ Столбец WalletID:

INSERT INTO Wallet (WalletID, Name) VALUES (1, 'Fan')
INSERT INTO Wallet (Name) VALUES ('Ardent Defender') --Constraint violation

SQL Server выдает ошибку:

(Затронут 1 ряд)
Сообщение 515, уровень 16, состояние 2, строка 2
Невозможно вставить значение NULL в столбец «WalletID», таблица «Scratch.dbo.Wallet»; столбец не допускает ноль, с. Вставить не удается.
Заявление было прекращено.

И это имеет смысл.

При подключении с использованием ADO / OLEDB и поставщика OLE DB для SQL Server (SQLOLEDB):

Провайдер = SQLOLEDB; Источник данных = гиперион; Идентификатор пользователя = Contoso; Пароль = Trub4dor;

И я выполняюВСТАВИТЬинфраструктура ADO / OLEDB / COM возвращает ошибку, которая в качестве исключения возвращает язык высокого уровня:

Невозможно вставить значение NULL в столбец «WalletID», таблица «Wallet»; столбец не допускает пустых значений. Вставить не удается

И это все имеет смысл.

Но попробуйте с драйвером ODBC

С дерьмом этонативный клиент Поставщики OLE DB (ирекомендация MS, что вы не используетенативный клиент ODBC драйверы), я думал, что попробую свои силы в использованииSQL Server Драйвер ODBC:

Поставщик = MSDASQL; Драйвер = {SQL Server}; Сервер = {hyperion}; UID = {Contoso}; PWD = {Trub4dor};

Обновление - не рекомендуется: Шесть лет спустя Microsoftобъявил об устаревании поддержки OLE DB для SQL Serverи создания третьего драйвера OLE DB для SQL Server: msoledbsql.(архив)

Ранее Microsoftобъявил об устаревании поставщика Microsoft OLE DB для SQL Server, часть собственного клиента SQL Server (SNAC). В то время это решение было принято, чтобы попытаться придать больше простоты истории разработчиков о разработке собственного программного обеспечения для Windows, когда мы перешли в облачную эру с базой данных SQL Azure, и попытаться использовать сходство JDBC и ODBC для разработчиков. Однако в ходе последующих проверок было установлено, что устаревание является ошибкой, поскольку существенные сценарии в SQL Server по-прежнему зависят от OLE DB, и их изменение может нарушить некоторые существующие сценарии заказчика.

Имея это в виду, мы решилинедооценивать OLE DB и выпустить новую версиюпервый квартал календарного года 2018 Март 2018 г.

Я выдаю свою партию:

INSERT INTO Wallet (WalletID, Name) VALUES (1, 'Fan')
INSERT INTO Wallet (Name) VALUES ('Ardent Defender')

Я был удивлен, узнав, что тот же оператор SQL:

что вызываетINSERT FAILS ошибка в самом SQL Server:

это приводит к ошибке на стороне клиента при использовании поставщика OLE DB для SQL Server

будутмолча ошибка при использовании драйвера ODBC. Оператор выполняется без каких-либо ошибок.

Я был сбит с толку около часа, когда мои операторы SQL выполнялись без ошибок, но строки не появлялись в базе данных.

Silent Fail

Очевидно, что молчаливая неудача не годится.

И, очевидно, я просто не могу использоватьSQL Server Драйвер ODBC,и продолжать использоватьПоставщик Microsoft OLE DB для SQL Server поставщик.

Но что происходит?

Как сказать драйверу ADO-OLEDB-ODBC сообщать об ошибках. Это настройка строки подключения ODBC? Это настройка строки подключения MSDASQL?

Образец Psuedocode

Я на самом деле использую Delphi с ADO. Но я перекодирую его в псевдо-код в стиле C # для более легкого концептуального понимания.

String commandText = 
      "INSERT INTO Wallet (WalletID, Name) VALUES (1, 'Fan')"+CRLF+
      "INSERT INTO Wallet (Name) VALUES ('Ardent Defender')";

ADOConnection conn = new ADOConnection();
conn.ConnectionString = szConnectionString;
conn.Open();

HRESULT hr = conn.Execute(commandText, ref recordsAffected, [eoExecuteNoRecords]);

На самом деле проверкаHRESULT обрабатывается инфраструктурой языка и магией компилятора - генерирует исключение на родном языке, если оноFAILED.

Ответы на вопрос(2)

Ваш ответ на вопрос