我試圖創建一個存儲過程,動態生成一個SQL負載。我試圖通過使用sp_executesql
將所有參數傳遞到查詢中來阻止字符串注入。查詢似乎執行正常,但我有兩個問題。首先,當我使用我的Alias
名稱使用xx\xxxxx
模式執行時,它會拋出一個錯誤消息,說明Alias的前兩個字母附近有錯誤。我認爲這是由於NVARCHAR類型,但不完全確定如何處理這個\
。其次,更重要的是,整個程序沒有任何回報。它告訴我它執行得很好,但我沒有按預期得到我的結果表。如何從SP_ExecuteSQL返回表輸出
我省略了報表生成簡潔的參數(這些工作,如果我生成整個字符串並運行EXEC string
我也謹慎使用全局臨時表的,因爲這將在運行多用戶環境
更新了完整的代碼
DECLARE @IDType NVARCHAR(255) = NULL
DECLARE @Customer NVARCHAR(MAX) = NULL
DECLARE @IdentifiedBy NVARCHAR(255) = NULL
DECLARE @ImpactArea NVARCHAR(MAX) = NULL
DECLARE @Gateway NVARCHAR(255) = NULL
DECLARE @ProbabilityRating NVARCHAR(255) = NULL
DECLARE @ImpactRating NVARCHAR(255) = NULL
DECLARE @CostRevenue NVARCHAR(255) = NULL
DECLARE @Status NVARCHAR(255) = NULL
DECLARE @Keywords NVARCHAR(MAX) = NULL
DECLARE @govOwner NVARCHAR(255) = NULL
DECLARE @Alias VARCHAR(50)
DECLARE @Role NVARCHAR(255)
DECLARE @SQL NVARCHAR(MAX)
DECLARE @Where NVARCHAR(MAX) = ''
DECLARE @SQLOrder NVARCHAR(MAX)
SET @Alias = SUSER_SNAME()
SET @Role =(SELECT [Role] FROM [FB].[Users] WHERE [Alias] = @Alias)
IF @IDType IS NOT NULL
BEGIN
IF @IDType = 'Blank'
SET @Where += ' AND IDType = NULL OR IDType = '''''
ELSE IF @IDType != 'All'
SET @Where += ' AND IDType = @IDType'
END
IF @Customer IS NOT NULL
BEGIN
IF @Customer = 'Blank'
SET @Where += ' AND Customer = NULL OR Customer = '''''
ELSE IF @Customer != 'All'
SET @Where += ' AND Customer = @Customer'
END
IF @IdentifiedBy IS NOT NULL
BEGIN
IF @IdentifiedBy = 'Blank'
SET @Where += ' AND IdentifiedBy = NULL OR IdentifiedBy = '''''
ELSE IF @IdentifiedBy != 'All'
SET @Where += ' AND IdentifiedBy = (SELECT FB.Alias(@IdentifiedBy))'
END
IF @ImpactArea IS NOT NULL
BEGIN
IF @ImpactArea = 'Blank'
SET @Where += ' AND ImpactArea = NULL OR ImpactArea = '''''
ELSE IF @ImpactArea != 'All'
SET @Where += ' AND ImpactArea = @ImpactArea'
END
IF @Gateway IS NOT NULL
BEGIN
IF @Gateway = 'Blank'
SET @Where += ' AND Gateway = NULL OR Gateway = '''''
ELSE IF @Gateway != 'All'
SET @Where += ' AND Gateway = @Gateway'
END
IF @ProbabilityRating IS NOT NULL
BEGIN
IF @ProbabilityRating = 'Blank'
SET @Where += ' AND ProbabilityRating = NULL OR ProbabilityRating = '''''
ELSE IF @ProbabilityRating != 'All'
SET @Where += ' AND ProbabilityRating = @ProbabilityRating'
END
IF @ImpactRating IS NOT NULL
BEGIN
IF @ImpactRating = 'Blank'
SET @Where += ' AND ImpactRating = NULL OR ImpactRating = '''''
ELSE IF @ImpactRating != 'All'
SET @Where += ' AND ImpactRating = @ImpactRating'
END
IF @CostRevenue IS NOT NULL
BEGIN
IF @CostRevenue = 'Blank'
SET @Where += ' AND CostRevenue = NULL OR CostRevenue = '''''
ELSE IF @CostRevenue != 'All'
SET @Where += ' AND CostRevenue = @CostRevenue'
END
IF @Status IS NOT NULL
BEGIN
IF @Status = 'Blank'
SET @Where += ' AND Status = NULL OR Status = '''''
ELSE IF @Status != 'All'
SET @Where += ' AND Status = @Status'
END
IF @Keywords IS NOT NULL
IF @govOwner IS NOT NULL
BEGIN
IF @govOwner = 'Blank'
SET @Where += ' AND govOwner = NULL OR govOwner = '''''
ELSE IF @govOwner != 'All'
SET @Where += ' AND govOwner = (SELECT FB.Alias(@govOwner))'
END
CREATE TABLE #tmp (
ID int
,FeedbackType varchar(255)
,ImpactArea varchar(255)
,CreatedDate varchar(11)
,Customer varchar(255)
,IdentifiedBy varchar(255)
,CriticalityRating varchar(255)
,govOwner varchar(255)
,Status varchar(255)
)
SET @SQL = 'SELECT
fb.ID
,FeedbackType
,ImpactArea
,CONVERT(VARCHAR(11), CreatedDate, 3) AS CreatedDate
,Customer
,IdentifiedBy
,CriticalityRating
,govOwner
,Status
INTO #tmp
FROM [FB].[Feedback] fb
INNER JOIN (SELECT
ID
,MAX(Version) AS MaxVer
FROM FB.Feedback
GROUP BY ID
) mv ON fb.ID = mv.ID AND fb.Version = mv.MaxVer'
SET @SQLOrder = ' ORDER BY [ID] DESC'
IF @Where IS NOT NULL
SET @Where = ' WHERE ' + (SELECT STUFF(@Where,1 , 4, '')) + ' '
IF (@Role != 'Governance Board' AND @Role != 'Admin')
BEGIN
IF @Where IS NOT NULL
SET @Where += ' AND [Author] = @Alias OR [IdentifiedBy] = @Alias'
ELSE
SET @Where = ' WHERE [Author] = @Alias OR [IdentifiedBy] = @Alias'
END
SET @SQL += @Where + @SQLOrder
EXECUTE SP_ExecuteSQL @SQL
,@Alias = @Alias
,@Customer = @Customer
,@IdentifiedBy = @IdentifiedBy
,@ImpactArea = @ImpactArea
,@Gateway = @Gateway
,@ProbabilityRating = @ProbabilityRating
,@ImpactRating = @ImpactRating
,@CostRevenue = @CostRevenue
,@Status = @Status
,@Keywords = @Keywords
,@govOwner = @govOwner
SELECT * FROM #tmp
DROP TABLE #tmp
偉大的工作謝謝。我現在唯一的問題是使用'@Alias'參數,如果變量爲空,執行'sp_executesql'的最佳實踐是什麼? – Tom
答案用該位更新。 – BeanFrog
僅供將來參考'DECLARE @params NVARCHAR(300)'太短了。我更新了這個'NVARCHAR(400)',它工作正常 – Tom