sql >> Databasteknik >  >> RDS >> Sqlserver

SQL Server:hur man får ett databasnamn som en parameter i en lagrad procedur

Om du använder EXEC @Var (utan hakparenteser - d.v.s. inte EXEC (@Var) ) SQL Server letar efter en lagrad procedur som matchar namnet som skickas i @Var . Du kan använda tre delars namngivning för detta.

Om sys.sp_executesql anropas med ett tredelat namn, kontexten sätts till den databas i vilken den anropas.

Så du kan göra detta med noll SQL-injektionsrisk enligt nedan.

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 

Även om ovanstående inte var möjligt skulle jag fortfarande hävda att det är fullt möjligt att använda dynamisk SQL för detta på ett säkert sätt som här.

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


  1. Hur ändrar man tryckknappsetikettens text och lägger till en ny funktionalitet under körning? Oracle Forms

  2. Laravel &multipla count frågor med Eloquent

  3. ECHO MYSQL RESULTAT VISAR BLANK SIDA

  4. codeIgniter använd mysql_real_escape_string() istället.databasanslutningsproblem