Грешката „Сървърът не е конфигуриран за ДОСТЪП ДО ДАННИ“ в SQL Server е често срещана грешка, когато се опитвате да изпълните разпределена заявка срещу сървър, който има деактивирана настройка за достъп до данни.
Грешката ще съдържа името на сървъра, до който се опитвате да осъществите достъп. Например, ако името на вашия сървър е SQL01, грешката ще се чете нещо подобно:
Msg 7411, Level 16, State 1, Line 1 Server 'SQL01' is not configured for DATA ACCESS.
„Достъп до данни“ е настройка, която активира и деактивира свързан сървър за достъп до разпределена заявка.
Често срещана причина за тази грешка е, когато се опитате да изпълните OPENQUERY()
срещу локалния сървър. Ако наистина искате да стартирате OPENQUERY()
срещу сървъра, ще трябва да се уверите, че достъпът до данни е активиран за този сървър – дори ако това е вашият локален сървър.
Тази статия разглежда пример за изпълнение на заявка, която генерира грешката, проверка дали сървърът има активиран достъп до данни, разрешаване на достъп до данни, повторна проверка и накрая стартиране на заявката отново. Ако не искате да преминете през целия сценарий, превъртете надолу до заглавието „Решението“ по-долу. Като алтернатива, вижте Как да активирате и деактивирате достъпа до данни в SQL Server за бърз пример за разрешаване и деактивиране на достъп до данни.
Вижте също 2 начина да проверите дали достъпът до данни е разрешен, ако просто искате да проверите настройката.
В противен случай, четете нататък – всичко е обхванато в тази статия.
Пример 1 – Грешката
Ето пример за сценарий, който причинява грешката.
SELECT COLUMN_NAME, TYPE_NAME, PRECISION, LENGTH FROM OPENQUERY ( sqlserver007, 'EXEC WideWorldImporters.[dbo].[sp_columns] Cities, Application;' );
Резултат:
Msg 7411, Level 16, State 1, Line 1 Server 'sqlserver007' is not configured for DATA ACCESS.
В този случай се опитвам да изпълня OPENQUERY()
срещу моя собствен локален сървър, наречен
sqlserver007
, но не успява, защото сървърът няма активиран достъп до данни.
Може би се чудите защо изпълнявам OPENQUERY()
срещу моя собствен сървър, когато можех просто да извикам съхранената процедура локално? Това е вярно, но в този случай съхранената процедура връща повече колони, отколкото са ми необходими, така че реших, че е достатъчно лесно просто да я стартирам през OPENQUERY()
за да мога да избера нужните ми колони. Дох! Не е толкова лесно, колкото си мислех!
Но този малък проблем е достатъчно лесен за разрешаване, така че нека продължим.
Пример 2 – Проверете настройката за достъп до данни
Можем да видим дали даден сървър има разрешен достъп до данни, като проверим sys.servers
изглед на системния каталог.
SELECT name, is_data_access_enabled FROM sys.servers;
Резултат:
+--------------+--------------------------+ | name | is_data_access_enabled | |--------------+--------------------------| | sqlserver007 | 0 | | Homer | 1 | +--------------+--------------------------+
В този случай достъпът до данни е разрешен за сървъра, наречен Homer , но не и за сървъра, наречен sqlserver007 .
В случай, че се интересувате, sp_helpserver
системната съхранена процедура ще ни даде и тази информация:
EXEC sp_helpserver;
Резултат:
+--------------+--------------------------------+----------------------------------+------+------------------+-------------------+-----------------+ | name | network_name | status | id | collation_name | connect_timeout | query_timeout | |--------------+--------------------------------+----------------------------------+------+------------------+-------------------+-----------------| | sqlserver007 | sqlserver007 | rpc,rpc out,use remote collation | 0 | NULL | 0 | 0 | | Homer | NULL | data access,use remote collation | 1 | NULL | 0 | 0 | +--------------+--------------------------------+----------------------------------+------+------------------+-------------------+-----------------+
Ако погледнете в статус колона, ще видите, че достъп до данни е включен в реда за Homer , но не и за sqlserver007 .
Пример 3 – Решението
Ето как да разрешите достъп до данни.
EXEC sp_serveroption @server = 'sqlserver007', @optname = 'DATA ACCESS', @optvalue = 'TRUE';
Резултат:
Commands completed successfully.
Пример 4 – Проверете отново настройката
Сега можем да проверим отново настройката за достъп до данни.
SELECT name, is_data_access_enabled FROM sys.servers;
Резултат:
+--------------+--------------------------+ | name | is_data_access_enabled | |--------------+--------------------------| | sqlserver007 | 1 | | Homer | 1 | +--------------+--------------------------+
Сега моят локален сървър има активиран достъп до данни.
И ето как изглежда с sp_helpserver
:
EXEC sp_helpserver;
Резултат:
+--------------+--------------------------------+----------------------------------------------+------+------------------+-------------------+-----------------+ | name | network_name | status | id | collation_name | connect_timeout | query_timeout | |--------------+--------------------------------+----------------------------------------------+------+------------------+-------------------+-----------------| | sqlserver007 | sqlserver007 | rpc,rpc out,data access,use remote collation | 0 | NULL | 0 | 0 | | Homer | NULL | data access,use remote collation | 1 | NULL | 0 | 0 | +--------------+--------------------------------+----------------------------------------------+------+------------------+-------------------+-----------------+
Вече можем да видим този достъп до данни е добавен под статус колона.
Пример 5 – Изпълнете отново оригиналната заявка
След като активирахме достъпа до данни, нека изпълним отново оригиналната заявка.
SELECT COLUMN_NAME, TYPE_NAME, PRECISION, LENGTH FROM OPENQUERY ( sqlserver007, 'EXEC WideWorldImporters.[dbo].[sp_columns] Cities, Application;' );
Резултат:
+--------------------------+-------------+-------------+------------+ | COLUMN_NAME | TYPE_NAME | PRECISION | LENGTH | |--------------------------+-------------+-------------+------------| | CityID | int | 10 | 4 | | CityName | nvarchar | 50 | 100 | | StateProvinceID | int | 10 | 4 | | Location | geography | 2147483647 | 2147483647 | | LatestRecordedPopulation | bigint | 19 | 8 | | LastEditedBy | int | 10 | 4 | | ValidFrom | datetime2 | 27 | 54 | | ValidTo | datetime2 | 27 | 54 | +--------------------------+-------------+-------------+------------+
Този път работи без грешка.
Въпреки че този пример използва OPENQUERY()
към моя локален сървър, същата корекция ще се приложи, ако се опитвам да изпълня разпределена заявка срещу (отдалечен) свързан сървър. Независимо от това, горните стъпки все още се извършват на моя локален сървър (няма нужда да докосвате отдалечения сървър).