2013-06-19 25 views
0

我有一個存儲過程生成一個將調用EXECUTE()的字符串。該字符串包含一個UPDATE語句。但是,它正在執行的列和值是事先不知道的。這些通過XML字符串進入存儲過程。然後我使用XML查詢來獲取數據並將其存入臨時表中。創建動態更新語句時轉義字符串

這不是淨化數據。

DECLARE @TBL_FLD TABLE (
    TBL   VARCHAR(MAX), 
    COL   VARCHAR(MAX), 
    VAL   VARCHAR(MAX) 
); 

-- Fill @TBL_FLD via xml parsing (omitted for brevity) 

DECLARE TBL_CURSOR CURSOR FOR 
SELECT distinct (TBL) FROM @TBL_FLD; 

OPEN TBL_CURSOR; 
WHILE 1 = 1 
BEGIN 
    FETCH NEXT FROM TBL_CURSOR INTO @TABLE_NAME 
    IF (@@FETCH_STATUS <> 0) 
     BREAK 

    SET @SETTING_STR = ''; 
    SELECT @SETTING_STR = STUFF((SELECT ', ' + COL + ' = ''' + VAL + '''' FROM @TBL_FLD WHERE TBL = @TABLE_NAME FOR XML PATH('')), 1, 2, ''); 

    SET @SQL_QUERY += 'UPDATE ' + @TABLE_NAME + ' SET ' + @SETTING_STR + ' WHERE KEY = ' + CONVERT(VARCHAR(MAX), @KEY_VAL) + '; '; 

END 
CLOSE TBL_CURSOR 
DEALLOCATE TBL_CURSOR 

EXECUTE (@SQL_QUERY); 

我相信@TBL_FLD的COL字段,但VAL將來自用戶。由於我只是將數據連接在一起,這留下了巨大的安全漏洞。一定有更好的方法。

由於存在未知數量的列,因此我無法輕鬆地爲該語句創建參數,以便清理數據。如果最壞的情況發生,我可以做到,(見Dynamically Create Update SQL In Stored Procedure的答案),但比我想要的更醜。

在我盲目地將它添加到語句之前,是否有一個函數或方法來清理數據?還是有更好的方法來做我想做的事情?

回答

1

我認爲這只是加倍的單引號與VAL一個REPLACE會解決任何問題,因爲攻擊者將無法退出「字符串範圍」來執行任意代碼:

SELECT @SETTING_STR = STUFF((SELECT ', ' + COL + ' = ''' + REPLACE(VAL, '''', '''''') + '''' FROM @TBL_FLD WHERE TBL = @TABLE_NAME FOR XML PATH('')), 1, 2, ''); 

我不記住一個內置的T-SQL函數可以做同樣的事情

+0

哇。這真的很簡單。謝謝。 –