Драйвер ODBC для SQL Server не вызывает ошибок
Этот вопрос является частью серии ошибок в драйвере Microsoft ODBC:
Драйвер ODBC не может вызвать ошибки; но вместо этого подавляет ихЧтение столбцов не по порядку возвращает неверные результатыНевозможно выполнить хранимую процедуру, которая является SYNONYMMicrosoft заявила, что они не будут исправлять эти ошибки в драйвере 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
.