अगर आप EXEC @Var
. का इस्तेमाल करते हैं (कोष्ठक के बिना - यानी नहीं EXEC (@Var)
) SQL सर्वर @Var
. में दिए गए नाम से मेल खाने वाली एक संग्रहीत कार्यविधि की तलाश करता है . आप इसके लिए तीन भागों के नामकरण का उपयोग कर सकते हैं।
अगर sys.sp_executesql
इसे तीन भागों के नाम से पुकारा जाता है, संदर्भ उस डेटाबेस पर सेट होता है जिसमें इसे कहा जाता है।
तो आप इसे शून्य . के साथ कर सकते हैं नीचे के रूप में SQL इंजेक्शन जोखिम।
CREATE PROCEDURE dbo.test @dbname SYSNAME,
@col SYSNAME
AS
SET NOCOUNT, XACT_ABORT ON;
DECLARE @db_sp_executesql NVARCHAR(300) = QUOTENAME(@dbname) + '.sys.sp_executesql'
EXEC @db_sp_executesql N'
SELECT TOP 100 *
FROM sys.columns
WHERE name = @col',
N'@col sysname',
@col = @col
यहां तक कि अगर उपरोक्त संभव नहीं था, तब भी मैं तर्क दूंगा कि इसके लिए गतिशील एसक्यूएल का उपयोग यहां सुरक्षित तरीके से करना पूरी तरह से संभव है।
CREATE PROCEDURE dbo.test
@dbname SYSNAME, /*Use Correct Datatypes for identifiers*/
@col SYSNAME
AS
SET NOCOUNT ON
SET XACT_ABORT ON
IF DB_ID(@dbname) IS NULL /*Validate the database name exists*/
BEGIN
RAISERROR('Invalid Database Name passed',16,1)
RETURN
END
DECLARE @dynsql nvarchar(max)
/*Use QUOTENAME to correctly escape any special characters*/
SET @dynsql = N'USE '+ QUOTENAME(@dbname) + N'
SELECT TOP 100 *
FROM sys.tables
WHERE name = @col'
/*Use sp_executesql to leave the WHERE clause parameterised*/
EXEC sp_executesql @dynsql, N'@col sysname', @col = @col