SQL Server Tips
所有者のないデータベースでのエラー
Adventure Works サンプルデータベースを以下の記事で公開していたスクリプトを使用して次の条件下でアタッチすると所有権の明示的に指定されていないデータベースが出来上がる場合があります。
この問題は [SQL Server 認証] を使用している場合や,Windows アカウントに対応する [ログイン] を明示的に作成している場合は発生しません。
- Windows 認証で SQL Server にログインしている
- Windows 認証に使用しているアカウントが OS の Administrator 権限を有する
- Windows 認証で使用しているアカウントに対応する [ログイン] を SQL Server 上の [セキュリティ] > [ログイン] に作成していない
この場合,データベースに所有者が指定されていないために [データベースダイアグラム] などの一部の機能を利用できずにエラーが発生します。
AdventureWorks サンプルデータベースのセットアップスクリプト
http://blogs.timberlandchapel.com/blogs/timberlandchapel/pages/1141.aspx

次の画像は,データベースのプロパティから [ファイル] を表示した画面です。
所有者の欄が指定されていないことがわかります。

問題の修正
この問題を回避するためには,以下のうちいずれかを行ってください。
対策1:既にアタッチしたデータベースを修正する場合
- [セキュリティ] > [ログイン] にて,使用する Windows アカウントに対応する [ログイン] を作成する
- データベースのプロパティの [ファイル] にて,[所有者] に作成した [ログイン] を割り当てる
対策2:データベースのアタッチを最初からやり直す場合
- [セキュリティ] > [ログイン] にて,使用する Windows アカウントに対応する [ログイン] を作成する
- 作成した [ログイン] でデータベースにログインし直して,スクリプトを実行する
いずれの対策についても,
目的はデータベースに [所有者] を設定することで,
そのためにWindows アカウントに対応する [ログイン] を作成しています。
サンプルデータベースの公開場所の変更
今まで [Microsoft ダウンロードセンター] から入手することのできた SQL Server 2005 のサンプルデータベースの公開場所が変更になっているます。
以前までの公開場所
http://www.microsoft.com/downloads/details.aspx?FamilyID=e719ecf7-9f46-4312-af89-6ad8702e4e6e&DisplayLang=en
現在はこのダウンロードページでは,サンプルデータベースの新しい公開先を示す PDF ファイルに置き換えられています。
Codeplex
SQL Server 2005 サンプルデータベースは,現在は [Codeplex] にて公開されています。
Codeplex は Microsoft が運営する共有ソースまたはオープンソース・プロジェクトのためのコミュニティ開発サイトです。
SQL Server 2005 サンプルデータベースは,[SQL Server Samples and Community Project] の一部として公開されています。
SQL Server Samples and Community Project
http://codeplex.com/SqlServerSamples
このうち [Adventure Works] サンプルデータベースは,2008 CTP 用のものと,従来の 2005 用のものの2つのリリースが公開されています。
SQL Server 2008 July 2007 CTP 向け
http://www.codeplex.com/MSFTDBProdSamples/Release/ProjectReleases.aspx?ReleaseId=5705
SQL Server 2005 SP2 向け
http://www.codeplex.com/MSFTDBProdSamples/Release/ProjectReleases.aspx?ReleaseId=4004
Codeplex で現在公開されている msi ファイルと,以前ダウンロードセンターで公開されていたものの MD5 ハッシュ値は異なっています。
詳細な内容の相違に関するリリースノートはいまのところ確認できていません。
また,Codeplex 上の [Source Code] ページには CSV ファイル形式のデータも公開されているようです。
BUG:既定の SQL Server 2000 インスタンスがインストールされないと、間違って構成された SNMP(機械翻訳)
http://support.microsoft.com/kb/279870/ja
今更ながらという感じですが。つい最近イベントログから新しく拾ったので,
SQL Server 2000 がインストールされたシステムでスタートアップ時に
SNMP(Simple Network Management Protocol)サービスのイベント ログに イベント 1101が吐き出されることがあります。
SNMP サービスが拡張エージェント キー SOFTWARE\Microsoft\MSSQLServer\SNMP\CurrentVersion が足りないかまたは正しく構成されていないので、SNMPサービスはそれを無視しています。
これは,SNMPが名前付きインスタンスを監視するように正しく構成されないからのようです。
レジストリエディタで該当のレジストリエントリを編集してあげる警告が発生しなくなります。
Microsoft SQL Server フルテキスト検索 次期バージョンに向けてのアンケート
https://live.datstat.com/WSS-Collector/Survey.ashx?Name=SQL_FTS_Survey_Ja
Microsoft SQL Server フルテキスト検索 の開発チームが,次期バージョンに向けてのアンケートを実施しています。
フルテキストサーチは,日本語処理がでも比較的安定してきており,
Knowledge Base や,データ辞書などの分野で様々な需要を生んでいます。
次期バージョンに向けて要件のアンケートを行ってくれているということは,
ここは日本からもフィードバックのし時かもしれませんね。
皆さんのご協力をお願いいたします。
DTS パッケージをストアドプロシージャから実行する
シナリオと要件
「DTS パッケージの実行をクライアントからキックしたい」
という要件がけっこうあるようです。
もちろん,DTS には DTSRUN ユーティリティが提供されており,DTS の実行をキックすることができます。
また,カスタムアプリケーションから,DTS のオブジェクトモデルを利用してキックすることも可能です。
しかし,上に書いた2つのアプローチでは,プッシュ型のキックになっており,クライアント側にコンポーネントのインストールが必要になってしまうのです。
そこででてくる要件が,データの転送をサーバー側からプルする形態です。
DTS パッケージをストアドプロシージャなどから呼び出すことができれば,クライアントには ADO や ADO.NET といった一般的なコンポーネントがあるだけで転送を実現できることになります。
この記事は,
SQL Server 2000 Developer Edition Service Pack 4
Data Transformation Services に基づいて記述しています。
一部セキュリティの設定を操作する必要があるため,利用する場合は自己責任でお願いします。
DTSRUN をプル型で利用する
[DTSRUN] は SQL Server のクライアントコンポーネントと共にインストールされるツールなので,通常はサーバーにもインストールされています。
これを利用して,サーバー側で [DTSRUN] をコマンド実行するストアドプロシージャを公開してあげることで要件を実現することができます。
1 [xp_CmdShell] 拡張ストアドプロシージャに渡す,[DTSRUN] の実行コマンドを作成する。
2 [xp_CmdShell] に [DTSRUN] 実行コマンドを引き渡すストアドプロシージャを作成する。
3 クライアント側からストアドプロシージャをコールする。
この方法の問題点は,
- [xp_CmdShell] の実行には特別な権限が必要になる
- [xp_CmdShell] の実行権限は非常に強力で,セキュリティ上の大問題になる
ことです。
この問題点を解決する方法はいくつかありますが,
「OPENROWSET を利用して実行権限を上昇させる」などを参照してください。
SQL Server Agent を利用する
[DTS パッケージ] の実行には [DTSRUN] を利用するのが順当ですが,裏口とでも言える方法があります。
それが,[SQL Server Agent] の [ジョブ] を利用する方法です。
[ジョブ] は標準で外部からコールするストアドプロシージャが用意されているのです。
[DTS パッケージ] をウィザードで作成すると,保存の際に [実行時期] オプションに [あとで実行するために DTS パッケージをスケジュール] という選択肢があります。
これを利用すると,外部からストアドプロシージャで呼び出し可能になるパッケージを簡単に作成することができます。
1 [DTS パッケージ] をウィザードで作成する。
2 [あとで実行するために DTS パッケージをスケジュール] をチェックして,右側のビルドボタンをクリックする。
実際にスケジュールする必要はないでしょうから,[実行間隔] などの情報を変更する必要はありません。
ここで,[開始日] と [終了日] を現在の日付より古い日付に指定します。
こうすることによって,スケジュールとしては実行されないジョブを作成することができます。
3 [DTS パッケージ] の名前と同じジョブが作成されます。
4 [sp_start_job] ストアドプロシージャを利用して作成したジョブを呼び出すストアドプロシージャを公開する。
5 クライアント側からストアドプロシージャをコールする。
CREATE PROCEDURE [ExecPack] AS
EXECUTE msdb..sp_start_job @job_name = 'Test'
GO
これで,外部から呼び出し可能な [DTS パッケージ] を [ストアドプロシージャ] を介して公開できます。
ただし,この方法を用いるためにも,[msdb] へのアクセス権及び公開するストアドプロシージャの実行権限をクライアントに与える必要があります。
システムデータベースにアクセスさせてしまうので,セキュリティ上の問題となることがあります。
もちろん,これを実行するためには,[SQL Server Agent] が起動されていることが必要ですし,[サービスアカウント] の権限の確認が必須です。
  ヒント 
