我有一个选择查询,该查询返回一列包含“ n”个记录的数据集。我想将此列用作存储过程中的参数。下面是我的案例的简化示例。
查询:
SELECT code FROM rawproducts
数据集:
CODE
1
2
3
存储过程:
ALTER PROCEDURE [dbo].[MyInsertSP]
(@code INT)
AS
BEGIN
INSERT INTO PRODUCTS description, price, stock
SELECT description, price, stock
FROM INVENTORY I
WHERE I.icode = @code
END
我已经完成了实际的查询和存储过程;我只是不确定如何将它们放在一起。
在此感谢您的协助!谢谢!
PS:当然,存储过程并不像上面那样简单。我只是选择使用一个非常愚蠢的示例来缩小内容范围。 :)
答案 0 :(得分:0)
有两种方法供您使用,一种是使用没有游标的循环:
DECLARE @code_list TABLE (code INT);
INSERT INTO @code_list SELECT code, ROW_NUMBER() OVER (ORDER BY code) AS row_id FROM rawproducts;
DECLARE @count INT;
SELECT @count = COUNT(*) FROM @code_list;
WHILE @count > 0
BEGIN
DECLARE @code INT;
SELECT @code = code FROM @code_list WHERE row_id = @count;
EXEC MyInsertSP @code;
DELETE FROM @code_list WHERE row_id = @count;
SELECT @count = COUNT(*) FROM @code_list;
END;
通过将代码放入表变量中并为每行分配一个从1..n开始的数字来工作。然后我们一次遍历它们,一次删除它们,直到处理完为止,直到表变量中没有剩余。
但这是我认为更好的方法:
CREATE TYPE dbo.code_list AS TABLE (code INT);
GO
CREATE PROCEDURE MyInsertSP (
@code_list dbo.code_list)
AS
BEGIN
INSERT INTO PRODUCTS (
[description],
price,
stock)
SELECT
i.[description],
i.price,
i.stock
FROM
INVENTORY i
INNER JOIN @code_list cl ON cl.code = i.code;
END;
GO
DECLARE @code_list dbo.code_list;
INSERT INTO @code_list SELECT code FROM rawproducts;
EXEC MyInsertSP @code_list = @code_list;
要使其工作,我创建了一个用户定义的表类型,然后使用该表类型将代码列表传递到存储过程中。这意味着稍微重写存储过程,但是完成工作的实际代码要小得多。
答案 1 :(得分:0)
(如何)使用选择列作为输入来运行存储过程 参数?
您要寻找的是APPLY; APPLY是将列用作输入参数的方式。唯一不清楚的是输入列的填充方式/位置。让我们从示例数据开始:
IF OBJECT_ID('dbo.Products', 'U') IS NOT NULL DROP TABLE dbo.Products;
IF OBJECT_ID('dbo.Inventory','U') IS NOT NULL DROP TABLE dbo.Inventory;
IF OBJECT_ID('dbo.Code','U') IS NOT NULL DROP TABLE dbo.Code;
CREATE TABLE dbo.Products
(
[description] VARCHAR(1000) NULL,
price DECIMAL(10,2) NOT NULL,
stock INT NOT NULL
);
CREATE TABLE dbo.Inventory
(
icode INT NOT NULL,
[description] VARCHAR(1000) NULL,
price DECIMAL(10,2) NOT NULL,
stock INT NOT NULL
);
CREATE TABLE dbo.Code(icode INT NOT NULL);
INSERT dbo.Inventory
VALUES (10,'',20.10,3),(11,'',40.10,3),(11,'',25.23,3),(11,'',55.23,3),(12,'',50.23,3),
(15,'',33.10,3),(15,'',19.16,5),(18,'',75.00,3),(21,'',88.00,3),(21,'',100.99,3);
CREATE CLUSTERED INDEX uq_inventory ON dbo.Inventory(icode);
功能:
CREATE FUNCTION dbo.fnInventory(@code INT)
RETURNS TABLE AS RETURN
SELECT i.[description], i.price, i.stock
FROM dbo.Inventory I
WHERE I.icode = @code;
使用情况:
DECLARE @code TABLE (icode INT);
INSERT @code VALUES (10),(11);
SELECT f.[description], f.price, f.stock
FROM @code AS c
CROSS APPLY dbo.fnInventory(c.icode) AS f;
结果:
description price stock
-------------- -------- -----------
20.10 3
40.10 3
更新后的程序(请注意我的评论):
ALTER PROC dbo.MyInsertSP -- (1) Lose the input param
AS
-- (2) Code that populates the "code" table
INSERT dbo.Code VALUES (10),(11);
-- (3) Use CROSS APPLY to pass the values from dbo.code to your function
INSERT dbo.Products ([description], price, stock)
SELECT f.[description], f.price, f.stock
FROM dbo.code AS c
CROSS APPLY dbo.fnInventory(c.icode) AS f;
这^^^是完成的方式。