web-dev-qa-db-ja.com

タスクを実行するためにSQLサーバーの設定を一時的に変更し、終了したら元に戻す方法

以下のスクリプトを一度に実行すると、次のエラーメッセージが表示されます。

メッセージ15281、レベル16、状態1、行58 SQL Serverは、コンポーネント 'アドホック分散クエリ'のステートメント 'OpenRowset/OpenDatasource'へのアクセスをブロックしました。このサーバーのセキュリティ構成の一部としてこのコンポーネントがオフになっているためです。システム管理者は、sp_configureを使用して「アドホック分散クエリ」の使用を有効にすることができます。 「アドホック分散クエリ」の有効化の詳細については、SQL Server Books Onlineで「アドホック分散クエリ」を検索してください。

しかし、これを最初に実行してから完全なスクリプトを実行すると、問題はありません。

exec sp_configure 'Ad Hoc Distributed Queries', 1
reconfigure

私が得た印象は、sql-serverがメモリ内の構成された値を調べ、それらが変更されたことを認識していないようです。

この動作を変更するにはどうすればよいですか?

ここに完全なスクリプトがあります:

    SET NOCOUNT ON;

    declare @prevAdvancedOptions int
    declare @prevXpCmdshell int
    declare @adhocdistque  int

-------------------------------------------------------------------------------------------         

--SQL Server blocked access to STATEMENT 'OpenRowset/OpenDatasource' of component 'Ad Hoc Distributed Queries' 
-- because this component is turned off as part of the security configuration for this server. 

--A system administrator can enable the use of 'Ad Hoc Distributed Queries' by using sp_configure. 
--For more information about enabling 'Ad Hoc Distributed Queries', see "Surface Area Configuration" in SQL Server Books Online. 





select @prevAdvancedOptions = cast(value_in_use as int) from sys.configurations where name = 'show advanced options'
select @prevXpCmdshell = cast(value_in_use as int) from sys.configurations where name = 'xp_cmdshell'
select @adhocdistque = cast(value_in_use as int) from sys.configurations where name = 'Ad Hoc Distributed Queries'

PRINT @prevAdvancedOptions
PRINT @prevXpCmdshell
print @adhocdistque 


if (@prevAdvancedOptions = 0)
begin
    exec sp_configure 'show advanced options', 1
    reconfigure
end

if (@prevXpCmdshell = 0)
begin
    exec sp_configure 'xp_cmdshell', 1
    reconfigure
end

if (@adhocdistque  = 0)
begin
    exec sp_configure 'Ad Hoc Distributed Queries', 1
    reconfigure
end

/* -----------------------------------------------------------------  do work - begin */


SELECT  * 
      FROM OPENROWSET('sqloledb', 'server=(local);trusted_connection=yes'
      , 'set fmtonly off exec msdb.dbo.sp_help_job')
      --where name in
      --        ( 'WebFeed UKProductOffer Offers'
            --   ,'WebFeed USProductOffer Offers'
            --   ,'WebFeed DEProductOffer Offers'
            --   ,'WebFeed ATProductOffer Offers'
            --   ,'WebFeed FRProductOffer Offers'
            --   ,'WebFeed EUProductOffer Offers'
            --   ,'WebFeed AUProductOffer Offers')


/* -----------------------------------------------------------------  do work - end */

---------------------------------------------------
-- restore the settings as they were previously
---------------------------------------------------

if (@prevXpCmdshell = 0)
begin
    exec sp_configure 'xp_cmdshell', 0
    reconfigure
end

if (@prevAdvancedOptions = 0)
begin
    exec sp_configure 'show advanced options', 0
    reconfigure
end

if (@adhocdistque = 0)
begin
    exec sp_configure 'Ad Hoc Distributed Queries', 0
    reconfigure
end
2

あなたが構築しているものが良いアイデアかどうかはわかりませんが、以下のコードでうまくいくはずです。

スクリプトを個別のバッチに分離するには、基本的にGOステートメントを含める必要があります。一時テーブルを使用して元の設定値を保存すると、各バッチで値にアクセスできます。

ストアドプロシージャにGOステートメントを含めることはできないため、このプロセスを自動化する場合は、スクリプトを別の方法(エージェントジョブステップ、SSIS、PowerShellなど)で分離する必要があります。

IF OBJECT_ID('tempdb.dbo.#Settings') IS NOT NULL
    DROP TABLE #Settings;

CREATE TABLE #Settings
(
    Setting VARCHAR(100),
    Val INT
)
INSERT #Settings (Setting, Val)
SELECT 'show advanced options', cast(value_in_use as int) from sys.configurations where name = 'show advanced options'
UNION
SELECT 'xp_cmdshell', cast(value_in_use as int) from sys.configurations where name = 'xp_cmdshell'
UNION
SELECT 'Ad Hoc Distributed Queries', cast(value_in_use as int) from sys.configurations where name = 'Ad Hoc Distributed Queries'

SELECT * FROM #Settings;


if ((SELECT val FROM #Settings where Setting = 'show advanced options') = 0)
begin
    exec sp_configure 'show advanced options', 1
    reconfigure
end

if ((SELECT val FROM #Settings where Setting = 'xp_cmdshell') = 0)
begin
    exec sp_configure 'xp_cmdshell', 1
    reconfigure
end

if ((SELECT val FROM #Settings where Setting = 'Ad Hoc Distributed Queries')  = 0)
begin
    exec sp_configure 'Ad Hoc Distributed Queries', 1
    reconfigure
end
go
/* -----------------------------------------------------------------  do work - begin */

    SELECT  * 
          FROM OPENROWSET('sqloledb', 'server=(local);trusted_connection=yes'
          , 'set fmtonly off exec msdb.dbo.sp_help_job')
          --where name in
          --        ( 'WebFeed UKProductOffer Offers'
                --   ,'WebFeed USProductOffer Offers'
                --   ,'WebFeed DEProductOffer Offers'
                --   ,'WebFeed ATProductOffer Offers'
                --   ,'WebFeed FRProductOffer Offers'
                --   ,'WebFeed EUProductOffer Offers'
                --   ,'WebFeed AUProductOffer Offers')

/* -----------------------------------------------------------------  do work - end */

---------------------------------------------------
-- restore the settings as they were previously
---------------------------------------------------
go
if ((SELECT val FROM #Settings where Setting = 'xp_cmdshell') = 0)
begin
    exec sp_configure 'xp_cmdshell', 0
    reconfigure
end

if ((SELECT val FROM #Settings where Setting = 'Ad Hoc Distributed Queries') = 0)
begin
    exec sp_configure 'Ad Hoc Distributed Queries', 0
    reconfigure
end

if ((SELECT val FROM #Settings where Setting = 'show advanced options') = 0)
begin
    exec sp_configure 'show advanced options', 0
    reconfigure
end

IF OBJECT_ID('tempdb.dbo.#Settings') IS NOT NULL
    DROP TABLE #Settings;
2
James Anderson