MSSQL如何在存储过程while循环中遍历表列传值调用UDF查所有股票盈亏
原问题(翻译)
涉及表名:Stocks
我需要获取Stocks表中各股票公司的盈亏情况。
我已经创建了自定义函数(UDF),入参为股票公司名称,返回代表盈亏的整数值,函数代码如下:
CREATE FUNCTION FetchStockProfitLoss( @stockCompany nvarchar(50) ) RETURNS INT AS BEGIN declare @buyStock as INT; declare @sellStock as INT; declare @profitLoss as INT; Set @buyStock = (SELECT SUM(stockvalue) from stocks where stockcompany=@stockCompanyand transactiontype='buy'); Set @sellStock = (SELECT SUM(stockvalue) from stocks where stockcompany=@stockCompanyand transactiontype='sell'); set @profitLoss = (@buyStock) -(@sellStock); RETURN @profitLoss END;
目前我可以传入单个股票公司名称调用UDF,调用代码如下:
SELECT distinct stock_symbol,dbo.FetchIndStock('Google') as ProfitLoss from stocks where stock_symbol='Google'
请问如何在存储过程中使用循环,实现获取所有股票公司对应盈亏结果的需求?
示例数据说明: TransactionID为表的主键列。
解答
前置修正
首先你现有代码有两处明显错误,先修正再做后续开发:
- UDF语法错误:
@stockCompanyand缺少空格,应该改为@stockCompany and,否则会报字段不存在的错误 - 调用语句函数名不匹配:你定义的UDF名为
FetchStockProfitLoss,调用时写的FetchIndStock需要对应修正,否则会报函数不存在的错误
循环实现存储过程方案
CREATE PROCEDURE GetAllStockProfitLoss AS BEGIN -- 存储去重后的股票公司列表,加自增ID用于循环遍历 CREATE TABLE #TempStock ( RowID INT IDENTITY(1,1) PRIMARY KEY, StockCompany NVARCHAR(50), StockSymbol NVARCHAR(50) ) INSERT INTO #TempStock (StockCompany, StockSymbol) SELECT DISTINCT stockcompany, stock_symbol FROM Stocks DECLARE @RowNum INT = 1 -- 当前遍历行数 DECLARE @MaxRow INT = (SELECT COUNT(*) FROM #TempStock) -- 总公司数 DECLARE @CurCompany NVARCHAR(50), @CurSymbol NVARCHAR(50) -- 存储最终盈亏结果 CREATE TABLE #Result ( StockSymbol NVARCHAR(50), ProfitLoss INT ) WHILE @RowNum <= @MaxRow BEGIN -- 取出当前行的公司信息 SELECT @CurCompany = StockCompany, @CurSymbol = StockSymbol FROM #TempStock WHERE RowID = @RowNum -- 调用UDF计算盈亏,插入结果表 INSERT INTO #Result (StockSymbol, ProfitLoss) VALUES (@CurSymbol, dbo.FetchStockProfitLoss(@CurCompany)) SET @RowNum = @RowNum + 1 END -- 输出所有公司盈亏结果 SELECT * FROM #Result -- 清理临时表 DROP TABLE #TempStock DROP TABLE #Result END
存储过程调用方法:
EXEC GetAllStockProfitLoss
可选优化方案(无循环,性能更高)
如果没有强制要求必须用循环,完全可以不用UDF和循环,直接用分组聚合查询实现,代码更简洁、执行效率更高:
SELECT stock_symbol, SUM(CASE WHEN transactiontype = 'buy' THEN stockvalue ELSE -stockvalue END) AS ProfitLoss FROM Stocks GROUP BY stock_symbol
内容的提问来源于stack exchange,提问作者PavanKumar GVVS
相关产品推荐
相关产品推荐

