1

次の SQL コードに何か問題がありますか。

ALTER TABLE [idconfirm].[EPS_ENROLLMENT] 
DROP CONSTRAINT select d.name from syscolumns c,sysobjects d, sysobjects t 
where c.id=t.id AND d.parent_obj=t.id AND d.type='D' AND t.type='U' 
AND c.name='ENC_TOKEN_KEK_SALT_SIZE' AND t.name='EPS_ENROLLMENT';
4

4 に答える 4

3

あなたはただ言うことはできません

 ALTER TABLE FOO DROP CONSTRAINT;

制約名を指定する必要があります:

 ALTER TABLE FOO DROP CONSTRAINT CONS_SOME_CONS_NAME;

後者のクエリを使用して、制約名の結果セットを返そうとしているようですか? そのような SELECT で ALTER ステートメントをフィードすることはできません。それも機能しません。SQL を使用してスクリプトを生成し、スクリプトを保存して実行するか、動的 SQL を使用します。

動的 SQL は、オブジェクトを削除する際に使用する最も危険な手法の 1 つですが、 StackOverflow でさりげなく提案されているのを目にします。自動化が必要で、潜在的な違いに適応するスクリプトが必要な場合 (顧客への変更スクリプトの展開など) を除き、これは使用しません。それ以外の場合は、安全な DBA を実践し、スクリプトをテキスト ウィンドウに生成してから、実行する前に検証する必要があります。動的 SQL は、生成から実行に直接ジャンプします。検証には 15 秒余分にかかります。

そのスクリプトのアクションのみが実行されるという知識を持って、それを保存して他のデータベースに展開できます。動的 SQL をデプロイすると、潜在的に異なるアクションが各データベースにデプロイされます。これが必要な場合もあれば、そうでない場合もあります。

このように DDL を生成するには、SSMS メニューから [Results to Text] を選択するか、略して CTRL-T を選択し、次を実行します。

SELECT 'ALTER TABLE T DROP CONSTRAINT ' + d.name
  from syscolumns c, sysobjects d, sysobjects t 
    where c.id=t.id AND d.parent_obj=t.id AND d.type='D' AND t.type='U' 
      AND c.name='ENC_TOKEN_KEK_SALT_SIZE' AND t.name='EPS_ENROLLMENT';

次に、スクリプトをコピーして貼り付け、検証し、保存します。この手法は、データ ディクショナリ カタログを使用するすべてのデータベースで機能します。

于 2014-06-02T07:48:14.793 に答える
1

ALTER TABLE .. DROP CONSTRAINT SELECT ..有効な構文ではありません。DROP CONSTRAINT の後に識別子 ("constraint_name") が必要です

すべてのSQL DDLと同様に、列識別子はではなく、式 (SELECT またはその他) の結果にすることはできません。このようなステートメントで値を使用するには、動的 SQLを構築して実行する 必要があります。

例えば、

declare @name varchar(200)

-- I recommend not using implicit cross-joins, but ..
select @name=d.name
from syscolumns c, sysobjects d, sysobjects t 
where c.id=t.id AND d.parent_obj=t.id AND d.type='D' AND t.type='U' 
  AND c.name='ENC_TOKEN_KEK_SALT_SIZE' AND t.name='EPS_ENROLLMENT';

-- Build dynamic SQL
SET @sql = 'ALTER TABLE idconfirm.EPS_ENROLLMENT DROP CONSTRAINT ' + @name;
-- And execute it
EXEC (@sql)
于 2014-06-02T07:54:12.087 に答える