SQL SERVER 2008

تجارب من در رابطه با SQL SERVER

وابستگی های اشیا در SQL Server 2008
ساعت ٢:٠٠ ‎ب.ظ روز ۱۳۸٧/۱٢/٢٧  کلمات کلیدی: sql server 2008 ، dependency ، clr ، schema-bound

SQL Server 2008 چندین آبجکت ارائه داده که اکتشاف وابستگیهای آبجکتها را به صورت قابل اطمینانی فراهم میکند، و جایگزین view قدیمی وغیرقابل اطمینان sys.sql_dependencies وهمچنین stored procedure قدیمی sp_depends شده است. آبجکتهای جدید اطلاعاتی درباره وابستگیها فراهم کرده که در یک کد ثابت ظاهر میشود، آنها شامل هر دوی آبجکتهای schema-bound  و non-schema-bound و نیز cross-database و حتی وابستگیهای cross-server میشوند. آبجکتهای جدید وابستگیهایی را که در کد SQL یا کد CLR به وجود بیایند را پوشش نمیدهند.
برای اینکه ببینید چگونه اطلاعات مربوط به وابستگیها را جستجو کنید، ابتدا کد زیر را اجرا کنید تا چند آبجکت در پایگاه داده tempdb برای تست ساخته شود :


USE tempdb;
IF OBJECT_ID('dbo.Proc1', 'P') IS NOT NULL DROP PROC dbo.Proc1;
IF OBJECT_ID('dbo.V1', 'V') IS NOT NULL DROP VIEW dbo.V1;
IF OBJECT_ID('dbo.V2', 'V') IS NOT NULL DROP VIEW dbo.V2;
IF OBJECT_ID('dbo.T1', 'U') IS NOT NULL DROP TABLE dbo.T1;
IF OBJECT_ID('dbo.T2', 'U') IS NOT NULL DROP TABLE dbo.T2;
GO
 
CREATE PROC dbo.Proc1
AS
SELECT * FROM dbo.T1;
EXEC('SELECT * FROM dbo.T2');
GO
CREATE TABLE dbo.T1(col1 INT);
CREATE TABLE dbo.T2(col2 INT);
GO
CREATE VIEW dbo.V1
AS
SELECT col1 FROM dbo.T1;
GO
CREATE VIEW dbo.V2
AS
SELECT col1 FROM dbo.T1;
GO


SQL Server 2008 سه آبجکت جدید را معرفی کرده که اطلاعاتی درباره وابستگی آبجکت به ما میدهد : catalog view با نام sys.sql_expression_dependencies ، و توابع مدیریت پویا (DMF) با نامهای sys.dm_sql_referenced_entities و sys.dm_sql_referencing_entities .
View اول وابستگیهای آبجکت را توسط نام فراهم میکند. این جایگزین view قدیمیتر با نام sys.sql_dependencies شده است. Query زیر در مقابل sys.sql_expression_dependencies تمام وابستگیها در پایگاه داده کنونی را نشان میدهد:


SELECT
  OBJECT_SCHEMA_NAME(referencing_id) AS srcschema,
  OBJECT_NAME(referencing_id) AS srcname,
  referencing_minor_id AS srcminorid,
  referenced_schema_name AS tgtschema,
  referenced_entity_name AS tgtname,
  referenced_minor_id AS tgtminorid
FROM sys.sql_expression_dependencies;


Query بالا خروجی زیر را تولید میکند :


srcschema srcname srcminorid tgtschema tgtname tgtminorid
--------- ------- ---------- --------- ------- ----------
dbo       Proc1   0          dbo       T1      0
dbo       V1      0          dbo       T1      0
dbo       V2      0          dbo       T1      0

توجه کنید که query تمام وابستگیها در کد ثابت  را شناسایی میکند نه وابستگیها در کد پویا را (ارتباط از dbo.T2 به dbo.Proc1).
DMF با نام sys.dm_sql_referenced_entities تمام entity هایی که entity ورودی به آن مراجعه میکند را مهیا میکند – به عبارت دیگر، تمام entity هایی که entity ورودی به آن وابسته است. به عنوان مثال، کد زیر تمام entity هایی که dbo.Proc1 به آن وابسته است را برمیگرداند :