パッケージを実行するジョブの中身
出来上がった [ジョブ] の中身を覗くと,[DTSRUN] をキックする [ステップ] が定義されているのがわかります。
結局は内部的に [DTSRUN] を利用しているだけなんですね。
[SQL Server Agent] のサービスアカウント
[ジョブ] を利用すると,[DTS パッケージ] の実行コンテキストが,[SQL Server Agent] のサービスアカウントになります。
プル型のパッケージ実行を行う場合は,ソースデータのアクセス権をこのサービスアカウントが持っている必要があります。
ちょっと前にアップされていたようなんですけど,気づいてませんでした。
Pattern & Practice に SQL Server のパフォーマンスに関するコンテンツがアップされています。
第14章 SQL Server のパフォーマンス向上
http://www.microsoft.com/japan/msdn/enterprise/pag/scalenetchapt14.asp
ざっと目を通したんですが,
読み応えもあるし,一方でプロジェクトに関係あるところだけ拾い読みするだけでも効果がある
かな,と。
2時間程度のちょっとしたプロセス改善ミーティングなどでいかがでしょう?
Pattern & Practice Home
http://www.microsoft.com/japan/msdn/enterprise/pag/scalenetchapt14.asp
この記事は@IT さんの Database Expert 会議室に投稿した記事のフォローアップです。
シナリオと要件
T-SQL ステートメントのエラー状態によって処理を分岐させ,その状態をイベントログに記録します。
今回は [RAISERROR],[IF~BEGIN~ELSE] を使用します。
[アドホックメッセージ] を利用する
[RAISERROR] の機能だけを利用して,メッセージを記録します。
この機能では SQL エラー番号 50000 としてログ記録されます。
USE TestDB
DECLARE @DBID INT
DECLARE @DBNAME NVARCHAR(128)
SET @DBID = DB_ID()
SET @DBNAME = DB_NAME()
BACKUP DATABASE TESTDB TO DISK = 'E:\test.bak'
IF @@ERROR = 0
BEGIN
RAISERROR ('ID :%d, NAME:%s Backup success.', 1, 1, @DBID, @DBNAME) WITH LOG
END
ELSE
BEGIN
RAISERROR ('ID :%d, NAME:%s Backup fail.', 1, 1, @DBID, @DBNAME) WITH LOG
END
GO
事前に [sp_addmessage] でメッセージを定義しておく。
この機能では SQL エラー番号 やログ記録のオン/オフなどを事前に定義しておくことができます。
EXEC sp_addmessage @msgnum = 50001, @severity =1,
@msgtext ='ID :%d, NAME:%s Backup success.',@with_log=True
EXEC sp_addmessage @msgnum =50002, @severity =1,
@msgtext ='ID :%d, NAME:%s Backup fail.',@with_log=True
GO
USE TestDB
DECLARE @DBID INT
DECLARE @DBNAME NVARCHAR(128)
SET @DBID = DB_ID()
SET @DBNAME = DB_NAME()
BACKUP DATABASE TESTDB TO DISK = 'E:\test.bak'
IF @@ERROR = 0
BEGIN
RAISERROR (50001, 1, 1, @DBID, @DBNAME)
END
ELSE
BEGIN
RAISERROR (50002, 1, 1, @DBID, @DBNAME)
END
GO
この記事は Microsoft SQL Server 2000
Developer Edition Service Pack 4 に基づいて記述しています。
SQL Server のロックとロックの仕組みを連載で再考したいと思います。
これからやってくる,SQL Server 2005 では [Service Broker] 周りなどであらたな特殊ロックが追加されています。
そのまえにもう一度 SQL Server 2000 のロックの仕組みついて総括しておきましょう。
アプリケーションロックを利用して排他制御をする
http://blogs.timberlandchapel.com/blogs/timberlandchapel/articles/204.aspx
初心者DBAさんがもしかしたら役に立つかもしれないクエリ? 第2段です。
SQL Server Agentを利用して実行できるジョブにはActiveXスクリプト(VBSやJScript)を実行させることができます。
以下のクエリでジョブの作成ができます。
USE msdb
GO
EXEC sp_add_job @job_name = 'Test',
@description = 'TestJob'
EXEC sp_add_jobstep @job_name = 'Test',
@step_name = 'TestStep',
@subsystem = 'ACTIVESCRIPTING',
@command = '
Option Explicit
Dim net, fso, OutStream, User
Set net = CreateObject("WScript.Network")
User = net.UserName
Set fso =CreateObject("Scripting.FileSystemObject")
Set OutStream = fso.OpenTextFile("D:\" & User & ".log",2,True)
OutStream.WriteLine Now
OutStream.Close
Set net = Nothing
Set OutStream = Nothing
Set fso = Nothing
'
さて,本題。
T-SQLクエリでジョブステップを作成した場合は働かないのですが,
Enterprise Managerでジョブステップを作成する場合には
ある程度のVBSの検証が行われます。
上のサンプルのオブジェクト解放部分(Set Nothing)を書かないと,
「スクリプトがオブジェクトを適切に破棄できません」
というエラーで警告してくれます。
これを利用するとちょっとしたスクリプトチェッカーとして利用できるかも
ただ,CreateObjectの数とSet Nothingの数の対比をとっている程度のようなので,
複雑なチェックには耐えられないようです。
また,一度T-SQLで作成してしまったジョブステップにはこの整合性チェックは有効になりません。
初心者DBAさんがもしかしたら便利かもしれないクエリ第1段です。
FETCHを利用して,指定したデータベース内の全テーブルに対して,
一括で処理をします。
サンプルでは,DBCC DBREINDEXをごりごり投げていますが,
ターゲットがテーブルのものであれば,CHECKTABLEでもなんでも投げることができます。
もちろん。
masterデータベースからデータベース名をフェッチすれば,
サーバー上の全DBに対して一括処理を行うことも可能ですね。
。。。実際は,あんまり実用性はありません(汗
↓↓↓以下サンプル
USE
<DBNAME>GO
DECLARE @table_name as sysname
DECLARE namefetch_cursor CURSOR FOR
SELECT name FROM sysobjects WHERE xtype='U' AND name <> 'dtproperties' ORDER BY name
OPEN namefetch_cursor
FETCH NEXT FROM namefetch_cursor
INTO @table_name
WHILE @@FETCH_STATUS = 0
BEGIN
DBCC DBREINDEX (@table_name)
FETCH NEXT FROM namefetch_cursor
INTO @table_name
END
CLOSE namefetch_cursor
DEALLOCATE namefetch_cursor
GO

Microsoft MVP Windows Server System - SQL Server 2005 July
を受賞させていただくことができました。
本当に本当にありがとうございます。
これからよりいっそう,努力していきたいと思います。
今後ともよろしくお願いいたします。
More Posts
Next page »