以下のコードから、最後のコマンドが実行されたデータベースの名前を確認したいと思います。
この場合、私はmy_other_database
を探しています。
彼はこれを見つける方法はありますか?この情報のために私が見なければならないDMVはありますか?
また、更新が動的SQLでラップされている場合、それを追跡することは可能でしょうか?
use my_database
go
begin tran t1
UPDATE my_other_database.REF.applicationReference
SET uploadPaperReferences = 0
WHERE REFERENCEID IN (
69361,
69690,
69354,
69358,
69362,
69732,
69863,
70187
)
commit tran t1
私は何を達成しようとしていますか?最後に、以下の例のように、サーバーの名前と使用しているデータベースの名前を出力します。
ただし、以下の例では、技術的にはデータベースcola
内にいましたが、ステートメントはapcore.upl.applicationDocument
であり、apcore
は別のデータベースです。
apcore
の代わりにcola
を印刷する方法はありますか?
SET NOCOUNT OFF
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN TRAN T1
PRINT ''
PRINT 'AFTER BEGIN TRAN'
PRINT ''
PRINT '@@TRANCOUNT: ' + CAST(@@TRANCOUNT AS VARCHAR)
PRINT '@@SERVERNAME: ' + CAST(@@SERVERNAME AS VARCHAR) + CHAR(10) + 'Databasename: ' + DB_NAME()
PRINT ''
DECLARE @row INT
USE COLA
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
update t
set documentstateid = 5
from apcore.upl.applicationDocument t
where applicationid in (
319761
,320455
,333433
,351642
,371539
,372508
)
and documentStateId not in (1,5)
SELECT @row = @@ROWCOUNT
PRINT ''
PRINT 'AFTER RUNNING THE UPDATE(s)'
PRINT ''
PRINT 'The number of rows updated:' + SPACE(1) + CAST(@row as varchar)
PRINT '@@TRANCOUNT: ' + CAST(@@TRANCOUNT AS VARCHAR)
PRINT 'Server Name is:' + space(1) + @@SERVERNAME + CHAR(10) + 'Databasename: ' + DB_NAME()
COMMIT TRAN T1
PRINT ''
PRINT 'AFTER COMMIT'
PRINT ''
PRINT '@@TRANCOUNT: ' + CAST(@@TRANCOUNT AS VARCHAR)
PRINT 'Server Name is:' + space(1) + @@SERVERNAME + CHAR(10) + 'Databasename: ' + DB_NAME()
アドホッククエリは、ログインしたか、ほとんどの場合USE
ステートメントを介して最近変更されたデータベースで実行されます。
ストアドプロシージャまたは関数内で実行されているクエリは、それらが含まれているモジュールが存在するデータベースで実行されます。
例えば:
_USE [tempdb];
-- DROP PROCEDURE dbo.CurrentDatabaseTest;
GO
CREATE PROCEDURE dbo.CurrentDatabaseTest
AS
SET NOCOUNT ON;
SELECT db.[database_id], db.[name]
FROM sys.dm_exec_sessions es
INNER JOIN sys.databases db
ON db.[database_id] = es.[database_id]
WHERE es.[session_id] = @@SPID;
GO
USE [model];
SELECT db.[database_id], db.[name]
FROM sys.dm_exec_sessions es
INNER JOIN sys.databases db
ON db.[database_id] = es.[database_id]
WHERE es.[session_id] = @@SPID;
EXEC tempdb.dbo.CurrentDatabaseTest;
GO
_
上記を実行すると、以下が返されます。
_database_id name
3 model
database_id name
2 tempdb
_
次のクエリからデータベースIDを取得できる場合がありますが、常にそうとは限りません。
_SELECT txt.*
FROM sys.dm_exec_connections con
OUTER APPLY sys.dm_exec_sql_text(con.[most_recent_sql_handle]) txt
--WHERE con.[session_id] = @@SPID;
_
documentation は、返されたdbid
フィールドの値に関して次のように述べています。
アドホックおよび準備されたSQLステートメントの場合、ステートメントがコンパイルされたデータベースのID。
ただし、私のテストでは、最後のステートメントがアドホックだった場合はNULL
のように見えることが示されています。
ああ、でも私は次のようなメモを見ました。
dbidは、アドホッククエリのsql_handleから決定できません。アドホッククエリのdbidを決定するには、代わりにplan_handleを使用します。
残念ながら、_plan_handle
_または_sys.dm_exec_connections
_から_sys.dm_exec_sessions
_を取得することはできません。 _sys.dm_exec_requests
_から取得できますが、行はセッションがクエリを実行しているときにのみ存在します。クエリが終了すると、その行はそのDMVに含まれなくなります。また、そのDMVを使用して現在のセッションの値を取得する場合、クエリはデータベースを見つけるために実行しているクエリになるため、常に現在のデータベースになります。この場合は、 _database_id
_から_sys.dm_exec_sessions
_を選択するか、組み込みのDB_NAME()
およびDB_ID()
関数を使用します(パラメーターを渡さないでください)。
UPDATE質問の追加情報への対応
[i]以下の例では、技術的にはデータベース
cola
内にいましたが、ステートメントは_apcore.upl.applicationDocument
_であり、apcore
は別のデータベースです。
はい、これらは2つの異なるデータベースですが、ここで何が起こっているのか誤解していると思います。そのステートメントは単一のオブジェクトを参照していました。ただし、マルチオブジェクトクエリについて考えてみます。
_ update t
set documentstateid = 5
from apcore.upl.applicationDocument t
INNER JOIN other_db.dbo.some_table st
ON st.column = t.column
where applicationid in (...
_
現在、2つのデータベースが参照されていますが、どちらも使用していません。
そのテーブルにトリガーがある場合、クエリでOUTPUT
句が使用されている場合、またはスナップショットアイソレーションが有効になっている場合は、tempdb
も含まれます。
実際に存在する唯一のコンテキストは、現在使用しているDBです。
また、モジュール(ストアドプロシージャ、トリガー、関数、およびビュー)に関しては、コンテキストは、それらがどこから呼び出されたかに関係なく、それらが存在するDBです。
ただし、モジュールには2つの例外があります。
master
に存在し、「システムストアドプロシージャ」としてマークされているストアドプロシージャには、実行されている場所のコンテキストがあります。CREATE PROCEDURE
_の時点での現在のDB、必ずしもtempdb
ではない)でクエリが実行されるという奇妙なケースですが、システム関数(例: DB_NAME()
、DB_ID()
など)はcurrentDBを取得します。このスクリプトのコンテキストはmy_database
。クエリが別のデータベースのオブジェクトを参照しているだけです。 1つのクエリで複数のデータベースのオブジェクトを使用するシナリオを考えてみます。どのデータベースを返したいですか?
何を達成しようとしていますか?