Премахнете всички обекти в базата данни на SQL Server, които принадлежат към различни схеми?

Има ли начин да пуснете всички обекти в db, като обектите принадлежат към две различни схеми?

Преди това работех с една схема, така че отправям запитвания към всички обекти, използвайки:

Select * From sysobjects Where type=...

след това изоставих всичко, което използвах

Drop Table ...

Сега, когато въведох друга схема, всеки път, когато се опитам да пусна, тя казва нещо за това, че нямам разрешение или обектът не съществува. НО, ако поставя префикс на обекта с [schema.object], той работи. Не знам как да автоматизирам това, защото не знам към кои обекти или към коя от двете схеми ще принадлежи обектът. Някой знае ли как да пусне всички обекти в db, независимо от коя схема принадлежи?

(Използваният потребител е собственик на двете схеми, обектите в DB са създадени от споменатия потребител, както и от потребителя, който премахва обектите - което работи, ако префиксът, който използвах, е IE. Drop Table Schema1.blah)


person Captain Alizee    schedule 07.09.2013    source източник
comment
намек: системни схеми. Всъщност: sys.schemas   -  person Mitch Wheat    schedule 07.09.2013


Отговори (4)


Използвайте sys.objects в комбинация с OBJECT_SCHEMA_NAME, за да създадете своите DROP TABLE изрази, прегледайте и след това копирайте/поставете за изпълнение:

SELECT 'DROP TABLE ' +
       QUOTENAME(OBJECT_SCHEMA_NAME(object_id)) + '.' +
       QUOTENAME(name) + ';'
  FROM sys.objects
 WHERE type_desc = 'USER_TABLE';

Или използвайте sys.tables, за да избегнете нуждата от филтъра type_desc:

SELECT 'DROP TABLE ' +
       QUOTENAME(OBJECT_SCHEMA_NAME(object_id)) + '.' +
       QUOTENAME(name) + ';'
  FROM sys.tables;

SQL Fiddle

person Bryan    schedule 07.09.2013
comment
Плюс това, от SQL Server 2005 и по-нов, бих препоръчал да използвате по-фокусирания изглед sys.tables вместо да избирате от sys.objects и да се налага да предоставяте type_desc .... - person marc_s; 07.09.2013
comment
Това е точно това, което търсих, същото ли е като първоначално препоръчаното от sys.schemas? Единственият проблем, с който се сблъсках, беше, че исках да премахна всички обекти и успях да намеря всички sys.table, sys.vew и т.н., с изключение на функциите. Но първото ви предложение работи добре за това. - person Captain Alizee; 10.09.2013

Нито един от другите въпроси изглежда не се е опитал да адресира частта от въпроса за всички обекти.

Изумен съм, че трябва да въртите своя собствена с това - очаквах да има схема за изпускане бла каскада. Със сигурност всеки един човек, който настройва сървър за разработчици, ще трябва да направи това и да се налага да прави малко мета-програмиране, преди да може да прави нормално програмиране, е наистина ужасно. Както и да е... разправя се!

Започнах да разглеждам някои от тези статии като начин да го направя чрез изчистване на схема: Има стара статия за това, но споменатите там таблици вече са означен като отхвърлен. Разгледах и документацията за новите таблици, за да помогна разберете какво става тук.

Има друг отговор и страхотен динамичен sql ресурс, към който има връзка.

След като разгледах всички тези неща известно време, всичко изглеждаше твърде объркано.

Мисля, че по-добрият вариант е да се насочим към

ALTER DATABASE 'blah' SET SINGLE_USER WITH ROLLBACK IMMEDIATE
drop database 'blah'

create database 'blah'

вместо. Допълнителното заклинание в горната част е основно принудително премахване на базата данни като споменати тук

Чувства се малко погрешно, но количеството сложност, свързано с писането на скрипта за изхвърляне, е добра причина да го избягвате според мен.

