質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Q&A

1回答

1424閲覧

SQLServerのテーブル定義取得用のSQL文について

sima9985

総合スコア4

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

0グッド

2クリップ

投稿2020/03/20 14:24

編集2020/03/21 13:04

前提・実現したいこと

参考URLを参考として
SQLServerでテーブル定義を取得したいと考えています。
出力した定義をExcelに貼り付けたいです。

発生している問題・エラーメッセージ

一部のデータベースでサブクエリで複数結果が返って来てしまい上手く結果が取得できません。
SELECT列でサブクエリを使用して該当の列をオブジェクト番号と行番号で絞り込んでいます。
その結果複数結果が返ってきてしまうのが原因だと考えていましたが
違うテーブルで同じ列名があるDBを作成し検証してもエラーが再現せずに困っています。

該当のソースコード

SQL

1--データベース定義取得用-- 2SELECT 3 tbl.name as 'テーブル名', 4 col.name as 'カラム名', 5 type_name(col.user_type_id) as 'データ型', 6 col.max_length as '桁数', 7 CASE( 8 select 9 indx.is_primary_key 10 from 11 sys.indexes indx 12 inner join 13 sys.index_columns indxcol 14 on indx.object_id = indxcol.object_id 15 where 16 indx.object_id = tbl.object_id 17 and indxcol.column_id = col.column_id 18 ) 19 WHEN 1 THEN '〇' 20 ELSE '×' 21 END as '主キー制約', 22 CASE col.is_nullable 23 WHEN 1 THEN '×' 24 ELSE '○' 25 END as 'NOTNULL制約', 26 CASE( 27 select 28 indx.is_unique 29 from 30 sys.indexes indx 31 inner join 32 sys.index_columns indxcol 33 on indx.object_id = indxcol.object_id 34 where 35 indx.object_id = tbl.object_id 36 and indxcol.column_id = col.column_id 37 ) 38 WHEN 1 THEN '〇' 39 ELSE '×' 40 END as '一意制約', 41 CASE col.is_identity 42 WHEN 1 THEN '〇' ELSE  '×' 43 END as '自動採番設定', 44 CASE 45 WHEN( 46 select 47 idcol2.seed_value as '初期値' 48 from 49 sys.identity_columns idcol2 50 inner join 51 sys.columns col2 52 on idcol2.column_id = col2.column_id 53 and col2.object_id = idcol2.object_id 54 where 55 idcol2.object_id = tbl.object_id 56 and idcol2.column_id = col.column_id 57 ) IS NULL THEN 'なし' 58 ELSE( 59 select 60 idcol2.seed_value as '初期値' 61 from 62 sys.identity_columns idcol2 63 inner join 64 sys.columns col2 65 on idcol2.column_id = col2.column_id 66 and col2.object_id = idcol2.object_id 67 where 68 idcol2.object_id = tbl.object_id 69 and idcol2.column_id = col.column_id 70 ) 71 END as '自動採番初期値', 72 CASE 73 WHEN( 74 select 75 idcol2.increment_value as '増減値' 76 from 77 sys.identity_columns idcol2 78 inner join 79 sys.columns col2 80 on idcol2.column_id = col2.column_id 81 and col2.object_id = idcol2.object_id 82 where 83 idcol2.object_id = tbl.object_id 84 and idcol2.column_id = col.column_id 85 ) IS NULL THEN 'なし' 86 ELSE( 87 select 88 idcol2.increment_value as '増減値' 89 from 90 sys.identity_columns idcol2 91 inner join 92 sys.columns col2 93 on idcol2.column_id = col2.column_id 94 and col2.object_id = idcol2.object_id 95 where 96 idcol2.object_id = tbl.object_id 97 and idcol2.column_id = col.column_id 98 ) 99 END as '自動採番増減値', 100 CASE 101 WHEN df.definition IS NULL THEN 'なし' 102 ELSE REPLACE(REPLACE(df.definition, '(', ''), ')', '') 103 END AS '初期値', 104 CASE( 105 select 106 indxcol.is_included_column 107 from 108 sys.indexes indx 109 inner join 110 sys.index_columns indxcol 111 on indx.object_id = indxcol.object_id 112 where 113 indx.object_id = tbl.object_id 114 and indxcol.column_id = col.column_id 115 ) 116 WHEN 0 THEN '〇' 117 ELSE '×' 118 END as 'インデックスキーの有無', 119 CASE 120 WHEN( 121 select 122 rftbl.name 123 from 124 sys.foreign_key_columns fkcol 125 inner join 126 sys.tables rftbl 127 on fkcol.referenced_object_id = rftbl.object_id 128 where 129 fkcol.parent_object_id = tbl.object_id 130 and fkcol.parent_column_id = col.column_id 131 ) IS NULL THEN 'なし' 132 ELSE( 133 select 134 rftbl.name 135 from 136 sys.foreign_key_columns fkcol 137 inner join 138 sys.tables rftbl 139 on fkcol.referenced_object_id = rftbl.object_id 140 where 141 fkcol.parent_object_id = tbl.object_id 142 and fkcol.parent_column_id = col.column_id 143 ) 144 END as '参照先テーブル', 145 CASE 146 WHEN( 147 select 148 rfcol.name 149 from 150 sys.foreign_key_columns fkcol 151 inner join 152 sys.columns rfcol 153 on fkcol.referenced_object_id = rfcol.object_id 154 and fkcol.referenced_column_id = rfcol.column_id 155 where 156 fkcol.parent_object_id = tbl.object_id 157 and fkcol.parent_column_id = col.column_id 158 ) IS NULL THEN 'なし' 159 ELSE( 160 select 161 rfcol.name 162 from 163 sys.foreign_key_columns fkcol 164 inner join 165 sys.columns rfcol 166 on fkcol.referenced_object_id = rfcol.object_id 167 and fkcol.referenced_column_id = rfcol.column_id 168 where 169 fkcol.parent_object_id = tbl.object_id 170 and fkcol.parent_column_id = col.column_id 171 ) 172 END as '参照先列' 173from 174 sys.tables tbl 175 inner join 176 sys.columns col 177 on tbl.object_id = col.object_id 178 left outer join 179 sys.default_constraints df 180 on col.column_id = df.parent_column_id 181WHERE 182 tbl.type = 'U' 183ORDER BY 184 tbl.name, 185 col.name 186; 187--ここまで--

