CREATE Function dbo.[EnToPersian] (@date datetime) Returns nvarchar(50) as BEGIN RETURN FORMAT(CAST( @date AS DATE),'yyyy/MM/dd', 'fa-ir') END SELECT dbo.[EnToPersian](GETDATE())
CREATE FUNCTION dbo.[PersianToEn] ( @Date NCHAR(10) ) RETURNS NVARCHAR(10) AS BEGIN DECLARE @PERSIAN_EPOCH AS INT; DECLARE @epbase AS BIGINT; DECLARE @epyear AS BIGINT; DECLARE @mdays AS BIGINT; DECLARE @Jofst AS NUMERIC(18, 2); DECLARE @jdn BIGINT; DECLARE @iYear INT = CAST(SUBSTRING(@Date, 1, 4) AS INT); DECLARE @iMonth INT = CAST(SUBSTRING(@Date, 6, 2) AS INT); DECLARE @iDay INT = CAST(SUBSTRING(@Date, 9, 2) AS INT); IF @iYear >= '1404' SET @PERSIAN_EPOCH = 1948322; ELSE SET @PERSIAN_EPOCH = 1948321; SET @Jofst = 2415020.5;
IF LEN(@Date) > 1 BEGIN IF @iYear >= 0 BEGIN SET @epbase = @iYear - 474; END; ELSE BEGIN SET @epbase = @iYear - 473; END; SET @epyear = 474 + (@epbase % 2820); IF @iMonth <= 7 BEGIN SET @mdays = (CONVERT(BIGINT, (@iMonth) - 1) * 31); END; ELSE BEGIN SET @mdays = (CONVERT(BIGINT, (@iMonth) - 1) * 30 + 6); END;
در این روزهای پرتنش که حملات سایبری هم شدت گرفته، یکی از حملاتی که بیشتر از همیشه باید جدی گرفته بشه، SQL Injection هست.
این نوع حمله میتونه آسیبهای جبرانناپذیری به دیتابیس وارد کنه: از حذف دادهها گرفته تا رمزنگاری یا دستکاری اطلاعات، و متأسفانه چون حمله از طریق اکانتی انجام میشه که نرمافزار به دیتابیس متصل شده، دسترسی کامل به اطلاعات فراهم میشه.
چند سوال کلیدی که باید از خودمون بپرسیم:
آیا نقاط ضعف مربوط به Injectionها در سیستم رو شناسایی و برطرف کردید؟
آیا اطلاعات حساس و مهم رو رمزنگاری کردید؟
آیا دسترسیها رو در سطح Schema تفکیک کردید، یا همچنان با یک یوزر Owner به کل دیتابیس متصل میشید؟
آیا ساختار Backup شما به گونهای هست که در صورت نفوذ بتونید دادهها رو بازیابی کنید؟
آیا از Backupها نسخهی دوم تهیه و در مکان امن نگهداری میکنید؟
آیا روی سرور دیتابیس، فایروال فعال و پیکربندیشده دارید؟
آیا آخرین Service Packها و Patchهای امنیتی نصب شدهاند؟
آیا تنظیمات امنیتی مربوط به Service Accountهای SQL Server بهدرستی رعایت شده؟
🔐 اینها تنها بخشی از سوالاتی هستند که باید در روزهای پرریسک امروز بهشون فکر کنیم.
برای تصمیم گیری در مورد نسخه SQL Server مناسب برای برنامهی خود، باید به عوامل زیر توجه کنید: تعداد همزمان کاربران: اگر برنامهی شما توسط تعداد زیادی همزمان کاربر استفاده میشود، نسخه SQL Server Express ممکن است محدودیتهای کاربران همزمان داشته باشد. در این مورد، احتمالاً نیاز به نسخههای پیشرفتهتر SQL Server مانند Standard یا Enterprise دارید. حجم دادهها: برنامه شما به نظر میآید که دادههای معمولی داشته باشد. اما تعداد روزانه فاکتورها و حجم دادهها میتواند افزایش یابد. اگر حجم دادهها به سرعت افزایش پیدا میکند، نسخه Express ممکن است به زودی به محدودیت حجم داده برخورد کند. در این صورت، نسخههای Standard یا Enterprise با قابلیتهای مدیریت داده بزرگتر مناسبتر هستند.
Attach و Detach در SQL Server دو عمل پرکاربرد در مدیریت دیتابیس هستند که به ترتیب، امکان افزودن داده به دیتابیسهای مختلف یا حذف داده از آنها را به کاربران میدهند. در این مقاله قصد داریم با این دو عملیات در SQL Server بیشتر آشنا شویم و روش اجرای هرکدام را به تفکیک بررسی کنیم. همچنین به استفادههای متداول از این دو عمل و تفاوت بین آنها میپردازیم. اگر میخواهید دو عمل حذف و اضافه دادهها را در SQL Server بهسادگی انجام دهید، مطالعه این مقاله را از دست ندهید.
برای تصمیم گیری در مورد نسخه SQL Server مناسب برای برنامهی خود، باید به عوامل زیر توجه کنید: تعداد همزمان کاربران: اگر برنامهی شما توسط تعداد زیادی همزمان کاربر استفاده میشود، نسخه SQL Server Express ممکن است محدودیتهای کاربران همزمان داشته باشد. در این مورد، احتمالاً نیاز به نسخههای پیشرفتهتر SQL Server مانند Standard یا Enterprise دارید. حجم دادهها: برنامه شما به نظر میآید که دادههای معمولی داشته باشد. اما تعداد روزانه فاکتورها و حجم دادهها میتواند افزایش یابد. اگر حجم دادهها به سرعت افزایش پیدا میکند، نسخه Express ممکن است به زودی به محدودیت حجم داده برخورد کند. در این صورت، نسخههای Standard یا Enterprise با قابلیتهای مدیریت داده بزرگتر مناسبتر هستند.
در SQL Server، میتوانید با استفاده از Check Constraint، شرطی را برای ستونهای جدول تعریف کنید که باید قبل از درج اطلاعات بررسی شود. برای ایجاد یک Check Constraint در SQL Server، میتوانید از دستور زیر استفاده کنید:
ALTER TABLE table_name ADD CONSTRAINT constraint_name CHECK (condition);
در این دستور، table_name نام جدولی است که میخواهید شرط برای ستونهای آن تعریف کنید و constraint_name نامی است که به شرط تعریف شده اختصاص داده میشود. همچنین، condition شرطی است که برای ستونهای جدول تعریف میشود و باید برای هر ردیف از جدول صحت آن بررسی شود.
به عنوان مثال، فرض کنید که میخواهید در ستون age جدول person، فقط اعداد بین 18 و 100 قابل قبول باشند. برای این منظور، میتوانید از دستور زیر استفاده کنید:
ALTER TABLE person ADD CONSTRAINT age_check CHECK (age >= 18 AND age <= 100);
با اجرای این دستور، Check Constraint با نام age_check برای ستون age جدول person تعریف میشود. هرگاه قرار باشد یک ردیف جدید به جدول person اضافه شود، ابتدا شرط تعریف شده در Check Constraint برای ستون age بررسی میشود و در صورتی که شرط برقرار نباشد، عملیات درج اطلاعات متوقف میشود.
فرض کنید یک دیتابیس آزمایشی دارید که میخواهید تمام رکوردهای آنرا حذف کنید. اگر در این دیتابیس انواع و اقسام کلیدهای خارجی و تریگر و امثال آن وجود داشته باشند، صرفا با یک دستور delete ساده کار به پایان نمیرسد و موفق به حذف رکوردها نخواهید شد (چون این قید و بندها به همین جهت طراحی شدهاند تا یکپارچگی دیتابیس حفظ شود). اما اگر واقعا این قیود در این لحظه مهم نبودند و نیاز بود تا تمام رکوردها را حذف کنیم، سریعترین راه حل موجود چیست؟
چنانچه سرویس SQL را در MS SQL server ریست نمایید، VALUE (مقدار)هایی که Identity SPECIFICATION آنها برابر YES باشد جهش پیدا میکنند. این افزایش مقدار، از نقطه نظر برنامه نویسی، به خصوص در زمانی که قصد نمایش دادهها به کاربر وجود دارد، قابل قبول نیست.
برای رفع این مشکل SQL SERVER CONFIGURATION MANAGER را باز کنید، از سمت چپ پنجره بر روی عبارت SQL services کلیک نمایید، از سمت راست همان پنجره بر روی عبارت «(SQL Server (MSSQLSERVER» کلیک راست کنید، سپس بر روی گزینهی Properties کلیک کنید تا پنجره آن باز شود.
در بخش Startup Parameters مقدار –t272 را اضافه نمایید.
در SQL Server بانکهای اطلاعاتی میتوانند وضعیتهای مختلفی داشته باشند ما در این مقاله سعی خواهیم کرد وضعیت بانکهای اطلاعاتی را بررسی کنیم. برای مشاهده وضعیت بانکهای اطلاعاتی میتوانید از روشهای زیر استفاده کنید.
۱- استفاده از Management Studio
اگر در SSMS کلید F8 را فشار دهید Object Explorer برای شما نمایش داده میشود. شما میتوانید اغلب وضعیتهای مربوط به بانک اطلاعاتی را در آن مشاهده کنید.
بدون تردید، execution plan یکی از مهمترین ابزارهای داخلی sql server در جهت کشف مشکلات کارایی و کندی سرعت اجرای کوئری ها است. برای هر فرد برنامه نویس و ادمین دیتابیس، آشنایی با execution plan از مهارت های کاربردی می باشد. اگر بخواهیم بطور خلاصه کاربرد execution plan را بدانیم، مواقعی که سرعت اجرای یک کوئری قابل قبول نیست و در اصطلاح، کوئری کند اجرا می شود، قبل از اینکه به زیاد بودن تعداد رکوردهای جدول و یا ضعیف بودن منابع سرور شک کنیم و دلیل اجرای کند و زیاد بودن میزان I/O یک کوئری رو با حدس و گمان برطرف کنیم، بهترین روش این است که از execution plan کمک بگیریم و دقیقا قسمتی از کوئری که باعث ایجاد مشکل شده رو کشف و حل نماییم. مطالبی که در این آموزش مطالعه خواهید کرد به عنوان یک پیش نیاز برای تعداد زیادی از آموزش های آتی در زمینه بهینه سازی کوئری ها (performance tuning) و همچنین آموزش هایی مانند معرفی عملگرها، نحوه خواندن execution plan و ... خواهد بود. در ادامه ابتدا بصورت مفهومی با execution plan آشنا خواهیم شد و تعدادی از مهمترین کاربردهای آن را اشاره می کنیم.
همواره با فعال بودن این ویزگی در SQL Server 2016 داده ها به صورت رمزنگاری خواهد بود. با فعال بود ن این ویژگی صاحبان نرم افزار دسترسی آنها به صورت رمزنگاری خواهد بود. و همچنین برنامه های کاربری به صورت یک کلید رمزنگاری شده باشدکه می توان این کلید را در Database یا مدیریت ویندوز نگهداری نمود و همچنین در بحث مدیریت بانک اطلاعات در cloud بحث رمزنگاری فعال می باشد
برنامه SQL HeartBeat يكي از برنامههاي ساده و جمع و جور براي مانيتور كردن SQL Server ميباشد. استفاده از امكانات موجود در اين برنامه شما ميتوانيد به يك سرور SQL وصل شده و به مانيتور كردن
۱- وضعيت Sessionها ۲- وضعيت IO ۳- وضعيت Processor ۴- وضعيت Memory بپردازيد. نسخه رايگان اين برنامه صرفاً قابليت نمايش وضعيت موارد ذكر شده را در يك داشبورد مديريتي دارد.
قصد داریم الگوهای مختلف ایندکس گذاری و استراتژی Non-Clustered Indexes را در Sql Server، بررسی کنیم.
مزایای ایجاد ایندکسهای صحیح بر اساس نیازهای واقعی کاری:
سریعتر شدن اجرای کوئریهای جستجو در تعداد رکوردهای بالا
مرتب سازی سریعتر نتایج (sorting)
کوئریهایی که بر اساس عبارت GROUP BY ایجاد شدهاند، سریعتر اجرا خواهند شد
Non-Clustered Indexes
تقریبا در تمام دیتابیسها به راههای دیگری برای دسترسی به دادههای جداول نیاز خواهد شد که لزوما این دادهها براساس ترتیب هنگام ذخیره سازی، مرتب نیستند. در چنین شرایطی ایندکسهای غیر خوشهای بر سر کار خواهند آمد. در ادامه الگوهای مختلف ایندکس گذاری مرتبط با ایندکسهای غیر خوشهای را بررسی کرده و برای هر کدام از آنها مثالی را بررسی خواهیم کرد. خواهیم دید هر ایندکسی که از جانب ما ایجاد میشود، نمیتوان مطمئن شد که توسط Sql Server مورد استفاده قرار میگیرد! این الگوها در تعیین زمان و مکان ساخت ایندکسهای غیر خوشهای، به ما کمک خواهند کرد که به شرح زیر میباشند:
این سوالی است که ممکن است هر توسعه دهندهای به آن در ابتدا پاسخ دهد: «جهت بالابردن سرعت و کارآیی!» حال اگر بپرسیم چگونه؟ توضیحات چندان دقیقی ارائه نمیشود.
ایندکس چیست؟
ایندکس شیءای از دیتابیس است میتواند برروی یک یا چند ستون ایجاد شود (تا 16 ستون). هنگامیکه ایندکسی ایجاد میگردد، ساختار دادهای (BTree) جهت بهینه سازی عملیات مقایسه نیز ایجاد میشود. اس کیو ال سرور بدون داشتن ایندکس، برای دریافت اطلاعات درخواستی مجبور است کل ردیفهای جدول را جستجو نماید. این کار مانند این است که شما بدون اطلاع از شماره صفحه (محل) عنوان درخواستی، به دنبال آن در صفحات یک کتاب باشید. حال اگر به ایندکس (فهرست) کتاب مراجعه کنید به سرعت و حداقل اتلاف وقت میتوانید محل یا شماره صفحهی عنوان مورد نظر را، بدون جستجوی کلیهی صفحات کتاب، پیدا کنید و به آن مراجعه کنید. ایندکس جدول نیز اجازه میدهد بدون جستجوی کلیه رکوردها، رکورد مورد نظر را دریافت نمایید. مثال:
SELECT KCU1.CONSTRAINT_NAME AS FK_CONSTRAINT_NAME ,KCU1.TABLE_NAME AS FK_TABLE_NAME ,KCU1.COLUMN_NAME AS FK_COLUMN_NAME ,KCU2.CONSTRAINT_NAME AS REFERENCED_CONSTRAINT_NAME ,KCU2.TABLE_NAME AS REFERENCED_TABLE_NAME ,KCU2.COLUMN_NAME AS REFERENCED_COLUMN_NAME FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU1 ON KCU1.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG AND KCU1.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA AND KCU1.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU2 ON KCU2.CONSTRAINT_CATALOG = RC.UNIQUE_CONSTRAINT_CATALOG AND KCU2.CONSTRAINT_SCHEMA = RC.UNIQUE_CONSTRAINT_SCHEMA AND KCU2.CONSTRAINT_NAME = RC.UNIQUE_CONSTRAINT_NAME AND KCU2.ORDINAL_POSITION = KCU1.ORDINAL_POSITION where KCU1.TABLE_NAME='Student'
USE AdventureWorks
GO
DECLARE @NumberOfRows INT = 10 -- Number of rows you want on a page
DECLARE @DesiredPageNumber INT = 5 -- Page number
SELECT *
FROM
(
SELECT RowNum = ROW_NUMBER() OVER (
ORDER BY EmployeeID), *
FROM HumanResources.Employee
) AS a
WHERE RowNum > (@NumberOfRows * (@DesiredPageNumber - 1))
AND RowNum <= (@NumberOfRows * (@DesiredPageNumber - 1)) + @NumberOfRows
ORDER BY EmployeeID
GO
تکنولوژی CTE از نسخه SQL Server 2005 رسمیت یافته است و شامل یک result set موقتی[1] است که دارای نام مشخص بوده و میتوان از آن در دستورات SELECT, INSERT, UPDATE, DELETEاستفاده کرد. همچنین از CTE میتوان در دستور CREATE VIEW و دستور SELECT مربوط به آن استفاده کرد. در نسخه SQL Server 2008 نیز امکان استفاده از CTE در دستور MERGE فراهم شده است. در SQL Serverاز دو نوع CTE بازگشتی[2] و غیر بازگشتی[3] پشتیبانی میشود. در این مقاله سعی شده است نحوه تعریف و استفاده از هر دو نوع آن آموزش داده شود.
انواع روشهای ایجاد جداول موقت برای استفاده از جداول موقتی در سرور اسکیوال، سه راه زیر وجود دارد.
روش اول: استفاده از دستوری مانند زیر است که سبب ایجاد جدول موقتی در بانک سیستمی tempdb میشود. زمانیکه شما ارتباط خود را با سرور SQL قطع میکنید به صورت اتوماتیک جداول موقت شما از بانک tempdb حذف میشوند. این روش در برنامه نویسی پیشنهاد نمیشود و فقط در کارهای موقتی و آزمایشی مناسب است.
CREATE FUNCTION [dbo].[CSVToTable] (@InStr VARCHAR(MAX)) RETURNS @TempTab TABLE (id int not null) AS BEGIN ;-- Ensure input ends with comma SET @InStr = REPLACE(@InStr + ',', ',,', ',') DECLARE @SP INT DECLARE @VALUE VARCHAR(1000) WHILE PATINDEX('%,%', @INSTR ) <> 0 BEGIN SELECT @SP = PATINDEX('%,%',@INSTR) SELECT @VALUE = LEFT(@INSTR , @SP - 1) SELECT @INSTR = STUFF(@INSTR, 1, @SP, '') INSERT INTO @TempTab(id) VALUES (@VALUE) END RETURN END
DECLARE @LIST VARCHAR(200) SET @LIST = '1,3' SELECT Id, Descr FROM CSVDemo WHERE Id IN (SELECT * FROM dbo.CSVToTable(@LIST))
در این مقاله قصد دارم شما رو با یک موضوع مهم در SQL Server که بیشتر مواقع برنامه نویس ها و DBA ها در درک اون مشکل دارند آشنا کنم. این موضوع تفاوت بین Primary Key و Clustered Index است.
Primary Key چیست؟
اجازه دهید ابتدا در مورد خود قید Primary Key صحبت کنیم. همانطور که می توان از نام این قید فهمید، شما با این قید از SQL Server می خواهید که در یک ستون یا گروهی از ستون ها فقط مقدار یونیک وارد شود. اسکریپت زیر تعریفی ساده از یک جدول نشان می دهد که در آن قید Primary Key روی ستون Col1 جدول تعریف شده است.
1
2
3
4
5
6
7
CREATETABLEFoo
(
Col1 INTNOTNULLPRIMARYKEY,
Col2 INTNOTNULL,
Col3 INTNOTNULL
)
GO
حالا وقتی در این جدول رکورد درج می کنید، SQL Server از یونیک بودن مقادیر وارده شده در ستون Col1 اطمینان حاصل می کند. حالا اگر سعی کنید مقادیر تکراری وارد کنید، SQL Server پیام خطا صادر می کند:
1
2
3
-- Try to insert a duplicate value
INSERTINTOFoo Values(1, 1, 1), (1, 2, 2)
GO
Msg 2627, Level 14, State 1, Line 9 Violation of PRIMARY KEY constraint ‘PK__Foo__A259EE544224D12A’. Cannot insert duplicate key in object ‘dbo.Foo’. The duplicate key value is (1). The statement has been terminated.
قید Primary Key خودش در سطح منطقی تعریف می شود- شما فقط به SQL Server می گوئید در این ستون مقادیر یونیک می خواهید. اما SQL Server این قید را در سطح فیزیکی هم باید تامین کند – در ساختمان داده هایی که شما در آنها داده هایتان را ذخیره می کنید.
در مورد SQL Server در سطح فیزیکی این کار توسط ایندکس ها انجام می شود : توسط یک Clustered Index یا NonClustered Index.
تحمیل قید Primary Key
و قتی شما قید Primary Key را مشخص می کنید، SQL Server به طور پیش فرض این قید را با استفاده از یک Unique Clustered Index در سطح فیزیکی تحمیل می کند. اگر به sys.indexes نگاهی بیندازید می بینید که SQL Server یک Unique Clustered Index ایجاد کرده است که برای تحمیل قید Primary Key استفاده شده است.
1
2
3
4
-- SQL Server generates by default a Unique Clustered Index
SELECT* FROMsys.indexes
WHEREobject_id = OBJECT_ID('Foo')
GO
همانطوری که گفتم به طور پیش فرض Unique Clustered Index ایجاد شده است. شما می توانید تحمیل قید Primary Key را با استفاده از NonClustered Index انجام دهید:
1
2
3
4
5
6
7
8
-- Enforces the Primary Key constraint with a Unique Non-Clustered Index
CREATETABLEFoo1
(
Col1 INTNOTNULLPRIMARYKEYNONCLUSTERED,
Col2 INTNOTNULL,
Col3 INTNOTNULL
)
GO
وقتی قید Primary Key را مشخص می کنید می توانید دو گزینه را مشخص کنید:
Clustered
Nonclustered
گزینه Clustered پیش فرض است، بنابراین لزومی بر تعیین آن نیست. حالا اگر دوباره به sys.indexes نگاه کنید، متوجه می شوید که یک HEAP در مقابل دارید (جدولی بدون Clustered Index) و اینکه SQL Server یک ایندکس Nonclustered اضافی برای تحمیل قید Primary Key ایجاد کرده است.
1
2
3
4
5
-- SQL Server has generated now a Unique Non-Clustered Index to
-- enforce the Primary Key constraint
SELECT* FROMsys.indexes
WHEREobject_id = OBJECT_ID('Foo1')
GO
Primary Key <> Clustered Index
نتیجه اینکه همیشه Primary Key و Clustered Index در SQL Server با هم برابر نیستند. این یک پیش فرض است و شما می توانید آن را تغییر دهید. قید Primary Key در سطح منطقی است و ساختار ایندکس در سطح فیزیکی برای تحمیل خود قید استفاده می شود.
هدف استفاده از Full-Text Search جستجو در داده های حجیم است.
انواع داده هایی که در Full-Text Search قابل پشتیبانی هستند:
Char / NChar
VarChar / NVarChar
Text / NText
Binary / VarBinary
Image
XML
FILESTREAM
در مقابل Full-Text Search از Like نمی توان برای جستجو در بین داده های باینری استفاده کرد و فقط برای جستجو در بین کاراکترها، طراحی شده است.
برای جستجو در بین حجم زیادی از داده ها، دستور Like در مقابل Full-Text Search بسیار کندتر عمل خواهد کرد.
برای جستجو در بین چند میلیون رکورد، دستور Like ممکن است چندین دقیقه طول بکشید در حالی که Full-Text Search در چند ثانیه نتیجه را نشان خواهد داد.
قابلیت Full-Text Search به توسعه دهندگان این امکان را می دهد که متن مورد نظر خود را با استفاده از query در ستون های متنی جداول جستجو کنند. برای انجام Full-Text Search برروی یک جدول ابتدا باید برای آن جدول یک ایندکس از نوع full-text تعریف شود که این ایندکس شامل یک یا چند ستون متنی از آن جدول است. ستون های متنی می توانند از انواع داده ای زیر باشند char, varchar, nchar, nvarchar, text, ntext, image, xml, یا varbinary و FILESTREAM.
برای استفاده از قابلیت Full-Text Search در Query باید از دستور CONTAINS استفاده کرد:
در مدل OLTP ، مخازن داده به صورت جداول رابطه ای که عموما” به جهت جلوگیری از تکرار و ناهمگونی اطلاعات به صورت هنجار (Normalize) درآمده اند ، سازماندهی می شوند. این نوع از بانک های اطلاعاتی برای درج و تغییر سریع اطلاعات توسط چندین کاربر بطور همزمان مناسب می باشند .
در مدل OLAP مخازن داده جهت تجزیه و تحلیل و خلاصه سازی حجم زیادی از اطلاعات سازماندهی می شوند . مخازن داده و ارتباط بین اطلاعات در این مدل توسط SQL Server مدیریت می گردد .
وظايف هر کدام بصورت زير است :
1- در پايگاه داده OLTP :
· سازماندهي در جدول روابط
· نرمال سازي و حذف دوگانگي داده ها
· اطلاعات فقط يکبار ذخيره مي شوند .
· افزايش دقت دراضافه کردن يا تغيير سريع داده ها توسط تعداد زيادي کاربر همزمان
2-در پايگاه داده OLAP :
· سازماندهي در اجازه تجزيه و تحليل و خلاصه سازي مقدار زيادي از داده ها با سرعت بالا
FETCH NEXT FROM Table_Cursor INTO @name,@id END CLOSE Table_Cursor DEALLOCATE Table_Cursor
Cursor :
هنگام استفاده از دستورات SQL نظیر Select کلیه رکوردهای درخواستی بطور کامل استخراج می گردد اما در مواردی نیاز است که رکوردهای استخراج شده تحت شرایطی خاص مورد پردازش مجدد قرار گرفته و به برنامه درخواست کننده ارسال گردد در این صورت استفاده از کرسرها بسیار حائز اهمیت خواهد بود در واقع برای استفاده از یک کرسر می توان به ترتیب مراحل ذیل عمل نمود. - یک متغیر از نوع کرسر تعریف می گردد. که شامل دستور Select درخواستی خواهد بود. - با استفاده از دستور Open یک کرسر آماده استفاده می گردد. - با استفاده از دستور Fetch حرکت درون یک کرسر امکان پذیر می گردد که در این حالت مقدار فیلدهای اعلام شده در رکورد جاری در دسترس می باشد. - با استفاده از دستور Close کرسر فعال شده بسته می شود. - با استفاده از Deallcate فضای اختصاص داده شده برای کرسر آزاد می گردد.
شما وقتی دستورات Select رو به صورت view مینویسی دستوراتی هستند که معمولا ثابت هستند. شما میتونی روی view یک clustered index بذاری و اونو با جداول دیگه join کنی و مانند یک جدول باهاش رفتار کنی. ولی این قابلیتها رو sp نداره. شما یک سری کار خاص درون sp قرار میدی و همیشه همون کارهارو انجام میده. نمیتونی در select اونو شرکت بدی. نمیتونی روش ایندکس بذاری.نمیتونی بایک جدول دیگه join کنی.
از مزیت های view این است که بعد از یک بار اجرا به صورت موقت در سرور ذخیره می شود و برای مراجعات بعدی از همان استفاده می شود و سرعت خیلی بالایی دارد.
1- برخورد Sql Server با view در هنگام خواندن دادها (select)دقیقا مانند یک جدول حقیقی می باشد. در همین جا یک مزیت بزرگ view آشکار می شود: می توان در مراحل پیاده سازی نرم افزار ساختار یک viewرا تغییر داد و ان را بهبود بخشید بدون آنکه رابط کاربر و کدهای user interface تغییر اساسی کنند.
2- تنها در مورد view هایی که با یک select ساده (بدون join) ساخته می شوند می توان انتظار داشت که دستورات Insert، Update و Delete به درستی عمل کنند. بدین معنا که برخورد Sql Server باViewدقیقا همانند یک جدول واقعی خواهد بود و دستورات DDL (Data Definition Language) و یا به عبارت ساده تر Insert، Update و Deleteعمل خواهند کرد.
View به خاطر کاربردش دارای دو لقب(یا اسم) هستش: 1) Saved Select 2) Virtual Table
اولی به این دلیله که شما یک Query طولانی رو تحت عنوان یک اسم ذخیره میکنین، و برای بدست آوردن نتیجه اون View، نیازی ندارین دوباره اون Query رو بنویسین.
1 سطح ویندوز(Windows Level): سطح بالا- از DP API ویندوز برای رمزنگاری استفاد می کند.
2 سطح SQL Server : سطح متوسط:از شاه کلید سرویس ( Service Master Key)، برای رمزنگاری استفاده می کند.
3 سطح بانک اطلاعاتی(Database Level): سطح پایین : از شاه کلید بانک اطلاعاتی برای رمزنگاری استفاده می کند.
کلید متقارن (symmetric) : در سیستم رمزگذاری متقارن فرستنده و گیرنده یک پیام یک کلید مشترک را بین خود به اشتراک می گذارند که از آن برای رمز کردن پیام و شکستن رمز استفاده می شود .این شیوه پیاده سازی نسبتا آسانی دارد و هردو فرستنده و گیرنده می توانند پیام را رمز گذاری ورمز گشایی کنند .
کلید نامتقارن (Asymmetric) : در این شیوه فرستنده و گیرنده یک جفت کلید عمومی و اختصاصی دارند که با استفاده از آنها رمزگذاری و رمزگشایی می کنند . این سیستم کمی پیچیده می باشد زیرا فرستنده می تواند از کلیدش استفاده کند پیام را رمز کند اما نمی تواند آن را رمز گشایی کند ، از طرف دیگر گیرنده می تواند با استفاده از کلیدش رمز گشایی کند اما نمی تواند رمز کند .
مثالایجاد یک کلید متقارن
blog.iranhost.com/9226
certcc.ir/ serch = SQL SERVER
رمز نگاری یک ویژگی مهم امنیتی در SQL می باشد . کلید های بزرگتر و نامتقارن باعث ایجاد رمزنگاری غیرقابل حمله و قویتری می شوند که این خود باعث مصرف بیشتر CPU می شود . وفتی حجم زیادی از داده برای رمزنگاری وجود دارد ، توصیه می شود از کلید متقارن استفاده شود . از آنجایی که داده رمز شده نمی تواند فشرده (Compress) شود توصیه می شود قبل از رمز نگاری داده تا حد ممکن فشرده شود .
کلیدها و الگوریتمها
SQL Server چندین الگوریتم متفاوت رمزگذاری با استفاده از کلید متقارن را پشتیبانی میکند. از جمله این الگوریتمهای کلید متقارن میتوان به DES، Triple DES، RC2، RC4، 128-bit RC4، 128-bit AES و 256-bit AES اشاره کرد. قابل ذکر است که تمامی الگوریتمهای مذکور با استفاده از Windows Crypto API پیادهسازی میشوند.
نوشتن SQL پویای امن در SQL Server
هرگز دستورات Transact-SQL را مستقیماً از ورودی کاربر نسازید؛ از روالهای ذخیره شده برای اعتبارسنجی ورودی کاربر استفاده کنید.
ورودی کاربر را با بررسی نوع، طول، فرمت و محدوده آن اعتبارسنجی نمایید. از تابع QUOTENAME() برای خلاصی از نامهای سیستم یا از تابع REPLACE() برای خلاصی از هر کاراکتری در رشته استفاده کنید.
چندین لایه اعتبارسنجی در هر بخش برنامه خود قرار دهید.
اندازه و نوع دادهای ورودی را بررسی کنید و محدودیتهای لازم را اعمال نمایید. این کار میتواند به جلوگیری از سرریز بافر تعمدی کمک کند.
محتویات متغیرهای رشتهای را بررسی کرده و فقط مقادیر مورد قبول را بپذیرید. از پذیرش ورودیهای حاوی دادههای باینری، فاصلههای متوالی و کاراکترهای کامنت خودداری کنید.
هنگامیکه با اسناد XML کار میکنید، تمامی دادهها را در مورد schema ی آن اعتبارسنجی کنید.
در محیطهای چندبخشی، تمامی دادهها باید پیش از پذیرش در محدوده مورد اعتماد، اعتبارسنجی گردند.
رشتههای زیر را در فیلدهایی که نام فایلها از آن ساخته میشود نپذیرید: AUX، CLOCK$، COM1 تا COM8،CON، CONFIG$، LPT1 تا LPT8، NUL و PRN.
از شیء SqlParameterبه همراه روالهای ذخیره شده و دستورات برای بررسی و اعتبارسنجی نوع و طول استفاده کنید.
از عبارات Regex در کد سمت کلاینت برای فیلتر کردن ورودیهای نامعتبر استفاده کنید.
CREATE FUNCTION [dbo].[GetCategoryName](@CategoryID int) RETURNS nvarchar(50) AS begin declare @CategoryName nvarchar(50)
SELECT @CategoryName = CategoryName from B_Categories WHERE CategoryID = @CategoryID RETURN @CategoryName end
select top 1 dbo.GetCategoryName(1) from B_Categories select * from B_Categories where CategoryName= dbo.GetCategoryName(1)
CREATE FUNCTION GetTable1() RETURNS @T1 TABLE (CatName NVARCHAR(50),ForumsName NVARCHAR(50)) AS BEGIN INSERT INTO @T1(CatName,ForumsName) SELECT Categories.CatName, Forums.ForumsName FROM Categories RETURN; END
آشنایی با مفهوم Index در SQL Server: به طور خیلی ساده، ایندکس لیست مرتب شدهای از دادهها است که بر اساس منطقی خاص مانند عدد، رشته، تاریخ و … ایجاد شده است. هدف از ایجاد ایندکس افزایش سرعت جستجو برای بازیابی دادهها میباشد.
• Clustered Index: این نوع ایندکسها بر روی دادههای عادی مانند عدد، رشته، تاریخ و… ایجاد میشوند. زمانیکه یک Clustered Index بر روی یک جدول ایجاد میکنید ترتیب و چینش فیزیکی رکوردها بر اساس کلید ایندکس خواهد بود. بنابراین یک جدول صرفاً میتواند یک ایندکس از نوع Clustered داشته باشد.
• NonClustered Index: این نوع ایندکسها مانند Clustered Indexها بر روی دادههای عادی مانند عدد، رشته، تاریخ و… ایجاد میشوند. زمانیکه یک ایندکس از نوع NonClustered بر روی جدول ایجاد میکنید کلید ایندکس در فضایی دیگری جدای از فضای جدول مرتب شده و مورد استفاده قرار میگیرد. به طور کلی در SQL Server میتوان تا ۹۹۹ ایندکس از نوع NonClustered را ایجاد کرد.
• XML Index : این نوع ایندکسها بر روی دادههایی که در قالب ساختار XML هستند ایجاد میشود.
• Spatial Index : این نوع ایندکسها بر روی دادههایی که از نوع جغرافیایی هستند ایجاد میشود.
• Column Stored Index : نوع جدیدی از ایندکسها هستند که در SQL Server 2012 معرفی شدهاند که سرعت دسترسی به دادهها در آن بیش از سایر ایندکسها میباشد.
نکته مهمی که باید در ایجاد این نوع از ایندکسها در نظر گرفت این است که به دلیل افزایش Performance معمولاً در بیشتر مواقع این ایندکسها با توجه به کوئریهای شما ایجاد میگردند. بدین صورتکه
۱- لیست تمامی کوئریهای پر استفاده به ازای جدول مورد نظر را استخراج نمایید. ۲- کلیه فیلدهای مربوط به مرحله اول را استخراج نمایید. ۳- در صورتیکه فیلدهای استخراج شده در مرحله دوم جزء فیلدهای قابل شرکت در Column Stored Index باشند در ایندکس مورد نظر شرکت نمایند.
۴- در صورتیکه بخواهید Column Stored Index را به صورت ویژوالی در Management Studio ایجاد کافی است مراحل زیر را انجام دهید.
۱- همانند تصویر زیر پس از انتخاب جدول بر روی قسمت ایندکس کلیک راست کرده و پس از انتخاب گزینه New Index گزینه Non Clustered Column Stored Index را انتخاب کنید.
۲- همانطور که در پنجره New Index مشاهده میکنید نوع ایندکس شما Non Clustered Column Store بوده و با استفاده از دکمه Add به راحتی میتوانید فیلدهای مورد نظر را به ایندکس اضافه نمایید.
مبانی و تشخیص اسنیفر برنامه یا ابزاری است برای استراق سمع کردن ترافیک شبکه اون هم بوسیله گرفتن اطلاعاتی که روی شبکه در حال تبادل هستند و از تکنولوژی جلوگیری اطلاعاتی استفاده میکنه . به این دلیل این کار انجام میشه چون اترنت بر مبنای اشتراک گذاری ساخته شده . بیشتر شبکه ها از تکنولوؤی broadCast استفاده میکنند که یک پیام به یک کامپیوتر میتونه توسط کامپیوتر های دیگه هم خونده بشه . به صوت معمولی کلیه کامپیوتر ها بجط کامپیوتری که مقصد پیام هست پیام را نادیده میگیرند . اما میشه کاری کرد که کامپیوتر پیامی را هم که به اون مربوط نیست را بخونه . این کار هم همان اسنیف کردن اطلاعات است . بسیاری از افرادی که توسط سوئیچ به شبکه وصل هستند از شر اسنیف در امان هستند . اما همین کامپیوتر ها نسبت به اسنیف کردن هم نقطه ضعف خواهند داشت در صورتی که سوئیچ به یک هاب وصل شده باشه .
راه های زیادی برای گرفتن اطلاعات از پابگاه داده وجود دارد مثل بکاب گرفتن از بانک اطلاعاتی . همان طور که میدانید گاهی اوقات در بکاب گرفتن از برنامه ، ممکن است برخی از جدول ها در بکاب برنامه وجود نداشته باشد که این همیشه یک مشکل برای برنامه نویسان است در این آموزش ، قصد داریم از یک روش که یک امکان در خود SQl استفاده کنیم که به این روش SCript گرفتن از بانک اطلاعاتی گویند
حال برای شروع به کار روی یک بانک اطلاعاتی راست کلیک کرده و گزینه Taske>Generate Scriptرا انتخاب کنید
حال پس از انتخاب Generate Script با صفحه ای مانند زیر روبرو میشویم
حال دکمه Next را انتخاب کنید.
در این مرحله برای انتخاب جداول موجود در بانک اطلاعاتی بر روی گزینه Advanced کلیک کنید
گزینهTypes of data Scripts را روی Schema and data میگذاریم این گزینه برای انتخاب جداول موجود در بانک اطلاعاتی به کار میرود
در file Name مسیری که میخواهید script بانک اطلاعاتی در آن ذخیره شود را انتخاب میکنیم.
سپس دکمه Next را برای رفتن به مرحله بعد انتخاب کنید
و در انتها دکمه Finish را انتخاب میکنیم
وحال اسکریپتی از بانک اطلاعاتی به همراه جداول و اطلاعات موجود در هر جدول برای اجرا در SQL ایجاد شده است
Shrink در لغت به معني جمع شدن و يا چروک شدن ميباشد.
با در نظر گرفتن همين مفهوم ميتوان گفت Shrink کردن فرآيندي است که در آن فضاي
Data File و Log File جمع و جور ميشود. (اين تعريف يک تعريف ساده و ابتدايي ميباشد)
همانطور که در تصوير بالا مشاهده ميکنيد طي فرآيند
Shrink فضاي خالي فايلهاي بانک اطلاعاتي تا حد امکان از بين رفته و دادهها در يک
قسمت جمع ميگردند.
با این همه، همانسان که در
پرسوجوی بالا هم میبینید؛ ناگزیر شدم تاریخ و زمان را خودم وارد
کنم و هرآینه در واقعیت شما جهت پرسوجو روی زمان کنونی، ناگزیر به
استفاده از یک تابع برای تبدیل تقویم میلادی به خورشیدی هستیم. به
نظر شما بهتر نیست دست به کار شویم و تابعی برای تبدیل تاریخ
میلادی به خورشیدی بنویسیم؟
برای اینکار پروژهای را
که در دو درس 1 ساختیم باز کنید و سپس روی نام پروژه در Solution
Explorer راستکلیک کرده و Add New Item را انتخاب کنید.
محتویات فایل بازشده را حذف کنید و دستورهای زیر را جایگزین کنید:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
مشکل save نشدن
table ها بعد از ایجاد تغییرات در SQL ، یکی از مشکلات عدیده ای است که در صورت
آشنا نبودن با روش حل آن ، برای برنامه نویسان و بالاخص طراحان دیتابیس (بانک
اطلاعاتی) بسیار مشکل ساز است. یکی از خصوصیات جدیدی که به SQL Server 2008 افزوده
شده است این است که به صورت پیش فرض اجازه تغییر در ساختار جداول از طریق Desgin
View داده نمیشود. این خصیصه به خاطر این اضافه شده که از تغییرات تصادفی روی DB
Server ها جلوگیری کند. خصیصه جدید ممکن است مقداری برای توسعه دهندگان دردسر آفرین
باشد زیرا اگر بخواهند تغییر خود را اعمال کنند با خطای زیر مواجه میشوند :
مشکل save نشدن table
ها بعد از ایجاد تغییرات در SQL
برای رفع این مشکل
توسعه دهندگان باید این خصوصیت را از مسیر ارائه شده در زیر غیر فعال کنند :
Tools > Options >
Designers > Table and Database Designers > Prevent saving changes that require
table re-creation
معادل فارسی لغت Transaction انجام یا اجراست که در فارسی بصورت رایج
تراکنش نامیده می شود. در این سری مقالات بنده از لغت تراکنش بجای
Transaction برای سهولت در تایپ استفاده خواهم نمود. همچنین تا جایی که
ممکن بوده است از معادل های فارسی کلمات انگلیسی استفاده نموده ام تا
درک آن برای فارسی زبانان ساده تر باشد.
در این سلسله مقالات قصد دارم شما را با مفاهیم و مسائل مختلف پیرامون
تراکنش آشنا کنم. لذا ترجیح دادیم ابتدا از بررسی مفهوم تراکنش کار را
شروع کرده و بحث را تا مشکلات همزمانی، قفل گذاری و سطوح جداسازی پیش
ببریم.
در این مقاله مطالب زیر ارائه شده است:
•
مفهوم تراکنش (Transaction)
•
نمونه های واقعی از تراکنش
•
بررسی پردازش تراکنش و فرامین آن در استاندارد ANSI/ISO شامل
COMMIT و ROLLBACK
•
فرامین تراکنش در SQL Server شامل COMMIT، ROLLBACK، SAVE
TRANSACTION و BEGIN TRANSACTION
تغییرات بانک اطلاعاتی معمولا ناشی از اتفاقات واقعی، مانند دریافت
یک سفارش جدید از مشتری، انتقال وجه از حسابی به حسابی دیگر و
امثال آن می باشد. در حقیقت، دریافت یک سفارش جدید تنها یک مورد
تغییر در بانک اطلاعاتی نمی باشد
بلکه باعث تغییرات چندگانه در بانک اطلاعاتی میشود:
1-
سفارش جدید در جدول سفارشات اضافه می شود.
2-
اعتبار مالی مشتری به اندازه سفارشی که داده است کاهش پیدا می کند.
3-
موجودی آن کالایی که سفارش داده شده است کاسته می شود.
4-
تعداد کل محصولات سفارش داده شده تغییر می کند.
5- کل
فروش ها برای دفتر مربوط به فروشنده تغییر می کند.
نکته
ی مهم این مثال آن است که عملی که در ظاهر یک عمل ساده و غیر قابل
تجزیه (اتمی) به نظر می رسد یعنی دریافت یک سفارش از مشتری، واقعا
5 عمل به هنگام سازی روی بانک اطلاعاتی یعنی یک عمل INSERT و چهار
عمل UPDATE است. علاوه بر این، بانک اطلاعاتی بین این چند عمل به
هنگام سازی، حالت پایدار و سازگاری ندارد و به طور موقت، قیدهایی
را نقض می کند مثلا بین عمل 1 و 2، سفارش مشتری ثبت شده اما اعتبار
مالی مشتری کاهش پیدا نکرده است.
توجه:این
تغییرات بستگی به طرح کلی بانک اطلاعاتی شما دارد. ممکن است در ساختار
مورد نظر شما تنها تغییر اول ضروری باشه یعنی ثبت سفارش جدید. و موارد
دیگر را توسط پرس و جو بدست آورد. بطور نمونه برای بدست آوردن اعتبار
مالی فعلی مشتری کافیه جمع مبلغ خرید را بدست آورده و از اعتبار اولیه
کم کنیم.
برای اینکه بانک اطلاعاتی حالت ثبات خود را حفظ کند، تمام تغییرات
چندگانه فوق باید با هم اعمال شوند. اگر اشتباه در یک سیستم حالتی را
بوجود آورد که بعضی تغییرات مورد پردازش واقع شوند و برخی واقع نشوند،
جامعیت بانک اطلاعاتی از بین خواهد رفت. مثلا مشتری محصولی را سفارش می
دهد اما از اعتبار مالی آن چیزی کاسته نمی شود.
به این ترتیب باید در بانک اطلاعاتی یک تناسب "همه یا هیچ" باشد. SQL
بطور دقیق این قابلیت را از طریق پردازش تراکنش ارائه می دهد. که موضوع
این سری مقالات آموزشی را تشکیل می دهد.
مورد دیگری که می توان در این راستا به آن اشاره کرد انتقال وجه بین دو
حساب است. در اینجا مبلغی از حساب شما کسر و به حساب دیگری واریز می
شود. در این فرایند، تراکنش این تضمین را می دهد که این میانه راه از
بین نرود و یکی را طلب کار و دیگری را بدهکار کند (مثلا پول از حساب
شما کسر ولی به حساب طرف واریز نشود یا برعکس)
تراکنش چیست؟
تراکنش یک یا چند دستور SQL می باشد مثل به روزرسانی، درج و یا حذف
یک یا چندین سطر از داده ها که با همدیگر یک واحد منظقی از کار را
شکل می دهند. این دستورات SQL که شکل دهنده ی تراکنش هستند، نوعا
کاملا مرتبط به هم هستند و اعمال وابسته به هم را انجام می دهند.
هر دستور در تراکنش قسمتی از یک کار را انجام می دهد، اما برای
تکمیل کار، همه ی دستورات مذکور ضروری هستند.
گروه
بندی دستورات بعنوان یک تراکنش به RDBMS می گوید که کل دستورات
باید بطور خودکار اجرا شوند؛ در واقع همه ی دستورات باید بطور کامل
اجرا شوند تا بانک اطلاعاتی حالت ثبات خود را حفظ کند.
بنابراین، واحد منطقی از کار (یعنی یک تراکنش) الزاما تنها یک عمل
بانک اطلاعاتی نیست بلکه دنباله ای از چند عمل است که در حالت کلی،
یک حالت سازگار از بانک اطلاعاتی را به یک حالت سازگار دیگر تبدیل
می کند بدون آنکه در تمام نقاط میانی لازم باشد بانک اطلاعاتی در
حالت سازگار باشد.
مثال های متعددی می شود برای تراکنش زد در ادامه به یک مورد اشاره
میکنم:
افزودن یک سفارش:برای
پذیرش سفارش یک مشتری، برنامه ورود سفارش باید (الف) جدول Products
را مورد بازیابی و پرسش قرار دهد تا اطمینان حاصل شود که محصول
سفارش شده موجود است یا خیر (ب) جدول Customers را مورد پرس و جو
قرار می دهد تا مطمئن شود که آیا مشتری به اندازه ای که می خواهد
سفارش دهد اعتبار مالی دارد یا خیر (ج) در صورت حصول اطمینان از دو
مورد قبل سفارش را به جدول Orders وارد کرده (د) جدول Products را
بروز در آورده، یعنی مقدار سفارش را از کل تعداد محصول کم کند (ه)
جدول Employee را بروز در آورده، یعنی مقدار سفارش را به کل
فروشهای فروشنده ای که سفارش را پذیرفته است اضافه کند و سایر به
هنگام سازی های مورد نیاز دیگر.
در
تراکنش فوق چند عمل، که هر یک مشتمل بر یک دستور مجزای SQL می باشد،
مورد نیاز است تا تراکنش منطقی مجزایی را اجرا نماید. مفهوم تراکنش
برای برنامه هایی که یک بانک اطلاعاتی را بروز در می آوردند، بسیار
حساس می باشد، زیرا جامعیت یک بانک اطلاعاتی را تضمین می کند.
یک
DBMS که بر مبنای SQL واقع شده است قرارداد زیر درباره ی دستورات
در یک تراکنش را در پی دارد:
همانطور که از نمودار پیداست. هنگامی که برنامه با خطایی مواجه می
شود DBMS تمام تغییرات را برگردانده و وضعیت را به زمانی که تراکنش
آغاز شده بود می گرداند. در مورد مشکل سخت افزاری نیز همین اتفاق
می افتد.
بدیهی
است در حالت ایده آل نمی توان تضمین کرد که تمام به هنگام سازی ها
انجام شود. متاسفانه، چنین تضمینی نمی تواند فراهم شود زیرا همیشه
این امکان وجود دارد که کارها به خوبی پیش نرود و اندکی بعد، سیستم
دچار اشکال شود. برای مثال، ممکن است از کار افتادن سیستم بین
عملیات اتفاق بیفتد یا هنگام اجرای عمل UPDATE، سرریزی محاسباتی
اتفاق بیفتد و غیره. اما سیستمی که از مدیریت تراکنش پشتیبانی می
کند چنین تضمینی را فراهم می کند. به ویژه این که تضمین می کند اگر
تراکنشی، به هنگام سازهایی را اجرا کند و قبل از رسیدن به پایان
تراکنش، به هر دلیلی سیستم دچار خرابی شود آنگاه به هنگام سازی ها
نادیده گرفته می شود. بنابراین، تراکنش باید به طور کامل اجرا شود
یا به طور کامل لغو شود.
دستورات و فرامین تراکنش
ابتدا
اجازه دهید مدل تراکنش در استاندارد ANSI/ISO را مورد بررسی قرار
داده سپس دستورات مدیریت تراکنش در محصول تجاری SQL مورد نظر یعنی
SQL Server را با هم مرور میکنیم.
SQL
تراکنش های بانک اطلاعاتی را از طریق دو دستور پرازش تراکنش حمایت
می کند:
1- دستور COMMITخاتمه
ی موفقیت آمیز یک تراکنش را اعلام می کند. این دستور به DBMS می
گوید که مبادله تکمیل شده است؛ تمام دستوراتی که دربرگیرنده تراکنش
هستند اجرا شده اند، و بانک اطلاعاتی باثبات می باشد.
2- دستور ROLLBACKاعلام
می کند که یک تراکنش با موفقیت به پایان نرسیده است. این دستور به
DBMS می گوید که کاربر نمی خواهد تراکنش کامل شود؛ بلکه DBMS باید
تمام تغییرات انجام شده روی بانک اطلاعاتی در طی تراکنش را
برگرداند. در واقع، DBMS بانک اطلاعاتی را به همان حالتی بر می
گرداند که قبل از شروع تراکنش بوده است.
دستورات COMMIT و ROLLBACK، مانند دستورات SELECT، INSERT و
UPDATE، دستورات قابل اجرای SQL هستند.
استاندارد ANSI/ISO یک مدل برای تراکنش در SQL و نقش دستورات
COMMIT و ROLLBACK تعیین کرده است. تقریبا بیشتر محصولات تجاری SQL
از این مدل تراکنش، که بر اساس DB2 می باشد، استفاده می کنند. این
استاندارد مشخص می کند که یک تراکنش در SQL بطور خودکار با اولین
دستوری که توسط کاربر یا برنامه اجرا می شود، آغاز می گردد.
تراکنش از طریق دستورات بعدی SQL ادامه پیدا می کند تا اینکه با
یکی از چهار مورد زیر خاتمه یابد:
1- یک دستور COMMITعمل
تراکنش را با موفقیت به اتمام می رساند و تغییرات بانک اطلاعاتی را
کامل می سازد. بلافاصله بعد از دستور COMMIT یک تراکنش جدید شروع
می شود.
2- یک دستور ROLLBACKبا
برگشت دادن تغییرات بانک اطلاعاتی، تراکنش را ناتمام می گذارد.
بلافاصله بعد از دستور ROLLBACK یک تراکنش جدید آغاز می گردد.
3- همچنین خاتمه موفقیت آمیزبرنامه
باعث خاتمه ی تراکنش می شود، دقیقا مانند این که دستور COMMIT اجرا
شده باشد. از آنجایی که برنامه پایان یافته است، تراکنش دیگری برای
شروع وجود ندارد.
4- همچنین خاتمه غیر طبیعیبرنامه
تراکنش را ناتمام می گذارد، دقیقا همانطور که دستور ROLLBACK اجرا
می شد. در این مورد هم، چون برنامه پایان یافته است، تراکنش جدید و
دیگری برای شروع وجود ندارد.
شکل
زیر چند تراکنش نمونه را نشان می دهد که چهار حالت فوق را به تصویر
کشیده اند.
توجه
داشته باشید که در این مدل استاندارد هیچگونه عملی جانبی برای شروع
یک تراکنش لازم نیست؛ تراکنش با اولین دستور SQL یا بلافاصله بعد
از خاتمه ی تراکنش قبلی آغاز می گردد.
مدلهای دیگر تراکنش
چند
محصول تجاری SQL از مدل تراکنش خاص ANSI/ISO و DB2 فراتر رفته اند
تا توانائیهای پردازش تراکنش بیشتری را برای کاربران آنها فراهم
نمایند. DBMS Sybase، مثالی از این دست می باشد. SQL Server که از
محصول Sybase گرفته شده است نیز از مدل تراکنش Sybase استفاده می
کند.
نسخه
T-SQL که توسط Sybase مورد استفاده قرار می گیرد دارای چهار دستور
پردازش تراکنش، به شرح زیر می باشد:
1- دستور BEGIN TRANSACTIONشروع
یک تراکنش را صریحا اعلام می کند. به جای کلیدواژه TRANSACTION
بطور کوتاه می توان نوشت TRAN و همچنین در پایان عبارت می توان به
تراکنش نامی داد این نام می تواند یک مقدار رشته ای ثابت یا یک
متغیر رشته ای باشد.
این
دستور مقدار متغیر @@trancount را یک مقدار افزایش می دهد.
2- دستور COMMIT TRANSACTIONاعلام
می دارد که یک تراکنش با موفقیت به پایان رسیده است. تمام تغییرات
انجام شده در بانک اطلاعاتی در طی انجام تراکنش دائمی می شوند.
3- دستور SAVE TRANSACTIONیک
نقطه ذخیره سازی تغییرات یا savepoint در یک تراکنش برقرار می کند.
وضعیت بانک اطلاعاتی را در موقعیت فعلی ذخیره کرده و به موقعیت
ذخیره شده، یک نام که در دستور مشخص شده است، اختصاص می دهد.
4- دستور ROLLBACK TRANSACTIONدارای
دو وظیفه می باشد. اگر نام نقطه ی ذخیره سازی در دستور ROLLBACK
بیاید، تغییرات انجام شده در بانک اطلاعاتی را از موقعیت ذخیره
سازی تا به حال بر میگرداند، عنی عملا تراکنش را به نقطه ای بر می
گرداند که دستور SAVE TRANSACTION اجرا شده بود. اگر نام نقطه ی
ذخیره سازی نیامده باشد، دستور ROLLBACK تمام تغییرات انجام شده در
بانک اطلاعاتی از زمان اجرای دستور BEGIN TRANSACTION را بر می
گرداند.
منابع:
کتاب
آشنایی با سیستم های بانک اطلاعاتی نوشته C.J. Date
چندی پیش در
تالار T-SQL سوالی مطرح شد راجع به مساله ای که معروف است به top N per group.
تنها موضوعی که باعث شد من مطلبی راجع به آن بنویسم محدودیتی بود که کاربر مورد نظر
داشت؛ که آن محدودیت چیزی نبود جز: query بایستی در نسخه 2000 جوابگو باشد.
قطعا شده است که بخواهید مثلا به ازای هر مشتری آخرین سفارش آن را انتخاب کنید. این
مساله Top N نامیده میشود.
فرض کنید جدولی داریم که حاوی سفارشات مشتریان میباشد. هر مشتری میتواند چندین
سفارش داشته باشد؛ هر سفارش دارای حداقل دو مقدار "تاریخ سفارش" و "مبلغ سفارش
است". هدف پیدا کردن آخرین سفارشات هر مشتری میباشد.
نکته: اگر چند تاریخ برای آخرین سفارش مشتری وجود داشت آنگاه بایستی بر اساس مبلغ
سفارش مرتب سازی نزولی صورت بگیرد. یا به عبارت دیگر ابتدا باید مرتب سازی نزولی بر
اساس ستون تاریخ سفارش انجام شود و سپس مرتب سازی نزولی بر اساس ستون مبلغ سفارش.
فرض میگیریم دادههای جدول ما چیزیست شبیه به این:
سطرهایی از
جدول که رنگی شده اند سطرهای مورد نظر ما هستند که باید در خروجی ظاهر شوند.
دادههای جدول با کمک قابلیت Sort نرم افزار word مرتب سازی شده اند، این تصویر را
به این خاطر در اینجا قرار دادم چون که دیدم میتواند در شفاف سازی مساله به من کمک
کند.
ابتدا مرتب سازی نزولی بر اساس ستون order_date انجام گرفته و سپس مرتب سازی نزولی
بر اساس ستون order_value. و در پایان اولین سطر مربوط به هر مشتری به عنوان خروجی
مورد نظر انتخاب میشوند.
راه حل
ها
خب پر واضح
است که در نسخه 2005 و بعد از آن سادهترین و بهینهترین راه حل استفاده از تابع
row_number میباشد
رخی از دادهها از ترکیب و ادغام شدن چند داده دیگر بدست میآیند. مثلا
شماره دانشجویی از ترکیب چند صفت مختلف بوجود میآید (مثل نیمسال ورودی،
کددانشگاه، کدرشته تحصیلی...).
برای پیاده سازی اینگونه ستونها SQL Server یک قابلیتی به نام computed column
ارائه داده است. برای تعریف این چنین ستون هایی بعد از نام ستون از کلمه
AS استفاده میکنیم. عبارتی که ستون محاسباتی را تشکیل میدهد میتواند
شامل این موارد باشد: تابع، نام ستون غیر محاسباتی و مقادیر ثابت ولی امکان
استفاده از subquery وجود ندارد.
ستونهای محاسباتی بطور پیشفرض مجازی هستند (بطور فیزیکی بر روی دیسک ذخیره
نشده اند). یعنی هر موقع که query اجرا میشود آنها نیز مجدد محاسبه شده و
نمایش داده میشوند.
برای اینکه نوع ذخیره سازی را از مجازی به فیزیکی تبدیل کنیم باید در هنگام
ساخت جدول (یا تغییر آن) از کلید واژه PERSISTED استفاده کنیم. وقتی بطور
فیزیکی ذخیره شده باشد با هر بار ویرایش یکی از ستونهای تشکلیل دهنده ستون
محاسباتی هم ویرایش میشود.
ستون محاسباتی بعد از تبدیل شدن از مجازی به فیزیکی میتواند به عنوان کلید اولیه و ایندکس در نظر گرفته شود.
به مثال زیر توجه کنید:
جدولی داریم با دو ستون، قرار هست بر اساس ترکیب مقادیر دو ستون جستجویی
انجام دهیم. ضمن اینکه ترکیب دو ستون باید منحصر بفرد باشد. برای این منظور
یک unique index روی دو ستون لحاظ میکنیم.
createtable t1
(
col1 char(1),
col2 char(1)
)
createunique nonclustered index ix_uq on t1 (col1 , col2);
اکنون به دنبال سطری میگردیم که ترکیب مقادیر دو ستون آن برابر با OP باشد. پس query زیر را اجرا میکنیم
select col1 + col2
from t1
where col1 + col2 = 'OP'
اما همانطور که در تصویر زیر مشاهده میشود عمل Index Seek صورت نگرفته
است. زمانی که از ستون به عنوان یک عبارت استفاده شود Index Seek نخواهیم
داشت. منظور عبارت، الحاق مقداری با ستون، قرار گرفتن ستون در یک تابع و
... میباشد.
برای اینکه Index Seek داشته باشیم بایستی مقادیر را جداگانه مقایسه کنیم(ستونها به صورت عبارت محاسباتی نباشند)
با دستور اول یک ستون محاسباتی از نوع persisted به جدول اضافه نمودیم. و با دستور دوم یک Index روی ستون محاسباتی ایجاد نمودیم.
حال مجددا عمل جستجو را انجام میدهیم ولی به کمک ستون محاسباتی که اخیرا ایجاد نمودیم:
select *
from t1
where col3 = 'OP';
حالا مشاهده میشود که شاخص ix1 اسکن نشده است. و از آنجایی که شاخص از نوع Clustered است مشکل Covering هم نخواهیم داشت.
Stored ProcedureیاSpیا به زبان فارسی " رویه های ذخیره شده " اشیاییاجرا پذیر در بانک اطلاعاتیSQL Serverهستند که شامل یک یا چندین دستورSQLمی شود ، این رویه ها میتوانند پارامتر های ورودی و خروجی داشته باشند.همچنین میتوان داخل این رویه ها به زبانSQLبرنامه نویسی کرد.مهم ترین کاربر این رویه ها ذخیره کردن دستوراتSelect , Insert , Update , Deleteهست یا ترکیبی از اینها.نحوه ساخت این رویه ها به صورت زیر می باشد:
وارد بانک اطلاعاتیSQL Serverشده ، پس از باز کردن بانک مورد نظر در قسمتProgrammabilityوارد بخشStored Procedureشوید .
بر رویStored Procedureکلیک راست کرده وNew Stored Procedureرا انتخاب نمایید .
احتمالا کد های پیشفرضی را در این صفحه مشاهده می کنید ، همه این کد هارا پا کرده و به صورت زیر کد نویسی کنید :
به جایYourProcedureNameیک
نام برای برای رویه انتخاب کنید . سعی کنید نامی که انتخاب می نمایید
مفهوم رویه شما را برساند مثلا برای درج یک رکورد جدید در جدولMembersمن نامAddNewMemberرا انتخاب می کنم و یا برای دریافت تمام رکورد های این جدول نامGetAllMembersنام با مفهومی است .
در
پرانتز مقابل نام رویه پارامتر های رویه به همراه نوع پارامتر تعیین میشود
، اگر تعداد پارامتر ها بیشتر از یکی بود با ویرگول آنها را جدا می کنیم .
به جایSQLStatementدستوراتSQlرا که بینBeginوEndنوشته می شوند تایپ کنید .
به عنوان مثالSpزیر اطلاعات کاربر را با دریافت پارامتر نام کاربری (( @IDاز جدولTBL_Membersدریافت می کند :
createprocedure GetMemberbyID(@ID nvarchar(100))
as
begin
select * from TBL_Members where ID=@ID
end
سپس بر روی دکمهExecuteکلیک کرده تا رویه شما ساخته و ذخیره گردد .
برخی از قابلیت های رویه های ذخیره شده یاStored Procedureعبارت است از :
Precompiledبودن
آنها به این معنی که به زبان ماشین بسیار نزدیک شده و به طور کامل از اول
ترجمه نمیشود ، این امر باعث افزایش سرعت بارگزاری می گردد .
قابلیت ذخیره داشته و میتوان از یک رویه چندین بار در کد نویسی استفاده کرد .
دارای ویرایشگرQueryمی باشد (میتوانید به سادگی یکQueryحرفه ای ایجاد کنید)
دارایSyntax Parserهست و از خطاهایSQLجلوگیری می کند .
دارای امنیت بالایی است و از هک شدن سایت شما توسطSQL Injectionدر بسیاری موارد جلوگیری می کند .
قابلیت درج چندین دستورSQLرا پشت سرهم داراست .
قابلیت ارسال ورودی و خروجی دارد .
قابلیت برنامه نویسی ( شرط ، حلقه و...) به زبانTransactSQLدارد .
و.....
حال که با قابلیت ها ونحوه ساختStored Procedureآشنا شدید بد نیست که به نحوه استفاده از این ابزار جالب درAsp.NETبپردازیم .
استفاده از این ابزار بسیار ساده هست .اگر ازSQL DatasourceیاObjectDatasourceاستفاده می کنید یک ویزارد برای ساخت و استفاده ازStored Procedureها قرار داده شده که به راحتی آن را مدیریت کنید .
اگر از کد نویسی برای کار با بانک های اطلاعاتی استفاده می کنید کافیه بعد از تعریفSQLCommandبه جای دستوراتSQLنامSPرا وارد نموده و بعد از آن کد زیر را اضافه نمایید :
Cmd.CommandType = CommandType.StoredProcedure;
این کد به برنامه می گوید که دستورات نوشته شده از نوعStored Procedureهستند و نیازی به ترجمه آن ها نیست .
همانطور
که ملاحظه می فرمایید فرض کردم که SP داری دو پارامتر به نام FirstParam و
SecondParam هست (البته شما باید به شکل صحیحی پارامتر ها را نام گزاری
کنید) و از طریق متد AddWithValue آنهارا مقدار دهی نموده ام .
select cast(SUM(DateDiff(MINUTE, CAST('0:00' as time), Time))/60 as nvarchar(3)) + ':' + cast(SUM(DateDiff(MINUTE, CAST('0:00' as time), Time))%60 as nvarchar(2)) from Table_1
یکی از مهمترین کارهایی که یک مدیر پایگاه داده
میتونه داشته باشه , داشتن یک طرج یا پلن برای پشتیبان گیری کارا و موثر از
دادها با توجه به شرایط هست تا در مواقع بروز نقص فنی بتونه کمترین گمشدگی داده
رو داشته باشه . در این مقاله نگاهی به Database Files و Database File group
میاندازیم و سپس به انواع SQLServer Recovery Mode میپردازیم .
Database FileGroups
حال که در مورد انواع فایلها آشنا شدم بهتره که
در مورد File group ها هم بدونیم . File Group ها بر خلاف مورد قبلی به هیچ
عنوان مفهموم فیزیکی ندارند بلکه دارای ساختار منطقی هستند . از File group ها
برای مقاصد گوناگونی استفاده میشه .مثلا برای مقاصد Back up گیری و Restore
کردن یا جدا کردن اعمال OLTP On-line Transaction Processing از OLAP On-Line
Analytical Processing. .
اگر با این دو اصلاح نا آشنا هستید باید بگویم
OLTP دیتابیسی هست که اعمال خواندن و نوشتن وبروزرسانی زیادی دراون داریم در
حالی که در OLAPبیشتر به صورت تنها خواندنی هست و بیشتر از اون در گزارش گیری
استفاده میکنیم .
ما همیشه Primary File Group رو داریم که میتونه
حاوی فایلهای mdf و ndf باشه . همچین میتونیم File Group های اختیاری دیگری رو
هم داشته باشیم که به اونها User Defined File Group’ گفته میشه که تنها میتونه
حاوی فایلهای ndf باشه . علیت اینکار میتونه دلایل متفاوتی داشته باشه . تصور
کنید که در دیتابیس شما جدولی وجود دارد که بر خلاف دیگر جدولها بسیار بزرگ هست
و متناوب از سوی کاربر درخواست خواندن دارد . در این شرایط میتونیم اون جدول
خاص رو در یک فایل ndf مجزا در یک درایو یا هارددیسک مجزا قرار دهیم . به این
طریق کارایی برنامه ما بالاتر خوهد رفت . نکته دیگر اینکه فایلهای Transaction
Log ما یا همان ndf درون File group ها قرار نمیگیرند .
ما میتونیم هنگام تعریف جدول جدید آن را به یک
File Group مشخص انتصاب بدیم , البته باید اینجا File Group رو ایجاد کرده
باشیم . از پنل Properties قسمت Table Designer مقدار Text/Image Filegroup را
به file group مورد نظر انتصاب میدیم .
Recovery Models
حال به بحث اصلی مان برمیگردیم . تعین Recovery
Model برای دیتابیس نقش مهمی در تعین استراتژی ما برای Disaster recovery بازی
میکنه . اگر بخواهیم خیلی ساده هدف Recovery Models رو بیان کینم , میتونیم
بگیم برای این بوجود اومده تا نحوه نگهداری یا maintenance فایلهای T-Log رو
مدیریت کنه .
Full Recovery Model
این مدل که پیشفرض هم میباشد , کاملترین نوع هست
که کمترین کمشدگی داده رو داریم . در اینجا ما( PIT ( Point In Time Restore
رو داریم یعنی میتونیم به هر لحظه ای از زمان دیتابیس رو برگردونیم . مناسب
دیتابیس های OLTP هست و نیازمند Back up گیری مستمر از Log هست .
Simple
شرایطی رو در نظر بگیرید که در صورت Failure برای
شما کافی باشد که تنها به وضعیت آخرین Back up گیری برگردید و لازم نداشته
باشید که به یک زمان مشخص برگردید , در این صورت Simple مناسب حال شماست . مثلا
فرض کینید که شما همیشه آخر شب Back up میگیرید و یک Failure در ساعت 10 صبح
برای شما رخ میده . در صورتی که مد Simple باشید , داده های بین ساعات 12 شب تا
10 صبح رو از دست خواهید داد و اگر این برای شما اهمیتی نداشته باشد که دادهای
بین آخرین Back up تا زمان Failure رو از دست بدهید از مد Simple استفاده کنید
.
در این مد شما به Back up گیری از فایل log نیازی
ندارید , PIT Recovery رو ندارید و Maintenance سادست و بیشتر مناسب دیتابیس
های OLAP هست .
Bulk-logged
این مد با Full تفاوت چندانی ندارد , تنها تفاوت آنها در اعمال Bulk انبوه هست
. مثلا فرض کنید دادههایی رو از دیتابیسی دیگر به این دیتابیس Import میکنید ,
در اینجا تنها یک Transaction در فایل لاگ ثبت میشود در صورتی که اگر در مد
full بود , به تعداد رکورهایی که درج میشد تراکنش ثبت میشد . به عبارت جامعتر
, در این مد اعمال Bulk یا انبوه به صورت minimal لاگ میشود . اگر ما یک
میلیون رکورد رو به صورت انبوه درج میکردیم , به ازای همه اون یک میلیون ما
تنها یک تراکنش در فایل لاگ ذخیره میکردیم در حالی که در مد Full یک میلیون
تراکنش ثبت میشد . در اینجا ما PIT Restore رو نداریم .
نکته مهمی که باید به خاطر داشته باشید این است
که در صورتی که در مد Full or Bulk -logged هستید , حتما باید از فایل لاگ Back
up بگیرید تا Trancate شود در غیر اینصورت این فایل آنقدر رشد خواهد کرد و تمام
فضای درایو رو به خودش اختصاص خواهد داد . بعضا دیتابیس هایی دیده شده است که
علیرغم اینکه حجم فایل mdf آن کم است , حجم فایل log آن چندین برابر mdf آن هست
. این ناشی از Back up گیری نکردن از فایل log هست .
در هرسرور موجود حداقل چهارپايگاه داده زير موجود است :
1) Master
: شامل تمامي اطلاعات لازم براي مديريت پايگاه، مانند پايگاه داده هاي تعريف شده
ومشخصات کاربران و
رويه هاي ذخيره شده سيستمي وپيام هاي خطاست. جداولي که در اين پايگاه داده موجود
است معمولاکاتالوگ سيستم ناميده مي شود .
2) Model
:
يک الگو براي ساخت پايگاه داده هاي جديد است وهر شي موجود در آن ،در پايگاه داده
هاي جديد ايجاد
مي شود. براي مثال اگر يک شناسه کاربر جديد در آن قرار دهيد ،در تمامي پايگاه هايي
که بعد ازاين ايجاد مي شوند اين شناسه هم وجود دارد .
3) Msdb
:
در نگهداري برنا مه هاي زمان بندي سيستم وJob
ها وتاريخچه نسخه هاي پشتيبان کاربرد دارد .
4) Tempdb:
محل موقتي براي اشيائي است که نياز به فضاي موقتي دارند .
براي پايگاه داده هاي تعريف شده در
SQL-SERVER
سه نوع فايل قابل تصور است :
1-
فايل هاي
Primary(
باپسوند .mdf)
:که
حاوي اطلاعات راه اندازي پايگاه هستند وبه بقيه فايل هاي پايگاه داده ها
اشاره
دارند
.
2-
فايل هاي
Secondary(
باپسوند .ndf)
:
بقيه فايل هاي داده اي به جز فايل هاي داده اي اصلي در اين گروه
قرار
مي گيرند
.
3-
فايل هاي Log(
باپسوند .ldf)
:
براي ثبت تراکنش هاي موجود در پايگاه به
کار مي روندو عضو هيچ گروه فايلي
نيستند.
براي بسياري از پايگاه هاي داده اي معرفي گروه 1و3کافي است وممکن است پايگاه داده
اي چندين فايل از
نوع دوم داشته باشد يا هيچ فايلي از اين نوع نداشته باشد.
يک فايل نمي تواند عضو بيش ازيک گروه فايلي باشد وفايل
هاي سيستم در گروه فايل Primary
قرار مي گيرند.
Trigger نوعی رویه ذخیره شده است که پس از یک رویداد اجرا می شود ،
برخلاف Stored Procedure که حتما باید فراخوانی شود Trigger ها قابل
فراخوانی نبوده و به صورت خودکار در واکنش به اعمال Insert , Update ,
Delete (قبل یا بعد از تراکنش) اجرا می شوند .
واضح است که چنین رویه بر خلاف SP نمیتواند پارامتر ورود و خروجی بپذیرد
و اطلاعات خود را از رکورد مورد نظر (رکوردی که Insert , Update یا Delete
بر روی آن صورت گرفته که اصطلاحا Updated , Inserted و Deleted خوانده می
شود)
مهمترین کاربر Trigger ها به شرح زیر است :
جلوگیری از ورود داده های نا معتبر
لاگ نمودن تراکنش ها
حذف یا به روز رسانی رکورد ها در جداول مرتبط
بالا بردن کارایی سیستم
تغییر و جایگزینی یک تراکنش
و...
به دلیل اینکه Trigger ها خیلی سریع عمل می کنند برای ما بسیار سودمند خواهند بود ، برای روش شدن مطلب چند مثال میزنم :
فرض کنید یک جدول کاربران دارید ، میخواهیم اگر یک یک رکورد از این
جدول حذف شد ، رکوردهایی از جداول مختلف حذف شده و برخی هم تغییر کنند .
شاید بگوید که Relation ها این کار را انجام می دهند در صورتی که اینطور
نیست و خیلی جای مانور وجود ندارد ، اما با یک Trigger ساده After
Delete میتوانید این کار را به سادگی انجام دهید .
فرض کنید جدول کاربران شما دارای یک ستون اعتبار است ، و یک جدول دیگر
برای ثبت اعتبار های کسر شده یا اضافه شده وجود دارد ، مایلیم هر گاه یک
رکورد به جدول اعتبارها اضافه شد ستون اعتبار جدول کاربر نیز به روز شود
(از اعتبار کاربر کسر شده یا به آن اضافه شود) ، این کار را میتوانید در کد
نویسی یا در SP انجام دهید ولی بهترین جای قرار گیری آن در Trigger است
چرا که استثنا ندارد یعنی به هر طریقی رکوردی کم و زیاد شود به روز رسانی
انجام خواهد شد در ضمن بسیار سریع عمل می کند .
لاگ کردن رویداد ها نیز استفاده دیگری از Trigger ها است ، شما میتوانید تراکنش های بانک اطلاعاتی را لاگ کنید .
فرض کنید قرار است در یک جدول اطلاعاتی وارد شود ، ممکن است این
اطلاعات تکراری باشند ، برای جلوگیری از تکرار معمولا ما از IF استفاده
میکنیم بدین معنی که چک می کنیم اگر این داده در بانک باشد از درج آن
جلوگیری می کنیم ، این شرط را میتوان در کدنویسی سمت سرور یا در SP قرار
داد ولی بازهم بهترین جا برای قرار دادن آن در یک Trigger می باشد .
برای ایجاد یک Trigger مطابق شکل زیر عمل کنید :
همانطور که ملاحظه می کنید فرمت یک Trigger در سمت
راست نمایش داده شده است ، پس از واژه Create trigger نام Trigger ذکر شده و
سپس واژه On و پس از آن نام جدولی که مد نظر ماست ذکر می شود ، سپس واژه
After و یکی از تراکنش های Insert , Delte یا Update و سپس کدها ما پس
از Begin قرار خواهد گرفت .
پس نوشتن کد فوق دکمه Execute را بفشارید تا
Trigger ایجاد شود ، برای ویرایش آن هم میتوانید روی Trigger کلیک راست
کرده و گزینه Alter را انتخاب کنید
همانطور که ملاحظه می کنید برای بدست آوردن کد کاربری که حذف شده است
از یک دستور Select ساده استفاده کرده ام ، نکته مهم اینجاست که به جای نام
جدول از کلمه "Deleted" استفاده شده یعنی "رکورد (یا رکوردهای) حذف شده" ،
این قضیه برای Insert و Update نیز صادق است یعنی "Inserted" و "Updated" ،
سپس مقدار بدست آمده از دستور Select را در یک متغیر به نام UserID@ ذخیره
کرده و در شرط حذف از آن استفاده کردیم .
از این پس هر رکوردی از جدول TBLUsersحذف شود تمام رکوردهای جدول TBLBlogs نیز حذف خواهد شد
البته در این مثال میتوانستیم از Relation ها جهت این عمل استفاده کنیم
ولی در بسیاری از شرایط بین بسیاری از جداول Relation وجود ندارد ولی ما
میخواهیم تراکنش ها روی سایر جداول نیز تاثیر بگذارند ، بنابراین نیاز به
Trigger ها امری مشخص است .
برخی از برنامه نویسان به جای استفاده از Trigger این اعمال را در لایه
Bussiness Logic انجام می دهند (مثلا پس از یک تراکنش یک Query دیگر اجرا
می کنند ) ، این کار با افزایش تعداد تراکنش ها باعث افت کارایی سیستم
خواهد شد .
برای مشاهده مثال های بیشتر میتوانید صفحه زیر را مطالعه بفرمایید :
حالتی را در نظر بگیرید که بخواهید
تعداد زیادی رکورد را که حجم هر رکورد هم قابل ملاحظه هست، نگهداری
کنید(مثلا چندین هزار مقاله) و همچنین قابلیت جستجو را در این رکوردها لحاظ
کنید به صورتی که بر اساس رکوردهایی که بیشترین تعداد تکرار کلمات مدنظر
را دارند مرتب شوند.
شاید اولین راه حل، مطلب آقای سلیم آبادی در اینجا باشه، که تعداد تکرار یک کلمه را در فیلدی در جدول بیان کردند و درست هم هست اما با 2 شرط:
1) رکوردهای ما حجم کمی داشته باشند چرا که دستور LIKE پاسخ سریعی را با حجم بالای اطلاعات به ما نمیدهد.
2) رکوردهای ما از خانوادهی char باشند. برای مثال اگر مقالات ما به صورت pdf باشند این کد جواب نمیدهد.
اما راه دوم استفاده از Ful Text Search و
دستور CONTAINSTABLE هست که 2 شرط لازم را برای راه حل اول احتیاج نداره.
در اینجا فقط نحوهی استفاده از CONTAINSTABLE رو مطرح میکنیم.
CONTAINSTABLE
جدولی از موارد یافت شده را بر اساس معیارهایی که ما به اون معرفی
میکنیم، ایجاد میکند. این جدول حاوی دو فیلد KEY(کلید فیلد مورد نظر) و
RANK(مقداری بین 0 تا 1000) است که میزان همسانی رکورد با معیار ما را مشخص
میکند و ما با استفاده از این فیلد میتوانیم رکوردهایمان را مرتب کنیم.
به این کد توجه کنید:
SELECT t.Title, p.[RANK]
FROM Articles AS t
INNERJOIN CONTAINSTABLE(Articles, Data, 'management' ) AS p
ON t.Id = p.[KEY]
ORDERBY p.RANK
در اینجا کار جستجو انجام شده و بر حسب میزان نزدیکی محتویات رکورد با معیار ما مرتب شده است.
نکته:
هیچ فرقی نمیکند که محتویات فیلد مورد نظر شما یک متن ساده، یک فایل word
یا حتی pdf باشد. فقط باید تنظیمات Full Text Search درست انجام شود.
همانگونه که میدانید مقدار Identity پس از درج به آن تخصیص مییابد
چنانچه بخواهید به این مقدار دسترسی پیدا کنید چندین روش به ازای اینکار
وجود دارد که ما در این مقاله سه روش معمول را بررسی خواهیم نمود.
1- استفاده از متغییر سیستمی Identity@@
2- استفاده از تابع () Scope_Identity
3- استفاده از تابع Ident_Current
هر
سه این توابع مقدار Identity ایجاد شده برای جداول را نمایش میدهند. اما
تفاوت هایی باهم دارند که در ادامه مقاله این تفاوتها بررسی شده است.
1- متغییر سیستمی Identity@@ :
این متغییر سیستمی حاوی آخرین Identity ایجاد شده به ازای Session جاری
شما است. لازم به ذکر است اگر به واسته Insert شما، Identity دیگری در یک
حوزه دیگر (مانند یک Trigger) ایجاد شود مقدار موجود در این متغییر حاوی
آخرین Identity ایجاد شده است. (یعنی Identity ایجاد شده توسط آن تریگر و
نه خود جدول). لازم به ذکر است این موضوع به طور کامل در ادامه مقاله شرح
داده شده است.
2- استفاده از تابع()Scope_Identity :
با استفاده از این تابع میتوانیم آخرین Identify ایجا دشده به ازای
Session جاری را بدست آوریم. لازم به ذکر است مقادیر Identity ایجاد شده
توسط سایر حوزهها تاثیر در مقدار بازگشتی توسط این تابع ندارد. در ادامه
مقاله این موضوع به طور کامل بررسی شده است.
3- استفاده از تابع ident_Current :
این تابع آخرین مقدار Identity موجود در یک جدول را نمایش میدهد. ذکر این
نکته ضروری است که Identity ایجاد شده توسط سایر Sessionها هم روی خروجی
این تابع تاثیرگذار است. چون این تابع آخرین Identity موجود در جدول را به
شما نمایش میدهد و نه Identity ایجاد شده به ازای یکSession را.
برای
بدست آوردن یک Identity کافی است که پس از درج رکورد در جدول مورد نظر
متغییر سیستمی @@Identity و یا توابع Scope_Identity و یا Ident_Current را
همانند مثال زیر Select کنید.
خروجی دستورات بالا پس از درج
رکورد مورد نظر به صورت زیر است.
اما
ممکن است از خودتان این سوال را بپرسید که آیا این توابع در سطح شبکه
آخرین مقدار Identity درج شده توسط سایر Sessionها را نمایش میدهند و یا
Session جاری را؟ (منظور Sessionی که درخواست مقدار موجود در identity را
نموده است).
برای دریافت پاسخ این سوال مطابق مراحل اسکریپهای زیر را اجرا نمایید.
1-ایجاد جدول Employees1
USE TEMPDB GO
IF OBJECT_ID(N'Employees1', N'U') ISNOTNULL
DROPTABLEEmployees1;
GO
CREATETABLEEmployees1
(
ID intIDENTITY(1,1),
FirstName NVARCHAR(50),
LastName NVARCHAR(50)
)
GO
همانطور که مشاهده میکنید مقدار شروع برای Identity برابر 1 و گام افزایش هم برابر 1 در نظر گرفته شده است(Identity(1,1)) .
2-در Sessionی جدید دستورات زیر را اجرا نمایید. (درج رکورد جدید در جدول Employees1 و واکشی مقدار Identity)
همانگونه
که ملاحضه میکنید @@Identity، Scope_Identity() و Ident_Current هر سه مقدار Identity (عدد 1) ایجاد شده بوسیله دستور Insert را به شما نمایش میدهند.
1-
و در انتها در یک Session دیگر دستورات زیر را اجرا نمایید.(واکشی مقدار Identity)
همانطور
که مشاهده میکنید در این Seesion ما از SQL خواستهایم آخرین مقدار
Identity را به ما نشان داده شود. باید به این نکته توجه کنید با توجه به
اینکه در این Session عملیات درجی هنوز انجام نگرفته است که ما Identity
ایجاد شده را مشاهده نماییم. بنابراین صرفاً تابع Iden_Current مقدار
Identity موجود در جدول را به ما نمایش میدهد.
پس میتوان به این نکته رسید که
@@Idnetity و Scope_Identity : Identity ایجاد به ازای Session جاری را نمایش داده و به مقادیر تولید شده توسط سایر Sessionهای دیگر دسترسی ندارد.
Ident_Current : آخرین Identity موجود در جدول را به شما نمایش میدهد. بنابراین باید این نکته را
در نظر داشته باشید که Identityها ایجاد شده توسط سایر Sessionها روی مقدار بازگشتی این تابع تاثیرگدار است.
اما یکی دیگر از مباحث مهم درباره Identity تاثیر Scope بر مقدار Identity است (یعنی چه!) . برای اینکه با مفهوم این موضوع آشنا شوید
اسکریپتهای مربوط به مثال زیر را بدقت اجرا کنید.
1-
ایجاد جدول Employees1
USE TEMPDB
GO
IF OBJECT_ID(N'Employees1', N'U') ISNOTNULL
DROPTABLEEmployees1;
GO
CREATETABLEEmployees1
(
ID intIDENTITY(1,1),
FirstName NVARCHAR(50),
LastName NVARCHAR(50)
)
GO
همانطور که مشاهده میکنید مقدار
شروع برای Identity برابر 1 و گام افزایش هم برابر 1 در نظر
گرفته شده است(Identity(1,1)) .
2-
ایجاد جدول Employees2
USE TEMPDB
GO
IF OBJECT_ID(N'Employees2', N'U') IS NOT NULL
DROP TABLE Employees2;
GO
CREATE TABLE Employees2
(
ID intIDENTITY(100,1),
FirstName NVARCHAR(50),
LastName NVARCHAR(50)
)
GO
همانطور که مشاهده میکنید مقدار
شروع برای Identity برابر 100 و گام افزایش هم برابر 1 در نظر
گرفته شده است(Identity(100,1)).
Trigger ایجاد شده به
ازای جدول Employees1 به ازای عملیات
Insert اجرا میشود. همچنین مقادیر درج شده در جدول Employees1 بوسیله
جدول Inserted در دسترس است. لازم به ذکر است جدول Inserted یک جدول موقت بوده که توسط Trigger ایجاد شده و
داخل خود آن معتبر است.
هدف ما از ایجاد این Trigger تهیه یک کپی از
رکوردهایی که در جدول Employees1 درج میشوند است. این کپی قرار است با
استفاده از دستور Insert…Select در جدول Employees2 ایجاد گردد.
4-
درج یک رکورد در جدول Employees1 و واکشی مقدار Identity
مقادیر استخراج شده به ازای Identity به شرح زیر است
1-
@@Identity : پس از درج رکورد در جدول Employees1 متغییر سیستمی @@Identity مقدار 100 را نمایش داده است دلیل این موضوع
بر میگردد به Trigger موجود در جدول Employees1.
با توجه به اینکه جدول Employees1 دارای یک فیلد Identity بوده است هنگام
درج رکورد در جدول مقدار @@Identity=1 است اما چون این جدول دارای Triggerی است که این Trigger خود با جدولی
دیگری درگیر است که دارای Identity است مقدار متغییر @@identity=100 خواهد شد.
2-
Scope_Identity() : مقدار نمایش داده شده توسط تابع Scope_Identity() برابر با مقدار Identity تخصیص (عدد 1) داده
شده به ازای رکورد شما میباشد که این موضوع در اغلب موارد مد نظر برنامهنویسان
میباشد.
3-
Ident_Current(‘Employees1’) : مقدار نمایش شده توسط تابع Ident_Current آخرین مقدار Identity (عدد 1) موجود در جدول Employees1 است.
4-
Ident_Current(‘Employees2’) : مقدار نمایش شده توسط تابع Ident_Current آخرین مقدار Identity (عدد 100) موجود در جدول Employees2 است.
چند نکته مهم
1- مقدار بازگردانده شده توسط تابع Ident_Current آخرین مقدار Identity موجود در جدول مورد نظر شما بوده است و عملیات
درج سایر کاربران در این مقدار تاثیر گذار است.
2-
برای بدست آوردن مقدار Identity درست بهتر است
از تابع Scope_Identity() استفاده نماییم. معمولاً در بیشتر مواقع
مقدار بازگردانده شده توسط این تابع مد نظر برنامه نویسان است.
3-
EntityFramework و Nhibernate هم برای بدست آوردن Identity از تابع Scope_Identity استفاده میکند.
Identity یکی از Attributeهایی که در SQL Server به ازای Columnهای عددی
میتوان در نظر گرفت. به طور خیلی ساده هنگامی که این Attribute به ازای یک
فیلد عددی تنظیم گردد. چنانچه رکوردی در جدول مربوط به Identity درج شود
فیلد Identity مقداری را به طور اتوماتیک دریافت خواهد نمود.
نحوه دریافت مقدار به ازای فیلد Identity با توجه به آخرین مقدار آن و گام افزایش است که در هنگام ایجاد identity تعریف میگردد.
برای
ایجاد یک فیلد از نوع Identity میتوانید زمانیکه جدول خود را ایجاد
میکنید این Attribute را به فیلد مورد نظر خود تخصیص دهید.
مثال 1 : این مثال نحوه ایجاد یک فیلد از نوع Identity را نمایش میدهد.
USE tempdb
GO
CREATETABLECustomers1
(
ID INTIDENTITY,-- ID INT IDENTITY(1,1)
NameNVARCHAR(100),
[Address] NVARCHAR(200)
)
GO
همانطور
که در مثال 1 مشاهده میکنید فیلد ID از نوع Identity تعریف شده است. در
این حالت (ID int IDENTITY) مقدار شروع و گام افزایش به ازای این فیلد 1 در
نظر گرفته خواهد شد. در این صورت اگر چند رکورد زیر را به ازای این جدول
درج کنید. مقدار Identity به صورت زیر خواهد بود.
INSERTINTOCustomers1 (Name,[Address]) VALUES
(N'مسعود',N'میانه'),
(N'فرید',N'میانه'),
(N'احمد',N'میانه')
GO
SELECT* FROMCustomers1
مثال 2 : این مثال نحوه ایجاد یک فیلد از نوع Identity به همراه مقدار شروع و گام افزایش را مشخص میکند.
USE tempdb
GO
CREATETABLECustomers2
(
ID INTIDENTITY(100,2),
NameNVARCHAR(100),
[Address] NVARCHAR(200)
)
GO
همانطور
که در مثال 2 مشاهده میکنید فیلد ID از نوع Identity تعریف شده است و
مقدار شروع آن از 100 و همچنین گام افزایش 2 در نظر گرفته شده است. در این
صورت اگر چند رکورد زیر را به ازای این جدول درج کنید. مقدار Identity به
صورت زیر خواهد بود.
INSERTINTOCustomers2 (Name,[Address]) VALUES
(N'مسعود',N'میانه'),
(N'فرید',N'میانه'),
(N'احمد',N'میانه')
GO
SELECT* FROMCustomers2
مثال 3 : این مثال نحوه تنظیم یک فیلد به صورت Identity را در محیط SQL Server Management Studio (SSMS) آموزش میدهد.
1- برای شروع کار همانند تصویر زیر بر روی قسمت Table کلیک راست کنید و گزینه New Table… را انتخاب کنید.
2-
پس از نمایش پنجره زیر فیلدی را که میخواهید از نوع Identity باشد را
انتخاب کرده و در قسمت Column Properties خصیصه Is Identity را برابر Yes
قرار دهید تا فیلد مورد نظر شما از نوع Identity در نظر گرفته شود. لازم به
ذکر است که Identity Seed مقدار شروع و Identity Increment گام افزایش را
مشخص مینماید.
احتمالا تاکنون هنگام Restore نمودن یک پایگاه داده با خطای زیر مواجه شده اید.
Msg 3101, Level 16, State 1, Line 1
Exclusive access could not be obtained because the database is in use.
Msg 3013, Level 16, State 1, Line 1
RESTORE DATABASE is terminating abnormally.
البته
مشکل فوق زمانی پیش خواهد آمد که پایگاه داده توسط شخص یا برنامه ای در
حال استفاده باشد و تا زمانی که این اتصالات وجود داشته باشند امکان
Restore نمودن پایگاه داده وجود ندارد.
معمولا در این هنگام با
Restart نمودن سرور برنامه SQL Server مشکل خاتمه می یابد و پس از آن به
راحتی می توان پایگاده داده را Restore نمود. اما این عمل گاهی به سادگی
امکان پذیر نیست و یا مشکلات دیگری را در پی خواهد داشت.
Restart
نمودن سرور برنامه SQL Server باعث می شود که برای مدتی (در حین راه اندازی
مجدد سرور) تمام پایگاه های داده موجود در این سرور از کار بیفتند و بدیهی
می باشد که این مسئله می تواند مشکلاتی را برای سایر پایگاه های داده به
وجود آورد. و ضمنا با توجه به تعداد پایگاه های داده و سایر عوامل، عمل راه
اندازی مجدد سرور می تواند زمانبر باشد.
راه حل:
با استفاده از اسکریپت زیر می توان تمام اتصالات زنده ی موجود به یک پایگاه داده خاص را از بین برد.
Use Master
Go
Declare@dbnamesysname
Set@dbname = 'databaseName'
Declare@spidint Select@spid = min(spid) from master.dbo.sysprocesses where dbid = db_id(@dbname) While@spidIsNotNull Begin Execute ('Kill ' + @spid) Select@spid = min(spid) from master.dbo.sysprocesses where dbid = db_id(@dbname) and spid > @spid End
پشتیبان گیری از حیث حالت
انجام در دوسته خودكار و دستی و از حیث نوع پشتیبان گیری به دو حالت عادی
(Full-Normal) و حالت تفاضلی (Differential) تقسیم می شوند.
بطور
معمول برای پشتیبان گیری، ابتدا یكبار به صورت عادی از دیتابیس مورد نظر
پشتیبان تهیه می شود و سپس با توجه به استراتژی و زمان بندی بصورت تفاضلی
از دیتابیش فایل های پشتیبان متعدد گرفته می شود.
در حالت دستی بعد
از تعیین پارامتر های مربوط به اجرای فعالیت در همان لحظه ، به صورت عادی
(Full-Normal) و حالت تفاضلی (Differential) (بسته به نوع انتخاب) پشتیبان
گیری انجام می شود.
درحالت خودكار كه در واقع حالت Maintenance Plan
می باشد ، امكان ایجاد یك برنامه با زمان بندی مشخص برای پشتیبان گیری از
دیتابیس مورد نظر وجود دارد.
پشتيبانگيري در حالت دستی (Manual)
با كلیك روی SQL Server Management Studio و وارد كردن نام سرور و اطلاعات كاربری وارد محیط SQL می شویم.
از
لیست پوشه های قابل مشاهده روی علامت + Databases كلیك كرده و سپس روی
پایگاه داده مورد نظرمان ( در اینجا پوشه dbrates ) كلیك راست كرده و مطابق
شكل ابتدا روی گزینه Task وسپس گزینه Backup می رویم.
با كلیك روی گزینه Backup پنجره مربوط به آن باز می شود.
مطابق
شكل بالا در قسمت Select a Page دو گزینه General و Options برای پیكره
بندی كلی فرآیند پشتیبانی وجود دارد. با انتخاب گزینه General مطابق شكل
بالا، امكان انتخاب دیتابیس برای پشتیبان گیری، نوع پشتیبان، نام گذاری
فایل و تعریف انقضا و مقصد ذخیره فایل وجود دارد که در ادامه بطور كامل
توضیح داده خواهد شد.
مطابق شكل در زیر عبارت Source
در گزینه Database پایگاه داده مورد نظر ( در اینجا dbrates ) را انتخاب می كنیم.
در گزینه Recovery Model حالت Simple را انتخاب می كنیم.
در
گزینه Backup Type بسته به نوع پشتیبان، در حالت Full یا Differential
قرار میدهیم. حالت Full به منزله پشتیبان گیری كامل از دیتابیس، و حالت
Differential به منزله پشتیبان گیری از تغییرات و دادههای اضافه شده به
دیتابیس موجود است.
در گزینه Backup Component گزینه Database را انتخاب می كنیم.
مطابق شكل در زیر عبارت Backup set موارد زیر قابل انجام است.
در
گزینه Name امكان درج نامی برای این پشتیبان است كه بطور پیش فرض نامی
برای آن انتخاب شده است ضمن اینكه امكان ویرایش آن وجود دارد.
در
گزینه Backup Set will expire (برای تعیین زمان انقضای دیتابیس پشتیبان شده
) دو انتخاب وجود دارد. تعیین تعداد روز بعد از پشتیبان گیری با انتخاب
گزینه After و درج روز (عدد صفر، مقدار پیش فرض و به معنی عدم انقضای فایل
پشتیبان است) و یا تعیین تاریخ خاص براساس سال میلادی برای انقضای فایل
پشتیبان مورد نظر با انتخاب گزینه On .
در بخش Description اطلاعات فایل پشتیبان با توجه به توضیحات زیر ثبت خواهد شد.
در
گزینه Back up to امكان مشخص كردن محل ذخیره سازی با توجه به انواع آن (
حالت های Disk یا Tape ) وجود دارد. بطور پیش فرض فایل پشتیبان با نام پیش
فرض در مسیر نصب SQL در پوشه Backup و بصورت تك فایل قرار خواهد گرفت.
امكان تغییر این مسیر وجود دارد. می توان فایل پشتیبان را در قالب چند فایل
جدا از هم ولی بهم پیوسته (در هنگام بازگردان نیاز به حضور تمامی فایل ها
است) ایجاد كرد. امكان حذف مسیر پیش فرض فایل پشتیبان (با زدن دکمه Remove )
و سپس اضافه كردن مسیر جدید با زدن كلید Add… و تعیین محل ذخیره فایل
پشتیبان مطابق شكل زیر، با انتخاب مسیر و نوشتن نام پشتیبان در بخش File
name وجود دارد.
مطابق شكل زیر در قسمت Select a Page با انتخاب گزینه Options امكانات پیشرفتهی دیگری فراهم می شود.
با
انتخاب گزینه Options ، امكان انتخاب تعیین حالت قرارگیری فایل های متعدد
پشتیبان و انتخاب خطایابی در هنگام پروسه پشتیبان گیری وجود دارد که در
ادامه بطور كامل توضیح داده خواهد شد.
مطابق شكل بالا در عبارت
Overwrite media گزینه ای برای الحاق Append"" نسخه های پشتیبان در یک فایل
وجود دارد، با انتخاب این گزینه اگر فایل انتخابی شما برای پشتیبان گیری،
پیش از این وجئود داشته باشد، پشتیبان جدید به همان فایل افزوده خواهد شد. (
این ویژگی در مواقعی كه بیش از یك پشتیبان در طول روز از دیتابیس تهیه می
شود كاربرد دارد.) این گزینه بطور پیش فرض فعال است. البته می توان با
انتخاب گزینه Overwrite به جای الحاق به فایل موجود، آنها را حذف و پشتیبان
جدید را جایگزین قبلی نمود.
با فعال كردن گزینه Check Media set ، وجود نسخه پشتیبان قبلی و زمان انقضای آن بررسی خواهد شد.
گزینه
Back up to a new media set, and erase all existing backup sets زمانی
انتخاب می شود كه نیازی به نسخههای پشتیبان قبلی نداشته باشید و میخواهید
تمامی آن ها حذف شوند
مطابق شكل در زیر عبارت Reliability امكان اطمینان از صحت پشتیبان گیری بدون اشكال و خطا وجود دارد.
با
انتخاب گزینه Verify backup when finished پس از اتمام روند پشتیبان گیری،
صحت عملیات و صحت ذخیره شدن نسخه پشتیبان در فایل (مقصد) مورد نظر، بررسی
خواهد شد.
انتخاب گزینه Perform checksum before writing to media
قابلیت بررسی اعتبار بخش های مختلف اطلاعات را به نسخه پشتیبان می افزاید.
این عمل عملیات پشتیبان گیری را سنگین خواهد کرد اما قابلیت نادیده گرفتن
خطا در عملیات یا باز یابی اطلاعات را به دست خواهید آورد. با انتخاب گزینه
Continue on error در صورت وجود خطا در عملیات، می توان با نادیده گرفتن
خطا، به ذخیره سازی دیگر اطلاعات پرداخت.
با فشردن كلید OK عملیات تهیه پشتیبان شروع می شود.
پشتيبانگيري در حالت خودكار (Maintenance Plan)
از
حالت دستی بطور معمول برای پشتیبان گیری عادی (Normal) و حالت كامل Full
استفاده میشود و از پشتیبان گیری خودكار برای گرفتن پشتیبان های متوالی در
طول روز استفاده می شود. همانطور كه قبلا اشاره شد برای این حالت معمولا
از پشتیبان گیری در حالت تفاضلی (Differential) استفاده می شود. در ادامه
به شرح چگونگی انجام و زمان بندی آن می پردازیم.
برای شروع وارد نرم
افزار SQL می شویم و سپس مطابق شكل زیر از پوشه نام سرور پوشه Management و
سپس روی پوشه Maintenance Plan كلیك راست كرده و سپس Wizard Maintenance
Plan را انتخاب می كنیم.
با انتخاب گزینه Wizard Maintenance Plan پنجره زیر ظاهر می شود.
با زدن كلید NEXT به مرحله بعدی می روید.
در
این مرحله نام و توضیح مربوط به عملیات را وارد کرده و میتوانید انتخاب
کنید که اگر قرار است بیش از یک عملیات انجام شود، هر عملیات با جدول
زمانبندی مجزا (Separate schedules for each task ) اجرا شوند. یا تمام
عملیات های انتخابی در یک جدول زمانبندی یکسان یا بدون جدول زمان بندی
(Single schedules for the entire plan or no schedule ) اجرا شوند.
با
زدن كلید NEXT به مرحله بعدی میروید. در این مرحله، عملیات (یا
عملیاتهای) مورد نظر را انتخاب میکنید. در تصویر زیر پشتیبانگیری تفاضلی
از لیست گزینهها انتخاب شده است.
با زدن كلید NEXT به مرحله بعدی می روید.
مطابق شكل زیر عملیات برای پشتبان گیری تفاضلی تایید و آماده انجام است.
با زدن كلید NEXT به مرحله بعدی می روید.
مطابق شكل زیر پنجره مربوط به انتخاب دیتابیس، انقضای دیتابیس، محل و جدول زمان بندی عملیات، قابل تعریف و تغییر است.
از گزینه Database روی كلید كلیك كنید.
مطابق تصویر فوق، از
پنجره باز شده دیتابیس مورد نظر خود را انتخاب كنید و كلید OK را بزنید.
مطابق شكل زیر از این گزینه محل ذخیره فایل ، در مسیر مورد نظر قرار دهید.
این كاراز طریق كلیك روی دكمه . . . انجام می شود.
دقت كنید برای سهولت درهنگام بازگردان محل ذخیره فایلهای الحاقی با مسیر فایل پشتیبان Full (حالت دستی) یكسان باشد. و مورد بعدی كه مطابق شكل زیر باید تعیین شود زمان و دوره پشتیبان گیری است. با
زدن كلید Change پنجره جدیدی باز می شود كه در آن می توان نوع برنامه ریزی
پشتیبان گیری، دفعات ، زمان و تاریخ شروع و اتمام پشتیبان گیری را تنظیم
كرد.
مطابق شكل زیر این گزینه ها را تنظیم میکنیم:
گزینه Schedule type در حالت Recurring (عملیات تکرا شود)
گزینه Occurs در حالت Daily ( نوع رخداد- در اینجا روزانه)
گزینه Recurs در حالت 1 day (تکرار عملیات – در اینجا هر یک روز)
گزینه Occurs every در حالت 6 hours (تکرار عملیات – در اینجا هر 6 ساعت)
گزینه Start date (تاریخ مدنظر برای شروع عملیات) بیاد
داشته باشید كه استراتژی پشتیبان گیری براساس اهمیت و حجم دیتا ذخیره شده
در دیتابیس تعیین می شود. شكل بالا بیان نگر پشتیبان گیری بطور روزانه ، هر
6 ساعت در شبانه روز (4 بار در روز) و با پایان نامحدود برای پشتیبان گیری
است.
با زدن OK به مرحله بعد می رویم.
در این مرحله، مطابق تصویر زیر، امکان تعریف محل و نوع تولید گزارش از روند پشتیبانگیری وجود دارد
گزینه Write areport to a text file گزارشی به صورت فایل نوشتاری قابل ذخیره در دیسك تولید میکند.
گزینه E-mail report امکان ارسال گزارش از طریق ایمیل را فعال خواهد کرد. با زدن Next به پنجره بعدی می رویم . با زدن Finish پشتیبان گیری مطابق تعریف شما در ساعت مقرر شروع می شود. شكل زیر اتمام ذخیره سازی عملیات مورد نظر را كه با موفقیت همراه بوده است را نشان می دهد.
بازگردان فایل پشتیبان (Restore)
با كلیك روی SQL Server Management Studio و وارد كردن نام سرور و اطلاعات كاربری وارد محیط SQL می شویم. از لیست پوشه های قابل مشاهده روی پوشه Databases كلیك راست كرده و سپس روی گزینه Restore Database… كلیك چپ كنید. پنجرهای مطابق تصویر زیر ظاهر می شود. نكته
: هنگام بازگردان یک دیتابیس، نباید دیتابیس مورد نظر (در صورت بودن در
سرور) مورد استفاده قرار گیرد. در غیر اینصورت با خطا مواجهه می شوید.
در این برگه امكان نام گذاری دیتابیس و تعیین زمان بازگردان وجود دارد.
در گزینه To database امكان تعیین نام برای دیتابیس بازگردان وجود دارد. این نام می تواند نام قبلی یا نام جدید باشد. در بخش Source for restore امكان تعیین مبداء بازگردان وجود دارد. در گزینه From database امكان انتخاب بازگردان ها از طریق دیتابیس شناسایی شده (درصورت اطلاع sql سرور از آن) وجود دارد.
در گزینه From device امكان انتخاب فایل/ فایلهای پشتیبان مجزا یا پیوسته (Append) وجود دارد.
با
توجه به محل ذخیره سازی كافی است كلید ... را فشرده و سپس از پنجره باز
شده همانند شكل زیر، كلید Add را بزنید و از پنجره باز شده مسیر و سپس فایل
پشتیبان مورد نظر برای بازگردان را انتخاب كنید. دقت
كنید در صورت الحاق مجموع فایل های پشتیبان (Backup set) در یك فایل در
هنگام بازگردان فایل های الحاق شده مطابق شكل زیر نمایش داده می شود. كافی
است فایل های مورد نظر را مطابق شكل زیر با توجه به زمان و نوع پشتیبان
گیری انتخاب و سپس كلید OK را بزنید تا عملیات بازگردان صورت پذیرد. در برگه Options گزينههايي برای بازگردان فایل های پشتیبان در نظر گرفته شده است. در بخش Restore options امكانات بازگردان و محل قرارگرفتن آنها تعریف میشود. با فعال كردن گزینه Overwrite the existing database فایل بازگردان روی دیتابیس هم نام (در صورت وجود) بازنویسی میشود.
با
فعال كردن گزینه Preserve the Replication settings عملیات شما، تنظیمات
مربوط به چندگانگی دیتابیس (وجود چند سرور مشابه که اطلاعات یکدیگر را با
شبیه سازی تغییرات، یکسان میکنند) ، را تغییر نخواهد داد.
با فعال كردن گزینه Prompt before restoring each backup قبل بازگردان هر فایل پشتیبان موضوع را اعلام میكند.
با فعال كردن گزینه Restrict access to the restored database بعد از بازگردان، امكان دسترسی به دیتابیس را محدود خواهد کرد.
با زدن كلید ... امكان انتخاب محل فایلهای دیتابیس، پس از بازگشت اطلاعات روی آن كه بطور معمول در مسیر زیر است، وجود دارد.
در بخش Recovery state اختیارات فعالیت دیتابیس بعد از بازگردان وجود دارد. گزینه
Leave the database ready … ( بطور پیش فرض فعال است) دیتابیس را به محض
بازگردان عملیاتی و قابل استفاده میكند. در صورتی که ملیاتی به صورت ناقص
در دیتابیس وجود داشته باشد، عملیات ناقص نادیده گرفته خواهد شد.
گزینه
Leave the database non-operational … در صورت فعال بودن، دیتابیس باز
میگردد ولی در صورت وجود تراكنش اعمال نشده، آن را roll back نمیكند.
گزینه
Leave the database read-only … در صورت فعال بودن، دیتابیس بصورت فقط
خواندنی می ماند و تراكنش ها در فایل دیگری جداگانه ذخیره می شوند
Store Procedure همون طور
که از نامش پیداست یعنی روال های ذخیره شده پرس و جو های
که از دیتا بیس می گیریم رو ما می تونیم به صورت StoreProcedure
بنویسیم، حالا چرا این کار رو می کنیم؟
1-اولا سرعت اجرا پرس و جو ها بالا میره
2-امنیت اجرای پرس و جو ها نیز بالا میره و از حملات SQL جلوگیری می
کنه
3-برنامه نویسی ماژولار(یا لایه ای بگیم بهتره)میشه و فهم برنامه و
دستورات آسون میشه
4-...
خوب یه مثال از Store Procedure بزنم:
فرض کنید جدول MyUser
رو با فیلد های زیر رو دارین:
Id:int
Name:Nvarchar(50)
خوب اینم یه Store
Procedure نوشته شده:
CreateProcedureGetUser@id
int
as
SelectMyUser.NamefromMyUserwhereMyUser.Id=@id
اما می مونه Trigger:
Trigger ها مانند Store Procedure ها هستند اما برای کارهای دیگه ای
استفاده میشن!
در واقع بیشتر برای کار های امنیتی و حمایتی استفاده میشه. (چه جمله ای
گفتم!)
مثلا اگه بخواهیم برای جلوگیری از Updateشدن یک جدول یک Trigger
بنویسیم باید به این صورت عمل کنیم:
CreateTriggerStopUpdates
on
MyUser
After
Update
AS
Begin
rollback
End
حالا هر وقت با بروز شدن
جدول MyUser با پیغام اینکه Trigger نوشته شده مانع بروز رسانی این
جدول می شود مواجه می شویم و از بروز شدن جدول جلوگیری می کند
اینم یه خلاصه ای از Store Prcedure ها و Trigger ها
DECLARE @Random INT; DECLARE @Upper INT; DECLARE @Lower INT ---- This will create a random number between 1 and 1000 SET @Lower = 1 ---- The lowest random number SET @Upper = 1000 ---- The highest random number SELECT @Random = ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0) SELECT @Random