Ако изглежда, че има проблеми с премахването на базата данни, може да прегледам някои от връзките и да публикувам друг отговор

person JonnyRaa    schedule 31.03.2014
comment
Определено съм съгласен с вас относно липсата на каскада от схема за изпускане. Този отговор ме убеди да спра да търся и вместо това просто да изтрия цялата база данни. - person flodin; 09.09.2014
comment
@flodin да, в началото се почувствах малко погрешно, но оттогава не съм поглеждал назад. Не е скъпа операция за разрушаване + създаване на нови бази данни в sql сървър. Радвам се, че помогнах! - person JonnyRaa; 09.09.2014

опитайте това с sql2012 или по-нова версия,

това ще помогне за изтриване на всички обекти от избраната схема

DECLARE @MySchemaName VARCHAR(50)='dbo', @sql VARCHAR(MAX)='';
DECLARE @SchemaName VARCHAR(255), @ObjectName VARCHAR(255), @ObjectType VARCHAR(255), @ObjectDesc VARCHAR(255), @Category INT;

DECLARE cur CURSOR FOR
    SELECT  (s.name)SchemaName, (o.name)ObjectName, (o.type)ObjectType,(o.type_desc)ObjectDesc,(so.category)Category
    FROM    sys.objects o
    INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
    INNER JOIN sysobjects so ON so.name=o.name
    WHERE s.name = @MySchemaName
    AND so.category=0
    AND o.type IN ('P','PC','U','V','FN','IF','TF','FS','FT','PK','TT')

OPEN cur
FETCH NEXT FROM cur INTO @SchemaName,@ObjectName,@ObjectType,@ObjectDesc,@Category

SET @sql='';
WHILE @@FETCH_STATUS = 0 BEGIN    
    IF @ObjectType IN('FN', 'IF', 'TF', 'FS', 'FT') SET @sql=@sql+'Drop Function '+@MySchemaName+'.'+@ObjectName+CHAR(13)
    IF @ObjectType IN('V') SET @sql=@sql+'Drop View '+@MySchemaName+'.'+@ObjectName+CHAR(13)
    IF @ObjectType IN('P') SET @sql=@sql+'Drop Procedure '+@MySchemaName+'.'+@ObjectName+CHAR(13)
    IF @ObjectType IN('U') SET @sql=@sql+'Drop Table '+@MySchemaName+'.'+@ObjectName+CHAR(13)

    --PRINT @ObjectName + ' | ' + @ObjectType
    FETCH NEXT FROM cur INTO @SchemaName,@ObjectName,@ObjectType,@ObjectDesc,@Category
END
CLOSE cur;    
DEALLOCATE cur;
SET @sql=@sql+CASE WHEN LEN(@sql)>0 THEN 'Drop Schema '+@MySchemaName+CHAR(13) ELSE '' END
PRINT @sql
EXECUTE (@sql)
person Haseeb    schedule 02.03.2019

Не знам коя версия на Sql Server използвате, но ако приемем, че е 2008 или по-нова, може би следната команда ще бъде много полезна (проверете дали можете да пуснете ВСИЧКИ ТАБЛИЦИ в един прост ред):

 sp_MSforeachtable "USE DATABASE_NAME DROP TABLE ?"

Този скрипт ще изпълни DROP TABLE .... за всички таблици от база данни DATABASE_NAME. Много е проста и работи перфектно. Тази команда може да се използва за изпълнение на други sql инструкции, например:

sp_MSforeachtable "USE DATABASE_NAME SELECT * FROM ?"
person Gaston Flores    schedule 07.09.2013
comment
use променя текущата база данни, а не текущата схема (дори не съм сигурен, че съществува концепцията за текуща схема в SQL Server) - person a_horse_with_no_name; 07.09.2013
comment
@a_horse_with_no_name съжалявам за грешката ми, публикацията ми беше коригирана. Благодаря. - person Gaston Flores; 07.09.2013