【发布时间】:2022-01-06 00:13:30
【问题描述】:
我有以下程序:
CREATE PROCEDURE sp_types
@type varchar(100)
AS
BEGIN
DECLARE @products table(productId int)
IF @type = 'Merchandise'
BEGIN
INSERT INTO @products
SELECT productId
FROM dbo.product
WHERE type = @type
END
ELSE IF @type = 'Electronics'
BEGIN
INSERT INTO @products
SELECT productId
FROM dbo.product
WHERE type = @type
END
ELSE IF @type = 'Home'
BEGIN
INSERT INTO @products
SELECT productId
FROM dbo.product
WHERE type = @type
END
ELSE
BEGIN
INSERT INTO @products
SELECT productId
FROM dbo.product
WHERE type = @type
END
/* here we have logic to convert all the productids in the @products table into an XML format
<products>
<productId>1</productId>
<productId>2</productId>
....
....
....
<productId>100</productId>
</products>
*/
/* after we get the XML string, it is passed to another procedure to print out details about the products */
EXEC sp_products_list @xml = @productXml
END /* procedure ends here */
这是sp_products_list 过程:
CREATE PROCEDURE sp_products_list
@xml XML
AS
BEGIN
DECLARE @products TABLE (productId int)
INSERT INTO @products
SELECT @xml.value('productId','int')
FROM @xml.nodes('products')
/* Select statement */
SELECT
a.productId, a.productName,
b.productRegion, b.ProductQuantity,
c.productSupplier
FROM
products a
JOIN
productRegion b ON a.productid = b.productid
JOIN
productSupplier c ON c.productRegion = b.productRegion
WHERE
a.productId IN (SELECT productId FROM @products)
END /* procedure end */
sp_products_list 由除sp_types 过程之外的许多其他过程调用。我有一个要求,当我将一种“商品”传递给sp_types 过程时,我需要显示一些额外的列,例如productSupplierRegion、productSupplierCount 等。
但是对于其余的类型,我只需要显示sp_products_list过程中的select语句当前显示的内容。
如果我只是将我需要的列添加到当前 sp_products_list 过程中的 select 语句中,那么它们将显示为传递给 sp_types 过程的任何类型,这不是我想要的。
我的解决方案:我能想到的解决方案之一是在sp_products_list 过程中接收一个@type 变量作为输入,并为select 语句添加一个if-else 语句。如果传入了“商品”的类型,则显示带有附加列的选择,否则显示常规列。
我将来使用这种方法可能面临的问题是,如果我们想为传入的不同 @type 变量添加不同类型的列。在这种情况下,我将不得不做多个 if -else 每种类型的语句。我计划使用动态 SQL,但我的想法被否决了,因为我的团队不是动态 SQL 的忠实拥护者。
现在我正在尝试为这个问题找到一个可能在任何情况下都有效的可靠解决方案。有什么想法或建议吗?谢谢!
【问题讨论】:
-
作为一项规则,存储过程不应返回具有不同列集、数据类型、结果集数量...的结果,具体取决于输入参数、月份时间、磁盘容量... ...有时它是有道理的,但很少。它要求使用数据的应用程序能够以合理的方式确定如何处理产生的一堆'o'bits。旁白:似乎所有处理
@type值的if/then代码对预期值执行完全相同的操作,但以相同方式处理意外值。你没有告诉我们什么? -
未来根据你的需求,你有多种类型,每种类型需要不同的列列表,那么你应该将类型和列详细信息存储在一个表中,并根据类型获取列详细信息,并且把它们放在一个选择语句上。不,需要任何 if else 语句。
-
旁注:您应该不为您的存储过程使用
sp_前缀。微软有reserved that prefix for its own use (see Naming Stored Procedures),你确实会在未来某个时候冒着名称冲突的风险。 It's also bad for your stored procedure performance。最好只是简单地避免sp_并使用其他东西作为前缀 - 或者根本不使用前缀! -
旁白:我建议您使用表类型在存储过程之间传递数据,这可能比 XML 更有效。尽管您可以使用 XML 来解决当前的问题:仅在某些时候适用的额外列,但是您会将其作为表类型的 XML 列,而不是作为每一行的整个 blob 一起
标签: sql sql-server database tsql stored-procedures