2

これはクレイジーな要求のように聞こえるでしょう。私が報告したデータベースには外部キーがなく、すべての主キーが identity_column です。これは、Intellisense が PK と FK の関係を読み取って機能するため、TOAD などのツールの使用を困難にします。

データベース内のすべてのテーブルから主キーを削除するスクリプトを持っている人がいるので、それらを「正しい」PKに置き換えて、レポートを支援するためにFKを追加できますか?

「やるな!!!」の雪崩を防ぐために 応答、これを実稼働データベースに対して行うのではなく、別のサーバーにコピーすることを明確にさせてください。

アドバイスをいただければ幸いです。

------- 編集これは正しい情報で更新されます。----------------

みんなありがとう、でも私は間違いを犯したことに気づきました。ほとんどすべてのテーブルには、アイデンティティのプロパティを持つ「identity_column」があります。その ID はクラスター化インデックスです。ただし、主キーとして指定されていません。

まず、主キーとクラスター化インデックスの違いは何ですか?

次に、すべてのクラスター化インデックスをスクリプト化するにはどうすればよいですか? これは機能しますか?

SELECT 
  'ALTER TABLE ' + OBJECT_NAME(OBJECT_ID) + ' DROP CONSTRAINT ' + name 
FROM sys.indexes WHERE type_desc = 'CLUSTERED'

お待ち頂きまして、ありがとうございます

4

5 に答える 5

6

もう 1 つのオプションは、次の 2 段階のプロセスです。

  1. まず、システム カタログ ビューから必要な情報を選択し、それらを使用して、インデックスと制約を実際に削除するために必要な T-SQL ステートメントを作成します。

    SELECT
      'ALTER TABLE ' + OBJECT_NAME(OBJECT_ID) + ' DROP CONSTRAINT ' + name
    FROM sys.indexes WHERE is_primary_key = 1
    
  2. その結果セットを使用し、それをコピーして新しいクエリ ウィンドウに貼り付けて実行します。これを実行するデータベース内のすべてのテーブルからすべての主キー制約が削除されます。

そうすれば、カーソルを回避し、実行するステートメントのリストを取得できます。これは、「そのまま」使用したり、微調整したり、必要がない場合は完全に破棄したりすることもできます。

于 2010-02-25T21:46:23.117 に答える
5

このようなものはどうですか?

-- Helper Procedure 
CREATE PROC #DropConstraints 
  @tableSchema nvarchar(max), 
  @tableName nvarchar(max), 
  @constraintType nvarchar(20) 
AS 
BEGIN 
  DECLARE @cName nvarchar(max); 

  DECLARE constraint_cursor CURSOR FOR 
    SELECT CONSTRAINT_NAME  
    FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
    WHERE  
      CONSTRAINT_TYPE = @constraintType 
      AND TABLE_NAME = @tableName 
      AND TABLE_SCHEMA = @tableSchema 

  OPEN constraint_cursor 

  FETCH NEXT FROM constraint_cursor INTO @cName 
  WHILE @@FETCH_STATUS = 0 
  BEGIN 
    EXEC ('ALTER TABLE ' + @tableSchema + '.' + @tableName + ' DROP CONSTRAINT ' + @cName); 
    FETCH NEXT FROM constraint_cursor INTO @cName 
  END 

  CLOSE constraint_cursor 
  DEALLOCATE constraint_cursor 
END 
GO

BEGIN TRANSACTION

  -- Setup Cursor for looping 
  DECLARE table_cursor SCROLL CURSOR FOR 
    SELECT TABLE_SCHEMA, TABLE_NAME  
    FROM INFORMATION_SCHEMA.TABLES 

  OPEN table_cursor

  -- Declare Variables

  DECLARE 
    @tableSchema nvarchar(max), 
    @tableName nvarchar(max) 

 -- Drop Primary Keys 

  FETCH FIRST FROM table_cursor INTO @tableSchema, @tableName 
  WHILE @@FETCH_STATUS = 0 
  BEGIN 
    EXEC #DropConstraints @tableSchema, @tableName, 'PRIMARY KEY'; 

    FETCH NEXT FROM table_cursor INTO @tableSchema, @tableName 
  END 

  -- Cleanup 
  CLOSE table_cursor 
  DEALLOCATE table_cursor

