我们正在编写一个存储过程,负责获取存储过程的名称,并返回包含存储过程列及其数据类型的结果。 但是,我们遇到了执行动态查询以返回存储过程结果的问题,但是我们无法将其存储在临时表中!
您可以在下面看到我们的查询:
DECLARE @ProcName VARCHAR(100)='spGetOraganizationsList',
@ParamName VARCHAR(100),@DataType VARCHAR(20),
@Query NVARCHAR(MAX)='EXEC '+'spGetOraganizationsList '
SELECT PARAMETER_NAME,DATA_TYPE
INTO #Tmp
FROM information_schema.PARAMETERS
WHERE SPECIFIC_NAME=@ProcName
DECLARE ParamCursor CURSOR
FOR SELECT * FROM #Tmp
OPEN ParamCursor
FETCH NEXT FROM ParamCursor
INTO @ParamName,@DataType
WHILE @@FETCH_STATUS = 0
BEGIN
SET @Query=@Query+@ParamName+'=Null,'
FETCH NEXT FROM ParamCursor INTO @ParamName,@DataType
END
CLOSE ParamCursor
DEALLOCATE ParamCursor
DROP TABLE #Tmp
EXEC sp_executesql @Query
问题是我无法将其结果存储在临时表中,
并且OPENROWSET
不接受变量。
答案 0 :(得分:1)
我认为它来自sql概念,它不信任存储过程的结果,因此我们无法通过“在查询表中建立”方法对其进行选择或将其存储在表中。 除非创建表并定义它的列和sql对您的信任,然后将其结果插入该表中,否则请采取以下情况
Create table test (name varchar(10),family varchar(20))
Insert into test
Exec sp-testResult
现在,如果您为表定义了错误的列,您将收到查询运行时错误。实际上sql无法预测sp的结果,而是将其留给您来定义存储过程的结果。
答案 1 :(得分:0)
您当然可以将存储过程的结果插入TEMP表中:
CREATE PROCEDURE PurgeMe
AS
SELECT convert(int, 1) AS DaData
UNION
SELECT convert(int, 2)
GO
CREATE TABLE #Doodles (AnInteger int)
INSERT #Doodles EXECUTE PurgeMe
SELECT * FROM #Doodles
但是,有关TEMP表的SCOPE的问题出现了。您可能会发现,在调用例程中,您将无法看到在例程中创建的TEMP表。
解决SCOPE问题的方法是执行以下操作:
如果对此感兴趣,我可以使用存储过程进行更长的发布,以完成上述操作。它是为促进动态SQL而编写的
答案 2 :(得分:0)
使用全局临时表和动态OPENROWSET
DROP TABLE ##Tmp;
GO
DECLARE @ProcName VARCHAR(100)='spGetOraganizationsList',
@ParamName VARCHAR(100), @DataType VARCHAR(20),
-- Mind to specify database and schema of the SP
@Query NVARCHAR(MAX)=' EXEC [mydb].[dbo].spGetOraganizationsList ';
SELECT PARAMETER_NAME,DATA_TYPE
INTO #Tmp
FROM information_schema.PARAMETERS
WHERE SPECIFIC_NAME=@ProcName;
-- Build SP exec
DECLARE ParamCursor CURSOR
FOR SELECT * FROM #Tmp
OPEN ParamCursor
FETCH NEXT FROM ParamCursor
INTO @ParamName,@DataType
WHILE @@FETCH_STATUS = 0
BEGIN
SET @Query=@Query+@ParamName+'=Null,'
FETCH NEXT FROM ParamCursor INTO @ParamName,@DataType
END
CLOSE ParamCursor
DEALLOCATE ParamCursor
SET @Query = left(@Query, len(@Query) - 1);
-- Build ad hoc distributed query which creates ##Tmp from SP exec.
SET @Query = 'SELECT * INTO ##Tmp FROM OPENROWSET(''SQLNCLI'', ''Server=localhost;Trusted_Connection=yes;'',''' + @Query + ''')';
EXEC (@Query);
-- Created by dynamic sql `##Tmp` is availabe in the current context.
SELECT *
FROM ##Tmp;
别忘了首先启用即席分布式查询。
sp_configure 'Show Advanced Options', 1
GO
RECONFIGURE
GO
sp_configure 'Ad Hoc Distributed Queries', 1
GO
RECONFIGURE
GO
答案 3 :(得分:0)
在存储过程中根据需要编写选择查询。您无需创建临时表即可得到结果。
答案 4 :(得分:0)
在C#中,您可以使用SqlDataReader或DataTable从存储过程中获取结果,而无需事先了解架构。如果您随后想将该数据写入临时表,我想您可以从C#中做到这一点(尽管我从未尝试过这样做)。
答案 5 :(得分:-1)
为什么不创建视图而不是创建和删除表。
CREATE VIEW "VIEW_NAME" AS "SQL Statement";
一个不相关的示例:-
CREATE VIEW V_Customer
AS SELECT First_Name, Last_Name, Country
FROM Customer;