简体   繁体   中英

Change table's schema name but cannot transfer a schema bound object

The schema name menu and the table dbo.Dinner has already existed in the database.

I would like to change

FROM

dbo.Dinner

TO

menu.Dinner

Using this query:

ALTER SCHEMA menu TRANSFER dbo.Dinner

And I get error message:

cannot transfer a schema bound object

How can I solve this problem?

As I commented, I suspect that you have at least one object that uses the WITH SCHEMABINDING clause in its CREATE / ALTER and therefore you can't change the table object. You'll need to DROP and recreate those object. As an example:

USE Sandbox;
GO

CREATE TABLE dbo.Dinner (ID int, Meal varchar(20));
GO

CREATE VIEW dbo.Dinners WITH SCHEMABINDING AS
    SELECT DISTINCT Meal
    FROM dbo.Dinner;
GO

CREATE SCHEMA menu;
GO
ALTER SCHEMA menu TRANSFER dbo.Dinner; --Fails
GO
DROP VIEW dbo.Dinners;
GO
ALTER SCHEMA menu TRANSFER dbo.Dinner; --Succeeds
GO
CREATE VIEW dbo.Dinners WITH SCHEMABINDING AS
    SELECT DISTINCT Meal
    FROM menu.Dinner;
GO
--Ceal up
DROP VIEW dbo.Dinners;
DROP TABLE menu.Dinner;
DROP SCHEMA menu;

You can get a list of the dependances by using:

SELECT DISTINCT
       o.[name],
       o.[type_desc]
FROM sys.sql_expression_dependencies sed
     JOIN sys.objects o ON sed.referencing_id = o.object_id
WHERE sed.referenced_schema_name = N'dbo'
  AND sed.referenced_entity_name = N'Dinner';

We are also getting this error, exactly because we are using materialized views with schema binding.

We ended up re-creating the objects in the new schema and using insert select statements to copy over the data to the new schema.

The steps for each table are:

  • drop table in target schema
  • create table in target schema
  • insert from source to target schema

Here is a sample script:

drop table if exists [target_schema].[dim_forexchange]
go

CREATE TABLE [target_schema].[dim_forexchange](
    [time_year] [int] NOT NULL,
    [local_acct_curr] [nvarchar](50) NOT NULL,
    [DivisorFXtoGBP] [float] NOT NULL,
    [id] [uniqueidentifier] NULL
) ON [PRIMARY]
GO

ALTER TABLE [target_schema].[dim_forexchange] ADD  DEFAULT (newid()) FOR [id]
GO

insert into [target_schema].[dim_forexchange] select * from [dbo].[dim_forexchange];
go

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM