Fer*_*een 1526 sql t-sql sql-server stored-procedures sql-server-2005
我该怎么办SELECT * INTO [temp table] FROM [stored procedure]
?不FROM [Table]
,没有定义[temp table]
?
Select
所有数据都可以BusinessLine
正常tmpBusLine
工作.
select *
into tmpBusLine
from BusinessLine
Run Code Online (Sandbox Code Playgroud)
我尝试相同,但使用stored procedure
返回数据,并不完全相同.
select *
into tmpBusLine
from
exec getBusinessLineHistory '16 Mar 2009'
Run Code Online (Sandbox Code Playgroud)
输出消息:
消息156,级别15,状态1,行2关键字'exec'附近的语法不正确.
我已经阅读了几个创建一个与输出存储过程结构相同的临时表的例子,它工作正常,但不提供任何列会很好.
Aar*_*ton 684
你可以使用OPENROWSET.看一看.我还添加了sp_configure代码以启用Ad Hoc Distributed Queries,以防它尚未启用.
CREATE PROC getBusinessLineHistory
AS
BEGIN
SELECT * FROM sys.databases
END
GO
sp_configure 'Show Advanced Options', 1
GO
RECONFIGURE
GO
sp_configure 'Ad Hoc Distributed Queries', 1
GO
RECONFIGURE
GO
SELECT * INTO #MyTempTable FROM OPENROWSET('SQLNCLI', 'Server=(local)\SQL2008;Trusted_Connection=yes;',
'EXEC getBusinessLineHistory')
SELECT * FROM #MyTempTable
Run Code Online (Sandbox Code Playgroud)
Gav*_*vin 593
如果要在不先声明临时表的情况下执行此操作,可以尝试创建用户定义的函数而不是存储过程,并使该用户定义的函数返回表.或者,如果您想使用存储过程,请尝试以下方法:
CREATE TABLE #tmpBus
(
COL1 INT,
COL2 INT
)
INSERT INTO #tmpBus
Exec SpGetRecords 'Params'
Run Code Online (Sandbox Code Playgroud)
Mat*_*ton 289
在SQL Server 2005中,您可以使用INSERT INTO ... EXEC
将存储过程的结果插入表中.从MSDN的INSERT
文档(事实上对于SQL Server 2000):
--INSERT...EXECUTE procedure example
INSERT author_sales EXECUTE get_author_sales
Run Code Online (Sandbox Code Playgroud)
Chr*_*ris 191
这是对您的问题的略微修改版本的答案.如果您可以放弃对用户定义函数使用存储过程,则可以使用内联表值用户定义函数.这本质上是一个存储过程(将采用参数),它返回一个表作为结果集; 因此将很好地与INTO声明.
这是一篇关于它和其他用户定义函数的快速文章.如果仍然需要存储过程,则可以使用存储过程包装内联表值用户定义函数.当存储过程从内联表值用户定义函数调用select*时,它只传递参数.
因此,例如,您将拥有一个内联表值用户定义函数来获取特定区域的客户列表:
CREATE FUNCTION CustomersByRegion
(
@RegionID int
)
RETURNS TABLE
AS
RETURN
SELECT *
FROM customers
WHERE RegionID = @RegionID
GO
Run Code Online (Sandbox Code Playgroud)
然后,您可以调用此函数来获得结果:
SELECT * FROM CustomersbyRegion(1)
Run Code Online (Sandbox Code Playgroud)
或者做一个SELECT INTO:
SELECT * INTO CustList FROM CustomersbyRegion(1)
Run Code Online (Sandbox Code Playgroud)
如果您仍需要存储过程,则将函数包装为:
CREATE PROCEDURE uspCustomersByRegion
(
@regionID int
)
AS
BEGIN
SELECT * FROM CustomersbyRegion(@regionID);
END
GO
Run Code Online (Sandbox Code Playgroud)
我认为这是获得预期结果的最"无懈怠"的方法.它使用现有的功能,因为它们的使用目的没有额外的复杂性.通过在存储过程中嵌套内联表值的用户定义函数,您可以通过两种方式访问该功能.加!实际的SQL代码只有一个维护点.
已经建议使用OPENROWSET,但这不是OPENROWSET函数的用途(来自联机丛书):
包括从OLE DB数据源访问远程数据所需的所有连接信息.此方法是访问链接服务器中的表的替代方法,是使用OLE DB连接和访问远程数据的一次性临时方法.要更频繁地引用OLE DB数据源,请改用链接服务器.
使用OPENROWSET将完成工作,但是它会产生一些额外的开销,用于打开本地连接和编组数据.它也可能不是所有情况下的选项,因为它需要临时查询许可,这会带来安全风险,因此可能不是所希望的.此外,OPENROWSET方法将排除使用返回多个结果集的存储过程.在单个存储过程中包装多个内联表值用户定义函数可以实现此目的.
Qua*_*noi 127
EXEC sp_serveroption 'YOURSERVERNAME', 'DATA ACCESS', TRUE
SELECT *
INTO #tmpTable
FROM OPENQUERY(YOURSERVERNAME, 'EXEC db.schema.sproc 1')
Run Code Online (Sandbox Code Playgroud)
Tig*_*z32 121
最简单的解决方案
Run Code Online (Sandbox Code Playgroud)CREATE TABLE #temp (...); INSERT INTO #temp EXEC [sproc];
如果您不知道架构,则可以执行以下操作.请注意,此方法存在严重的安全风险.
SELECT *
INTO #temp
FROM OPENROWSET('SQLNCLI',
'Server=localhost;Trusted_Connection=yes;',
'EXEC [db].[schema].[sproc]')
Run Code Online (Sandbox Code Playgroud)
dot*_*joe 103
当存储过程返回大量列并且您不想手动"创建"临时表来保存结果时,我发现最简单的方法是进入存储过程并在其上添加"into"子句最后一个select语句并将1 = 0添加到where子句.
运行存储过程一次,然后返回并删除刚刚添加的SQL代码.现在,您将拥有一个与存储过程的结果匹配的空表.您可以为临时表"创建脚本表",也可以直接插入该表.
小智 66
declare @temp table
(
name varchar(255),
field varchar(255),
filename varchar(255),
filegroup varchar(255),
size varchar(255),
maxsize varchar(255),
growth varchar(255),
usage varchar(255)
);
INSERT @temp Exec sp_helpfile;
select * from @temp;
Run Code Online (Sandbox Code Playgroud)
Ras*_*dit 48
您的存储过程是否仅检索数据或修改它?如果它仅用于检索,则可以将存储过程转换为函数并使用公用表表达式(CTE)而无需声明它,如下所示:
with temp as (
select * from dbo.fnFunctionName(10, 20)
)
select col1, col2 from temp
Run Code Online (Sandbox Code Playgroud)
但是,无论需要从CTE检索什么,都只能在一个声明中使用.with temp as ...
在几行SQL之后你无法做到并尝试使用它.您可以在一个语句中包含多个CTE,以进行更复杂的查询.
例如,
with temp1020 as (
select id from dbo.fnFunctionName(10, 20)
),
temp2030 as (
select id from dbo.fnFunctionName(20, 30)
)
select * from temp1020
where id not in (select id from temp2030)
Run Code Online (Sandbox Code Playgroud)
Fis*_*ury 46
如果存储过程的结果表太复杂而无法手动输入"create table"语句,并且您无法使用OPENQUERY OR OPENROWSET,则可以使用sp_help为您生成列和数据类型列表.获得列列表后,只需格式化它就可以满足您的需求.
步骤1:将"into #temp"添加到输出查询中(例如"从[...]中选择[...]到#temp").
最简单的方法是直接在proc中编辑输出查询.如果您无法更改存储过程,则可以将内容复制到新的查询窗口并在那里修改查询.
步骤2:在临时表上运行sp_help.(例如"exec tempdb..sp_help #temp")
创建临时表后,在临时表上运行sp_help以获取列和数据类型的列表,包括varchar字段的大小.
第3步:将数据列和类型复制到create table语句中
我有一个Excel工作表,用于将sp_help的输出格式化为"create table"语句.您不需要任何花哨的东西,只需复制并粘贴到您的SQL编辑器中即可.使用列名,大小和类型构造"创建表#x [...]"或"声明@x表[...]"语句,您可以使用该语句来插入存储过程的结果.
第4步:插入新创建的表中
现在,您将拥有一个与此线程中描述的其他解决方案类似的查询.
DECLARE @t TABLE
(
--these columns were copied from sp_help
COL1 INT,
COL2 INT
)
INSERT INTO @t
Exec spMyProc
Run Code Online (Sandbox Code Playgroud)
此技术还可用于将临时表(#temp
)转换为表变量(@temp
).虽然这可能比仅create table
自己编写语句更多的步骤,但它可以防止手动错误,例如大型进程中的拼写错误和数据类型不匹配.调试拼写错误可能比首先编写查询花费更多时间.
Dou*_*ana 30
Quassnoi把我的大部分路都放在那里,但有一件事遗失了:
所以我找到了一种方法来处理系统,也没有必要使表定义如此严格,并在另一个存储过程中重新定义它(当然也有可能破坏它)!
是的,您可以通过使用带有伪造变量的OPENQUERY语句动态创建从存储过程返回的表定义(只要NO RESULT SET返回相同数量的字段并且与具有良好数据的数据集位于相同位置).
创建表后,您可以整天将exec存储过程用于临时表.
EXEC sp_serveroption 'MYSERVERNAME', 'DATA ACCESS', TRUE
Run Code Online (Sandbox Code Playgroud)
declare @locCompanyId varchar(8)
declare @locDateOne datetime
declare @locDateTwo datetime
set @locDateOne = '2/11/2010'
set @locDateTwo = getdate()
--Build temporary table (based on bogus variable values)
--because we just want the table definition and
--since openquery does not allow variable definitions...
--I am going to use bogus variables to get the table defintion.
select * into #tempCoAttendanceRpt20100211
FROM OPENQUERY(DBASESERVER,
'EXEC DATABASE.dbo.Proc_MyStoredProc 1,"2/1/2010","2/15/2010 3:00 pm"')
set @locCompanyId = '7753231'
insert into #tempCoAttendanceRpt20100211
EXEC DATABASE.dbo.Proc_MyStoredProc @locCompanyId,@locDateOne,@locDateTwo
set @locCompanyId = '9872231'
insert into #tempCoAttendanceRpt20100211
EXEC DATABASE.dbo.Proc_MyStoredProc @locCompanyId,@locDateOne,@locDateTwo
select * from #tempCoAttendanceRpt20100211
drop table #tempCoAttendanceRpt20100211
Run Code Online (Sandbox Code Playgroud)
感谢最初提供的信息... 是的,最后我不必在使用来自另一个存储过程或数据库的数据时创建所有这些伪(严格)表定义,是的,您也可以使用参数.
搜索参考标签:
SQL 2005存储过程转换为临时表
openquery with stored procedure and variables 2005
openquery with variables
将存储过程执行到临时表中
更新:这不适用于临时表,所以我不得不求助于手动创建临时表.
无赖注意:这不适用于临时表,http://www.sommarskog.se/share_data.html#OPENQUERY
参考:接下来是定义LOCALSERVER.它可能看起来像示例中的关键字,但它实际上只是一个名称.这是你如何做到的:
sp_addlinkedserver @server = 'LOCALSERVER', @srvproduct = '',
@provider = 'SQLOLEDB', @datasrc = @@servername
Run Code Online (Sandbox Code Playgroud)
要创建链接服务器,您必须具有ALTER ANY SERVER权限,或者是任何固定服务器角色sysadmin或setupadmin的成员.
OPENQUERY打开与SQL Server的新连接.这有一些影响:
使用OPENQUERY调用的过程无法引用当前连接中创建的临时表.
新连接有自己的默认数据库(使用sp_addlinkedserver定义,默认为master),因此所有对象规范都必须包含数据库名称.
如果您有一个打开的事务并且在调用OPENQUERY时持有锁,则被调用的过程无法访问您锁定的内容.也就是说,如果你不小心,你会阻止自己.
连接不是免费的,因此会有性能损失.
Stu*_*rtQ 30
如果OPENROWSET导致您出现问题,那么从2012年开始还有另一种方式; 使用sys.dm_exec_describe_first_result_set_for_object,如下所述:检索存储过程的列名和类型?
首先,创建此存储过程以生成临时的SQL
CREATE PROCEDURE dbo.usp_GetStoredProcTableDefinition(
@ProcedureName nvarchar(128),
@TableName nvarchar(128),
@SQL nvarchar(max) OUTPUT
)
AS
SET @SQL = 'CREATE TABLE ' + @tableName + ' ('
SELECT @SQL = @SQL + '['+name +'] '+ system_type_name +'' + ','
FROM sys.dm_exec_describe_first_result_set_for_object
(
OBJECT_ID(@ProcedureName),
NULL
);
--Remove trailing comma
SET @SQL = SUBSTRING(@SQL,0,LEN(@SQL))
SET @SQL = @SQL +')'
Run Code Online (Sandbox Code Playgroud)
要使用该过程,请按以下方式调用它:
DECLARE @SQL NVARCHAR(MAX)
exec dbo.usp_GetStoredProcTableDefinition
@ProcedureName='dbo.usp_YourProcedure',
@TableName='##YourGlobalTempTable',@SQL = @SQL OUTPUT
INSERT INTO ##YourGlobalTempTable
EXEC [dbo].usp_YourProcedure
select * from ##YourGlobalTempTable
Run Code Online (Sandbox Code Playgroud)
请注意,我正在使用全局临时表.这是因为使用EXEC运行动态SQL会创建自己的会话,因此普通的临时表将超出任何后续代码.如果全局临时表是一个问题,您可以使用普通临时表,但任何后续SQL都需要是动态的,也就是说,也是由EXEC语句执行的.
bri*_*ler 23
这个存储过程完成了这项工作:
CREATE PROCEDURE [dbo].[ExecIntoTable]
(
@tableName NVARCHAR(256),
@storedProcWithParameters NVARCHAR(MAX)
)
AS
BEGIN
DECLARE @driver VARCHAR(10)
DECLARE @connectionString NVARCHAR(600)
DECLARE @sql NVARCHAR(MAX)
DECLARE @rowsetSql NVARCHAR(MAX)
SET @driver = '''SQLNCLI'''
SET @connectionString =
'''server=' +
CAST(SERVERPROPERTY('ServerName') AS NVARCHAR(256)) +
COALESCE('\' + CAST(SERVERPROPERTY('InstanceName') AS NVARCHAR(256)), '') +
';trusted_connection=yes'''
SET @rowsetSql = '''EXEC ' + REPLACE(@storedProcWithParameters, '''', '''''') + ''''
SET @sql = '
SELECT
*
INTO
' + @tableName + '
FROM
OPENROWSET(' + @driver + ',' + @connectionString + ',' + @rowsetSql + ')'
EXEC (@sql)
END
GO
Run Code Online (Sandbox Code Playgroud)
这是对此的轻微修改:将存储过程结果插入表中以使其实际工作.
如果您希望它与临时表一起使用,那么您将需要使用##GLOBAL
表并在之后删除它.
小智 20
如果您有幸拥有SQL 2012或更高版本,则可以使用 dm_exec_describe_first_result_set_for_object
我刚刚编辑了gotqn提供的sql.谢谢你拿到了.
这将创建一个名称与过程名称相同的全局临时表.稍后可以根据需要使用临时表.只是不要忘记在重新执行之前删除它.
declare @procname nvarchar(255) = 'myProcedure',
@sql nvarchar(max)
set @sql = 'create table ##' + @procname + ' ('
begin
select @sql = @sql + '[' + r.name + '] ' + r.system_type_name + ','
from sys.procedures AS p
cross apply sys.dm_exec_describe_first_result_set_for_object(p.object_id, 0) AS r
where p.name = @procname
set @sql = substring(@sql,1,len(@sql)-1) + ')'
execute (@sql)
execute('insert ##' + @procname + ' exec ' + @procname)
end
Run Code Online (Sandbox Code Playgroud)
Dev*_*nsh 17
现在我知道我的程序的结果是什么,所以我正在执行以下查询.
CREATE TABLE [dbo].[tblTestingTree](
[Id] [int] IDENTITY(1,1) NOT NULL,
[ParentId] [int] NULL,
[IsLeft] [bit] NULL,
[IsRight] [bit] NULL,
CONSTRAINT [PK_tblTestingTree] PRIMARY KEY CLUSTERED
(
[Id] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[tblTestingTree] ON
INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (1, NULL, NULL, NULL)
INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (2, 1, 1, NULL)
INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (3, 1, NULL, 1)
INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (4, 2, 1, NULL)
INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (5, 2, NULL, 1)
INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (6, 3, 1, NULL)
INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (7, 3, NULL, 1)
INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (8, 4, 1, NULL)
INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (9, 4, NULL, 1)
INSERT [dbo].[tblTestingTree] ([Id], [ParentId], [IsLeft], [IsRight]) VALUES (10, 5, 1, NULL)
SET IDENTITY_INSERT [dbo].[tblTestingTree] OFF
Run Code Online (Sandbox Code Playgroud)
VALUES(10,5,1,NULL)SET IDENTITY_INSERT [dbo].[tblTestingTree] On
create procedure GetDate
as
begin
select Id,ParentId from tblTestingTree
end
create table tbltemp
(
id int,
ParentId int
)
insert into tbltemp
exec GetDate
select * from tbltemp;
Run Code Online (Sandbox Code Playgroud)got*_*tqn 16
要将存储过程的第一个记录集插入临时表,您需要知道以下内容:
sp_executesql
)上面可能看起来像限制,但恕我直言它完全有道理 - 如果你使用sp_executesql
你可以一次返回两列,一旦十,如果你有多个结果集,你也不能将它们插入到几个表中 - 你可以插入最大值在一个T-SQL语句中的两个表中(using OUTPUT
子句和无触发器).
因此,问题主要是如何在执行EXEC ... INTO ...
语句之前定义临时表结构.
第一个适用,OBJECT_ID
第二个和第三个也适用于Ad-hoc查询.我更喜欢使用DMV代替sp,因为您可以使用它CROSS APPLY
并同时为多个过程构建临时表定义.
SELECT p.name, r.*
FROM sys.procedures AS p
CROSS APPLY sys.dm_exec_describe_first_result_set_for_object(p.object_id, 0) AS r;
Run Code Online (Sandbox Code Playgroud)
此外,请注意该system_type_name
领域,因为它可能非常有用.它存储列完整定义.例如:
smalldatetime
nvarchar(max)
uniqueidentifier
nvarchar(1000)
real
smalldatetime
decimal(18,2)
Run Code Online (Sandbox Code Playgroud)
并且您可以在大多数情况下直接使用它来创建表定义.
因此,我认为在大多数情况下(如果存储过程符合某些条件),您可以轻松构建动态语句来解决此类问题(创建临时表,将存储过程结果插入其中,使用数据执行所需操作) .
请注意,上述对象在某些情况下无法定义第一个结果集数据,例如在执行动态T-SQL语句或在存储过程中使用临时表时.
Pro*_*ver 15
如果查询不包含参数,请使用OpenQuery
else OpenRowset
.
基本的事情是根据存储过程创建模式并插入到该表中.例如:
DECLARE @abc TABLE(
RequisitionTypeSourceTypeID INT
, RequisitionTypeID INT
, RequisitionSourcingTypeID INT
, AutoDistOverride INT
, AllowManagerToWithdrawDistributedReq INT
, ResumeRequired INT
, WarnSupplierOnDNRReqSubmission INT
, MSPApprovalReqd INT
, EnableMSPSupplierCounterOffer INT
, RequireVendorToAcceptOffer INT
, UseCertification INT
, UseCompetency INT
, RequireRequisitionTemplate INT
, CreatedByID INT
, CreatedDate DATE
, ModifiedByID INT
, ModifiedDate DATE
, UseCandidateScheduledHours INT
, WeekEndingDayOfWeekID INT
, AllowAutoEnroll INT
)
INSERT INTO @abc
EXEC [dbo].[usp_MySp] 726,3
SELECT * FROM @abc
Run Code Online (Sandbox Code Playgroud)
Sof*_*ARM 13
码
CREATE TABLE #T1
(
col1 INT NOT NULL,
col2 NCHAR(50) NOT NULL,
col3 TEXT NOT NULL,
col4 DATETIME NULL,
col5 NCHAR(50) NULL,
col6 CHAR(2) NULL,
col6 NCHAR(100) NULL,
col7 INT NULL,
col8 NCHAR(50) NULL,
col9 DATETIME NULL,
col10 DATETIME NULL
)
DECLARE @Para1 int
DECLARE @Para2 varchar(32)
DECLARE @Para3 varchar(100)
DECLARE @Para4 varchar(15)
DECLARE @Para5 varchar (12)
DECLARE @Para6 varchar(1)
DECLARE @Para7 varchar(1)
SET @Para1 = 1025
SET @Para2 = N'6as54fsd56f46sd4f65sd'
SET @Para3 = N'XXXX\UserName'
SET @Para4 = N'127.0.0.1'
SET @Para5 = N'XXXXXXX'
SET @Para6 = N'X'
SET @Para7 = N'X'
INSERT INTO #T1
(
col1,
col2,
col3,
col4,
col5,
col6,
col6,
col7,
col8,
col9,
col10,
)
EXEC [dbo].[usp_ProcedureName] @Para1, @Para2, @Para3, @Para4, @Para5, @Para6, @Para6
Run Code Online (Sandbox Code Playgroud)
我希望这有帮助.请视情况而定.
kev*_*ers 11
我发现将传递数据/数据表传递到存储过程中可能会让您对如何解决问题有所了解.
该链接建议使用Image类型参数传递到存储过程.然后在存储过程中,图像被转换为包含原始数据的表变量.
也许有一种方法可以用于临时表.
zho*_*o37 10
我遇到了同样的问题,这就是我从保罗的建议中为此做的.这里的主要部分是使用NEWID()
避免多个用户同时运行存储过程/脚本,全局临时表的痛苦.
DECLARE @sql varchar(max) = '',
@tmp_global_table varchar(255) = '##global_tmp_' + CONVERT(varchar(36), NEWID())
SET @sql = @sql + 'select * into [' + @tmp_global_table + '] from YOURTABLE'
EXEC(@sql)
EXEC('SELECT * FROM [' + @tmp_global_table + ']')
Run Code Online (Sandbox Code Playgroud)
另一种方法是创建一个类型并使用PIPELINED然后传回你的对象.但这仅限于知道列.但它的优点是能够做到:
SELECT *
FROM TABLE(CAST(f$my_functions('8028767') AS my_tab_type))
Run Code Online (Sandbox Code Playgroud)
这可以在 SQL Server 2014+ 中完成,前提是存储过程只返回一张表。如果有人找到对多个表执行此操作的方法,我很想知道。
DECLARE @storedProcname NVARCHAR(MAX) = ''
SET @storedProcname = 'myStoredProc'
DECLARE @strSQL AS VARCHAR(MAX) = 'CREATE TABLE myTableName '
SELECT @strSQL = @strSQL+STUFF((
SELECT ',' +name+' ' + system_type_name
FROM sys.dm_exec_describe_first_result_set_for_object (OBJECT_ID(@storedProcname),0)
FOR XML PATH('')
),1,1,'(') + ')'
EXEC (@strSQL)
INSERT INTO myTableName
EXEC ('myStoredProc @param1=1, @param2=2')
SELECT * FROM myTableName
DROP TABLE myTableName
Run Code Online (Sandbox Code Playgroud)
这将从系统表中提取返回表的定义,并使用它为您构建临时表。然后,您可以如前所述从存储过程中填充它。
还有一些变体也适用于动态 SQL。
小智 6
这是一个简单的两步过程:-创建一个临时表-插入到临时表中。
执行相同的代码:
CREATE TABLE #tempTable (Column1 int, Column2 varchar(max));
INSERT INTO #tempTable
EXEC [app].[Sproc_name]
@param1 = 1,
@param2 =2;
Run Code Online (Sandbox Code Playgroud)
在四处搜寻之后,我发现了一种无需使用OPENROWSET
或OPENQUERY
使用存储过程结果定义的通用模式就可以为任何存储过程动态创建临时表的方法,尤其是当您不是数据库管理员时。
SQL Server具有一个内置的proc sp_describe_first_result_set
,可以为您提供任何过程结果集的架构。我根据此过程的结果创建了一个模式表,并将所有字段手动设置为NULLABLE。
declare @procname varchar(100) = 'PROCEDURENAME' -- your procedure name
declare @param varchar(max) = '''2019-06-06''' -- your parameters
declare @execstr nvarchar(max) = N'exec ' + @procname
declare @qry nvarchar(max)
-- Schema table to store the result from sp_describe_first_result_set.
create table #d
(is_hidden bit NULL, column_ordinal int NULL, name sysname NULL, is_nullable bit NULL, system_type_id int NULL, system_type_name nvarchar(256) NULL,
max_length smallint NULL, precision tinyint NULL, scale tinyint NULL, collation_name sysname NULL, user_type_id int NULL, user_type_database sysname NULL,
user_type_schema sysname NULL,user_type_name sysname NULL,assembly_qualified_type_name nvarchar(4000),xml_collection_id int NULL,xml_collection_database sysname NULL,
xml_collection_schema sysname NULL,xml_collection_name sysname NULL,is_xml_document bit NULL,is_case_sensitive bit NULL,is_fixed_length_clr_type bit NULL,
source_server sysname NULL,source_database sysname NULL,source_schema sysname NULL,source_table sysname NULL,source_column sysname NULL,is_identity_column bit NULL,
is_part_of_unique_key bit NULL,is_updateable bit NULL,is_computed_column bit NULL,is_sparse_column_set bit NULL,ordinal_in_order_by_list smallint NULL,
order_by_list_length smallint NULL,order_by_is_descending smallint NULL,tds_type_id int NULL,tds_length int NULL,tds_collation_id int NULL,
tds_collation_sort_id tinyint NULL)
-- Get result set definition of your procedure
insert into #d
EXEC sp_describe_first_result_set @exestr, NULL, 0
-- Create a query to generate and populate a global temp table from above results
select
@qry = 'Create table ##t(' +
stuff(
(select ',' + name + ' '+ system_type_name + ' NULL'
from #d d For XML Path, TYPE)
.value(N'.[1]', N'nvarchar(max)')
, 1,1,'')
+ ')
insert into ##t
Exec '+@procname+' ' + @param
Exec sp_executesql @qry
-- Use below global temp table to query the data as you may
select * from ##t
-- **WARNING** Don't forget to drop the global temp table ##t.
--drop table ##t
drop table #d
Run Code Online (Sandbox Code Playgroud)
在Sql Server版本上开发和测试-Microsoft SQL Server 2016(RTM)-13.0.1601.5(内部版本17134 :)
您可以调整正在使用的SQL Server版本的架构(如果需要)。
归档时间: |
|
查看次数: |
1891120 次 |
最近记录: |