我使用下面的SQL语句(SQL 2008 R2)将表模式从dbo更改为db_owner:
DECLARE @old sysname, @new sysname, @sql varchar(1000)
SELECT
@old = 'db_owner'
, @new = 'dbo'
, @sql = '
IF EXISTS (SELECT NULL FROM INFORMATION_SCHEMA.TABLES
WHERE
QUOTENAME(TABLE_SCHEMA)+''.''+QUOTENAME(TABLE_NAME) = ''?''
AND TABLE_SCHEMA = ''' + @old + '''
)
EXECUTE sp_changeobjectowner ''?'', ''' + @new + ''''
EXECUTE sp_MSforeachtable @sql
我需要通过切换旧名称和新名称来更改它,但是我收到错误:
Msg 15001,Level 16,State 1,Procedure sp_changeobjectowner,第75行 对象'[db_owner]。[language_link]'不存在或无效 此操作的对象。
该表确实存在,甚至使用旧的db_owner。有什么方法可以解决这个问题吗?
这是一个关于如何告诉它仍然由db_owner拥有的屏幕截图。只有一些表格被正确移回:
答案 0 :(得分:1)
您确定要使用sp_changeobjectowner吗? (从SQL 2005开始,对象实际上不再拥有所有者。)您是如何验证db_owner.language_link存在的?就个人而言,我会使用ALTER SCHEMA
,我也倾向于目录视图(sys.tables)而不是information_schema.tables。最后,我不会使用未记录和不受支持的sp_MSforeachtable - 我已经强调了sp_MSforeachdb的问题,这些问题可能是潜在问题,因为代码非常相似。
DECLARE
@old SYSNAME = N'db_owner',
@new SYSNAME = N'dbo',
@sql NVARCHAR(MAX) = N'';
SELECT @sql += CHAR(13) + CHAR(10) + 'ALTER SCHEMA ' + @new
+ ' TRANSFER ' + QUOTENAME(SCHEMA_NAME([schema_id]))
+ '.' + QUOTENAME(name) + ';'
FROM sys.tables AS t
WHERE SCHEMA_NAME([schema_id]) = @old
AND NOT EXISTS (SELECT 1 FROM sys.tables WHERE name = t.name
AND SCHEMA_NAME([schema_id]) = @new);
PRINT @sql;
--EXEC sp_executesql @sql;
编辑添加代码以查找两个模式共有的对象。并将已经在新架构中的那些移动到一些虚拟架构:
CREATE SCHEMA dummy AUTHORIZATION dbo;
GO
DECLARE
@old SYSNAME = N'db_owner',
@new SYSNAME = N'dbo',
@sql NVARCHAR(MAX) = N'';
SELECT @sql += CHAR(13) + CHAR(10) + 'ALTER SCHEMA dummy TRANSFER '
+ QUOTENAME(@new) + '.' + QUOTENAME(t1.name) + ';'
FROM sys.tables AS t1
INNER JOIN sys.tables AS t2
ON t1.name = t2.name
WHERE t1.schema_id = SCHEMA_ID(@new)
AND t2.schema_id = SCHEMA_ID(@old);
PRINT @sql;
-- EXEC sp_executesql @sql;
但实际上它听起来像是搞砸了,需要手动清理......
编辑添加证据,因为OP似乎确信此代码无效,因为无法将内容移入dbo架构。不,不是这样,只是不可能移动dummy.floob - > dbo.floob如果已经有一个名为dbo.floob的对象。请注意,可能不是表格!
CREATE DATABASE schema_test;
GO
USE schema_test;
GO
CREATE SCHEMA floob AUTHORIZATION dbo;
GO
CREATE TABLE dbo.x(a INT);
CREATE TABLE dbo.y(a INT);
GO
从dbo移动所有表格 - > floob:
DECLARE
@old SYSNAME = N'dbo',
@new SYSNAME = N'floob',
@sql NVARCHAR(MAX) = N'';
SELECT @sql += CHAR(13) + CHAR(10) + 'ALTER SCHEMA ' + @new
+ ' TRANSFER ' + QUOTENAME(SCHEMA_NAME([schema_id]))
+ '.' + QUOTENAME(name) + ';'
FROM sys.tables AS t
WHERE SCHEMA_NAME([schema_id]) = @old
AND NOT EXISTS (SELECT 1 FROM sys.tables WHERE name = t.name
AND SCHEMA_NAME([schema_id]) = @new);
EXEC sp_executesql @sql;
GO
SELECT SCHEMA_NAME([schema_id]),name FROM sys.tables;
结果:
将所有表格从floob移回 - > DBO:
DECLARE
@old SYSNAME = N'floob',
@new SYSNAME = N'dbo',
@sql NVARCHAR(MAX) = N'';
SELECT @sql += CHAR(13) + CHAR(10) + 'ALTER SCHEMA ' + @new
+ ' TRANSFER ' + QUOTENAME(SCHEMA_NAME([schema_id]))
+ '.' + QUOTENAME(name) + ';'
FROM sys.tables AS t
WHERE SCHEMA_NAME([schema_id]) = @old
AND NOT EXISTS (SELECT 1 FROM sys.tables WHERE name = t.name
AND SCHEMA_NAME([schema_id]) = @new);
EXEC sp_executesql @sql;
GO
SELECT SCHEMA_NAME([schema_id]),name FROM sys.tables;
结果: