簡體   English   中英

接受查詢作為參數的存儲過程

[英]Stored procedure that accepts a query as parameter

我正在嘗試編寫一個MySQL存儲過程,該存儲過程接受SELECT查詢並針對數據庫列表執行它。 MySQL甚至有可能嗎?

我們應用程序中的每個客戶在同一實例上都有自己的數據庫。 所有客戶數據庫的架構結構都相同。 有時,我需要在所有客戶數據庫中執行一個簡單的SELECT查詢(例如SELECT COUNT(*) FROM users )。

我已經為常見的重復“實例級”查詢(例如用戶計數)存儲了存儲過程,但我不想為一次性查詢創建更多的存儲過程(例如,由於錯誤代碼而查詢損壞的記錄,查詢那些我們打算棄用,等等。)

我當前的解決方案是我有一個node腳本,該腳本在本地運行以為每個數據庫生成SELECT查詢,然后使用UNION將它們全部連接起來以生成一個大型查詢,然后在數據庫實例上執行該查詢。

SELECT 'customerdb1' AS customer,
       COUNT(*) AS user_count
FROM customerdb1.users
UNION
SELECT 'customerdb2' AS customer,
       COUNT(*) AS user_count
FROM customerdb2.users
UNION
SELECT 'customerdb3' AS customer,
       COUNT(*) AS user_count
FROM customerdb3.users

您可以使用PREPARE和EXECUTE在存儲過程中完成此操作,但是將其視為以這種方式運行任意SQL的安全漏洞。 您說過,該程序只能由特殊帳戶使用,但是僅允許該程序存在是一種風險。 如果修改了特權並允許任何人運行該程序怎么辦?

在許多模式下運行該查詢也將非常慢,因為MySQL每個查詢只運行一個線程。 它必須串行運行查詢,並將結果收集到臨時表中。

此外,您對任何單個SQL查詢的長度都有一個限制,即max_allowed_packet 這應該非常大,但是如果您有足夠的UNION術語,您仍然可以超過長度。

我在一個您所描述的網站上工作,那里有許多模式,每個客戶一個,具有相同的表。 當我們想在所有架構上運行查詢時,我將在多個並行線程中運行一個簡單查詢(不使用UNION ),並將結果收集到應用程序代碼中。


有關允許輸入任意SQL的存儲過程的有趣故事,請參見https://thedailywtf.com/articles/For-the-Ease-of-Maintenance

暫無
暫無

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

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