一个关于“OLE DB 提供程序 'sqloledb' 指出该对象中没有任何列”错误的解决方法
2009-09-14 14:15
936 查看
一个关于“OLE DB 提供程序 'sqloledb' 指出该对象中没有任何列”错误的解决方法
在网上看到一个网友提问把系统过程的结果输出到文本文件 ,心想这不简单呀,bcp+openrowset呀轻松解决呀,本着认真的态度(其实是怕写个错误的让人家笑话我)我在我的查询分析器里写个试:
--1
select *
from
OPENROWSET('SQLOLEDB','SERVER=.;UID=sa;PWD=','exec csdn_test.dbo.sp_helpsrvrolemember') AS a
--2
SELECT *
FROM
openrowset('sqloledb','Trusted_Connection=yes','exec csdn_test..sp_helpsrvrolemember ')
F5一运行,完了,出丑了
服务器: 消息 7357,级别 16,状态 2,行 1
未能处理对象 'exec csdn_test.dbo.sp_helpsrvrolemember'。OLE DB 提供程序 'SQLOLEDB' 指出该对象中没有任何列。
OLE DB 错误跟踪[Non-interface error: OLE DB provider unable to process object, since the object has no columnsProviderName='SQLOLEDB', Query=exec csdn_test.dbo.sp_helpsrvrolemember']。
这老写的语法怎么会报错呢,自己写一个过程试试,一试更呆了
create proc pr_test
as
begin
select * from tb
end
go
SELECT *
FROM openrowset('sqloledb', 'Trusted_Connection=yes','exec csdn_test..pr_test')
drop proc pr_test
/*
TypeID Type
----------- ----
1 t1
2 t2
3 t3
4 t4
(所影响的行数为 4 行)
*/
结果是想的,那为什么这个系统过程不行呢?那先看看这个过程是什么东东:
sp_helptext 'master..sp_helpsrvrolemember'
/*
Text
------------------------------------------
CREATE PROCEDURE sp_helpsrvrolemember
@srvrolename sysname = NULL
AS
if @srvrolename is not null
begin
-- VALIDATE GIVEN NAME
if not exists (select * from master.dbo.spt_values
where name = @srvrolename and low = 0 and type = 'SRV')
begin
raiserror(15412, -1, -1, @srvrolename)
return (1)
end
-- RESULT SET FOR SINGLE SERVER-ROLE
select 'ServerRole' = spv.name, 'MemberName' = lgn.name, 'MemberSID' = lgn.sid
from master.dbo.spt_values spv, master.dbo.sysxlogins lgn
where spv.name = @srvrolename and
spv.low = 0 and
spv.type = 'SRV' and
lgn.srvid IS NULL and
spv.number & lgn.xstatus = spv.number
end
else
begin
-- RESULT SET FOR ALL SERVER-ROLES
select 'ServerRole' = spv.name, 'MemberName' = lgn.name, 'MemberSID' = lgn.sid
from master.dbo.spt_values spv, master.dbo.sysxlogins lgn
where spv.low = 0 and
spv.type = 'SRV' and
lgn.srvid IS NULL and
spv.number & lgn.xstatus = spv.number
end
return (0) -- sp_helpsrvrolemember
*/
一看,哦,难道这个结果因为输入参数不同而有不同select来返回影响了?或是为空时raiserror 没有select 结果集吗?好办,我们再试:
create proc pr_test
@p int =null
as
begin
if @p is null
select * from tb
else
return 0
return 1
end
go
create proc pr_test1
@p int =null
as
begin
if @p is not null
return 0
else
select * from tb
return 1
end
go
create proc pr_test2
@p int =null
as
begin
if @p is not null
return 0
else
select * from tb
return 1
end
go
SELECT *
FROM openrowset('sqloledb', 'Trusted_Connection=yes','exec csdn_test..pr_test')
SELECT *
FROM openrowset('sqloledb', 'Trusted_Connection=yes','exec csdn_test..pr_test 1')
SELECT *
FROM openrowset('sqloledb', 'Trusted_Connection=yes','exec csdn_test..pr_test1')
SELECT *
FROM openrowset('sqloledb', 'Trusted_Connection=yes','exec csdn_test..pr_test2')
drop proc pr_test,pr_test1,pr_test2
通过以上的测试,结果很明显了,也就是查询语句对过程可能的结果集进行了分析,特别第一个过程带参与不带参的结果就很明显了,上网一gg,问的人还真不少,好多人期待2005进行改进,难道2000就真的不行了?,通过查sql2000的联机帮助,发现这个设置项,很管用,哈哈
语法
SET FMTONLY { ON | OFF }
注释
当 SET FMTONLY 为 ON 时,将不对行进行处理,也不将行作为请求的结果发送到客户端。
SET FMTONLY 的设置是在执行或运行时设置,而不是在分析时设置。
很显然,这个开关项正是我们所想要分析器应该执行的结果,好试一下吧:
select *
from
OPENROWSET('SQLOLEDB','DRIVER={SQL Server};SERVER=.;UID=sa;PWD=','set fmtonly off;exec csdn_test.dbo.sp_helpsrvrolemember') AS a
select *
from
OPENROWSET('SQLOLEDB','SERVER=.;UID=sa;PWD=','set fmtonly off;exec csdn_test.dbo.sp_helpsrvrolemember') AS a
exec master..xp_cmdshell
'bcp "select * from OPENROWSET(''SQLOLEDB'',''SERVER=.;UID=sa;PWD='',''set fmtonly off;exec csdn_test.dbo.sp_helpsrvrolemember'') AS a " queryout c:/Authors.txt -c -S. -Usa -P'
/*
ServerRole MemberName MemberSID
----------------------------------- ------------------- ------
sysadmin BUILTIN/Administrators 0x01020000000000052000000020020000
sysadmin sa 0x01
(所影响的行数为 2 行)
ServerRole MemberName MemberSID
--------------------- ----------- ---------------------------
sysadmin BUILTIN/Administrators 0x01020000000000052000000020020000
sysadmin sa 0x01
(所影响的行数为 2 行)
output
-------------------
NULL
开始复制...
NULL
已复制了 2 行。
数据包的大小(字节): 4096
时钟时间(毫秒): 共 10
NULL
(所影响的行数为 7 行)
*/
在sql2005内确实进行了改进,下面 二种写法都可以得到结果:
select *
from
openrowset('SQLNCLI','Server=./sql2005;Trusted_Connection=yes','exec testcsdn..sp_helpsrvrolemember')as a
select *
from
OPENROWSET('SQLOLEDB','DRIVER={SQL Server};SERVER=./sql2005;UID=sa;PWD=flystone','exec testcsdn.dbo.sp_helpsrvrolemember') AS a
在网上看到一个网友提问把系统过程的结果输出到文本文件 ,心想这不简单呀,bcp+openrowset呀轻松解决呀,本着认真的态度(其实是怕写个错误的让人家笑话我)我在我的查询分析器里写个试:
--1
select *
from
OPENROWSET('SQLOLEDB','SERVER=.;UID=sa;PWD=','exec csdn_test.dbo.sp_helpsrvrolemember') AS a
--2
SELECT *
FROM
openrowset('sqloledb','Trusted_Connection=yes','exec csdn_test..sp_helpsrvrolemember ')
F5一运行,完了,出丑了
服务器: 消息 7357,级别 16,状态 2,行 1
未能处理对象 'exec csdn_test.dbo.sp_helpsrvrolemember'。OLE DB 提供程序 'SQLOLEDB' 指出该对象中没有任何列。
OLE DB 错误跟踪[Non-interface error: OLE DB provider unable to process object, since the object has no columnsProviderName='SQLOLEDB', Query=exec csdn_test.dbo.sp_helpsrvrolemember']。
这老写的语法怎么会报错呢,自己写一个过程试试,一试更呆了
create proc pr_test
as
begin
select * from tb
end
go
SELECT *
FROM openrowset('sqloledb', 'Trusted_Connection=yes','exec csdn_test..pr_test')
drop proc pr_test
/*
TypeID Type
----------- ----
1 t1
2 t2
3 t3
4 t4
(所影响的行数为 4 行)
*/
结果是想的,那为什么这个系统过程不行呢?那先看看这个过程是什么东东:
sp_helptext 'master..sp_helpsrvrolemember'
/*
Text
------------------------------------------
CREATE PROCEDURE sp_helpsrvrolemember
@srvrolename sysname = NULL
AS
if @srvrolename is not null
begin
-- VALIDATE GIVEN NAME
if not exists (select * from master.dbo.spt_values
where name = @srvrolename and low = 0 and type = 'SRV')
begin
raiserror(15412, -1, -1, @srvrolename)
return (1)
end
-- RESULT SET FOR SINGLE SERVER-ROLE
select 'ServerRole' = spv.name, 'MemberName' = lgn.name, 'MemberSID' = lgn.sid
from master.dbo.spt_values spv, master.dbo.sysxlogins lgn
where spv.name = @srvrolename and
spv.low = 0 and
spv.type = 'SRV' and
lgn.srvid IS NULL and
spv.number & lgn.xstatus = spv.number
end
else
begin
-- RESULT SET FOR ALL SERVER-ROLES
select 'ServerRole' = spv.name, 'MemberName' = lgn.name, 'MemberSID' = lgn.sid
from master.dbo.spt_values spv, master.dbo.sysxlogins lgn
where spv.low = 0 and
spv.type = 'SRV' and
lgn.srvid IS NULL and
spv.number & lgn.xstatus = spv.number
end
return (0) -- sp_helpsrvrolemember
*/
一看,哦,难道这个结果因为输入参数不同而有不同select来返回影响了?或是为空时raiserror 没有select 结果集吗?好办,我们再试:
create proc pr_test
@p int =null
as
begin
if @p is null
select * from tb
else
return 0
return 1
end
go
create proc pr_test1
@p int =null
as
begin
if @p is not null
return 0
else
select * from tb
return 1
end
go
create proc pr_test2
@p int =null
as
begin
if @p is not null
return 0
else
select * from tb
return 1
end
go
SELECT *
FROM openrowset('sqloledb', 'Trusted_Connection=yes','exec csdn_test..pr_test')
SELECT *
FROM openrowset('sqloledb', 'Trusted_Connection=yes','exec csdn_test..pr_test 1')
SELECT *
FROM openrowset('sqloledb', 'Trusted_Connection=yes','exec csdn_test..pr_test1')
SELECT *
FROM openrowset('sqloledb', 'Trusted_Connection=yes','exec csdn_test..pr_test2')
drop proc pr_test,pr_test1,pr_test2
通过以上的测试,结果很明显了,也就是查询语句对过程可能的结果集进行了分析,特别第一个过程带参与不带参的结果就很明显了,上网一gg,问的人还真不少,好多人期待2005进行改进,难道2000就真的不行了?,通过查sql2000的联机帮助,发现这个设置项,很管用,哈哈
SET FMTONLY
只将元数据返回给客户端。语法
SET FMTONLY { ON | OFF }
注释
当 SET FMTONLY 为 ON 时,将不对行进行处理,也不将行作为请求的结果发送到客户端。
SET FMTONLY 的设置是在执行或运行时设置,而不是在分析时设置。
很显然,这个开关项正是我们所想要分析器应该执行的结果,好试一下吧:
select *
from
OPENROWSET('SQLOLEDB','DRIVER={SQL Server};SERVER=.;UID=sa;PWD=','set fmtonly off;exec csdn_test.dbo.sp_helpsrvrolemember') AS a
select *
from
OPENROWSET('SQLOLEDB','SERVER=.;UID=sa;PWD=','set fmtonly off;exec csdn_test.dbo.sp_helpsrvrolemember') AS a
exec master..xp_cmdshell
'bcp "select * from OPENROWSET(''SQLOLEDB'',''SERVER=.;UID=sa;PWD='',''set fmtonly off;exec csdn_test.dbo.sp_helpsrvrolemember'') AS a " queryout c:/Authors.txt -c -S. -Usa -P'
/*
ServerRole MemberName MemberSID
----------------------------------- ------------------- ------
sysadmin BUILTIN/Administrators 0x01020000000000052000000020020000
sysadmin sa 0x01
(所影响的行数为 2 行)
ServerRole MemberName MemberSID
--------------------- ----------- ---------------------------
sysadmin BUILTIN/Administrators 0x01020000000000052000000020020000
sysadmin sa 0x01
(所影响的行数为 2 行)
output
-------------------
NULL
开始复制...
NULL
已复制了 2 行。
数据包的大小(字节): 4096
时钟时间(毫秒): 共 10
NULL
(所影响的行数为 7 行)
*/
在sql2005内确实进行了改进,下面 二种写法都可以得到结果:
select *
from
openrowset('SQLNCLI','Server=./sql2005;Trusted_Connection=yes','exec testcsdn..sp_helpsrvrolemember')as a
select *
from
OPENROWSET('SQLOLEDB','DRIVER={SQL Server};SERVER=./sql2005;UID=sa;PWD=flystone','exec testcsdn.dbo.sp_helpsrvrolemember') AS a
相关文章推荐
- 一个关于“OLE DB 提供程序 'sqloledb' 指出该对象中没有任何列”错误的解决方法
- 未能处理对象 'select * from teacher.dbf'。OLE DB 提供程序 'microsoft.JET.OLEDB.4.0' 指出该对象中没有任何列。
- SQL 错误 7391 因为 OLE DB 提供程序 'SQLOLEDB' 无法启动分布式服务
- 链接服务器 "(null)" 的 OLE DB 访问接口 "Microsoft.Ace.OleDb.12.0" 报错。提供程序未给出有关错误的任何信息。
- 该操作未能执行,因为 OLE DB 提供程序 'SQLOLEDB' 无法启动分布式事务。新事务不能登记到指定的事务处理器中。
- SQL2008无法连接到.\SQLEXPRESS,用户'sa'登录失败(错误18456)图文解决方法 已成功与服务器建立连接,但是在登录过程中发生错误。 (provider: 共享内存提供程序, er
- SQL2005,2008备份集中的数据库备份与现有的 'DB' 数据库不同,错误号码:3154,解决方法
- ADODB.Connection 错误 '800a0e7a' 未找到提供程序。该程序可能未正确安装。解决办法集锦
- 创建SQL作业错误的解决方法(不能将值 NULL 插入列 'owner_sid',表 'msdb.dbo.sysjobs';列不允许有空值。) .
- 关于Ajax 错误:'sys'未定义解决方法.
- 创建SQL作业错误的解决方法(不能将值 NULL 插入列 'owner_sid',表 'msdb.dbo.sysjobs';列不允许有空值。)
- Thin的DateChooser代码学习(关于js的函数参数为一个完整的函数以及“对象不支持此属性或方法”错误的解决)(原创,转载请声明)
- 关于Ajax 错误:'sys'未定义解决方法.
- SQL2005安装"错误1706,安装程序找不到需要的文件。请检查……,SQL没有安装OWC11”解决方法
- Excel2007 运行时错误'91' 对象变量或 With 块变量没有设置 的一种解决办法
- 关于IE7打开任何网页弹出[未处理的异常('对象不支持此属性或方法')发生在iexplorer.exe]错误调试框的解决办法
- 编译boost程序出现如下错误fatal error LNK1104: cannot open file 'libboost_system-vc100-mt-gd-1_54.lib'的解决方法
- 关于Ajax 错误:'sys'未定义解决方法.
- java.sql.SQLException: Value'0000-00-00'错误解决方法
- 在向服务器发送请求时发生传输级错误。 (provider: TCP 提供程序, error: 0 - 远程主机强迫关闭了一个现有的连接。) ---> System.Data.SqlClient.Sql