試したこと

違うテーブルに同じ列名が存在するのが原因かと思い
検証として新たにDBを作成し複数テーブルで同じ列名を定義しSQLを実行しましたが
エラーにはなりませんでしたが下記のDBではエラーとなっています。
(追記):マイクロソフトが提供しているサンプルDB
エラーとなるDB
現在サブクエリを1つずつ検証中ですが、主キー制約の所でエラーとなっています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gentaro

2020/03/20 17:10 編集

複雑なSQLのデバッグは大変面倒ですし、これだけだと丸投げに見えます。 エラーの内容も書いててないのもよろしくないし。 サブクエリに問題があることがわかっているのであれば、個々のサブクエリを実行してメインのクエリとの結合条件において「複数テーブルに同じ列名がある」場合にどうなるのかを確認しましょう。 SELECT句で使っているサブクエリの結合キーで集計して複数レコード返っているのであれば、そこが原因なんでしょう。 個別の部分で原因までわかっているのであれば、改善案の相談ぐらいは載ってもらえるかもしてません。
guest

回答1

0

字下げしていないSQLを読むのも辛いので、直接の回答ではありませんが、
SQL Server CREATE TABLE 取得方法 を試してみては?

投稿2020/03/20 15:25

Orlofsky

総合スコア16415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sima9985

2020/03/21 01:11

回答頂きありがとうございます。 スクリプトでCREATEを生成し定義を作成してもよいのですが 複数テーブルの定義を作成しようとすると 時間がかかると思うので出来れば一括で出力出来ればと思っています。
Orlofsky

2020/03/21 09:07

[質問への追記・修正依頼]で gentaro さんが書かれた事を試されては? このSQLはご自分で全部書かれたのですか? 参考にしたURLがあったら質問に追記しましょう。 SQLは正常に動くこと確認して1コずつサブクエリを追加するものです。 質問に出力したいテーブルのCREATE TABLEと現行の結果を追記して、どこが悪いか検討しましょう。 sys.tables はいちばん下と外部キーを参照されるテーブルを取得するところ以外は不要では?sys.columnsも同様かと。 https://johobase.com/sqlserver-catalogview-table-column/ はかなり使えそうです。
sima9985

2020/03/21 15:15

参考URLとアドバイスを頂きありがとうございます。 SQLは正常に動くこと確認して1コずつサブクエリを追加するものです。 >SQLを書いたことがあまりなくサブクエリも一気に書いてしまいました。一度書いたものが動いたので他のDBでも動くはずだと思っていたので今後はしっかり動作確認をしたいと思います。
Orlofsky

2020/03/22 00:17

PRIMARY KEY, INDEX, 外部キーは複数の列から構成されることもあるし、同じ列が複数のINDEXで使われることもあるから、別のSQLにするか、LOOPが使えるストアドプログラムにしてテーブル毎の最後に持って行かないと実用的ではないでしょう。 ORDER BY の最後の列はCOLUMN_NAMEではなく、COLUMN_ID(テーブル内の列の並び)かと。 良かったら、質問の最後に完成したコードを追記したり、quiita 辺りで公開すると感謝されますよ。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問