我已经在SQL管理工作室中在我们的内部SQL框中创建了一个链接服务器对象,我可以按照以下语法插入其中:
insert into [Azure].[budget].dbo.Bill
我想设置身份插入并尝试了以下内容:
SET IDENTITY_INSERT [Azure].[budget].dbo.Bill ON
insert into [Azure].[budget].dbo.Bill
这会产生前缀太多的错误。为什么我可以在没有身份插入的情况下插入它,是否可以以任何其他方式执行此操作?
然后我将身份插入部分更改为SP,如下所示:
EXEC [Azure].[budget].dbo.sp_executesql N'SET IDENTITY_INSERT Bill ON'
insert into [Azure].[budget].dbo.Bill
但我收到一条关于没有获得BillID字段许可的警告
答案 0 :(得分:1)
您无法在链接服务器中直接使用SET IDENTITY INSERT
。
您需要使用动态SQL SET IDENTITY_INSERT ON
sp_executesql N'SET IDENTITY_INSERT [Azure].[budgetenergy].dbo.Bill ON;insert into [Azure].[budget].dbo.Bill ....';
答案 1 :(得分:0)
您可以 INSERT
将一个标识值添加到标识列的表格中链接服务器上,并使用“SWITCH TO” “技巧。
如果您没有使用“SWITCH TO”技巧来添加和删除列上的标识,那么即使在大型表格上也非常快!
从概念上讲,您只需创建一个新的SCHEMA,就像您想要INSERT
到的表一样,不需要定义的标识。然后将表格切换到该SCHEMA并执行INSERT
。然后切换回定义了标识的SCHEMA
以下示例已在AZURE的链接服务器上进行了测试。
使用“SWITCH TO”的所有注意事项(索引必须相同,删除并重新创建外键等)
要进行测试,您可以在链接的Azure SQL Server数据库上运行以下完整脚本。您需要使用[LINKED_SERVER_NAME]
和[DATABASE_NAME]
进行查找/替换,并替换为您的值。在非Azure数据库上,您可能需要在表创建中添加“ON PRIMARY”。
--Let's setup the example by creating a table with an IDENTITY column on the Linked Server
EXEC('
CREATE TABLE [DATABASE_NAME].[dbo].[Example_Table](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nchar](10) NULL
)
'
) AT [LINKED_SERVER_NAME]
--INSERT some data into the table
INSERT INTO [LINKED_SERVER_NAME].[DATABASE_NAME].[dbo].[Example_Table] ([Name]) VALUES ('Travis')
INSERT INTO [LINKED_SERVER_NAME].[DATABASE_NAME].[dbo].[Example_Table] ([Name]) VALUES ('Jay')
-- Looks good
SELECT * FROM [LINKED_SERVER_NAME].[DATABASE_NAME].[dbo].[Example_Table]
GO
-- Create a TABLE with an identical schema, without the identity defined
EXEC('
CREATE TABLE [DATABASE_NAME].[dbo].[Example_Table_temp](
[ID] [int] NOT NULL,
[Name] [nchar](10) NULL
)
'
) AT [LINKED_SERVER_NAME]
--Now Use the "SWITCH TO" to move the data to the new table
EXEC('
ALTER TABLE [DATABASE_NAME].[dbo].[Example_Table] SWITCH TO [DATABASE_NAME].[dbo].[Example_Table_temp]
'
) AT [LINKED_SERVER_NAME]
--Drop the old table (It should now be empty, but you may want to verify that if you are unsure here)
EXEC('
DROP TABLE [DATABASE_NAME].[dbo].[Example_Table]
'
) AT [LINKED_SERVER_NAME]
--Rename the new table back to the old table name
-- NOTE the lack of database and owner identifiers in the new name
-- NOTE the use of double single qoutes (ESCAPED single quotes)
EXEC('
EXEC sp_rename ''[DATABASE_NAME].[dbo].Example_Table_temp'',''Example_Table''
'
) AT [LINKED_SERVER_NAME]
-- Now do your IDENTITY INSERTs !!!!
INSERT INTO [LINKED_SERVER_NAME].[DATABASE_NAME].[dbo].[Example_Table] (ID,[Name]) VALUES (888,'Travis')
INSERT INTO [LINKED_SERVER_NAME].[DATABASE_NAME].[dbo].[Example_Table] (ID,[Name]) VALUES (999,'Jay')
--Verify they got put in
SELECT * FROM [LINKED_SERVER_NAME].[DATABASE_NAME].[dbo].[Example_Table]
--Now let's switch it back to our SCHEMA with an IDENTITY
EXEC('
CREATE TABLE [DATABASE_NAME].[dbo].[Example_Table_temp](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nchar](10) NULL
)
ALTER TABLE [DATABASE_NAME].[dbo].[Example_Table] SWITCH TO [DATABASE_NAME].[dbo].[Example_Table_temp]
DROP TABLE [DATABASE_NAME].[dbo].[Example_Table]
EXEC sp_rename ''[DATABASE_NAME].[dbo].Example_Table_temp'',''Example_Table''
'
) AT [LINKED_SERVER_NAME]
--Data is still there
SELECT * FROM [LINKED_SERVER_NAME].[DATABASE_NAME].[dbo].[Example_Table]
GO
-- And note you can no longer INSERT the IDENTITY
INSERT INTO [LINKED_SERVER_NAME].[DATABASE_NAME].[dbo].[Example_Table] (ID,[Name]) VALUES (45,'Travis')
GO