2012-04-23 6 views
0

新...ストアド・プロシージャ、システム名およびquotname()この時

プロバイダーは(私はそれが彼らのコードであると仮定)、ユーザーのSQLサーバーのパスワードを変更するためにストアドプロシージャを設定しています。彼らは、渡された情報(OLD、NEW、LOGINAME)にsysnameタイプを使用しています。

パスワードを変更するコマンドを実行すると、関数に渡されたテキストを括弧でくくってquotename()を使用します。

これまでに、ユーザー名が存在するかどうかを確認しながら、フォーマット制御なしでLOGINAMEを渡しました。

これは過去には問題ありませんでしたが、私たちは最近、ユーザー名ポリシーをinitial + surname(FSURNAME)からfirstname(dot)surname(FIRST.SURNAME)に変更しているため、ルーチンがクラッシュします。私は、see-if-they-exist-functionに渡されたときにユーザー名に対するquotabase()スタイルの制御がないためだと思います。

コード:

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
ALTER procedure [sys].[sp_password] 
    @old sysname = NULL,  -- the old (current) password 
    @new sysname,    -- the new password 
    @loginame sysname = NULL -- user to change password on 
as 
-- SETUP RUNTIME OPTIONS/DECLARE VARIABLES -- 
set nocount on 
declare @exec_stmt nvarchar(4000) 

-- RESOLVE LOGIN NAME 
if @loginame is null 
    select @loginame = suser_sname() 

if @new is null 
    select @new = '' 

-- DISALLOW USER TRANSACTION -- 
set implicit_transactions off 
IF (@@trancount > 0) 
begin 
    raiserror(15002,-1,-1,'sys.sp_password') 
    return (1) 
end 

-- CHECK IT'S A SQL LOGIN -- 
if not exists (select * from master.dbo.syslogins where 
       loginname = @loginame and isntname = 0) 
begin 
    raiserror(15007,-1,-1,@loginame) 
    return (1) 
end 

if @old is null 
    set @exec_stmt = 'alter login ' + quotename(@loginame) + 
     ' with password = ' + quotename(@new, '''') 
else 
    set @exec_stmt = 'alter login ' + quotename(@loginame) + 
     ' with password = ' + quotename(@new, '''') + ' old_password = ' + quotename(@old, '''') 

exec (@exec_stmt) 

if @@error <> 0 
    return (1) 

-- RETURN SUCCESS -- 
return (0) -- sp_password 

私は強く、ここでのコードと思われる:私はそれを理解するよう、コードはチェックルーチンにFIRST.LASTを通過している、と

if not exists (select * from master.dbo.syslogins where 
       loginname = @loginame and isntname = 0) 

が問題を引き起こしていますそれはテキストではなくオブジェクトとして解釈されます。

同じことをすることはできますが、強制的にテキストを送信できますか? quotename()関数はコードのどこかで使用されていますか?


はEDIT:

このストアドプロシージャを実行コール:sp_passwordをするNULL、ABCDEFGHを、FIRST.LAST

エラーは受け取ら:メッセージ102、レベル15、状態1、行1 '。'の近くの構文が正しくありません。

手動では、当然のことながら([FIRST.LAST]、ABCDEFGH、sp_passwordをNULLの)ブラケットを追加することによって実行される完全に機能します。

+0

どのようなエラーが表示されますか? SQL Serverに新しいユーザーを追加しましたか? SSMSを使用し、「オブジェクトエクスプローラ - セキュリティ - ログイン」を参照してください。ユーザーがいない場合、 '' FIRST.SURNAME 'は有効なログインではないか、または権限を持っていないので、パスワードの変更は失敗します。 –

+0

オブジェクトの名前を引用することはできません。 'loginname = @ loginame'が正しいです。また、動的SQLのものを引用する方法も正しいようです。だからあなたが見ているエラーは何ですか? –

+0

オリジナルの質問が編集されました。 – Lindsay

答えて

0

これは、Sql Serverがsysname型のパラメータ値をどのように処理するかによるものです。このことを考慮。

create procedure TakeSysname 
    @Sysname sysname 
as 
    --does nothing; 
go 

--This works. 
exec TakeSysname JohnDoe; 
print N'Worked'; 
go 

--This works. 
exec TakeSysname 'John.Doe'; 
print N'Worked' 
go 

--This does not. 
exec TakeSysname John.Doe; 
print N'Worked'; 
go 

私はまだ良い説明を探しています。

関連する問題