ورود

View Full Version : خالی کردن جداول Database



Galawij
شنبه 01 مرداد 1390, 07:48 صبح
سلام
می خوام تمام داده های آزمایشی بانک اطلاعاتیم رو خالی کنم با توجه به اینکه بعضی از این جداول داده های ثابت و اولیه دارند که نباید خالی شوند(در نام گذاری این جداول هم تبعیض خاصی با بقیه جداول قائل نشده ام)، در ضمن تعداد جداول زیاد هست و اینکه Cascade Delete ارتباطات بین آن ها فعال نمی باشد. راهکارتون برای نوشتن یک query جامع چی هست؟
Thanks in Advance

حمیدرضاصادقیان
شنبه 01 مرداد 1390, 08:42 صبح
سلام.
با استفاده از sp_MsforEachTable (http://riteshshah.wordpress.com/2009/03/04/empty-all-table-or-delete-all-data-from-all-table-by-sp_msforeachtable-in-sql-server-2005/) میتوانید اینکارو بکنید.

Galawij
شنبه 01 مرداد 1390, 09:55 صبح
مرسی آقای صادقیان.
من این لینک رو خوندم دو تا سوال دارم علامت ؟ در جلوی عبارت ’? EXEC sp_MSForEachTable ‘DELETE FROM به مفهوم چی هست و اینکه این دستور که برای همه جداول هست من یک سری جداول کنترلی هم دارم که نمی خوام خالی شوند.

خوب علامت سوال را پیدا کردم به صورت اتوماتیک نام جداول ها را جایگزین می کنه مثل یک حلقه ولی چطوری می تونم لیست جداول را جلوی این روال محدود کنم؟

حمیدرضاصادقیان
شنبه 01 مرداد 1390, 10:49 صبح
اینجا (http://www.databasejournal.com/features/mssql/article.php/3441031/SQL-Server-Undocumented-Stored-Procedures-spMSforeachtable-and-spMSforeachdb.htm) رو کامل مطالعه کنید به واسطه پارامتر whereand@ میتوانید نام جداول رو محدود کنید.

Galawij
شنبه 01 مرداد 1390, 10:50 صبح
واقعاً ممنونم آقای صادقیان، بعضی وقت ها دکمه تشکر جواب نمی ده.
جواب سوالاتم را پیدا کردم
طریقه ارسال پارامتر ها به این روال :

Below is the syntax for calling the sp_MSforeachtable SP:
exec @RETURN_VALUE=sp_MSforeachtable @command1, @replacechar, @command2, @command3, @whereand, @precommand, @postcommandWhere:

@RETURN_VALUE - is the return value which will be set by "sp_MSforeachtable"
@command1 - is the first command to be executed by "sp_MSforeachtable" and is defined as a nvarchar(2000)
@replacechar - is a character in the command string that will be replaced with the table name being processed (default replacechar is a "?")
@command2 and @command3 are two additional commands that can be run for each table, where @command2 runs after @command1, and @command3 will be run after @command2
@whereand - this parameter can be used to add additional constraints to help identify the rows in the sysobjects table that will be selected, this parameter is also a nvarchar(2000)
@precommand - is a nvarchar(2000) parameter that specifies a command to be run prior to processing any table
@postcommand - is also a nvarchar(2000) field used to identify a command to be run after all commands have been processed against all tables

Galawij
شنبه 01 مرداد 1390, 12:29 عصر
آقای صادقیان این روال ها برای هر جدولی و هر بانک اطلاعاتی قابل اجرا هست.
آیا روالی مشابه داریم که برای همه ستون های هر جدول هم استفاده بشه؟؟!
چیزی مثل sp_MSforeachColumn

حمیدرضاصادقیان
شنبه 01 مرداد 1390, 12:48 عصر
با استفاده از sp_MsforEachTable میتوانید اعمال خودتونو رو ی ستونها نیز پیاده کنید.
با استفاده از sp_MsforEachDb میتوانید روی دیتابیس های مختلف کار کنید

Galawij
شنبه 01 مرداد 1390, 13:00 عصر
با استفاده از sp_MsforEachTable میتوانید اعمال خودتونو رو ی ستونها نیز پیاده کنید
منظورتون این دستور هست:
' ?exec sp_MSforeachtable ' SELECT * from
من چه طوری می تونم به نام یک ستون خاص از یک جدول دسترسی پیدا کنم؟

حمیدرضاصادقیان
شنبه 01 مرداد 1390, 13:35 عصر
میتوانید به جای * نام ستونهای مورد نظر رو بنویسید.
میخواهید روی ستونها چه کاری انجام بدید.

Galawij
شنبه 01 مرداد 1390, 13:45 عصر
نام ستون ها که در همه جداول یکی نیستند! تا بتونم نام ستون ها را بنویسم.
می خوام با استفاده از این روال روی ستون های با نوع داده nvarchar,char,text,.. یک عملیات update بنویسم. قبلاً این کار را با کرسر انجام دادم و این بار می خوام از این روال استفاده کنم.

اینم که خطا میده:
'?exec sp_MSforeachtable 'select ?.Id from

حمیدرضاصادقیان
شنبه 01 مرداد 1390, 13:58 عصر
اینم (http://www.codeproject.com/Tips/228148/Sp_MSForeachTable-to-update-tables-having-common-c) یک نگاهی بکنید بد نیست.

Galawij
شنبه 01 مرداد 1390, 14:03 عصر
یک چیزی هم خودم پیدا کردم ببینم نتیجه می ده:

exec sp_msforeachtable N'
IF EXISTS(SELECT 1 FROM sys.columns WHERE object_id=OBJECT_ID(''?'') AND name = ''Col1'')
EXEC (''UPDATE ? SET Col1= case when Col1 = ''''ppp'''' then ''''qqq'''' when Col1 = ''''aaa'''' then ''''xxx'''' end'')'

ممنوم که راهنمایی می کنید.

Galawij
شنبه 01 مرداد 1390, 19:45 عصر
سلام آقای صادقیان
حدود 11 ساعت روی این روال کار کردم که کرسر را حذف کنم وقتی خود روال را باز کردم ساختار داخلیش از کرسر استفاده می کند.

exec(N'declare hCForEachTable cursor global for select ''['' + REPLACE(schema_name(syso.schema_id), N'']'', N'']]'') + '']'' + ''.'' + ''['' + REPLACE(object_name(o.id), N'']'', N'']]'') + '']'' from dbo.sysobjects o join sys.all_objects syso on o.id = syso.object_id '
+ N' where OBJECTPROPERTY(o.id, N''IsUserTable'') = 1 ' + N' and o.category & ' + @mscat + N' = 0 '
+ @whereand)
declare @retval int
select @retval = @@error
if (@retval = 0)
exec @retval = sys.sp_MSforeach_worker @command1, @replacechar, @command2, @command3, 0

if (@retval = 0 and @postcommand is not null)
exec(@postcommand)

یوسف زالی
شنبه 01 مرداد 1390, 22:01 عصر
با اجازه جناب مدیر و شما دوست عزبز.
من فکر می کنم که کلا دو تا روش برای این کارها باشه.
یکیش همون Cursor هست و یکی دیگه داینامیک کار کردن.
مثلا این جوری:


declare @x varchar(max)
set @x =''
select @x +='truncate table '+ TABLE_NAME +' '
from INFORMATION_SCHEMA.TABLES
where TABLE_TYPE ='BASE TABLE'
-- and TABLE_NAME like '%SomeThings%'
exec(@x)


به این ترتیب شما دستتون بازه که در Like هرجوری خواستید فیلتر کنید.
دستورهای مشابهی هم می تونین برای Column ها بنویسید:
INFORMATION_SCHEMA.COLUMNS

این ویو ها خیلی کمک خوبی هستند برای دسترسی به اشیا در دیتابیس
موفق باشید.

راستی اون کد رو ران نکنی کلی تو دلت دعام کنی!
اول جای Exec رو با Print عوض کن تا مطمئن شی.
:لبخند: