首页 > 解决方案 > SQL Server 2008 R2 Express 上的表值参数 READONLY 错误

问题描述

我有用户定义的表类型和使用这种类型的存储过程

create type dbo.ut_Type1(
        Col1 varchar(10),
        Col2 varchar(10),
        Col3 int) 
go
create procedure dbo.p_Procedure1(
        @TVP ut_Type1 READONLY,
        @Year int,
        @ID int)
as
begin

这是从客户端应用程序调用

var td:TMSTableData;

......

TMSQuery1.SQL.Text:='exec dbo.p_Procedure1 @TVP = :Par1, @Year = :Par2, @ID = :Par3';
TMSQuery1.ParamByName('Par1').AsTable:=td.Table;
TMSQuery1.ParamByName('Par2').AsInteger:=2019;
TMSQuery1.ParamByName('Par3').AsInteger:=4605;

除了一个特定的 SQL Server 之外,一切都运行良好。这是 Profiler 为该服务器执行的操作。( Microsoft SQL Server 2008 R2 (SP2) - 10.50.4000.0 (X64) Express Edition with Advanced Services (64-bit))

declare @p3 dbo.ut_Type1
insert into @p3 values('001','112',142)

exec sp_executesql N'exec dbo.p_Procedure1 @Table = @P1, @Year = @P2, @ID = @P3', N'@P1 dbo.ut_Type1,@P2 int,@P3 int',@p3,2019,4605

并得到错误

“表值参数 @P1 必须使用 READONLY 选项声明”

我在类似的 SQL Server( Microsoft SQL Server 2008 R2 (SP2) - 10.50.4042.0 (X64) Express Edition with Advanced Services (64-bit))上尝试了相同的调用。这是 Profiler 的执行

declare @p3 dbo.ut_Type1
insert into @p3 values('001','112',142)

exec sp_executesql N'exec dbo.p_Procedure1 @Table = @P1, @Year = @P2, @ID = @P3', N'@P1 dbo.ut_Type1 READONLY,@P2 int,@P3 int',@p3,2019,4605

并且没有出错。

唯一的区别是第一个服务器表值参数上缺少的关键字 READONLY。

我必须设置 SQL Server 的任何配置吗?
谢谢!

标签: sql-servertable-valued-parameters

解决方案


根据微软的文档表参数有以下限制:

  • SQL Server 不维护表值参数列的统计信息。
  • 表值参数必须作为输入 READONLY 参数传递给 Transact-SQL 例程。您不能对例程主体中的表值参数执行 DML 操作,例如 UPDATE、DELETE 或 INSERT。
  • 不能将表值参数用作 SELECT INTO 或 INSERT EXEC 语句的目标。表值参数可以在 SELECT INTO 的 FROM 子句中,也可以在 INSERT EXEC 字符串或存储过程中。

推荐阅读