Nếu bạn sử dụng EXEC @Var
(không có dấu ngoặc - ví dụ: khôngEXEC (@Var)
) SQL Server tìm kiếm một thủ tục lưu trữ phù hợp với tên thông qua vào @Var
. Bạn có thể sử dụng ba phần đặt tên cho việc này.
Nếu sys.sp_executesql
được gọi với tên có ba phần, bối cảnh được đặt thành cơ sở dữ liệu mà nó được gọi.
Vì vậy, bạn có thể làm điều này với số không Nguy cơ tiêm SQL như sau.
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
Ngay cả khi những điều trên không thể, tôi vẫn cho rằng hoàn toàn có thể sử dụng SQL động một cách an toàn như ở đây.
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
Nguồn
2010-10-15 17:46:15
Ngoại trừ cách bạn sử dụng lệnh 'USE' bên trong một proc được lưu trữ khi SQL Server đặc biệt không cho phép nó? –
JNK
Cảm ơn thông tin này! – jjoras
Rất tiếc - SQL Server không cho phép 'sử dụng' trong một proc được lưu trữ. Đã cập nhật câu trả lời. –