天天看點

用sp_executesql執行動态SQL語句及獲得傳回值

過去我執行拼湊出來的動态SQL語句,都直接使用EXEC @sql 的方式。有好幾次,都看到有資料說,應該盡量使用 sp_executesql。

究其原因,是因為僅僅參數不同的情況下,sp_executesql可以重用執行計劃,這不就有跟存儲過程一樣的優勢了嗎?同時,sp_executesql還可以提供動态SQL語句執行的傳回值,友善得很。

但sp_executesql的使用方式看上去比較複雜,一點都不像EXEC那樣直覺。

用法:

EXEC sp_executesql SQL語句,參數聲明,參數

CREATE TABLE #tmp(t INT NOT NULL,it DECIMAL(18,4),pt DECIMAL(18,4));
  INSERT INTO #tmp(t,it,pt) VALUES(1,10.00,15.00);
  INSERT INTO #tmp(t,it,pt) VALUES(2,20.00,30.00);

  DECLARE @sql NVARCHAR(2000) = N'SELECT @it=it,@pt=pt FROM #tmp WHERE t=@tN;';
  DECLARE @Param NVARCHAR(500) = N'@tN INT,@it DECIMAL(18,4) OUTPUT,@pt DECIMAL(18,4) OUTPUT';
  DECLARE @tN INT,@it DECIMAL(18,4),@pt DECIMAL(18,4);
  
  SET @tN = 1;
  --@tN=@tN,第一個@tN是@Param裡的聲明,而第二個@tN則是外部的聲明,其他類似
  EXEC sp_executesql @sql,@Param,@tN=@tN,@it=@it OUTPUT,@pt=@pt OUTPUT;
  SELECT @it,@pt;
  
  DROP TABLE #tmp;      

為什麼有傳回值那麼重要呢?我在不知道這個用法以前,如果需要捕捉動态SQL語句裡的傳回值,要借用表對象:

詳見拙作:

declare @sql NVARCHAR(MAX) = N'SELECT @i,@j;';
declare @paramdefine NVARCHAR(MAX) = N'@i INT,@j INT,@k INT=3';
exec sp_executesql @sql,@paramdefine,@i=1,@j=2;