Stary sterownik potrafi działać przez lata, aż nagle po aktualizacji SQL Servera albo aplikacji pojawia się błąd „provider not found”. SQL Server Native Client był popularnym interfejsem dostępu do SQL Servera, ale dziś trzeba wiedzieć, gdzie kończy się jego użyteczność i czym go zastąpić. Wyjaśniam, jak działał, czym różniły się jego warianty ODBC i OLE DB oraz jak bezpiecznie przejść na współczesne sterowniki w aplikacjach .NET i C++.
Najważniejsze decyzje dotyczące dostępu do SQL Servera
- SQL Server Native Client jest technologią starszą i niewskazaną do nowych projektów.
- Rozwiązanie łączyło dwa interfejsy: ODBC dla aplikacji natywnych oraz OLE DB dla aplikacji COM.
- Nie jest dostarczane z SQL Server 2022 ani nowszymi wersjami SSMS.
- W nowych aplikacjach .NET najlepiej użyć pakietu Microsoft.Data.SqlClient.
- Dla C i C++ właściwym następcą jest Microsoft ODBC Driver for SQL Server.
- Przy migracji trzeba sprawdzić sterownik, składnię connection stringa, szyfrowanie i uwierzytelnianie.

Czym był SQL Server Native Client i co właściwie zawierał
SQL Server Native Client, znany także jako SNAC lub SQLNCLI, był natywnym interfejsem programistycznym do komunikacji z SQL Serverem. Pojawił się wraz z SQL Server 2005 i łączył w jednej technologii sterownik ODBC oraz dostawcę OLE DB.
Jego zadanie było proste. Aplikacja wysyłała zapytanie, parametry albo polecenie transakcyjne, a biblioteka tłumaczyła je na komunikację z serwerem SQL i zwracała wynik. Dzięki natywnej implementacji rozwiązanie było używane tam, gdzie liczyły się wydajność, niskie opóźnienia i bezpośredni dostęp do funkcji SQL Servera.
W dokumentacji i konfiguracjach można spotkać przede wszystkim nazwy SQLNCLI oraz SQLNCLI11. Liczba 11 odnosi się do generacji związanej z SQL Server 2012. To ważne podczas diagnozowania starej aplikacji, ponieważ błąd dotyczący właśnie tego providera zwykle oznacza brak odpowiedniej biblioteki, a nie problem z samą bazą.
ODBC i OLE DB w jednym pakiecie
ODBC to standardowy interfejs oparty na funkcjach, często wykorzystywany w C, C++ i narzędziach integracyjnych. Aplikacja może korzystać z DSN, czyli zapisanej konfiguracji połączenia, albo przekazać connection string bezpośrednio w kodzie.
OLE DB jest starszym modelem opartym na interfejsach COM. Spotykam go głównie w aplikacjach Windows, rozwiązaniach korzystających z ADO, starszych usługach oraz komponentach integracyjnych. W tym modelu dostawca występował między innymi pod nazwą SQLNCLI11.
Oba warianty oferowały dostęp do funkcji takich jak MARS, snapshot isolation, typ XML, FILESTREAM czy table-valued parameters. Nie oznacza to jednak, że każda aplikacja musi dziś korzystać z tych samych interfejsów. Współczesny wybór powinien wynikać przede wszystkim z języka, platformy i wymagań utrzymaniowych.
Dlaczego nie warto używać go w nowym projekcie
Najważniejsza informacja jest praktyczna: technologia została wycofana z nowych instalacji. Nie jest dostarczana z SQL Server 2022 i nowszymi wydaniami, a także z SQL Server Management Studio 19 i kolejnych wersji. Microsoft nie zaleca jej również do nowych aplikacji.
To nie znaczy, że każda istniejąca aplikacja przestanie działać natychmiast. Jeżeli ma własną instalację biblioteki lub działa na środowisku, w którym odpowiedni komponent jest obecny, może nadal funkcjonować. Problem pojawia się przy migracji serwera, zmianie systemu, instalacji nowego SSMS albo wdrożeniu na czystej maszynie.
Najczęstsze objawy to komunikaty o nieznanym providerze, brak biblioteki DLL, nieudane otwarcie połączenia albo różnice w obsłudze szyfrowania. W praktyce oznacza to, że stara aplikacja może działać poprawnie, ale jej środowisko staje się trudniejsze do odtworzenia.
Nie polecam też traktować samej obecności biblioteki jako argumentu za pozostaniem przy niej. Brak nowych funkcji, ograniczone wsparcie i ryzyko problemów podczas wdrożenia są ważniejsze niż fakt, że połączenie działa na komputerze dewelopera.
Co wybrać zamiast starszego klienta
Dobór następcy zależy od technologii użytej w aplikacji. W .NET, C++ i aplikacjach COM najlepsze rozwiązanie będzie inne, choć wszystkie współczesne sterowniki komunikują się z tym samym silnikiem SQL Server.
| Technologia aplikacji | Rekomendowany wybór | Kiedy ma sens |
|---|---|---|
| .NET, ASP.NET Core, worker service | Microsoft.Data.SqlClient |
Nowe aplikacje i migracja z System.Data.SqlClient
|
| C lub C++ z ODBC | Microsoft ODBC Driver for SQL Server | Aplikacje natywne, narzędzia systemowe, integracje wieloplatformowe |
| COM, ADO, OLE DB | Microsoft OLE DB Driver for SQL Server | Istniejące aplikacje wymagające modelu OLE DB |
| Entity Framework Core | Provider SQL Server oparty na Microsoft.Data.SqlClient
|
Aplikacje korzystające z ORM |
W projektach .NET wybieram dziś Microsoft.Data.SqlClient, ponieważ jest rozwijany niezależnie od środowiska .NET i obsługuje współczesne scenariusze SQL Server oraz Azure SQL. Starszy System.Data.SqlClient może nadal występować w aplikacjach opartych na .NET Framework, ale do nowego kodu nie jest już rozsądnym wyborem.
Przykładowe połączenie w aplikacji .NET może wyglądać tak:
using Microsoft.Data.SqlClient;
await using var connection = new SqlConnection(connectionString);
await connection.OpenAsync();
await using var command = new SqlCommand(
"SELECT Id, Name FROM dbo.Customers WHERE IsActive = @active",
connection);
command.Parameters.AddWithValue("@active", true);
await using var reader = await command.ExecuteReaderAsync();
while (await reader.ReadAsync())
{
Console.WriteLine($"{reader.GetInt32(0)}: {reader.GetString(1)}");
}
Ważne są tu dwie rzeczy. Parametr @active chroni przed wstrzykiwaniem SQL, a użycie async/await pozwala nie blokować wątku aplikacji podczas oczekiwania na odpowiedź serwera.
Jak wygląda migracja istniejącej aplikacji
Migrację zaczynam od ustalenia, z czego aplikacja faktycznie korzysta. Sama nazwa „SQL Native Client” w dokumentacji projektu niewiele mówi, dlatego sprawdzam kod, pliki konfiguracyjne, zależności instalacyjne i connection stringi.
- Zidentyfikuj interfejs - sprawdź, czy aplikacja używa ODBC, OLE DB, ADO.NET albo biblioteki pośredniej.
- Zapisz obecne ustawienia - skopiuj nazwę providera, tryb uwierzytelniania, timeouty i opcje szyfrowania.
- Wybierz nowy sterownik zgodnie z językiem i modelem dostępu.
- Zmień connection string oraz referencje do bibliotek.
- Przetestuj transakcje i typy danych, a nie tylko prosty SELECT.
- Wdóż aplikację na czystym środowisku, na którym nie ma starego klienta.
Dla aplikacji ODBC przykładowy connection string może wyglądać następująco:
Driver={ODBC Driver 18 for SQL Server};
Server=tcp:sql01.example.local,1433;
Database=Sales;
Encrypt=yes;
TrustServerCertificate=no;
Trusted_Connection=yes;
W środowisku produkcyjnym nie ustawiam bezrefleksyjnie TrustServerCertificate=yes. Ta opcja może ukryć problem z certyfikatem, ale jednocześnie osłabia weryfikację serwera. Lepiej skonfigurować poprawny certyfikat i pozostawić pełną walidację połączenia.
W aplikacji OLE DB zmiana często polega na zastąpieniu providera SQLNCLI11 przez MSOLEDBSQL19. Tu trzeba zwrócić uwagę na różnice w domyślnym szyfrowaniu, typach właściwości oraz wersji sterownika. Nie zakładam, że samo podmienienie nazwy zapewni bezproblemowe działanie.
Typowe błędy podczas przejścia na nowy sterownik
Podmiana tylko nazwy providera
To najczęstszy skrót myślowy. Nowy sterownik może wymagać dodatkowych ustawień dotyczących szyfrowania, certyfikatów albo uwierzytelniania. Jeżeli po zmianie pojawia się błąd TLS, nie oznacza to automatycznie problemu z SQL Serverem.
Test wyłącznie na lokalnym komputerze
Lokalne środowisko często ma zainstalowane kilka generacji sterowników. Dlatego aplikacja działa u programisty, ale nie na serwerze CI/CD lub maszynie klienta. Ja zawsze wykonuję przynajmniej jeden test na czystej maszynie wdrożeniowej, bez przypadkowych komponentów odziedziczonych po starszych projektach.
Brak testów typów danych i transakcji
Proste zapytanie zwracające kilka kolumn nie wystarczy. Trzeba sprawdzić między innymi wartościNULL, daty, dane binarne, duże teksty, procedury składowane, parametry tabelaryczne, timeouty i rollback transakcji.
Przeczytaj również: Transakcje baz danych - ACID, COMMIT, ROLLBACK i izolacja
Przechowywanie haseł w connection stringu
Connection string zapisany w repozytorium jest łatwym celem wycieku. W aplikacjach serwerowych lepiej użyć sekretów środowiskowych, bezpiecznego magazynu konfiguracji albo uwierzytelniania bezhasłowego. W Azure szczególnie warto rozważyć Microsoft Entra ID i tożsamość zarządzaną, jeśli architektura na to pozwala.
Jak podejść do wyboru w aplikacji .NET
Jeżeli tworzę nową aplikację w .NET, nie zaczynam od wyboru starego providera OLE DB ani ODBC. Sięgam po Microsoft.Data.SqlClient, a dopiero później decyduję, czy potrzebuję bezpośredniego ADO.NET, Dappera czy Entity Framework Core. Warstwa ORM nie zastępuje sterownika. Entity Framework Core nadal korzysta z providera komunikującego się z SQL Serverem, dlatego aktualność i konfiguracja tego providera wpływają na szyfrowanie, retry, uwierzytelnianie oraz dostęp do funkcji serwera.Warto też oddzielić migrację sterownika od zmian w logice biznesowej. Najbezpieczniej najpierw zachować istniejące zapytania i przetestować samą komunikację, a dopiero później poprawiać model danych czy optymalizować zapytania. Dzięki temu łatwiej ustalić, czy problem wynika z migracji, czy z równoległej zmiany kodu.
Decyzja zależy od wieku aplikacji i jej celu
Do nowego projektu nie wybierałbym już SQL Server Native Client. Dla .NET właściwym kierunkiem jest Microsoft.Data.SqlClient, dla natywnego ODBC nowy sterownik Microsoftu, a dla istniejącego kodu COM lub OLE DB dostawca MSOLEDBSQL19.
Jeżeli utrzymujesz starszą aplikację, nie musisz przepisywać jej natychmiast. Zacznij od inwentaryzacji zależności, testu na czystym środowisku i sprawdzenia szyfrowania. Taka mała migracja wykonana przed zmianą serwera jest zwykle znacznie tańsza niż ratowanie produkcyjnego wdrożenia po usunięciu starego providera.
