0

Imagine the following schema:

create table tempdb..t1 (id int, name sysname); 
create table tempdb..t2 (id int, name sysname); 
create index IX1 on tempdb..t1 (id); 
create index IX2 on tempdb..t2 (id);

Now I'm trying to script index definition:

declare @stmt nvarchar(max) = '';
select @stmt += 'create index ' + ix.name + ' on ' + t.name 
    + isnull(' where ' + ix.filter_definition, '') + char(13)
    from tempdb.sys.tables t
    join tempdb.sys.indexes ix on t.object_id = ix.object_id
    where ix.type > 0 and t.name in ('t1','t2')
    order by ix.name;
print @stmt;

I'm expecting to get two index definitions:

create index IX1 on t1
create index IX2 on t2

but get only second. If I remove order by or isnull part, or add top statement, I get both definitions.

Am I missing something obvious?

4

2 回答 2

0

我很惊讶这种行为是设计使然。

总结来自 Martin 链接的信息:不要像这样进行连接。即使没有 . 也不能保证工作order by。要获得保证有效的结果,请使用for xml.

declare @stmt nvarchar(max) = '';
select @stmt = (select  
    'create index ' + ix.name + ' on ' + t.name 
    + isnull(' where ' + ix.filter_definition, '') + char(10)
    from tempdb.sys.tables t
    join tempdb.sys.indexes ix on t.object_id = ix.object_id
    where ix.type > 0 and t.name in ('t1','t2')
    order by ix.name
    for xml path(''));
print @stmt;

其他选项是使用游标或 SQLCLR。

于 2013-04-05T10:49:18.813 回答
0

当您使用 select 将值放入标量变量时,只会将一行放入变量中。它不会将您的两行(或无论您的结果集有多大)聚合为一行。

想象一下,您有一个整数变量,您尝试为其分配 700 个不同的值,但这是行不通的。尝试将两个字符串分配给同一个变量也是如此。相反,只会使用其中一个值。

declare @i int;

SELECT @i = t.value
FROM myTable AS t
WHERE t.value between 1 and 700

SELECT @i

创建伪字符串连接聚合函数的一个好方法是将 XML 功能与 FOR XML PATH 一起使用。看看这个问题:如何将 T-SQL 中的结果连接到列中?

于 2013-04-04T13:43:12.847 回答