1

チェック (if ステートメント) を実行してから、2 つの可能なプロシージャのうちの 1 つを作成したいと考えています。

現在、IF EXISTSステートメント内でCREATE PROCEDUREステートメントを使用しようとしています。

CREATE PROCEDURE [dbo].[TestProc]
AS

SET NOCOUNT ON
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER OFF

IF EXISTS (select * from table)
BEGIN
DECLARE @region NVARCHAR(100)

SELECT *
INTO #TempTable
FROM User

... #TempTable などで何かをする..

DROP #TempTable
END

ELSE
BEGIN
DECLARE @region NVARCHAR(100)

SELECT *
INTO #TempTable
FROM User

... #TempTable などで何か他のことをする

DROP #TempTable
END

次の2つのエラーが表示されます

There is already an object named 'TempTable' in the database.

The variable name '@region' has already been declared. Variable names must be unique within a query batch or stored procedure.
4

2 に答える 2

1

a) ストアド プロシージャで最初に一時テーブルを作成し、それを使用INSERT INTO (...) SELECT ...して入力するか、b) 2 つの分岐で一時テーブルに別の名前を使用します。

T-SQL パーサーは非常に単純な獣であり、制御フローはどのオブジェクトが存在するかどうかの解釈に影響しませんIF。分岐 - 制御フローが分岐に入るかどうかに関係なく「存在」しIFます。

同様の議論が変数にも当てはまります。

明らかに、オプションaは一時テーブルの構造が同一である場合にのみ機能します。


制御フローを無視する簡単な例:

if 1=2
begin
    declare @a int
end

set @a = 5

print @a

印刷し5ます。ただ:

set @a = 5

print @a

エラー が生成されますMust declare the scalar variable "@a".。これは、( のフォローされていないブランチ内のif) 宣言がまだ有効であることを示しています。

于 2013-01-03T08:28:18.163 に答える
0

1.2つの異なる一時テーブルを使用する必要があり、SELECT * INTOステートメントの前にそれらを削除します

2.ボディプロシージャで一度宣言された変数の必要性。あなたの場合、IF EXISTSの前に

CREATE PROCEDURE [dbo].[TestProc]
AS
SET NOCOUNT ON
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER OFF

DECLARE @region NVARCHAR(100)

IF EXISTS(SELECT 1 FROM dbo.test6)
BEGIN
  IF OBJECT_ID('tempdb.dbo.#TempTable') IS NOT NULL DROP TABLE dbo.#TempTable
  SELECT *
  INTO #TempTable
  FROM dbo.test6
END
ELSE
BEGIN
  IF OBJECT_ID('tempdb.dbo.#TempTable2') IS NOT NULL DROP TABLE dbo.#TempTable2
  SELECT *
  INTO #TempTable2
  FROM dbo.test6
END
于 2013-01-03T15:48:57.420 に答える