2014-09-29 111 views
0

我有一個存儲過程,我試圖根據提供的tinyint參數有條件地選擇一個特定的表。這是我的代碼:有條件地選擇CASE的表格

ALTER PROCEDURE [dbo].[GetAllStuff] 
    @countryId tinyint 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @marketSpecific TABLE 

    SET @marketSpecific = 
    (CASE (@countryId) 
     WHEN 1 THEN test_sv 
     WHEN 2 THEN test_dk 
     WHEN 3 THEN test_no 
     WHEN 4 THEN test_ge 
     ELSE test_sv 
    END) 

    [..] 

END 

不幸的是,這是行不通的。我收到以下錯誤:

「必須聲明標量變量@marketSpecific

無效的列名test_sv

顯然我誤解CASE如何運作。誰能提供任何見解?

+0

你不能這樣做我害怕。你只能做一組'IF'語句,比如'IF @countryId = 1 SELECT * FROM test_sv ELSE IF @countryId = 2 SELECT * FRMO test_dk etc' – DavidG 2014-09-29 09:42:10

+0

是test_sv,test_dk等表嗎?他們有相同的結構嗎? – schudel 2014-09-29 09:43:46

+0

是的,結構相同。我希望有條件地選擇表的原因是爲了避免重現代碼,因爲我的SELECT語句有些複雜,它會有很多重複的代碼。 – Marcus 2014-09-29 10:33:55

回答

1

你可以編寫一個動態查詢爲:

create PROCEDURE [dbo].[GetAllStuff] 
    @countryId tinyint 
AS 
BEGIN 
    SET NOCOUNT ON 
    DECLARE @IntVariable int 
    DECLARE @SQLString nvarchar(500) 
    DECLARE @marketSpecific varchar(100) 

    /* Assign parameter value to local variable to avoid parameter sniffing */ 
    SET @IntVariable = @countryId 

    SET @marketSpecific = (CASE (@IntVariable) 
     WHEN 1 THEN 'test_sv' 
     WHEN 2 THEN 'test_dk' 
     WHEN 3 THEN 'test_no' 
     WHEN 4 THEN 'test_ge' 
     ELSE 'test_sv' 
    END) 

    /* Build the SQL string one time.*/ 
    SET @SQLString = 
    N'SELECT * 
     FROM '+ @marketSpecific 


    EXECUTE sp_executesql @SQLString 

END 

Demo

+0

不是最優的,但我想這可能是我的情況下最好的解決方案。謝謝! – Marcus 2014-09-29 10:35:01

+0

請記住,這意味着您的查詢計劃可能會非常低效。 – DavidG 2014-09-29 10:51:52

+0

這個sproc的結果無論如何都被緩存了,它只被調用一次。 – Marcus 2014-10-07 15:45:19

1

您不能選擇在CASE語句中使用的表。你可以做這樣的事情:

IF @countryId = 1 
    SELECT * FROM test_sv 
ELSE IF @countryId = 2 
    SELECT * FROM test_dk 
ELSE IF @countryId = 3 
    SELECT * FROM test_no 
... etc. 

但這種方法可能會產生一些奇怪的查詢計劃和影響性能。一個替代方案是創建一個視圖,工會的所有表一起(提供具有相同的結構:

CREATE VIEW test_all 
AS 
SELECT 1 AS table_type, col1, col2, col3 FROM test_sv 
UNION  
SELECT 2 AS table_type, col1, col2, col3 FROM test_sdk 
UNION  
SELECT 3 AS table_type, col1, col2, col3 FROM test_no 
UNION  
... etc. 

現在,您可以查詢您的存儲過程,視圖是這樣的:

ALTER PROCEDURE [dbo].[GetAllStuff] 
    @countryId tinyint 
AS 
BEGIN 

SELECT * FROM test_all WHERE table_type = @countryId 
1
DECLARE @countryId  TINYINT =1, 
     @sql   NVARCHAR(max), 
     @marketSpecific VARCHAR(10) 

SELECT @marketSpecific = CASE @countryId 
         WHEN 1 THEN 'test_sv' 
         WHEN 2 THEN 'test_dk' 
         WHEN 3 THEN 'test_no' 
         WHEN 4 THEN 'test_ge' 
         ELSE 'test_sv' END 

Set @sql='select * from '[email protected] 

EXEC sp_excecutesql @sql