是否可以为UDF返回的表命名主键?

时间:2015-01-21 02:29:20

标签: sql sql-server tsql user-defined-types

我有一个类似于以下内容的用户定义函数:

create function paying_customers(@report_month int, @report_year int)
returns @customer_subs table
(
  customer_id int primary key not null,
  amount money not null
)
as
begin
etc.

这很好用,但是我想命名主键(它似乎仍然是数据库中的一个对象)。

以下是错误消息(关键字约束附近的语法不正确):

create function paying_customers(@report_month int, @report_year int)
returns @customer_subs table
(
  customer_id int not null,
  amount money not null,
  constraint pk_paying_customers primary key clustered (customer_id)
)
as
begin
etc.

我正在尝试命名主键,因为我们有一个比较数据库的脚本,它发现了一个区别 - 在sys.objects中为第一次运行UDF时临时返回表的主键创建了一个对象(我不确定为什么这应该继续存在......)。

2 个答案:

答案 0 :(得分:2)

UDF返回一个表变量,而不是具体表(想想DECLARE @t TABLECREATE TABLE),因此返回表和主键都不会在数据库中显示出来。您不能命名表变量,因为在任何给定时间可能有多个副本浮动,因此名称会发生​​冲突。

您可以创建一个表,为其指定一个命名主键,并将UDF结果放入表中。或者你可以忘记命名主键......

答案 1 :(得分:1)

当您在函数返回的表变量上指定主键时,它会获得一个名称,但它是某种默认名称,据我所知,您无法指定在函数声明syntax中拥有。要查看数据库中自动命名的主键,请使用以下查询:

SELECT 
    i.name AS IndexName, 
    OBJECT_NAME(ic.OBJECT_ID) AS TableName, 
    COL_NAME(ic.OBJECT_ID,ic.column_id) AS ColumnName
FROM sys.indexes AS i
INNER JOIN sys.index_columns AS ic
ON i.OBJECT_ID = ic.OBJECT_ID
AND i.index_id = ic.index_id
WHERE i.is_primary_key = 1
and i.Name like 'PK[_][_]%'

当我创建OP提到的示例函数,然后运行上面的查询时,我发现该函数返回的表的主键名为" PK__paying_c__CD65CB8504D1D82C"。

我确实发现您可以在创建功能后重命名主键。继续这个例子,它将是:

exec sp_rename 'PK__paying_c__CD65CB8504D1D82C', 'PK_PayingCustomersAreGreat'

为什么这样做?没有很好的理由,但在我的情况下,我们有一个应该遵守的命名约定,并且这些自动命名的主键开始显示。