これで新しい...
プロバイダー (私はそれが彼らのコードだと思います) が、ユーザーの 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] )を追加して手動で実行すると、もちろん完全に機能します。