2

ビューで選択されている列のis_nullableis_computed、およびdefault_object_id列の値が必要なため、ビューの sys.columns のレコードを参照しているテーブルのsys.columnsのレコードに結合しようとしています。

ビューのsys.columnsレコードには「正しくない」値が含まれています。これは、以下のサンプル クエリを実行することで確認できます。

CREATE TABLE TestTable (
    FieldA int NOT NULL,
    FieldB int DEFAULT (1),
    FieldC as CONVERT(INT, FieldA + FieldB),
    FieldD int NOT NULL
)
GO

CREATE VIEW TestView WITH SCHEMABINDING AS
SELECT  FieldA, FieldC as TestC, FieldB + FieldC as TestD
FROM dbo.TestTable WHERE FieldD = 1
GO

SELECT  OBJECT_NAME(c.object_id) as ViewName, c.name as ColumnName,
        c.is_nullable as Nullable, c.is_computed as Computed,
   cast(CASE WHEN c.default_object_id > 0 THEN 1 ELSE 0 END as bit) as HasDefault
FROM sys.columns c
WHERE object_id = OBJECT_ID('TestTable')
GO

SELECT  OBJECT_NAME(c.object_id) as ViewName, c.name as ColumnName,
        c.is_nullable as Nullable, c.is_computed as Computed,
   cast(CASE WHEN c.default_object_id > 0 THEN 1 ELSE 0 END as bit) as HasDefault
FROM sys.columns c
WHERE object_id = OBJECT_ID('TestView')
GO

システム ビューを使用して依存関係を結合しようとしましたが、ビューのどの列がテーブルのどの列を参照しているかについての情報は得られません。

-- dm_sql_referenced_entities gives us all columns referenced, but all records
-- have referencing_minor_id 0, so we do not know which column refers to what
SELECT * FROM sys.dm_sql_referenced_entities('dbo.TestView', 'OBJECT')
GO

-- sql_dependencies gives us all columns referenced, but all records has
-- column_id 0 so we can not use this either of joining the columns
SELECT * FROM sys.sql_dependencies WHERE object_id = OBJECT_ID('TestView')
GO

-- sql_expression_dependencies just tells us what table we are referencing 
-- if view is not created WITH SCHEMABINDING. If it is, it will return columns,
-- but with referencing_minor_id 0 for all records, so not able use this either
SELECT * FROM sys.sql_expression_dependencies
    WHERE referencing_id = OBJECT_ID('TestView')
GO

誰かが提出した social.msdn に関するこの未回答の投稿は、同じ問題のようです: http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/4ae5869f-bf64-4eef-a952-9ac40c932cd4

4

3 に答える 3

1

あなたは「TestView TestC が計算列を参照していることを知る必要がある」と言いました。これは SQL Server 2008 R2 ではサポートされていません (ただし、2012 についてはわかりませんが、疑わしいと思います)。

まず、sys.columns または INFORMATION_SCHEMA.COLUMNS を照会できますが、必要なものが見つかりません。

さらに深く掘り下げると、おそらく sys.sql_expression_dependencies と sys.dm_sql_referenced_entities (N'dbo.TestView', N'OBJECT') を試すことになりますが、列と列ではなく、テーブルと列のマッピングが見つかります。SQL サーバーは、詳細 (列) ではなく、「高レベル」オブジェクト (テーブル、トリガーなど) ごとに依存関係情報を格納します。sys.sysdepends にも同じものがあります。実際のところ、依存関係情報は信頼できない SQL サーバーにあります。

最後に、あなたの唯一の可能性は、ビュー本体を自分で解析することです。これは sys.sql_modules にあります。

SELECT m.definition
FROM 
    sys.objects o
    JOIN sys.sql_modules m 
        ON m.object_id = o.object_id
WHERE 
    o.object_id = object_id('dbo.TestView')
    and o.type = 'V'

T-SQL の解析は非常に難しく、努力の限界に追い込まれる可能性があります。たとえば、特にビューがスキーマにバインドされている場合は、ビューからテーブル参照を取得し、次にテーブル列を取得するのは多かれ少なかれ簡単です。しかし、そうでない場合は...再帰的なCTEを参照するOUTER APPLYを参照するアスタリスクを考えてみてください...

とにかく、頑張ってください!

于 2012-10-30T09:26:38.237 に答える