【问题标题】:SQL Stored Procedure with infinite optional parameters具有无限可选参数的 SQL 存储过程
【发布时间】:2010-12-07 17:52:41
【问题描述】:

我想创建一个至少有 2 个必需参数的存储过程,但它也可以用 2,3,4,5... 等参数调用。 原因:我有多个具有键值对的表,但是这个键值可以是另一个键值对列表的组。这样第一个是下一个列表的父键。 这是一个可以用相同过程调用的2个表的例子,后面会详细说明:

--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 参数存储过程所拥有的:

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 用于将值分组以知道它们属于哪一个。

这就是我想从我的 Java 代码中调用 MyListTableAlpha 的方式(注意 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

这就是我想从我的 Java 代码中调用 MyListTableBravo 的方式(注意 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

【问题讨论】:

  • 看起来您的数据库设计严重损坏。
  • 数据库设计正在运行,因此如果需要,我可以拥有分组的键值。提出这个问题已经被愚弄了。我的问题是如何向 SQL 存储过程添加无限参数。
  • 如果你选择一个略小于无穷大的上限,你将有更大的成功机会。

标签: sql-server-2008 stored-procedures optional-parameters


【解决方案1】:

您可能需要考虑制作包含 XML 的第三个参数。然后,您可以根据需要添加尽可能多的信息。

【讨论】:

  • XML 更好的替代方法是表值参数,在 SQL Server 2008 中引入。msdn.microsoft.com/en-us/library/bb510489.aspx
  • 如果您可以使表值参数起作用,那么我同意。但不确定@elcool 调用此存储过程的上下文。
  • 顺便说一句,我并不是说我已经想到了这个解决方案并驳回了它。我没有想到。您应该将其发布为答案。
  • 我已经有一段时间没有这样做了,我在 2008 年还没有这样做。我刚刚在 SO:stackoverflow.com/questions/1212504/… 找到了这个
【解决方案2】:

我就是这样解决的。

我没有设置无限参数,而是将自己限制为最多 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

:-)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    • 2018-11-08
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多