Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

SQL Server:come ottenere un nome di database come parametro in una stored procedure

Se usi EXEC @Var (senza parentesi - cioè non EXEC (@Var) ) SQL Server cerca una stored procedure che corrisponda al nome passato in @Var . Puoi utilizzare la denominazione in tre parti per questo.

Se sys.sp_executesql viene chiamato con un nome in tre parti il ​​contesto è impostato sul database in cui viene chiamato.

Quindi puoi farlo con zero Rischio di iniezione SQL come di seguito.

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 

Anche se quanto sopra non fosse possibile, direi comunque che è perfettamente possibile utilizzare SQL dinamico per questo in modo sicuro come qui.

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