0

これで新しい...

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

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

その前に、ユーザー名が存在するかどうかを確認する際に、形式制御なしで LOGINAME を渡します。

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

コード:

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

ここのコードは次のように思われます:

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

私が理解しているように、コードがFIRST.LASTをチェックルーチンに渡しているため、問題が発生しています。これは、テキストではなくオブジェクトとして解釈されます。

同じことを行うことは可能ですが、テキストを強制的に送信することはできますか? コードの他の場所で使用されている quotename() 関数のようなものはありますか?


編集:

このストアド プロシージャを実行する呼び出し: sp_password NULL、abcdefgh、FIRST.LAST

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

ブラケット ( sp_password NULL, abcdefgh, [FIRST.LAST] )を追加して手動で実行すると、もちろん完全に機能します。

4

1 に答える 1

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

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

于 2015-08-06T06:14:34.703 に答える