我正在尝试将 SQL 语句转换为支持 sp_executesql 以使其安全,但我遇到了一个不安全的区域。希望你们能帮助我解决这个问题。我创建了临时表以便更容易地演示问题。
问题出在第 6 步。我可以使用第 5 步,但这并不安全,而且很容易被黑客入侵。由于系统性能,我真的不想破坏关键字并多次搜索。
MS SQL 2008 错误消息 4145,级别 15,状态 1,第 4 行 在预期条件的上下文中指定的非布尔类型表达式,靠近“ORDER”。
GO
/****** Object: StoredProcedure [dbo].[ups_MultiWareHouse] Script Date: 06/14/2012 09:12:38 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER OFF
GO
create PROCEDURE ups_TestSearch(
@Keywords nvarchar(4000),
@SortColumns nvarchar(4000)
)
AS
--STEP #1 - Create Temp Table - Begin
CREATE TABLE #TempTable
(
ProductID uniqueidentifier,
ProductName varchar(600),
Price decimal(18,2),
Active bit
)
--STEP #2 - Insert couple records to search
INSERT INTO #TempTable (ProductID,ProductName,Price,Active) VALUES(NEWID(),'Mouse','10.12','1')
INSERT INTO #TempTable (ProductID,ProductName,Price,Active) VALUES(NEWID(),'Keyboard','20.45','1')
INSERT INTO #TempTable (ProductID,ProductName,Price,Active) VALUES(NEWID(),'Monitor','150.87','0')--Disable this product
--STEP #3 - Display the current table data
select 'STEP #3' as STEP, * FROM #TempTable
--STEP #4 - SETTING UP sp_executesql to support parameter substitution
--Set definition
DECLARE @ParmDefinition nvarchar(4000);
SET @ParmDefinition='
@Param1ProductName nvarchar(4000),
@Param2SortColumns nvarchar(4000)
'
DECLARE @SQLString nvarchar(4000);
--STEP #5- CONVERT THE @SQLString TO use @Keywords and @SortColumns
--Run query for the below like this ups_TestSearch'ProductName=''Mouse'' OR ProductName=''Keyboard''', 'Price DESC, ProductName ASC'
SET @SQLString = N'SELECT ''STEP #5'' as STEP, #TempTable.* FROM #TempTable WHERE ('+@Keywords+') ORDER BY '+@SortColumns;--unsafe, open to hackers
EXECUTE sp_executesql @SQLString, @ParmDefinition, @Param1ProductName = @Keywords, @Param2SortColumns=@SortColumns;
--STEP #6- CONVERT THE @SQLString TO use @Keywords and @SortColumns
--Run query for the below like this ups_TestSearch'ProductName=''Mouse'' OR ProductName=''Keyboard''', 'Price DESC, ProductName ASC'
SET @SQLString = N'SELECT ''STEP #6'' as STEP, #TempTable.* FROM #TempTable WHERE (@Param1ProductName) ORDER BY @SortColumns';--Safe but not working
SELECT @SQLString AS SeeStatement
EXECUTE sp_executesql @SQLString, @ParmDefinition, @Param1ProductName = @Keywords, @Param2SortColumns=@SortColumns;
--Drop temp table
DROP TABLE #TempTable