1

SqlServer の基本データベースとログイン/ユーザー作成用のスクリプトを作成しようとしています。スクリプトを実行すると、次のような多くのエラーが発生します。

スカラー変数「@varname」を宣言する必要があります

EXECスクリプトの実行中に変数がステートメントで 2 回目に使用されたとき。

declare
     @dbname nvarchar(50) ,
     @userName nvarchar(50) ,
     @password nvarchar(50);
SET @dbname = N'DBNAME';
SET @userName = N'DBUSERNAME';
SET @password= N'PASSWORD';

Begin transaction
    IF EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name = @dbname)
    BEGIN
        exec ('
            DROP login '+ @userName + '
            DROP USER '+  @userName + '
            alter database '+  @dbname + '
            SET OFFLINE 
            WITH ROLLBACK IMMEDIATE;
            ALTER DATABASE '+  @dbname + '
            SET ONLINE;
            DROP DATABASE '+  @dbname)
    END 

    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    SET ANSI_PADDING ON
    GO
    EXEC ('CREATE DATABASE '+ @dbname)
    GO 
    EXEC (@dbname+ '.[dbo].[sp_fulltext_database] @action = ''disable''')
    GO 
    EXEC ('ALTER DATABASE '+ @dbname + ' SET COMPATIBILITY_LEVEL = 100')
    GO 
     ...
    EXEC ('ALTER DATABASE '+ @dbname + ' SET DB_CHAINING OFF')
    GO

    EXEC('create login '+ @userName + 'with password = '+ @password);
    EXEC('use  '+ @dbname+ '
    create user '+ @userName + ' for login '+ @userName);
    EXEC ('EXEC sp_addrolemember  ''db_owner'', '+  @userName)

commit transaction

すべてのクエリでsp_executesqlを使用する必要がありますか? より短い解決策はありますか?

4

3 に答える 3

3

GO ステートメントは、バッチが完了したことをクエリ アナライザーに伝えます。

http://technet.microsoft.com/en-us/library/ms188037.aspx

したがって、設定されている宣言済み変数は、動的コードが実行されるまでにスコープ外になります。

トランザクションで本当にこれが必要な場合 は、BEGIN CATCH /END CATCHでBEGIN TRY/END TRYでラップし、 ROLLBACKを実行します。

http://craftydba.com/?p=5930

CREATE DATABASE ステートメントでこれを試したことはありません。楽しい練習になるかもしれません。データベースの作成を元に戻しますか? 試してみたいバケットリストに追加したいもの。

また、複数のコマンドを組み合わせる場合は、セミコロン (;)を使用する必要があります。そうしないと、構文エラーが発生します。

于 2013-11-13T13:40:06.453 に答える
1

RajVaibhav Parmarのコメントのおかげで、スクリプトを変更したところ、問題なく動作するようになりました。

主なエラーは、サーバーに一緒に送信される SQL コマンドをバッチにグループ化するために使用されるため、削除する必要がある GO ステートメントでした。バッチに含まれるコマンド、つまり、最後の GO コマンドまたはセッションの開始以降の一連のコマンドは、論理的に一貫している必要があります。変数のスコープはそれが定義されているバッチに限定されているため、あるバッチで変数を定義してから別のバッチで使用することはできません。

2番目のエラーは、トランザクションを許可しないステートメントでトランザクションを使用しようとしたことです

修正したスクリプトを参照として残します。

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
SET ANSI_PADDING ON

declare
     @dbname nvarchar(50) ,
     @userName nvarchar(50) ,
     @password nvarchar(50);
SET @dbname = N'DATABASENAME';
SET @userName = N'DBUSERNAME';
SET @password= N'DBUSERPASSWORD';

IF EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name = @dbname)
BEGIN
    exec ('
    DROP USER '+  @userName + '
    DROP login '+ @userName + '
    alter database '+  @dbname + '
    SET OFFLINE 
    WITH ROLLBACK IMMEDIATE;
    ALTER DATABASE '+  @dbname + '
    SET ONLINE;
    DROP DATABASE '+  @dbname)
END 

EXEC ('CREATE DATABASE '+ @dbname);
EXEC (@dbname+ '.[dbo].[sp_fulltext_database] @action = ''disable''');
EXEC ('ALTER DATABASE '+ @dbname + ' SET COMPATIBILITY_LEVEL = 100');
EXEC ('ALTER DATABASE '+ @dbname + ' SET ANSI_NULL_DEFAULT OFF');
EXEC ('ALTER DATABASE '+ @dbname + ' SET ANSI_NULLS ON');
EXEC ('ALTER DATABASE '+ @dbname + ' SET ANSI_PADDING ON');
EXEC ('ALTER DATABASE '+ @dbname + ' SET AUTO_CLOSE OFF');
EXEC ('ALTER DATABASE '+ @dbname + ' SET AUTO_SHRINK OFF');
EXEC ('ALTER DATABASE '+ @dbname + ' SET QUOTED_IDENTIFIER ON');
EXEC ('ALTER DATABASE '+ @dbname + ' SET RECOVERY FULL');
EXEC ('ALTER DATABASE '+ @dbname + ' SET PAGE_VERIFY CHECKSUM');
EXEC ('ALTER DATABASE '+ @dbname + ' SET ANSI_WARNINGS ON');
EXEC ('ALTER DATABASE '+ @dbname + ' SET ARITHABORT ON');
EXEC ('ALTER DATABASE '+ @dbname + ' SET AUTO_CREATE_STATISTICS ON');
EXEC ('ALTER DATABASE '+ @dbname + ' SET AUTO_UPDATE_STATISTICS ON');
EXEC ('ALTER DATABASE '+ @dbname + ' SET CURSOR_CLOSE_ON_COMMIT OFF');
EXEC ('ALTER DATABASE '+ @dbname + ' SET CURSOR_DEFAULT  GLOBAL');
EXEC ('ALTER DATABASE '+ @dbname + ' SET CONCAT_NULL_YIELDS_NULL OFF'); 
EXEC ('ALTER DATABASE '+ @dbname + ' SET NUMERIC_ROUNDABORT OFF'); 
EXEC ('ALTER DATABASE '+ @dbname + ' SET RECURSIVE_TRIGGERS OFF'); 
EXEC ('ALTER DATABASE '+ @dbname + ' SET  ENABLE_BROKER'); 
EXEC ('ALTER DATABASE '+ @dbname + ' SET AUTO_UPDATE_STATISTICS_ASYNC OFF'); 
EXEC ('ALTER DATABASE '+ @dbname + ' SET DATE_CORRELATION_OPTIMIZATION OFF'); 
EXEC ('ALTER DATABASE '+ @dbname + ' SET TRUSTWORTHY OFF'); 
EXEC ('ALTER DATABASE '+ @dbname + ' SET ALLOW_SNAPSHOT_ISOLATION OFF'); 
EXEC ('ALTER DATABASE '+ @dbname + ' SET PARAMETERIZATION SIMPLE'); 
EXEC ('ALTER DATABASE '+ @dbname + ' SET READ_COMMITTED_SNAPSHOT OFF'); 
EXEC ('ALTER DATABASE '+ @dbname + ' SET HONOR_BROKER_PRIORITY OFF'); 
EXEC ('ALTER DATABASE '+ @dbname + ' SET  READ_WRITE'); 
EXEC ('ALTER DATABASE '+ @dbname + ' SET  MULTI_USER'); 
EXEC ('ALTER DATABASE '+ @dbname + ' SET DB_CHAINING OFF');

EXEC ('create login '+  @userName + ' with password = '''+ @password+ ''', default_database = ' + @dbname);
EXEC ('use  '+ @dbname+ ' create user '+ @userName + ' for login '+ @userName);
EXEC ('use  '+ @dbname+ ' EXEC sp_addrolemember  ''db_owner'', '+  @userName);
于 2013-11-13T10:53:28.093 に答える
0

以下のコードを使用するだけで役立つ場合があります。

declare @dbname nvarchar(50) ,@userName nvarchar(50) ,@password nvarchar(50);
SET @dbname = N'DBNAME';
SET @userName = N'DBUSERNAME';
SET @password= N'PASSWORD';

Begin transaction
IF EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name = @dbname)
BEGIN
    exec ('
        DROP login '+ @userName + '
        DROP USER '+  @userName + '
        alter database '+  @dbname + '
        SET OFFLINE 
        WITH ROLLBACK IMMEDIATE;
        ALTER DATABASE '+  @dbname + '
        SET ONLINE;
        DROP DATABASE '+  @dbname)
END 
   else
   begin
--SET ANSI_NULLS ON
--GO
SET QUOTED_IDENTIFIER ON
--GO
--SET ANSI_PADDING ON
--GO
EXEC ('CREATE DATABASE '+ @dbname)
--GO 
EXEC (@dbname+ '.[dbo].[sp_fulltext_database] @action = ''disable''')
--GO 
EXEC ('ALTER DATABASE '+ @dbname + ' SET COMPATIBILITY_LEVEL = 100')
--GO 

EXEC ('ALTER DATABASE '+ @dbname + ' SET DB_CHAINING OFF')
--GO

EXEC('create login '+ @userName + 'with password = '+ @password);
EXEC('use  '+ @dbname+ '
create user '+ @userName + ' for login '+ @userName);
EXEC ('EXEC sp_addrolemember  ''db_owner'', '+  @userName)
end

commit transaction
于 2013-11-13T10:32:14.493 に答える