系统存储过程和表参数

时间:2012-10-04 01:39:30

标签: sql-server stored-procedures table-variable

我习惯这样做:

use MyDb
go
create type table_list as table (name sysname)
go
create proc rebuild_indexes
    @ls table_list readonly
as
  [...]

但现在我想在 master 中创建proc并在其他数据库中使用它:

use master
go
create type table_list as table (name sysname)
go
create proc sp_rebuild_indexes
    @ls table_list readonly
as
  [...]

......它构建得很好,但我不能使用它!

use MyDb
go
declare @ls table_list

的产率:

  

消息2715,级别16,状态3,行1列,参数或变量#1:   找不到数据类型table_list。参数或变量'@ls'有一个   数据类型无效。

所以我尝试创建一个同义词,它在创建过程中不会抱怨,但没有帮助:

create synonym table_list for master.dbo.table_list

任何想法?

2 个答案:

答案 0 :(得分:2)

在不同数据库中声明的表类型,即使它们共享相同的名称和结构,也不会被SQL Server视为相同:

create database DB1
go
use DB1
go
create type TT1 as table (ID int not null)
go
create procedure Echo
    @T TT1 readonly
as
    select * from @T
go
create database DB2
go
use DB2
go
create type TT1 as table (ID int not null)
go
declare @T TT1
insert into @T(ID) values (1)
exec DB1..Echo @T

结果:

(1 row(s) affected)
Msg 206, Level 16, State 2, Procedure Echo, Line 0
Operand type clash: TT1 is incompatible with TT1

据我所知,没有办法使用另一个数据库中的表类型定义在数据库中声明变量。 (例如,您可以使用任何可以使用用户定义的表类型的地方,它只能命名为<table type><schema>.<table type>。不允许使用3或4个部分名称。

(以上情况适用于2008年和2012年;显然,未来版本可能会采取措施解决这个问题)


作为解决方法,您可以使用“穷人”的方式 - 让您的主定义存储过程针对临时表工作,而不是用户定义的表类型:

use Master
go
create procedure sp_Echo
as
    select DB_NAME(),* from #t
go
create database DB1
go
use DB1
go
create table #t (ID int not null)
insert into #t (ID) values (1),(2)
exec sp_Echo

结果:

------------- -----------
DB1           1
DB1           2

答案 1 :(得分:1)

AFAIK,用户定义的类型不能在创建它们的数据库的上下文之外使用。

您可能必须在每个数据库中创建UDT,但将sProc保留在master中。

您是否有使用sp_命名约定的特定原因?

皮特