Si utiliza EXEC @Var
(sin paréntesis - es decir, no EXEC (@Var)
) de SQL Server busca un procedimiento almacenado coincide con el nombre aprobado en @Var
. Puede usar nombres de tres partes para esto.
Si se llama a sys.sp_executesql
con un nombre de tres partes, el contexto se establece en la base de datos a la que se llama.
Así que puede hacer esto con cero Riesgo de inyección SQL como a continuación.
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
Incluso si el anterior no era posible todavía diría que es perfectamente posible utilizar SQL dinámico para esto de una manera segura como en este caso.
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
Excepto cómo se usa el comando 'USE' dentro de un proceso almacenado cuando SQL Server específicamente lo deshabilita? –
JNK
¡Gracias por esta información! – jjoras
Whoops - sí, SQL Server no permite 'use' en un proceso almacenado. Respuesta actualizada –