22

これは、 SSMSがsp_executesqlを使用してSPのスクリプトを作成するのを停止するのと非常によく似た質問だと思いますか?

ただし、SSMS2012では動作が変わったようです。

次のように、[存在の確認]オプションが選択されている場合。

ここに画像の説明を入力してください

...これで、作成しようとしているプロシージャのIF NOT EXISTSと、前のドロッププロシージャのIF EXISTSが生成さます。通常どおり、DROPandCREATEオプションを選択した場合は次のようになります。

ここに画像の説明を入力してください

これにより、sp_executesqlを使用してCREATEをスクリプト化するように強制されます。DROPがCREATEをドロップしたばかりの場合は、CREATEでIF NOT EXISTSチェックを行う必要がないため、意味がありません。

一方を他方なしで持つことは不可能のようです。

何か案は?

4

4 に答える 4

9

ストアドプロシージャは独自のバッチである必要があるため、動的SQLなしではこれを行うことはできません。したがって、あなたは言うことはできません:

IF <some condition>
  <start a new batch>

同じバッチでそれを維持する唯一の方法は、を使用することsp_executesqlです。

DROPとをCREATE同時にスクリプト化する場合は、オブジェクトの存在をチェックせずにスクリプトを実行します。これはあなたに与えるでしょう:

DROP PROCEDURE ...;
GO
CREATE PROCEDURE ...;
GO

失敗しても誰が気にしDROPますか?(スクリプトを作成しただけなので、そうすべきではありません!)

オブジェクトが存在する可能性のある別のシステムに対してこれをスクリプト化する場合、オブジェクトDROPが存在しない場合はエラーメッセージが表示されますが、CREATEそれでも発生するため、DROPエラーは無視してかまいません。本当に必要な場合は、DROPステートメントを手動でラップすることができますがTRY/CATCH、それは必要ではないと思います。

多くの手順でこれを行う必要がある場合、または問題のないエラーを生成しないプロセスが本当に必要な場合は、Management Studioの基本的なスクリプトオプションを放棄し、サードパーティのツールを使用することをお勧めします。彼らはあなたがまだ遭遇していない問題の多くをすでに扱っているでしょうが、そうするでしょう。私はこれについてブログを書きました:

http://bertrandaaron.wordpress.com/2012/04/20/re-blog-the-cost-of-reinventing-the-wheel/

于 2012-05-16T14:55:00.800 に答える
5

この機能に最も近い方法は、ツール、オプション、SQL Serverオブジェクトエクスプローラー、スクリプトを実行し、[既存のオブジェクトのチェック]をfalseに設定することです。

欠点は、これを行うと、オブジェクトが存在しない場合でも、ドロップして作成すると常にドロップしようとすることです。理想的な解決策は、ビュー、プロシージャ、およびユーザー定義関数を作成するためのスクリプトを以下の例のように見せることができる設定です。

/****** Object:  View [dbo].[vEmployees]    Script Date: 9/14/2012 9:18:57 AM ******/
IF  EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[vEmployees]'))
DROP VIEW [dbo].[vEmployees]
GO

CREATE VIEW [dbo].[vEmployees]
AS
    SELECT DISTINCT
        Employees.EmployeeID,
        FirstName,
        LastName
    from
        Employees
            JOIN Sales on Employees.EmployeeID=Sales.EmployeeID
GO

つまり、スクリプトエンジンがオブジェクトの存在をチェックする際にドロップと作成を一緒に考えている場合、作成に条件を設定する必要はありません。

于 2012-09-14T14:48:19.813 に答える
1

私はこの問題の良い解決策を見つけました。スクリプトを作成するときは、「2つのパス」を作成する必要があります。最初のパスで、存在を確認するオプションと、DROPスクリプトのみのオプションを選択します。次に、2番目のパスで、[存在の確認]のオプションの選択を解除し、CREATEスクリプトを選択します。さらに、[ファイルに追加]オプションを使用します。次に、2回目のパスで生成スクリプトを実行するときに、[ファイルの上書き]オプションのチェックを外します。これは、オブジェクトごとに個別のファイルを生成する場合にのみ機能します。

于 2015-03-31T16:27:04.647 に答える
0

私も同じ問題に苦労しました。データベース全体のオブジェクトをスクリプト化する必要がある場合は、ApexSQLスクリプトを検討することをお勧めします。私はいくつかのツールを試しましたが、ApexSQLは必要な方法でオブジェクトを正確にスクリプト化しました。(オブジェクトが存在する場合は、ドロップします。オブジェクトを作成します)。コマンドラインからも機能すると思います。注意してください、それはシェアウェアです。ほんの数回しか必要なかったので、評価版のみを使用しました。

以下は、いくつかの構成後のプロシージャの出力例です。

IF (EXISTS(SELECT * FROM sys.objects WHERE [object_id] = OBJECT_ID(N'[dbo].[myProcedure]') AND [type]='P'))
DROP PROCEDURE [dbo].[myProcedure]
GO

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE dbo.myProcedure
AS
    select 1 as a
GO
于 2014-01-08T22:07:11.207 に答える