对于我正在处理的应用程序......我们正在创建一个自定义日志系统。用户可以查看日志并对其应用“标签”(就像您可以在此处将标签应用于问题一样!)
在这个例子中,我试图获得一个给出“标签”的所有日志的列表。我意识到我可以通过使用连接来实现这一点......但这也是我练习存储过程的一个练习:)
我有一个看起来像这样的存储过程来通过PK
选择日志ALTER PROCEDURE [dbo].[getLogByLogId]
-- Add the parameters for the stored procedure here
@ID int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT TOP 1
LOG_ID,
a.A,
a.B,
a.C
FROM dbo.LOG a
WHERE a.LOG_ID = @ID
现在我想把这个存储过程称为另一个......就像这样
ALTER PROCEDURE [dbo].[getLogsByTagName]
-- Add the parameters for the stored procedure here
@TAG nvarchar(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT TOP 1000
LOG_ID --somehow store this and execute the dbo.getLogByLogId procedure here
FROM dbo.LOG_TAG a
WHERE a.TAG = @TAG
由于
答案 0 :(得分:2)
如果您的logbyid SP中有复杂的逻辑,您试图避免在系统中的多个位置进行复制(选择列,派生列等),我建议将其转换为内联表值函数(可能没有获取ID参数,在这种情况下,您实际上可以使用普通视图。
然后你可以加入到你的其他存储过程中的ITVF /视图(或者也可以创建另一个udf)进行搜索或使用OUTER APPLY功能(效率不高)。
内联表值函数基本上是参数化视图,可以通过优化器相当容易地优化。
答案 1 :(得分:0)
如果你想在sproc中调用另一个sproc,只需使用:
CREATE PROCEDURE myTestProc
AS
BEGIN
--Do some work in this procedure
SELECT blah FROM foo
--now call another sproc
EXEC nameOfSecondSproc
END
答案 2 :(得分:0)
您可以使用CURSOR
来实现您尝试的内容的唯一方法如果这只是为了你的学习,那么一定要试一试,但我不会推荐这个用于制作。
它会像这样
DECLARE @Table TABLE(
ID INT
)
INSERT INTO @Table SELECT 1
INSERT INTO @Table SELECT 2
INSERT INTO @Table SELECT 3
INSERT INTO @Table SELECT 4
INSERT INTO @Table SELECT 5
INSERT INTO @Table SELECT 6
DECLARE Cur CURSOR FOR
SELECT ID
FROM @Table
OPEN Cur
DECLARE @ID INT
FETCH NEXT FROM Cur INTO @ID
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @ID
FETCH NEXT FROM Cur INTO @ID
END
CLOSE Cur
DEALLOCATE Cur
通过使用 WHILE 循环中检索到的 @ID ,您可以执行所需的sp并将值插入表变量
INSERT INTO @Table EXEC sp_MySP @ID
答案 3 :(得分:0)
您可以使用以下语法从另一个存储过程调用存储过程:
ALTER PROCEDURE [dbo].[getLogsByTagName]
-- Add the parameters for the stored procedure here
@TAG nvarchar(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT TOP 1000
LOG_ID --somehow store this and execute the dbo.getLogByLogId procedure here
FROM dbo.LOG_TAG a
WHERE a.TAG = @TAG
-- Execute dbo.getLogByLogId stored procedure
DECLARE @logId INTEGER
SET @logId = <some value>
EXEC dbo.getLogByLogId @logId
END
但是,您的问题的难点在于您的dbo.getLogByLogId过程只能接受单个LogID参数,因此只能返回单个日志记录。您需要返回LogId在Tags表中具有相应记录的所有Log的信息。
执行此操作的正确方法是将Log和Tag表连接在一起,如下所示:
SELECT *
FROM dbo.LOG_TAG a
INNER JOIN dbo.LOG b ON a.LOG_ID = b.LOG_ID
WHERE a.TAG = @TAG
如果您担心多次返回相同的logId,可以使用SELECT语句中的DISTINCT关键字来过滤掉重复的logId。
您也可以将dbo.getLogByLogId过程重写为用户定义的函数(UDF)。 UDF可以接受表作为参数并返回表结果。
可以在this article中找到用户定义函数的介绍。