我正在尝试设置一个数据仓库应用程序,以便我的公司使用分区数据导入表。我试图删除旧数据并为新数据腾出空间。这是我收到此错误消息的地方:
Msg 4947, Level 16, State 1, Line 1 ALTER TABLE SWITCH statement failed. There is no identical index in source table 'AssetServer.dbo.IISLog061122' for the index 'IDX_IISLogPartitioned_IP' in target table 'AssetServer.dbo.IISLogPartitioned' .
以下是需要复制的索引的定义
/ ******对象:索引[IDX_IISLogPartitioned_IP]脚本日期:07/01/2009 10:44:45 ****** /
CREATE NONCLUSTERED INDEX [IDX_IISLogPartitioned_IP] ON [dbo].[IISLogPartitioned] (
[c-ip] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
下面你会看到我在存储过程中创建了一个相同的索引。我已经验证它已成功创建,但alter table语句失败并显示上述消息。存储过程的主循环归结为:
ALTER PARTITION FUNCTION fnIISLogRequestTime() SPLIT RANGE ('20090612 01:59:59:000');
CREATE TABLE [dbo].[IISLog061201]
([RequestTime] [datetime] NULL,
[weekday] [int] NOT NULL,
[cs-method] [varchar](50) NOT NULL,
[cs-uri-stem] [varchar](255) NOT NULL,
[cs-uri-query] [varchar](2048) NULL,
[c-ip] [varchar](50) NOT NULL,
[cs(Referer)] [varchar](2048) NULL,
[cs-host] [varchar](255) NULL,
[sc-status] [int] NOT NULL,
[sc-substatus] [int] NULL,
[sc-bytes] [int] NULL,
[cs-bytes] [int] NULL,
[time-taken] [int] NULL,
[insertiontime] [datetime] NOT NULL,
[TimeSinceLast] [int] NULL,
[VIP] [varchar](50) NULL) ON [PRIMARY];
CREATE NONCLUSTERED INDEX [IDX_IISLogPartitioned_IP] ON [dbo].[IISLog061201](
[c-ip] ASC
) WITH (
PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF,
DROP_EXISTING = OFF, ONLINE = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON);
ALTER TABLE [dbo].[IISLog061201] SWITCH TO IISLogPartitioned PARTITION 7
如何摆脱此错误消息?
答案 0 :(得分:5)
您收到错误的原因是因为这两个索引实际上不相同。分区表上的索引在其定义中包含分区列,即使您的代码没有明确说明它。 (这是一个幕后的事情。)
如果要在分区表时进行分区切换,则索引需要显式引用分区列。更改您提供的索引包括RequestTime(假设这是分区列)。您可以将其作为索引列或仅包含列。下面我去包括。
CREATE NONCLUSTERED INDEX [IDX_IISLogPartitioned_IP] ON [dbo].[IISLog061201](
[c-ip] ASC) INCLUDE ( RequestTime ) WITH (
PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF,
DROP_EXISTING = OFF, ONLINE = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON);
现在应该可以了。
答案 1 :(得分:0)
根据您的文字,似乎此代码在存储过程中?
或许问题是程序在某个时刻被重新编译 - 它注意到了索引问题。即使您稍后可能创建索引,它也无法工作,因为编译失败。
如果向一个过程中的表添加一个列并稍后加入此列,则会发生同样的事情:有时它可能会起作用,因为没有重新编译,但有时它不会因为(例如因为不同的数据集)重新编译完成。
有时这些问题可以通过使用动态SQL和sp_executesql来解决,或者您可以将代码拆分为两个SP。或者,如果不真正需要SP,只需将脚本分成不同的部分即可。