2015-10-19 33 views
2
IF NOT EXISTS (select * from sys.server_principals where lower([name]) =lower('DOMAIN\t''acct')) 
BEGIN 
    CREATE LOGIN [DOMAIN\t'acct] FROM WINDOWS WITH DEFAULT_DATABASE=[master] 
END 

上述代碼正常工作。我的問題是,有沒有辦法有效地使用佔位符,以便我可以傳入同一個帳戶並在兩個地方都使用特殊字符?如何有效地轉義T-SQL中的特殊字符?

IF NOT EXISTS (select * from sys.server_principals where lower([name]) =lower('$(account)')) 
BEGIN 
    CREATE LOGIN [$(account)] FROM WINDOWS WITH DEFAULT_DATABASE=[master] 
END 

我在哪裏用DOMAIN \ t''acct或DOMAIN \ t'acct替換$(account)?

前者僅適用於第一次更換更換和說

CREATE LOGIN [DOMAIN\t''acct] FROM WINDOWS WITH DEFAULT_DATABASE=[master] 
Windows NT user or group 'DOMAIN\t''acct' not found. Check the name again. 

爲創建登錄語句。

而對於後者,我不能用t'acct來代替,因爲那樣會錯誤地逃脫。做一個盒子會拋出這個錯誤:

select * from sys.server_principals where lower([name]) = lower([DOMAIN\t'acct]) 
Invalid column name 'DOMAIN\t'acct'. 

任何額外的指針,以防止SQL注入將是有益的。我正在考慮像DOMAIN \ tacct這樣的帳戶(輸入被驗證爲有效的Windows用戶以及域名格式(在名稱中包含\))。

回答

1

爲了防止sql注入,我認爲最好使用參數化查詢而不是佔位符。

要使CREATE LOGIN語句與sql參數一起工作,您必須使用動態sql。功能QUOTENAME將幫助您正確地轉義登錄名。在這種情況下,你的SQL代碼可能看起來像:

if not exists(select * from sys.server_principals where lower([name]) = lower(@loginName)) 
begin 
    declare @sql nvarchar(max); 
    set @sql = 
     'CREATE LOGIN ' + quotename(@loginName) + 
     ' FROM WINDOWS WITH DEFAULT_DATABASE = [master]'; 

    exec sp_executesql @sql; 
end 

其中@loginName是你要提供的參數。

0

使用SQL替換功能僅在選擇查詢 '與 '取代',同時使該佔位符

+0

SELECT * FROM sys.server_principals其中較低([名稱])=低級(REPLACE(' DOMAIN \ t'acct ')','')) go Msg 102,Level 15,State 1,Server myserver,Line 1'acct'附近語法不正確。 – orderof1