0

Я хочу создать хранимую процедуру, которая имеет как минимум 2 требуемых параметра, но также может быть вызвана с параметрами 2,3,4,5 ... и так далее. Причина: У меня есть несколько таблиц, имеющих пары «ключ-значение», но тогда это значение «ключ-значение» может быть группой в другой список пар «ключ-значение». Итак, первый из них является родительским ключом к следующему списку. Это пример 2 таблицы, которые могут быть вызваны с той же процедурой, которая подробно впоследствии:SQL Хранимая процедура с бесконечными необязательными параметрами

--MyListTableAlpha 
    +- Key1 (ValueA) 
    +- Key2 (ValueB) 
    +- Key3 (ValueC) 
    +- Key4 (ValueD) 

--MyListTableBravo 
    +- Parent Uno 
    +- Key1 (Value1A) 
    +- Key2 (Value1B) 
    +- Parent Dos 
    +- Key1 (Value2A) 
    +- Key2 (Value2B) 
    +- Key3 (Value3C) 

Код должен быть для SQL Server 2008.

Это то, что у меня есть для 2 paremeter хранимых процедур:

CREATE PROCEDURE [dbo].[SPListValue] 
    -- Add the parameters for the stored procedure here 
    @listName nvarchar(100) = null, 
    @keyVal nvarchar(100) = null 
    -- optional parameters go here?!? 
AS 
BEGIN 
    SET NOCOUNT ON; 

    SELECT [value_string] from [tablenames] 
    JOIN [keyvalues] on [tablenames].[id] = [keyvalues].[tableid] 
    WHERE [dbo].[keyvalues].[key] = @keyVal 
END 

Таблица [keyvalues] имеет столбцы: id, tableid, parentkeyid, key, value. Где parentkeyid используется, когда значения группируются, чтобы знать, к какому из них принадлежит.

Это, как я хотел бы назвать MyListTableAlpha от моего Java кода (уведомление 2 s):

CallableStatement cs1 = conn1.prepareCall("{call SPListValue(?,?}"); //notice 2 ?s 
cs1.setString(1, "MyListTableAlpha"); 
cs1.setString(2, "Key1"); 
ResultSet rs1 = cs1.executeQuery(); 
rs1.next(); 
value = rs1.getString("value_string"); // Prints ValueA 

Это, как я хотел бы назвать MyListTableBravo от моего Java кода (заметьте 3 s?) :

CallableStatement cs1 = conn1.prepareCall("{call SPListValue(?,?,?}"); //notice 3 ?s 
cs1.setString(1, "MyListTableBravo"); 
cs1.setString(2, "Parent Uno"); 
cs1.setString(3, "Key2"); 
ResultSet rs1 = cs1.executeQuery(); 
rs1.next(); 
value = rs1.getString("value_string"); // Prints Value1B 
+5

Похоже, у вас есть плохо сломанный дизайн DB. – Oded 2010-12-07 17:54:06

+0

Конструкция БД работает так, что при желании я могу иметь сгруппированные значения ключа. Это было подавлено, чтобы представить этот вопрос. Мой вопрос заключается в том, как добавить бесконечные параметры в хранимую процедуру SQL. – elcool 2010-12-07 18:33:25

ответ

0

Вот как я это решил.

Вместо бесконечных параметров, я ограничился максимум 4

CREATE PROCEDURE [dbo].[SPListValue] 
    @listName nvarchar(100) = null, 
    @key1Val nvarchar(100) = null, 
    @key2Val nvarchar(100) = null, 
    @key3Val nvarchar(100) = null, 
    @key4Val nvarchar(100) = null 
AS 
BEGIN 

SET NOCOUNT ON; 

if @key4Val is not null 

    SELECT fourCE.[value_string] from [tablenames] as fourCE   
    JOIN [keyvalues] as fourLS ON fourCE.[object_id] = fourLS.[parent_id] 

    JOIN [tablenames] as threeCE ON threeCE.[object_id] = fourCE.[parent_id]   
    JOIN [keyvalues] as threeLS on threeCE.[object_id] = threeLS.[parent_id] 

    JOIN [tablenames] as twoCE ON twoCE.[object_id] = threeCE.[parent_id]  
    JOIN [keyvalues] as twoLS on twoCE.[object_id] = twoLS.[parent_id] 

    JOIN [tablenames] as oneCE ON oneCE.[object_id] = threeCE.[parent_id]  
    JOIN [keyvalues] as oneLS on oneCE.[object_id] = oneLS.[parent_id] 

    JOIN [Cvl] on oneCE.[parent_cvl_id] = [Cvl].[object_id] 
    WHERE oneLS.[text] = @key1Val 
    AND twoLS.[text] = @key2Val 
    AND threeLS.[text] = @key3Val 
    AND fourLS.[text] = @key4Val 
    AND [Cvl].[display_name] = @listName 

else if @key3val is not null 

    SELECT threeCE.[value_string] from [tablenames] as threeCE  
    JOIN [keyvalues] as threeLS ON threeCE.[object_id] = threeLS.[parent_id] 

    JOIN [tablenames] as twoCE ON twoCE.[object_id] = threeCE.[parent_id]  
    JOIN [keyvalues] as twoLS on twoCE.[object_id] = twoLS.[parent_id] 

    JOIN [tablenames] as oneCE ON oneCE.[object_id] = twoCE.[parent_id]  
    JOIN [keyvalues] as oneLS on oneCE.[object_id] = oneLS.[parent_id] 

    JOIN [Cvl] on oneCE.[parent_cvl_id] = [Cvl].[object_id] 
    WHERE oneLS.[text] = @key1Val 
    AND twoLS.[text] = @key2Val 
    and threeLS.[text] = @key3Val 
    AND [Cvl].[display_name] = @listName 

else if @key2Val is not null 

    SELECT twoCE.[value_string] from [tablenames] as twoCE  
    JOIN [keyvalues] as twoLS ON twoCE.[object_id] = twoLS.[parent_id] 

    JOIN [tablenames] as oneCE ON oneCE.[object_id] = twoCE.[parent_id]  
    JOIN [keyvalues] as oneLS on oneCE.[object_id] = oneLS.[parent_id] 

    JOIN [Cvl] on oneCE.[parent_cvl_id] = [Cvl].[object_id] 
    WHERE oneLS.[text] = @key1Val AND twoLS.[text] = @key2Val 
    AND [Cvl].[display_name] = @listName 

else 

    SELECT [value_string] from [tablenames] 
    JOIN [keyvalues] ON [tablenames].[object_id] = [keyvalues].[parent_id] 
    JOIN [Cvl] on [tablenames].[parent_cvl_id] = [Cvl].[object_id] 
    WHERE [keyvalues].[text] = @key1Val 
    AND [Cvl].[display_name] = @listName 

END 

:-)

2

Возможно, вы захотите рассмотреть третий параметр, содержащий XML. Затем вы можете разместить столько информации, сколько хотите.

Смежные вопросы