簡體   English   中英

如何在存儲過程中執行動態查詢?

[英]How execute a dynamic query in stored procedure?

我想從用戶變量中獲取:num for 'Top' 子句和來自 Northwind DB 的 Tbl 名稱,並獲取前 5 名的結果集,我的腳本已關閉

create procedure sp_getTop5 
(
    @num int , 
    @tbl nvarchar(max)
)    
as       
    declare @res nvarchar(max);       
    set @res =  'select top '+str(@num)+' *   from '+@tbl

    exec @res   

---- check
exec sp_getTop5 5, employees

哇...除了這是我見過的最可怕的動態陳述之一,我無話可說。 您實際上是在讓惡意人員訪問價值 2GB 的字符進行注入(即 1,073,741,824 個字符,帶有nvarchar(MAX) ),以對抗很容易受到注入的語句。 他們會從字面上可以做任何事情,他們有足夠的時間(和權限)通緝。 請花時間閱讀我關於動態 SQL的注意事項和注意事項的文章, 查看Little Bobby Tables以了解您擁有的內容有多么危險。

至於你的 SQL,我不在乎你沒有真正問過一個問題,你現在需要修復你的安全模型中的巨大漏洞:

CREATE PROC getTop5 @Num int, @schema sysname, @table sysname AS --Removed sp_ prefix, see after the answer
BEGIN
    DECLARE @SQL nvarchar(MAX);
    SELECT @SQL = N'SELECT TOP (@Num) FROM ' + QUOTENAME(s.[name]) + N'.' + QUOTENAME(t.[name]) + N';'
    FROM sys.schemas s
         JOIN sys.tables t ON s.schema_id = t.schema_id
    WHERE s.[name] = @schema
      AND t.[name] = @table;

    EXEC sp_executesql @SQL, N'@Num int', @Num;
END;
GO

然后你可以執行它如下:

EXEC dbo.getTop5 5, N'dbo', N'YourTable';

這將(正如評論者剛剛提醒我的那樣)從表中給出N任意行(不是“頂部”行,並且表沒有內置順序)。 因此,沒有ORDER BYTOP意味着每次運行查詢時返回的行可能不同。

至於我對前綴的評論: sp_ 前綴仍然是禁忌嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM