5

私たちは本番環境に移行しており、DBA で生成したスクリプトを実行した直後に、ロールを持つユーザーを作成できるスクリプトを作成したいと考えていますaspnet_regsql。開発環境では、Global.asax.cs のメンバーシップ プロバイダーの API を使用してユーザーとロールを追加しています。しかし、このハードコーディングされたアプローチは避けたいと思います。今、私の T-SQL の経験不足が明らかになりました。次のスクリプトを作成しました。これは、一度にすべて実行しなくても機能します。

Use MyApps_Prod;
GO

DECLARE @user_identity CHAR(40);
DECLARE @scalar_userid AS NVARCHAR(255);
DECLARE @scalar_roleid AS NVARCHAR(255);
DECLARE @app_id AS NVARCHAR(255);
SET @user_identity = N'AMERICAS\First.Last';

SET @app_id = (SELECT DISTINCT ApplicationId 
            FROM [dbo].[aspnet_Applications] 
            WHERE loweredapplicationname = 'MyApplication');
SELECT * FROM [dbo].[aspnet_Users] WHERE UserName = @user_identity

IF NOT EXISTS (SELECT * FROM [dbo].[aspnet_Users] WHERE UserName = @user_identity ) 
BEGIN
    INSERT INTO [dbo].aspnet_Users
             ( [ApplicationId], [UserName], [LoweredUserName], [LastActivityDate] )
    VALUES
        ( @app_id, @user_identity, LOWER(@user_identity), GETDATE());
END;

DECLARE @role_name CHAR(40);
SET @role_name = N'Communicator';
IF NOT EXISTS (SELECT * FROM [dbo].[aspnet_Roles] WHERE RoleName = @role_name ) 
BEGIN
    INSERT INTO [dbo].[aspnet_Roles]
        ( [ApplicationId], [RoleName], [LoweredRoleName])
    VALUES
        (@app_id, @role_name, LOWER(@role_name))
END;


SET @scalar_userid = (SELECT DISTINCT UserID FROM [dbo].aspnet_Users WHERE UserName = @user_identity);
SET @scalar_roleid = (SELECT DISTINCT RoleID FROM [dbo].aspnet_Roles WHERE RoleName = @role_name);

INSERT INTO [dbo].aspnet_UsersInRoles (UserID, RoleID)
    VALUES (
        @scalar_userid ,
        @scalar_roleid
    );


SET @role_name = N'AccessAdministrator';
IF NOT EXISTS (SELECT * FROM [dbo].[aspnet_Roles] WHERE RoleName = @role_name ) 
BEGIN
    INSERT INTO [dbo].[aspnet_Roles]
        ( [ApplicationId], [RoleName], [LoweredRoleName])
    VALUES
        (@app_id, @role_name, LOWER(@role_name))
END;


SET @scalar_roleid = (SELECT DISTINCT RoleID FROM [dbo].aspnet_Roles WHERE RoleName = @role_name);

INSERT INTO [dbo].aspnet_UsersInRoles (UserID, RoleID)
    VALUES (
        @scalar_userid ,
        @scalar_roleid
    );
GO

それぞれをセミコロンでINSERTs終了してから を追加すると、 が機能することがわかりましたが、各変数を再宣言して再割り当てする必要があります。INSERTGO

実際の SQL 開発者はこれをどのように行うのでしょうか?

4

4 に答える 4

10

INSERT ステートメントを手動で記述するのではなく、SqlMembershipProvider実装プロバイダーの一部であり、aspnet_reg.exeツールを使用してアプリケーション サービスをインストールするときに含まれるストアド プロシージャを使用します。

特に、次を使用します。

  • aspnet_Roles_CreateRole新しい役割を作成する
  • aspnet_Membership_CreateUserユーザーを作成し、メンバーシップ データ (パスワード、セキュリティの質問と回答など) を提供する
  • aspnet_UsersInRoles_AddUsersToRoles既存のユーザーを既存の役割に追加するには

多くのaspnet_Membership_CreateUser中で唯一のトリッキーなものです。パスワードをプレーンテキストで保存していないと仮定すると、パラメーターを介してハッシュまたは暗号化されたバージョンを sproc に渡す必要があり@Passwordます。Reflector を使用して、SqlMembershipProviderクラスのCreateUserメソッド内のコードを調べることをお勧めします。.NET がこのロジックを内部で処理する方法を確認できます。

これをスクリプト化する代わりに、おそらくテキスト ファイルを読み取り、指定されたロールとユーザー、およびユーザーとロールの関連付けを作成するコマンド ライン プログラムを作成することを検討してください。このコマンド ライン プログラムは、Membership API を直接使用するため、すべての低レベルの詳細を処理します。その後、ビルドまたはデプロイ プロセスの一部として、このコマンド ライン プログラムを実行できます。

ハッピープログラミング!

于 2010-12-18T23:48:07.173 に答える
2

SQL プロファイラーを実行して、ハードコーディングされた実装を実行してみましたか? これにより、物事を実行する正確な順序が示されるはずです。

于 2010-12-17T00:15:27.630 に答える
0

スクリプトを使用して作成することはお勧めできません。また、APIを使用している場合は、手動で作成する必要があると言うのかわかりません。既存のデータを移行してみましたか?

しかし、それが選択である場合は、ReflectorToolを使用してそれらのメンバーシップ/Rolesメソッドのコードを確認することをお勧めします。ストアドプロシージャがこれらのAPIメソッドによって実行される前に、web.configの設定に従って、暗号化/ハッシュ、正しいapplicationNameの選択、およびその他のいくつかのチェックが必要になる可能性があるため、ストアドプロシージャを実行するだけでは不十分です。

したがって、ユーザーの詳細を挿入できるようになるため、これらすべてを考慮してください。ただし、それを使用する場合は、APIを使用することになり、他の問題が発生する可能性があります。

于 2010-12-18T22:42:11.930 に答える
0

「実際の SQL 開発者はこれをどのように行うでしょうか?」

ここから始めます。T-SQL は配列を直接サポートしていませんが、通常はテーブル変数をループして配列として扱い、コードを圧縮/再利用します。あなたの例では、それは大きな利点ではありません。しかし、ロールネームが10個あれば、そうなる。

例:


DECLARE @roles TABLE (rolename CHAR(40));
INSERT @roles
 SELECT 'Communicator'
 UNION ALL
 SELECT 'AccessAdministrator';
DECLARE @rolename CHAR(40);

--loop through the @roles table variable like it's an array
WHILE (SELECT COUNT(*) FROM @roles) > 0
  BEGIN
    SELECT TOP 1 @rolename = rolename FROM @roles;
    --Do something with the current rolename
    SELECT @rolename;
    DELETE @roles WHERE rolename = @rolename;
  END
于 2010-12-17T01:46:54.747 に答える