SQLのバッチ(トランザクション内で実行される)のデバッグを支援するために、トランザクション内で一部のデータをグローバル一時テーブルにダンプします。グローバル一時テーブルはトランザクション内に作成されます(ここでは説明しないので、選択の余地はありません)。
「with(nolock)」を使用して、トランザクションの外部から(つまり、別の接続の下で)一時テーブルから選択できると思いました。ただし、選択は完了できません。
トランザクションの外部から一時テーブルから選択する方法はありますか?
「できるからといって、そうする必要があるわけではない」の下にこれを提出する
最初のセッションでバインドトークンを生成し、それを何らかの形で公開すると、別のセッションからトランザクションに参加できます。
たとえば、spid 61から:
if @@TRANCOUNT > 0 rollback
go
begin transaction
select *
into ##t
from sys.objects
declare @bind_token varchar(255);
exec sp_getbindtoken @bind_token output
declare @bind_token_bin as varbinary(128) = cast(@bind_token as varbinary(128))
set context_info @bind_token_bin
--rollback
その後、別のセッションから
declare @bind_token varchar(255) = (
select cast(context_info as varchar(255))
from sys.dm_exec_sessions
where session_id = 61
)
exec sp_bindsession @bind_token
go
select * from ##t
いいえ、違います。
作成されたがコミットされていないグローバル一時テーブルは、スキーマ変更ロックによって保護されます。これは、コミットされていない読み取りの分離で必要な最小限のスキーマ安定性ロックを含む、他のすべてのものと 非互換 です。
これが必要な理由を推測するのは難しいですが、通常の問題はグローバル一時テーブルの存続期間に関係しています。これに対する長年の解決策は、プロシージャ内にグローバル一時テーブルを作成することです インスタンスの起動時に実行するようにマークされています 。この方法で作成されたグローバル一時テーブルは、自動的に削除されることはありません。
Azure SQLデータベース(現在はパブリックプレビュー)で、おそらく将来のボックス製品の場合、_ GLOBAL_TEMPORARY_TABLE_AUTODROP
引数がALTER DATABASE SCOPED CONFIGURATION
にあります。
現在のプロセスに小さなコードを追加することが可能である場合、あなたはmightがcheatにできるようになります。
_--Demo setup
DROP TABLE IF EXISTS [dbo].[CUSTOMER]
CREATE TABLE [dbo].[CUSTOMER](
[CustomerID] [int] NOT NULL,
[FirstName] [varchar](20) NOT NULL,
[LastName] [varchar](20) NOT NULL,
[Email] [varchar](30) NOT NULL,
[PhoneNo] [int] NOT NULL,
[StreetAddress] [varchar](40) NULL,
[City] [varchar](20) NULL,
[OrderID] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
[CustomerID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
USE [Test]
GO
INSERT [dbo].[CUSTOMER] ([CustomerID], [FirstName], [LastName], [Email], [PhoneNo], [StreetAddress], [City], [OrderID]) VALUES (13579246, N'David', N'Casey', N'[email protected]', 12826363, N'34 Bray Rd', N'Dublin', 94724274)
GO
INSERT [dbo].[CUSTOMER] ([CustomerID], [FirstName], [LastName], [Email], [PhoneNo], [StreetAddress], [City], [OrderID]) VALUES (16579946, N'Donal', N'Smith', N'[email protected]', 13826563, N'78 Ballybrack Rd', N'Dublin', 14724274)
GO
INSERT [dbo].[CUSTOMER] ([CustomerID], [FirstName], [LastName], [Email], [PhoneNo], [StreetAddress], [City], [OrderID]) VALUES (17579946, N'Steve', N'Reidy', N'[email protected]', 13827563, N'22 Conna Rd', N'Cork', 64724274)
GO
INSERT [dbo].[CUSTOMER] ([CustomerID], [FirstName], [LastName], [Email], [PhoneNo], [StreetAddress], [City], [OrderID]) VALUES (18579946, N'Michael', N'Yule', N'[email protected]', 14827563, N'44 Blasket Rd', N'Kilkenny', 44424274)
GO
_
トランザクションの外側で、XMLを保持する新しいテーブルを作成します
_drop table if exists XmlDataTable
CREATE TABLE XmlDataTable (XmlDataColumn xml)
_
次に、トランザクションでグローバル一時テーブルを作成し、そこから選択してxml rawに変換します。次に、その値をXmlDataTable
に挿入します。
_begin transaction
drop table if exists ##temp
SELECT * INTO ##temp FROM customer --This is your normal create for the global temp table
DECLARE @XmlData XML
--select the data from the global temp table as xml raw
SET @XmlData = (SELECT * FROM ##temp FOR XML raw)
--insert that value into LargeVarcharTable
INSERT INTO XmlDataTable VALUES (@XmlData)
--rollback
_
別のセッションでは、select * from xmldatatable (nolock)
を使用して生のxmlを選択できます。
_select * from xmldatatable (nolock)
<row CustomerID="13579246" FirstName="David" LastName="Casey" Email="[email protected]" PhoneNo="12826363" StreetAddress="34 Bray Rd" City="Dublin" OrderID="94724274"/>
<row CustomerID="16579946" FirstName="Donal" LastName="Smith" Email="[email protected]" PhoneNo="13826563" StreetAddress="78 Ballybrack Rd" City="Dublin" OrderID="14724274"/>
<row CustomerID="17579946" FirstName="Steve" LastName="Reidy" Email="[email protected]" PhoneNo="13827563" StreetAddress="22 Conna Rd" City="Cork" OrderID="64724274"/>
<row CustomerID="18579946" FirstName="Michael" LastName="Yule" Email="[email protected]" PhoneNo="14827563" StreetAddress="44 Blasket Rd" City="Kilkenny" OrderID="44424274"/>
_