SELECT
  referenced_schema_name AS objschema,
  referenced_entity_name AS objname,
  referenced_minor_name  AS minorname,
  referenced_class_desc  AS class
FROM sys.dm_sql_referenced_entities('dbo.Proc1', 'OBJECT');


این کد خروجی زیر را برمیگرداند :


objschema objname   minorname class
--------- --------- --------- ----------------
dbo       T1        NULL      OBJECT_OR_COLUMN
dbo       T1        col1      OBJECT_OR_COLUMN


خروجی نشان میدهد که dbo.Proc1 به جدول dbo.T1 و ستون dbo.T1.col1 وابسته است. مجددا بیان میکنم که وابستگیهایی که در کد پویا نشان داده میشود، شناسایی نمیشود.
DMF با نام sys.dm_sql_referencing_entities تمام entity هایی که به entity ورودی ارجاع داده اند را فراهم میکند – به عبارت دیگر، تمام entity هایی که به entity ورودی وابسته هستند. برای مثال،کد زیر تمام entity هایی را که dbo.T1 وابسته هستند را بر میگرداند:


SELECT
  referencing_schema_name AS objschema,
  referencing_entity_name AS objname,
  referencing_class_desc  AS class
FROM sys.dm_sql_referencing_entities('dbo.T1', 'OBJECT');

این کد خروجی زیر را بازمیگرداند :


objschema objname   class
--------- --------- ----------------
dbo       Proc1     OBJECT_OR_COLUMN
dbo       V1        OBJECT_OR_COLUMN
dbo       V2        OBJECT_OR_COLUMN


خروجی نشان میدهد که dbo.Proc1 و dbo.V1 و dbo.V2 به dbo.T1 وابسته اند.


 
بهبودهای SQL و CLR
ساعت ٥:٤٤ ‎ب.ظ روز ۱۳۸٧/۱٢/۱٢  کلمات کلیدی: tvf ، clr ، sql server 2008 ، table-valued

بهبود در توابع Table-Valued


در حال حاضر CLR TVF ها یک عبارت ORDER جدید را به عنوان بخشی از عبارت CREATE FUNCTION DDL پشتیبانی میکنند. شما میتوانید از این عبارت برای مشخص کردن نام ستونها در جدول خروجی زمانیکه میدانید که سطرها همیشه با آن ترتیب برگردانده خواهند شد، استفاده نمایید.  این میتواند بهینه ساز را زمانیکه روی تابع جدول query میزنید و به ستونهای آن برای مرتب سازی (Ordering)  استناد میکنید کمک نماید.( مانند زمانیکه برای ORDER BY و GROUP BY  و DISTINCT استفاده میشود.)
به عنوان مثال، کد C# زیر یک تابع با نام fn_split  که لیستی مجزا از مقادیر و یک Seprator را میپذیرد و سپس رشته ورودی را به عناصر مجزا میشکند. تابع یک جدول با دو ستون (pos و element) با یک ردیف برای هر عنصر به عنوان نتیجه باز میگرداند. Pos موقعیت عنصر در لیست را نشان میدهد و ستون element خود عنصر را نمایش میدهد :


using System;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Collections;
using System.Collections.Generic;
 
public partial class TVF
{
    // Struct used in string split functions
    struct row_item
    {
        public string item;
        public int pos;
    }
 
    // Split array of strings and return a table
    // FillRowMethodName = "ArrSplitFillRow"
    [SqlFunction(FillRowMethodName = "ArrSplitFillRow",
     DataAccess = DataAccessKind.None,
     TableDefinition = "pos INT, element NVARCHAR(MAX)")]
    public static IEnumerable fn_split(SqlString inpStr,
        SqlString charSeparator)
    {
        string locStr;
        string[] splitStr;
        char[] locSeparator = new char[1];
        locSeparator[0] = (char)charSeparator.Value[0];
        if (inpStr.IsNull)
            locStr = "";
        else
            locStr = inpStr.Value;
        splitStr = locStr.Split(locSeparator,
              StringSplitOptions.RemoveEmptyEntries);
        //locStr.Split(charSeparator.ToString()[0]);
        List<row_item> SplitString = new List<row_item>();
        int i = 1;
        foreach (string s in splitStr)
        {
            row_item r = new row_item();
            r.item = s;
            r.pos = i;
            SplitString.Add(r);
            ++i;
        }
        return SplitString;
    }
 
