آموزش SQL Server
نوشتن Stored Procedure با پارامتر ورودی و خروجی
Create Procedure MYSP (@Input nvarchar(100),@Selector int, @Output sql_variant Output)
As
Begin
If @Selector = 1
Begin
Set @Output = (Select Substring(@Input, 1, Charindex(‘ ‘,@Input)))
End
Else If @Selector = 2
Begin
Set @Output = (Select Substring(@Input, Charindex(‘ ‘,@Input)+1,Len(@Input)))
End
End
نحوه فراخوانی Stored Procedure
Declare @Output sql_variant
Exec MYSP @Input=’10 Kg’, @Selector=1, @Output=@Output Output
Select @Output
انتخاب سطر iام از یک جدول بدون استفاده از دستور Where
در مثال بررسی شده میخواهیم سطر سوم جدول زیر را بدون استفاده از دستور Where استخراج کنیم.
Family | |
Esmaeili | |
Rostami | |
Amiri |
برای انجام این کار از سورس کد زیر استفاده میکنیم:
Select * From Table_Test Order By First_Name
Offset 2 ROWS
Fetch Next 1 Rows Only
در واقع در اینجا، سطر بعد از سطر دوم را انتخاب مینماییم.
تابع Stuff
از تابع Stuff، برای حذف یک زیر رشته که شروع آن با Start و طول آن با Length مشخص میشود از رشتهی String استفاده میگردد. پس از حذف زیر رشته مشخص شده از رشتهی String، مقدار جدید رشته String در NewString قرار داده میشود. در زیر نحوه استفاده از این تابع آورده شده است.
Stuff(String,Start,Length,NewString)
توابع Table-Valued در SQL Server
توابع Table-Valued، توابعی هستند که خروجی آنها یک جدول میباشد. در زیر این توابع را با یک مثال مورد بررسی قرار میدهیم. در مثال زیر تابع Table-Valued را مینویسم که یک رشته از اعداد را که با کاما از یکدیگر جدا شدهاند را به عنوان ورودی گرفته و سپس هر یک از این اعداد جدا شده توسط کاما را در یک سطر از جدول قرار داده و در نهایت این جدول را به عنوان خروجی بر میگرداند.
Create Function Split_Comma_String (@Input_String varchar(100),@Delimeter varchar(1))
Returns @Out_Table Table(Number varchar(100))
As
Begin
Declare @Number varchar(100)
Declare @New_Input_String varchar(100)
While len(@Input_String)> 0 and charindex(@Delimeter,@Input_String)<>0
Begin
Set @Number = (substring(@Input_String,1,charindex(@Delimeter,@Input_String)-1))
Insert Into @Out_Table(Number) Values (@Number)
Set @Input_String = (select Stuff (@Input_String , 1 , charindex(@Delimeter,@Input_String) ,@New_Input_String ))
End
Insert Into @Out_Table(Number) Values (@Input_String)
Return
End
نحوه فراخوانی این تابع به صورت زیر میباشد:
Select * From Split_Comma_String(‘0,25,101,1200,101010’, ‘,’)
تابع Concat
از تابع Concat برای اتصال دو رشته به یکدیگر به صورت زیر استفاده میگردد:
Select Concat(First_Name,N’ ‘,Last_Name) As ‘Full Name’ From Table_Test
توابع Date
در زیر مثالهایی از کار با توابع مربوط به تاریخ آورده شده است:
Declare @Current_Date Date
Set @Current_Date = Getdate()
Select @Current_Date
Select Datepart(YYYY,@Current_Date)
Select Datepart(MM,@Current_Date)
Select Datepart(DD,@Current_Date)
Select Datepart(Dayofyear,@Current_Date)
Select Datepart(WW,@Current_Date)
Select Datediff(Day,’1398/06/01′,’1399/07/30′)
Select Datediff(MONTH,’1398/06/01′,’1399/07/30′)
Select Datediff(YEAR,’1398/06/01′,’1399/07/30′)
Select DateAdd(YEAR,1,’2020/06/01′)
Select DateAdd(MONTH,-3,’2020/06/01′)
دستور Case در SQL Server
Select First_Name,Last_Name,Mobile,
Case Sex
When 1 Then ‘Male’
When 0 Then ‘Female’
End
From Table_Test
در اینجا با استفاده از دستور Case مشخص میکنیم در صورتی که مقدار فیلد Sex جدول Table_Test برابر ۱ باشد به جای آن عبارت Male و در صورتی که مقدار آن ۰ باشد به جای آن عبارت Female چاپ گردد.
تعریف و استفاده از جداول موقت در SQL Server
Select Last_Name, Mobile Into #Temp_Table
From Table_Test
Where Mobile = ‘09122122222’
Go
Select * From #Temp_Table
در مثال بالا یک جدول موقت به نام Temp_Table ایجاد گردیده و سپس دادههای مربوط به دو ستون Last_Name و Mobile از جدول Table_Test در آن ریخته شده است.
بررسی وجود داشتن یک جدول موقت در SQL Server و حذف آن در صورت وجود داشتن
IF OBJECT_ID(‘tempdb..#Temp_Table’) IS NOT NULL
BEGIN
DROP TABLE #Temp_Table
END
در مثال بالا بررسی کردیم که در صورتی که جدول موقت Temp_Table در SQL Server وجود داشته باشد، جدول موقت Temp_Table حذف گردد.
توجه : جداول موقت در SQL Server در مسیر Databases\System Databases\tempdb\Temporary Tables ذخیره میگردند.
اشارهگرهای تودرتو (Nested Cursor) در SQL Server
در پرس و جوی (Query) زیر، دو جدول Product_Information و Product_Price به ترتیب حاوی اطلاعات محصولات تولید شده و آخرین قیمتهای اصلاح شده محصولات یک شرکت میباشند.
create table Product_Information
)
,product_code bigint not null
,product_name nvarchar(50) null
,product_price bigint null
,price_status nvarchar(50) null
primary key (product_code)
(
create table Product_Price
)
,product_code bigint not null
,product_price bigint null
primary key (product_code)
(
در این پرس و جوی (Query)، در صورتی که قیمت یک محصول در جدول Product_Information با توجه به اطلاعات جدول Product_Price، کاهش پیدا کرده باشد، قیمت آن محصول در جدول Product_Information، بهروزرسانی میشود و در صورتی که قیمت یک محصول با توجه به اطلاعات جدول Product_Price، افزایش پیدا کرده باشد، افزایش قیمت نادیده گرفته شده و قیمت آن محصول در جدول Product_Information بهروزرسانی نمیگردد. در اینجا در هر حالت فیلد Price_Status جدول Product_Information با توجه به وضعیت پیش آمده با مقادیر Decreased، Increased و Not Changed بهروزرسانی میگردد.
declare @cpp_product_code bigint
declare @cpp_product_price nvarchar(50)
declare @cpi_product_code bigint
declare @cpi_product_name nvarchar(50)
declare @cpi_product_price nvarchar(50)
declare @cpi_price_status nvarchar(50)
declare my_cursor_1 cursor for select product_code, product_price from Product_Price
open my_cursor_1
fetch next from my_cursor_1 into @cpp_product_code, @cpp_product_price
WHILE @@FETCH_STATUS = 0
begin
declare my_cursor_2 cursor for select product_code, product_name, product_price, price_status from Product_Information
open my_cursor_2
fetch next from my_cursor_2 into @cpi_product_code, @cpi_product_name, @cpi_product_price,@cpi_price_status
WHILE @@FETCH_STATUS = 0
begin
if @cpi_product_code = @cpp_product_code
begin
if @cpp_product_price < @cpi_product_price
begin
update Product_Information set price_status = ‘Decreased’, product_price = @cpp_product_price
where Product_Code = @cpi_product_code
end
else if @cpp_product_price > @cpi_product_price
begin
‘update Product_Information set price_status = ‘Increased
where Product_Code = @cpi_product_code
end
else if @cpp_product_price = @cpi_product_price
begin
‘update Product_Information set price_status = ‘Not Changed
where Product_Code = @cpi_product_code
end
end
fetch next from my_cursor_2 into @cpi_product_code, @cpi_product_name, @cpi_product_price, @cpi_price_status
end
close my_cursor_2
deallocate my_cursor_2
fetch next from my_cursor_1 into @cpp_product_code, @cpp_product_price
end
close my_cursor_1
deallocate my_cursor_1
تریگر (Trigger)
تریگر قطعه کدی میباشد که میتواند بعد از انجام یک عملیات (After Trigger) و یا به جای یک عملیات (Instead of Trigger) اجرا شود و عملیات خاصی را انجام دهد. تریگرها میتوانند بعد یا به جای عملیات Update، Delete و یا Insert انجام شوند. در SQL Server در مجموع شش نوع تریگر وجود دارد که در ادامه به نحوه عملکرد هر کدام از آنها خواهیم پرداخت.
تریگر After Insert
این تریگر بعد از ذخیره یک رکورد در جدول اجرا میشود.
تریگر After Update
این تریگر بعد از ویرایش اطلاعات یک رکورد از جدول اجرا میشود.
تریگر After Delete
این تریگر بعد از حذف یک رکورد از جدول اجرا میشود.
تریگر Instead of Insert
وقتی میخواهیم یک رکورد را در جدول ذخیره نماییم، این تریگر به جای دستور Insert اجرا میشود.
تریگر Instead of Delete
وقتی میخواهیم یک رکورد را از جدول حذف نماییم، این تریگر به جای دستور Delete اجرا میشود.
تریگر Instead of Update
وقتی میخواهیم یک رکورد را ویرایش نماییم، این تریگر به جای دستور Update اجرا میشود.
در مثال زیر یک تریگر After Insert بر روی جدول data_table تعریف شده است. این تریگر شماره سطر درج شده در جدول data_table را به همراه تاریخ و ساعت درج آن را در جدولی به نامه log_table ذخیره میکند.
create table data_table
)
,id bigint null
,fullname nvarchar(50) null
phone nvarchar(50) null
(
create table log_table
)
,id bigint null
modify_date_time datetime null
(
create trigger my_trigger_insert on data_table
after insert
as begin
insert into log_table (id, modify_date_time) values ((select max(id) from data_table),GETDATE())
end
در اینجا، تریگر ایجاد شده، از قسمت Object Explorer و از زیر شاخه جدولی که تریگر بر روی آن تعریف شده قابل دسترس میباشد.
حلقه While
در مثال زیر با استفاده از حلفه while اعداد فرد بین ۱ تا ۱۰ در خروجی چاپ میشوند.
declare @i int
set @i = 1
while @i < 10
begin
if @i % 2 = 0
begin
set @i = @i + 1
continue
end
print @i
set @i = @i + 1
end
تابع COALESCE
این تابع چند مقدار را از ورودی گرفته و اولین مقدار غیر NULL را بر میگرداند. جدول phone_information با اطلاعات زیر را در نظر بگیرید. همانطور که مشخص است برای هر کاربر سه فیلد شماره تلفن با نامهای phone 2، phone 1 و phone 3 موجود است. که تنها یک فیلد برای هر کاربر با اطلاعات صحیح پر شده و دو فیلد دیگر دارای مقدار NULL هستند.
create table phone_information
)
,fullname nvarchar(50) null
,phone_01 nvarchar(50) null
,phone_02 nvarchar(50) null
phone_03 nvarchar(50) null
(
Fullname | Phone 3 | Phone 2 | Phone 1 | |
Sobhan Esmaeili | NULL | NULL | ۰۹۱۲۲۱۲۳۲۰۳ | |
Mehdi Karimi | NULL | ۰۹۱۲۴۵۱۲۴۲۰ | NULL | |
Amin Amiri | ۰۹۱۲۴۴۵۳۱۷۵ | NULL | NULL | |
Sara Karami | NULL | ۰۹۱۲۷۷۵۱۴۵۲ | NULL |
در مثال زیر، پرس و جوی نوشته شده با وجود اینکه مشخص نیست کدام فیلد شماره تلفن دارای مقدار غیر NULL است،برای هر کاربر یک شماره تلفن با مقدار غیر NULL را بر میگرداند و نمایش میدهد.
select fullname as ‘Fullname’, COALESCE(phone_01,phone_02,phone_03) as ‘Mobile’ from phone_information
Fullname | Mobile | |||
Sobhan Esmaeili | ۰۹۱۲۲۱۲۳۲۰۳ | |||
Mehdi Karimi | ۰۹۱۲۴۵۱۲۴۲۰ | |||
Amin Amiri | ۰۹۱۲۴۴۵۳۱۷۵ | |||
Sara Karami | ۰۹۱۲۷۷۵۱۴۵۲ |
تابع ISNULL
این تابع مقدار ورودی اول را بررسی میکند و اگر مقدار آن برابر NULL باشد، آن را با مقدار ورودی دوم جایگزین میکند. در غیر این صورت مقدار ورودی اول را بر میگرداند.
create table product_table
)
,product_name nvarchar(50) null
Product_Price bigint null
(
product_name | Product_price | |||
P1 | ۱۰۰ | |||
P2 | NULL | |||
P3 | NULL | |||
P4 | ۸۰ |
select product_name, isnull(Product_Price, 0)
from product_table
product_name | Product_price | |||
P1 | ۱۰۰ | |||
P2 | ۰ | |||
P3 | ۰ | |||
P4 | ۸۰ |