2017-02-20 29 views
0

Первый плакат! : DСохраненная процедура, содержащая множественные, если только выставляемые выписки

Я искал ответ на этот вопрос повсюду, и так же просто, как я думаю, это должно быть, я не могу найти прямой ответ нигде. Я пытаюсь создать хранимую процедуру, которая будет хранить несколько, потенциально сотни операторов select ... Только один из них на самом деле закончится ... после того, как задан параметр @Look (т. Е. Имя таблицы).

Однако, я получаю эту ошибку:

Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.

Ошибка указывает на заявления Else If и Else. Как я могу ввести exists в эти утверждения? Я пробовал настроить их безрезультатно.

Вот мой скрипт из базы данных образца:

CREATE PROCEDURE [dbo].[sp_Look] 
    (@Look varchar(50)) 
AS 
    DECLARE @Lookup VARCHAR(500) 

    IF (@Look = 'Employee_Information') 
     SET @Lookup = (SELECT EmployeeId, EmployeeSSN, EmployeeStatus 
         FROM Employee_Information) 
    Else If (@Look = 'Employee_Demographic') 
     SET @Lookup = (SELECT LastName, FirstName, DateOfBirth 
         FROM Employee_Demographic) 
    Else 
     SET @Lookup = 'No Table' 

    SELECT @Lookup 
+0

что заставило вас думать, чтобы иметь логику в СП, тогда она может быть легко обработаны в вас бизнес-слой – user7417866

+0

[не является префиксом sp_ еще нет-нет? - Аарон Бертран] (https://sqlperformance.com/2012/10/t-sql-queries/sp_prefix) – SqlZim

+0

Я честно довольно новичок в SQL, и это небольшой проект, над которым я работаю, поэтому я не совсем уверен, что вы имеете в виду в отношении того, что он обрабатывается бизнес-слоем? – Mesanic

ответ

0

Если мы можем сделать предположение, что значение переменной @Look будет именем таблицы, то все, что вам действительно нужно сделать, это установить переменную, содержащую имена столбцов. Хранимая процедура может выглядеть следующим образом:

CREATE PROCEDURE [dbo].[sp_Look] 
(@Look varchar(50)) 

AS 

SET NOCOUNT ON; 

-- check for sql injection 
IF CHARINDEX(';', ISNULL(@Look,'')) != 0 
BEGIN 
RAISERROR('Invalid input parameter', 16, 1) 
RETURN -1 
END 

Declare @SQL nvarchar(MAX);  

IF (@Look = 'Employee_Information') 
    SET @SQL = N'EmployeeId, EmployeeSSN, EmployeeStatus'      
ELSE IF (@Look = 'Employee_Demographic') 
    SET @SQL = N'LastName, FirstName, DateOfBirth' 

IF (@SQL is not null) 
BEGIN 
    SET @SQL = N'SELECT ' + @SQL + ' FROM '+ QUOTENAME(@Look) + ';'; 
    EXEC sys.sp_executesql @SQL; 
END 
ELSE 
    SELECT 'No Table' 
+0

Спасибо, это замечательно и выполняет то, что я искал. Я был в стороне от моего оригинального дизайна, и я ценю, что вы нашли время, чтобы собрать это вместе.:) Я не могу сказать, что я полностью понимаю все, что происходит в этом ответе, но это работает, и это замечательно, так что это достаточно хорошо для меня. Мне нужно вникать и понять, как это работает. – Mesanic

0

не знаю, почему вы делаете это, но если вы должны по какой-то странной причине, сделать это что-то вроде этого .....

Create Procedure [dbo].[usp_Look] --<-- do not use sp_ prefix for user procs 
@Look SYSNAME      --<-- Use appropriate data type for sql server objects 
AS 
BEGIN 
    SET NOCOUNT ON; 
    Declare @Sql nvarchar(MAX); 

     -- Use dynamic sql rather than using if..else blocks 
IF OBJECT_ID(@Look) IS NOT NULL 
BEGIN 
    SET @Sql = N' SELECT * FROM ' + QUOTENAME(@Look) + ';'; 
    EXEC sys.sp_executesql @Sql; 
END 
ELSE 
    BEGIN 
    SELECT 'Table Does not exists'; 
    END 

END 
+0

Это было бы хорошим решением, если бы я оставил выбранные столбцы одинаковыми для каждой таблицы; однако в этом случае каждый оператор select должен вытягивать другой определенный набор столбцов. Мне нравится этот сценарий, который вы предоставили много, но вам нужно будет преодолеть этот горб. Кроме того, цель состоит в том, чтобы объявить каждое имя таблицы коротким сокращением, то есть вместо Employee_Information, это будет EI, и это параметр, который вы предоставили бы @Look. – Mesanic