    public static void ArrSplitFillRow(
      Object obj, out int pos, out string item)
    {
        pos = ((row_item)obj).pos;
        item = ((row_item)obj).item;
    }
}

تابع اغلب سطرها را مرتب شده بر اساس pos برمیگرداند. اگرچه شما نمیتوانید به این ترتیب تا زمانیکه در query خارجی و در ORDER BY ترتیب را مشخص نکرده باشید، اعتماد کنید.
فرض کنید که مسیر فایل dll برابر باشد با : C:\TVF\TVF\bin\Debug\TVF.dll . کد زیر اسمبلی مربوطه را در tempdb  برای تست میسازد:


USE tempdb;
CREATE ASSEMBLY TVF FROM 'C:\TVF\TVF\bin\Debug\TVF.dll';


کد زیر دو تابع بر اساس تابع fn_split CLR  ثبت میکند : تابع  fn_split_no_order عبارت ORDER ندارد و fn_split_order_by_pos عبارت ORDER را برای مرتب سازی بر اساس pos مشخص کرده است :


CREATE FUNCTION dbo.fn_split_no_order
  (@string AS NVARCHAR(MAX), @separator AS NCHAR(1))
RETURNS TABLE(pos INT, element NVARCHAR(4000))
EXTERNAL NAME TVF.TVF.fn_split;
GO
CREATE FUNCTION dbo.fn_split_order_by_pos
  (@string AS NVARCHAR(MAX), @separator AS NCHAR(1))
RETURNS TABLE(pos INT, element NVARCHAR(4000))
ORDER (pos)
EXTERNAL NAME TVF.TVF.fn_split;
GO


حال به query های زیر توجه نمایید:


SELECT *
FROM dbo.fn_split_no_order(
  N'a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z',
  N',') AS T
ORDER BY pos;

SELECT *
FROM dbo.fn_split_order_by_pos(
  N'a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z',
  N',') AS T
ORDER BY pos;


اولی تابع جدولی را که بدون عبارت ORDER ثبت شده را جستجو میکند و دومی این کار را روی تابع جدولی که با ORDER ثبت شده (pos) را جستجو میکند.هر دو داده ها را مرتب شده بر اساس pos درخواست میکنند.اگر شما هر دو را برای آزمایش اجرا کنید خواهید دید که اولی شامل اطلاعات sort شده است اما دومی اینطور نیست. همچنین هزینه برای ارزیابی کردن اولی حدود 10 برابر بیشتر از دومی است.


 
بهبود های SQL و CLR
ساعت ۳:٤۱ ‎ب.ظ روز ۱۳۸٧/۱٢/٥  کلمات کلیدی: sql server 2008 ، clr ، tvf ، uda

پشتیبانی CLR (Common Language Runtime) در SQL SERVER 2008 در روشهای مختلف بهبود یافته است. بهبودهای UDT ها که در قبل توضیح داده شد. این بخش بهبودهای UDA ها (user defined aggregates) و TVF ها (table valued function) را بیان میکند.

بهبود در UDA

پشتیبانی از UDT های بزرگ در مطالب قبلی بیان شد. به همین نحو SQL Server 2008 از UDA های بزرگ نیز پشتیبانی میکند. اندازه ماکزیمم در این نسخه از 8000 بایت تجاوز کرده و میتواند تا 2 گیگابایت افزایش یابد. برای اجازه دادن به یک UDA برای تجاوز از 8000 بایت، ویژگی MaxByteSize را برابر 1- قرار دهید. در غیر این صورت شما باید یک مقدار کهکمتر یا مساوی 8000 است را معین کنید، که در این مورد دیگر سایز UDA شما نباید از مقدار مشخص شده تجاوز کند.

UDA ها در راه دیگری نیز به همین خوبی بهبود یافته اند.آنها هم اکنون از چندین ورودی پشتیبانی میکنند.یک مثال از UDA ای که میتواند از هر دو بهبود بهره ببرد موارد مربوط به الحاق رشته هاست. UDA میتواند دو پارامتر ورودی قبول کند: ستون رشته را برای الحاق و کاراکتری را که به عنوان separator استفاده میشود نگهداری میکند. UDA میتواند خروجی را با حجم یش از 8000 را برگرداند.

 

ادامه دارد ....