COMMIT TRANSACTION 
GO

DROP PROCEDURE #DropConstraints;
GO
于 2010-02-25T21:30:34.330 に答える
1

PK とクラスター化インデックスの違いに関する質問に答えるには:

主キーは、レコードを一意に識別できることを保証するキー値です。クラスター化インデックス (レコードが物理的に格納される順序を決定する) とは何の関係もありませんが、主キーを作成するための既定の設定はクラスター化インデックスにすることです。ただし、クラスター化インデックスにする必要はありません。

過去に主キーと外部キーを持っていなかった場合は、データが完全に整理されている可能性があるため、クリーンアップするまで外部キーを作成しないでください。

于 2010-02-25T22:23:47.747 に答える
1

すべてのクラスター化インデックスを削除するには、制約 (プライマリまたは一意) がクラスター化インデックスである状況と、制約のないインデックスがクラスター化インデックスであるかどうかを区別する必要があります。DROP INDEX を使用して制約インデックスを削除することはできず、DROP CONSTRAINT を使用してインデックスを削除することもできません。したがって、次のようなことを行う必要があります。

Select 'ALTER TABLE ' + QUOTENAME(OBJECT_NAME([object_id])) + ' DROP CONSTRAINT ' + QUOTENAME([name])
From sys.indexes
Where is_primary_key = 1 Or is_unique_constraint = 1
 And type_desc = 'CLUSTERED'
Union All
Select 'DROP INDEX ' + QUOTENAME([name]) + ' ON ' + QUOTENAME(OBJECT_NAME([object_id])) 
from sys.indexes
Where is_primary_key = 0 And is_unique_constraint = 0
 And type_desc = 'CLUSTERED'

率直に言って、主キーを削除する前に、主キーへのすべての外部キーを削除する必要があるため、これでもおそらく機能しません。正しく行うには、すべての外部キーをスクリプト化し、それらをすべて削除してから、クラスター化されたすべての制約を削除してから、すべての外部キーを再作成する必要があります。

これが本当にあなたのやりたいことなのか、私は尋ねなければなりません。すべてのクラスター化インデックスを削除すると、影響を受けるすべてのテーブルのすべてのインデックスが強制的に再構築されます。

于 2010-02-25T23:14:58.000 に答える
0

私が作業する前に提供されたコード サンプルは、主キーのみのバージョンと、他の種類のクラスター化インデックスも処理するバージョンの両方です。

ただし、オブジェクトが既定のスキームに存在しない可能性があるという事実に注意を払っていません。また、インデックスと制約が SQL Server が必要とするシステム オブジェクトではないことを制御していません。

これは単純なバージョンで、主キーのみを削除しています:

select  'ALTER TABLE ' + quotename(object_schema_name(object_id)) + '.'
        + quotename(object_name(object_id)) + ' DROP CONSTRAINT ' + name
from    sys.indexes
where   is_primary_key = 1

これは 2 番目のバージョンで、主キー以外のクラスター化インデックスの削除もスクリプト化しています。

select  'ALTER TABLE ' + quotename(object_schema_name(object_id)) + '.'
        + quotename(object_name([object_id])) + ' DROP CONSTRAINT '
        + quotename([name])
from    sys.indexes
where   is_primary_key = 1
        or is_unique_constraint = 1
        and type_desc = 'CLUSTERED'
union all
select  'DROP INDEX ' + quotename(i.[name]) + ' ON '
        + quotename(object_schema_name(i.[object_id])) + '.'
        + +quotename(object_name(i.[object_id]))
from    sys.indexes as i
        inner join sys.objects as o on o.object_id = i.object_id
where   is_primary_key = 0
        and is_unique_constraint = 0
        and i.type_desc = 'CLUSTERED'
        and o.[type] not in ( 'S' )
        and o.is_ms_shipped = 0
于 2015-07-27T09:27:10.470 に答える