2014-09-29 2 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

Invalid имя столбца test_sv

Очевидно, я неправильно понял, как работает СЛУЧАЙ. Может ли кто-нибудь дать представление?

+0

Вы не можете этого сделать, я боюсь. Вы могли бы выполнять только набор операторов 'IF', таких как' IF @countryId = 1 SELECT * FROM test_sv ELSE IF @countryId = 2 SELECT * FRMO test_dk и т. Д. – DavidG

+0

- это таблицы test_sv, test_dk etc? они имеют одинаковую структуру? – schudel

+0

Да, та же структура. Причина, по которой я хотел выбрать таблицу условно, заключалась в том, чтобы избежать воспроизведения кода, что было бы альтернативой операторам IF/ELSE, и поскольку мой оператор SELECT несколько сложный, было бы много дублированного кода. – Marcus

ответ

1

You может написать динамический запрос как:

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

+0

Имейте в виду, что это означает, что ваши планы запросов, скорее всего, будут довольно неэффективными. – DavidG

+0

Результаты этого sproc кэшированы в любом случае, он вызывается только один раз. – Marcus

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 
Смежные вопросы