01. プロシージャの結果セットを持つ一時テーブルへのSELECT INTO
開発中には、結果セットを一時テーブルに格納したいと思うことが多々ありますが、これには2つの一般的な方法があります。
I. SELECT INTO
1. select into を使って、事前にテンポラリテーブルを作成することなく、自動的に生成される
select * into #temp from sysobjects
select * from #temp
<スパン 2. 現在のセッションに同名のテンポラリーテーブルが既に存在する場合
select * into #temp from sysobjects
もう一度実行すると、'%1!'という名前のオブジェクトがすでにデータベースに存在するというエラーが報告されます。
Msg 2714, Level 16, State 6, Line 2
データベースに '#temp' という名前のオブジェクトがすでに存在します。
select intoを使う前に、次のような判断をすることができます。
if OBJECT_ID('tempdb... #temp') is not null
drop table #temp
select * into #temp from sysobjects
select * from #temp
3. select into を使って空のテーブルを生成する
データを含まない空のテーブル構造を生成するには、次のように定数不等式を与えればよい。
select * into #temp from sysobjects where 1=2
select * from #temp
II. INSERT INTO
1. insert into を使用するには、まず手動でテンポラリテーブルを作成する必要がある
1.1 select文から返された結果セットを保存する
create table test_getdate(c1 datetime) insert into test_getdate select GETDATE() select * from test_getdate
1.2 ストアドプロシージャから返された結果セットを保存する
create table #helpuser
(
UserName nvarchar(128),
RoleName nvarchar(128),
LoginName nvarchar(128),
DefDBName nvarchar(128),
DefSchemaName nvarchar(128),
UserID smallint,
SID smallint
)
insert into #helpuser exec sp_helpuser
select * from #helpuser
1.3 ダイナミック・ステートメントから返された結果セットの保存
create table test_dbcc
(
TraceFlag varchar(100),
Status tinyint,
Global tinyint,
Session tinyint
)
insert into test_dbcc exec('DBCC TRACESTATUS')
select * from test_dbcc
動的SQLや、DBCCのような型破りなSQL文では、このように結果セットを保存することができます。
2. insert exec文はネストできません
2.1 sp_help_jobの結果セットを一時テーブルに保存しようとする次の例では、エラーが発生します。
create table #JobInfo
(
job_id uniqueidentifier,
originating_server nvarchar(128),
name nvarchar(128),
enabled tinyint,
description nvarchar(512),
start_step_id int,
category nvarchar(128),
owner nvarchar(128),
notify_level_eventlog int,
notify_level_email int,
notify_level_netsend int,
notify_level_page int ,
notify_email_operator nvarchar(128),
notify_netsend_operator nvarchar(128),
notify_page_operator nvarchar(128),
delete_level int,
date_created datetime,
date_modified datetime,
version_number int,
last_run_date int,
last_run_time int,
last_run_outcome int,
next_run_date int,
next_run_time int,
next_run_schedule_id int,
current_execution_status int,
current_execution_step nvarchar(128),
current_retry_attempt int,
has_step int,
has_schedule int,
has_target int,
type int
)
insert into #JobInfo exec msdb..sp_help_job
エラーメッセージを返します。INSERT EXEC文はネストできません。
Msg 8164, Level 16, State 1, Procedure sp_get_composite_job_info, Line 72
INSERT EXEC文は入れ子にできません。
エラーメッセージのストアドプロシージャを展開してください。
exec sp_helptext sp_get_composite_job_info
内部に SQL Server が構文的にサポートしていない別の INSERT INTO...EXEC ネストされた呼び出しを発見しました。
INSERT INTO @xp_results
EXECUTE master.dbo.xp_sqlagent_enum_jobs @can_see_all_running_jobs, @job_owner, @job_id
2.2 この問題は、以下のような分散型クエリで回避することができます。
この書き方は、著者がINSIDE SQL Server 2005で言及している
(1) まず、オープンサーバーのオプションのアドホック分散クエリにアクセスします。
exec sp_configure 'show advanced options',1
RECONFIGURE
GO
exec sp_configure 'Ad Hoc Distributed Queries',1
RECONFIGURE
GO
(2) OPENROWSETでローカルマシンに接続し、プロシージャを実行し、結果セットを取得する。
Windows認証の利用
select * into #JobInfo_S1
from openrowset('sqloledb', 'server=(local);trusted_connection=yes','exec msdb.dbo.sp_help_job')
select * from #JobInfo_S1
SQL Server 認証を使用する
SELECT * INTO #JobInfo_S2
FROM OPENROWSET('SQLOLEDB','127.0.0.1';'sa';'sa_password','exec msdb.dbo.sp_help_job')
SELECT * FROM #JobInfo_S2
これは、手動でテーブルを構築する必要がなく、insert execがネストできない問題を回避するように書かれています。ほとんどすべてのSQL文が使用可能です。
--dbcc cannot be run directly
SELECT a.* into #t
FROM OPENROWSET('SQLOLEDB','127.0.0.1';'sa';'sa_password',
'dbcc log(''master'',3)') AS a
-- can be adapted
SELECT a.* into #t
FROM OPENROWSET('SQLOLEDB','127.0.0.1';'sa';'sa_password',
'exec(''DBCC LOG(''''master'''',3)')') AS a
関連
-
2021MySql-8.0.26インストール詳細チュートリアル(ベビーシッターレベル)
-
解決策: テーブルの定義が正しくありません。
-
INSERT EXEC文は入れ子にできません。
-
SQL SERVER データベース SELECT INTO および INSERT INTO の使用法(テンポラリテーブルへのデータ挿入を含む)
-
は、GROUP BY句に含まれるか、集約関数で使用される必要があります。
-
ORA-30926: ソース・テーブルの安定した行のセットを取得できませんか?
-
DB2 SQL エラーの解決法。sqlcode=-420, sqlstate=22018
-
PDOデータベース接続エラー。SQLSTATE[HY000] [2002] そのようなファイルやディレクトリはありません。
-
MySqlエラー解析'where節'の未知の列'xxx'
-
Linuxでmysql-5.7.30をインストールするための詳細な手順
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
親行が削除または更新できない: 外部キー制約に失敗 解決策
-
ERROR 1046 (3D000)の解決策です。MySQLでアカウント削除時にデータベースが選択されない問題
-
Hibernateでhibernate.propertiesが見つからない問題とデータベース方言の更新の問題
-
解決方法 テーブルの定義が正しくありません。自動列は1つだけで、キーとして定義する必要があります。
-
MySQLデータベースのクエリ機能を使用する際に、グループ関数の使用が無効である問題の解決方法
-
SocketTimeoutExceptionが発生しました。読み取りがタイムアウトした問題のトラブルシューティング
-
IEntityChangeTracker の複数のインスタンスからエンティティオブジェクトを参照できない場合の対処法
-
Postgresql でテーブル "t" の FROM 句の項目が見つからない。
-
ORA-06550 "の解決策。1 行目、7 列目"
-
mysql: この操作には (少なくとも 1 つの) RELOAD 権限が必要です。