Reputation: 877
As I have seen so far, people suggested using dynamic SQL.
For example:
How to pass schema as parameter to a stored procedure in sql server?
How to pass schema name as parameter in stored procedure
However, dynamic SQL has the risk of SQL injection. Hence, I want to know if there are any other safe alternatives?
Basically, this stored procedure that I am creating will be called at runtime. There will be 2 possible schemas to be passed in. And the table name will be passed in as well.
Something like below: (It does not work)
CREATE PROCEDURE [EFM].[usp_readApexTable]
@SCHEMANAME VARCHAR(20) = NULL,
@TABLENAME VARCHAR(100) = NULL
AS
BEGIN
SET NOCOUNT ON;
SELECT *
FROM [@SCHEMANAME].[@TABLENAME];
END
GO
This is just an example of READ action. My plan is to create for CRUD, which requires 4 different stored procedures.
Upvotes: 4
Views: 11995
Reputation: 17943
You can use QUOTENAME
to avoid any SQL injection and build your dynamic query like the following:
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
Note: If you have any plan to add parameters also for your WHERE
clause, in that case QUOTENAME
will not help much, I suggest to to use sp_executesql
by passing appropriate parameters used in WHERE
clause.
Still you need to use QUOTENAME
for schema and table name as SQL
excepts it only as literal, you can't use variable names for table and schema.
For example.
declare @sql nvarchar(max)
set @sql = N'select * from ' + quotename(@SCHEMANAME ) + '.' + quotename(@TABLENAME )
+ ' where (City = @City)'
exec sp_executesql
@sql,
N'@City nvarchar(50)',
@City
You can find more details here
Upvotes: 4
Reputation: 2954
You need to use dynamic sql to do this operation
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
Upvotes: 0