3

注意:最高链接的问题并没有解决系统存储过程的问题,但它很接近。在评论者的帮助下,我得出了一个可行的答案

尝试对sp_spaceused使用如下语句,会引发错误

SELECT * INTO #tblOutput exec sp_spaceused 'Account'
SELECT * FROM #tblOutput 

错误:

必须指定要从中选择的表。

和:

缺少对象或列名称或为空。对于 SELECT INTO 语句,验证每一列都有一个名称。对于其他语句,请查找空别名。不允许使用定义为 "" 或 [] 的别名。将别名更改为有效名称。

当我完全声明一个表变量时,它会按预期工作,所以在我看来,存储过程确实返回了一个实际的表。

CREATE TABLE  #tblOutput (
    name NVARCHAR(128) NOT NULL, 
    rows CHAR(11) NOT NULL, 
    reserved VARCHAR(18) NOT NULL,
    data VARCHAR(18) NOT NULL,
    index_size VARCHAR(18) NOT NULL,
    unused VARCHAR(18) NOT NULL)

INSERT INTO #tblOutput exec sp_spaceused 'Response'
SELECT * FROM #tblOutput

为什么不能使用结果集为的临时表或表变量EXECUTE sp_xxx?或者:是否存在比每次都必须预定义完整表更紧凑的表达式?

(顺便说一句,在撰写本文时,谷歌搜索确切的术语,只返回一个结果)SELECT * INTO #tmp exec sp_spaceused

4

3 回答 3

4

TL;DR:与 一起使用SET FMTONLY OFFOPENQUERY详情如下。

Daniel E. 提供的链接似乎只是解决方案的一部分。例如,如果您尝试:

-- no need to use sp_addlinkedserver
-- must fully specify sp_, because default db is master
SELECT * FROM OPENQUERY(
   [SERVERNAME\SQL2008], 
   'exec somedb.dbo.sp_spaceused ''Account''')

您将收到以下错误:

链接服务器“LOCALSERVER\SQL2008”的 OLE DB 提供程序“SQLNCLI10”为列提供了不一致的元数据。名称在执行时已更改。

通过这篇文章找到了解决方案,然后在 OPENQUERY 上发表了一篇博文,然后又告诉我,在 SQL2008 之前,您需要使用SET FMTONLY OFF. 最终的解决方案,本质上非常简单(并且更容易完成,因为不需要指定环回链接服务器),它是:

SELECT * FROM OPENQUERY(
   [SERVERNAME\SQL2008], 
   'SET FMTONLY OFF 
   EXEC somedb.dbo.sp_spaceused ''Account''')

另外,如果你没有设置DATA-ACCESS,你可能会得到如下错误:

没有为数据访问配置服务器“SERVERNAME\SQL2008”。

这可以通过运行以下命令来解决:

EXEC sp_serveroption 'SERVERNAME\SQL2008', 'DATA ACCESS', TRUE
于 2014-04-27T18:26:37.537 回答
2

我们不能SELECT使用存储过程,这就是为什么SELECT * INTO ..Exec sp_不起作用。

要获取从存储过程返回的结果集,我们可以INSERT INTO使用一个表。

SELECT INTO语句动态创建表并从源表/视图/函数中插入数据。唯一的条件是源表应该存在并且您应该能够从中选择。

Sql Server 不允许您使用SELECTfrom,sp_因此您只能INSERT INTO在执行存储过程时使用该语句,这意味着在运行时您可以将返回的结果集添加到表中,并在稍后阶段从该表中选择。

INSERT INTO语句需要目标表名,一个现有的表。因此,无论您使用临时表、表变量还是 Sql server 持久表,您都需要先创建表,并且只有它们才能使用语法

INSERT INTO #TempTable
EXECUTE sp_Proc
于 2014-04-27T17:50:05.103 回答
-1
Using [YOUR DATABASE NAME]

CREATE TABLE [YOURTABLENAME]
(Database_Name Varchar(128),
DataBase_Size VarChar(128),
unallocated_Space Varchar(128),
reserved Varchar(128),
data Varchar(128),
index_size Varchar(128),
unused Varchar(128)
);

INSERT INTO dbo.[YOUR TABLE NAME]
(
    Database_Name,
    DataBase_Size,
    unallocated_Space,
    reserved,
    data,
    index_size,
    unused

)

EXEC sp_spaceused @oneresultset = 1  
--To get it to return it all as one data set add the nonresultset=1 at the end and viola good to go for writing to a table. :)
于 2017-08-03T19:10:51.710 回答