SQLServer2012通过链接服务器执行SQLServer2000的存储过程的问题

时间:2021-12-19 06:59:39

今天发现个问题,就是SQLServer2012通过链接服务器执行SQLServer2000的存储过程的问题,就是用2012的数据库链接服务器执行2000的数据库的带参数存储过程,必须要把参数写齐,不然会出错如下:

在远程的2000版本

创建表:

USE [pubs]
GO
CREATE TABLE [dbo].[ceshi](
[id] [int] IDENTITY(1,1) NOT NULL,
[ce] [nvarchar](50) NULL,
[shi] [nvarchar](50) NULL,
[ceshi] [nvarchar](50) NULL,
 CONSTRAINT [PK_ceshi] 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


创建存储过程

create PROCEDURE proc_ceshi
@ce nvarchar(50)=null ,
@shi nvarchar(50)=null,
@ceshi nvarchar(50)=null
AS
BEGIN
SET NOCOUNT ON;
insert into ceshi(ce,shi,ceshi) values (@ce,@shi,@ceshi)
END
GO

在本地的2012

先安装sqlncli.msi (百度一下或者2008或者以下版本的数据库文件里面有)

创建链接服务器

USE [master]
GO
EXEC master.dbo.sp_addlinkedserver @server = N'172.16.18.11', @srvproduct=N'sqlserver', @provider=N'MSDASQL', @provstr=N'DRIVER={SQL Server Native Client 10.0};SERVER=172.16.18.11;'
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'172.16.18.11',@useself=N'False',@locallogin=NULL,@rmtuser=N'sa',@rmtpassword='password'
GO
EXEC master.dbo.sp_serveroption @server=N'172.16.18.20', @optname=N'rpc', @optvalue=N'true'
GO
EXEC master.dbo.sp_serveroption @server=N'172.16.18.20', @optname=N'rpc out', @optvalue=N'true'
GO

执行报错:

exec [172.16.18.11].pubs.dbo.proc_ceshi @ce=1,@ceshi=1 --(这个在执行里面赋值参数在本地服务器就能执行,通过链接服务器就会报错。)

--链接服务器"172.16.18.11"的 OLE DB 访问接口 "MSDASQL" 返回了消息 "至少一个变量参数的参数类型无法确定。"。
--消息 7212,级别 17,状态 1,第 1 行

解决办法:

必须遵循SQLServer数据库的原始赋值方式,定义赋值再执行。

declare @ce nvarchar(50);
declare @shi nvarchar(50);
declare @ceshi nvarchar(50);

set @ce=1;
set @ceshi=4;
exec [172.16.18.11].pubs.dbo.proc_ceshi @ce,@shi,@ceshi 

或者

declare @ce nvarchar(50)=1;
declare @shi nvarchar(50)=2;
declare @ceshi nvarchar(50)=3;

exec [172.16.18.11].pubs.dbo.proc_ceshi @ce,@shi,@ceshi

意思就是不管存储过程是否允许参数有默认值,exec执行的存储过程的参数必须写完全,而且不能直接赋值在执行存储过程语句里面。

如果在执行语句里面没有写完参数并且创建时有默认值的情况下,它会按顺序填入而不会指定填入(如果类型有问题还会报错),其实这样就有点像

exec [172.16.18.11].pubs.dbo.proc_ceshi 1,2,3

它只会按参数顺序填入;

这个问题 ,链接服务器执行存储过程一般出现在跨版本的情况下,所以只有执行语句的参数写完全,对需要的参数赋值就可以了(不需要的创建时已经有默认值),这样才会识别正确的对应参数。