正如我到目前为止所见,人们建议使用动态SQL。
例如:
How to pass schema as parameter to a stored procedure in sql server?
How to pass schema name as parameter in stored procedure
但是,动态SQL存在SQL注入的风险。因此,我想知道是否还有其他安全的选择?
基本上,我创建的这个存储过程将在运行时调用。将传递2个可能的模式。表名也将被传入。
如下所示:(它不起作用)
CREATE PROCEDURE [EFM].[usp_readApexTable]
@SCHEMANAME VARCHAR(20) = NULL,
@TABLENAME VARCHAR(100) = NULL
AS
BEGIN
SET NOCOUNT ON;
SELECT *
FROM [@SCHEMANAME].[@TABLENAME];
END
GO
这只是READ操作的一个示例。我的计划是为CRUD创建,这需要4个不同的存储过程。
答案 0 :(得分:1)
您可以使用QUOTENAME
来避免任何SQL注入,并构建动态查询,如下所示:
CREATE PROCEDURE [EFM].[usp_readApexTable]
@SCHEMANAME VARCHAR(20) = NULL,
@TABLENAME VARCHAR(100) = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE @SQL VARCHAR(MAX)=N'SELECT * FROM '
+ QUOTENAME(@SCHEMANAME) + '.' + QUOTENAME(@TABLENAME)
EXEC (@SQL)
END
GO
注意:如果您有任何计划为WHERE
子句添加参数,那么QUOTENAME
也无济于事,我建议使用{{ 1}}通过传递sp_executesql
子句中使用的适当参数。
您仍然需要将WHERE
用于架构和表名称QUOTENAME
,除了它只是文字,您不能使用表和架构的变量名称。
例如。
SQL
您可以找到更多详情here
答案 1 :(得分:0)
您需要使用dynamic sql来执行此操作
CREATE PROCEDURE [EFM].[usp_readApexTable]
@SCHEMANAME VARCHAR(20) = NULL,
@TABLENAME VARCHAR(100) = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE @sqlCommand nvarchar(MAX)
SET @sqlCommand='SELECT * FROM ['+@SCHEMANAME+'].['+@TABLENAME+'];'
--Create Your Temp Table where you can set the records after executing the dynamic query
CREATE TABLE #tmpTbl(
Column1 [datatype]
Column2 [datatype]
.
.
ColumnN
)
INSERT INTO #tmpTbl EXEC sp_executesql @sqlCommand --Copy data to #tmpTbl table
SELECT * FROM #tmpTbl
DROP TABLE #tmpTbl
END
GO