Sql server 在SELECT中执行存储过程
我有一个表Sql server 在SELECT中执行存储过程,sql-server,sql-server-2008,stored-procedures,Sql Server,Sql Server 2008,Stored Procedures,我有一个表tblDashboard,结构如下: CREATE TABLE [dbo].[tblDashboard] ( [DashboardID] [uniqueidentifier] NOT NULL, [Name] [nvarchar](255) NOT NULL, [Description] [nvarchar](2047) NOT NULL, [StoredProcedureName] [nvarchar](511) NULL, CONSTRAI
tblDashboard
,结构如下:
CREATE TABLE [dbo].[tblDashboard]
(
[DashboardID] [uniqueidentifier] NOT NULL,
[Name] [nvarchar](255) NOT NULL,
[Description] [nvarchar](2047) NOT NULL,
[StoredProcedureName] [nvarchar](511) NULL,
CONSTRAINT [PK_Dashboard]
PRIMARY KEY CLUSTERED ([DashboardID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
对于每个仪表板项,我都附带了一个存储过程。我必须针对仪表板项执行相应的存储过程集
我需要的输出基本上是以下格式
SELECT
DashboardID, Name,
<stored procedure output>
FROM
tblDashboard
选择
仪表板ID、名称、,
从…起
TBL仪表板
我知道,在SELECT
query中不可能有EXEC
语句,但需要寻找建议/替代方法来实现此输出。谢谢
所有存储过程都返回一个nvarchar(MAX)
类型值。我是否应该将每个存储过程更改为函数并在SELECT
query中调用
我已将存储过程更改为函数,并添加了帮助执行函数的命令
我需要的不是最后一列中的函数名,而是该函数的输出。使用动态查询可以做到这一点吗?最好的解决方案是将存储过程重写为
TVF
。通过这种方式,您将能够:
SELECT dashboardId, name, tvf.*
FROM dashboard
CROSS APPLY
my_tvf(dashboardId) tvf
如果无法执行此操作,并且存储过程仅返回一个resultset,则需要声明一个表变量或临时表(与过程的resultset布局相同),然后为仪表板条目声明一个游标,并在循环中追加到表中:
DECLARE cr_dashboard CURSOR FAST_FORWARD FORWARD_ONLY
FOR
SELECT *
FROM dashboard
DECLARE @id INT
OPEN cr_dashboard
WHILE 1 = 1
BEGIN
FETCH cr_dashboard
INTO @id
IF @@FETCH_STATUS <> 0
BREAK
INSERT
INTO @tv
EXEC my_sp @id
END
CLOSE cr_dashboard
DEALLOCATE
cr_dashboard
仅声明cr\u仪表板光标快进\u
对于
挑选*
从仪表板
声明@id INT
打开cr_仪表板
而1=1
开始
获取cr_仪表板
进入@id
如果@@FETCH\u状态为0
打破
插入
进入@tv
EXEC my_sp@id
结束
关闭控制面板
解除分配
CRU仪表板
然后,您需要将
@tv
与仪表板
(前提是存储过程返回结果集中某个地方的仪表板id)。最好的解决方案是将存储过程重写为TVF
。通过这种方式,您将能够:
SELECT dashboardId, name, tvf.*
FROM dashboard
CROSS APPLY
my_tvf(dashboardId) tvf
如果无法执行此操作,并且存储过程仅返回一个resultset,则需要声明一个表变量或临时表(与过程的resultset布局相同),然后为仪表板条目声明一个游标,并在循环中追加到表中:
DECLARE cr_dashboard CURSOR FAST_FORWARD FORWARD_ONLY
FOR
SELECT *
FROM dashboard
DECLARE @id INT
OPEN cr_dashboard
WHILE 1 = 1
BEGIN
FETCH cr_dashboard
INTO @id
IF @@FETCH_STATUS <> 0
BREAK
INSERT
INTO @tv
EXEC my_sp @id
END
CLOSE cr_dashboard
DEALLOCATE
cr_dashboard
仅声明cr\u仪表板光标快进\u
对于
挑选*
从仪表板
声明@id INT
打开cr_仪表板
而1=1
开始
获取cr_仪表板
进入@id
如果@@FETCH\u状态为0
打破
插入
进入@tv
EXEC my_sp@id
结束
关闭控制面板
解除分配
CRU仪表板
然后,您需要将您的
@tv
与仪表板
(前提是存储的进程在结果集中某处返回仪表板id)。您希望SP输出结果中出现什么?从你得到它的方式来看,你似乎期待着一个大团块的结果。一个大的XML结果会起作用吗?所有存储过程都返回相同类型的输出吗?我已经用答案更新了我的问题;它返回相同的输出,而不是创建标量值函数。如果可以的话。谢谢@GordonLinoff,我也有同样的想法;我可以将SP转换为功能您希望SP输出结果中出现什么?从你得到它的方式来看,你似乎期待着一个大团块的结果。一个大的XML结果会起作用吗?所有存储过程都返回相同类型的输出吗?我已经用答案更新了我的问题;它返回相同的输出,而不是创建标量值函数。如果可以的话。谢谢@GordonLinoff,我也有同样的想法;我可以将SP转换为函数。我在将存储过程更改为函数的问题中添加了SQLFIDLE。你有没有想过用一种不同的方法来代替游标?谢谢。。。事情并不是那么简单;功能完全不同,;我不能将所有函数的逻辑组合成一个函数并返回我的output@techspider:tough luckI我想可能会添加一个通用包装函数,并使用多个IF调用包装函数中硬编码的实际函数conditions@techspider:那可能行。如果你对函数的布局和用途不那么神秘的话,我们甚至可以给你一些建议,告诉你怎么做。你有没有想过用一种不同的方法来代替游标?谢谢。。。事情并不是那么简单;功能完全不同,;我不能将所有函数的逻辑组合成一个函数并返回我的output@techspider:tough luckI我想可能会添加一个通用包装函数,并使用多个IF调用包装函数中硬编码的实际函数conditions@techspider:那可能行。如果您对函数的布局和用途不那么神秘的话,我们甚至可能会给您关于如何做到这一点的建议。