ورود

View Full Version : سوال: درج تاریخ بدون تداخل



akbar_online
یک شنبه 15 شهریور 1388, 16:54 عصر
تو تا فیلد داریم که مثلا یکیش تاریخ ورود ودیگری تاریخ خروج حالا می خوام تاریخ هایی راکه درج می کنم تداخل نداشته باشه یعنی مثلا اگر تاریخ ورود 1388/06/01 و تاریخ خروج 1388/06/05
باشد تاریخ های دیگر که درج می شود نباید بین این دو تاریخ باشد یعنی تاریخ 1388/06/03 نباید
درج بشود.و به همین صورت

محمد سلیم آبادی
یک شنبه 15 شهریور 1388, 17:33 عصر
جزئیات مساله را بیان نکردید ولی اگر مشکلتان را دقیقا می خواهید حل کنید باید با جزئیات کامل (تاپیک پیوست شده تالار را مشاهده کنید) مساله را بیان کنید.

مجموعه ی زیر را فرض کنید،



-- A={(1,3),(4,5),(9,11),(18,30)}
-- (6,8) True
-- (11,17) False
-- (6,12) False





declare @gap table (start int, [end] int)

insert into @gap
select 1,3 union all
select 4,5 union all
select 9,11 union all
select 18, 30

select * from @gap

insert into @gap
select *
from
(
select start=6, [end]=8 union all
select 11, 17 union all
select 6, 12
)d
where not exists (select * from @gap g
where (d.start between g.start and g.[end]) or
(d.[end] between g.start and g.[end]) or
g.start between d.start and d.[end] or
g.[end] between d.start and d.[end])

select * from @gap





/*
start end
----------- -----------
1 3
4 5
9 11
18 30

start end
----------- -----------
1 3
4 5
9 11
18 30
6 8

*/

akbar_online
یک شنبه 15 شهریور 1388, 18:54 عصر
اینو بری رزرو کردن اتاق های هتل می خوام با توجه به عکس تاریخ نفر بعدی تداخل داره با نفر اول
چون نباید بین 16 تا 22 برای این اتاق رزروی صورت بگیرد ممنون می شم سریع جواب بدین اگر کدی نوشتین یک مقدار هم توضیح بدین
با تشکر

محمد سلیم آبادی
یک شنبه 15 شهریور 1388, 19:10 عصر
شما می توانید از query که در پست دوم ارسال کردم استفاده کنید! کافی نام ستون ها و جدول را جابجا کنید.در ضمن اگر می خواهید سیستم به طور خود کار این چگ کردن را انجام دهد باید از instead of insert trigger استفاده کنید

اگر واقعا نمی توانید از مثالی که زدم استفاده کنید، بعد افطار در خدمت هستیم :)

akbar_online
یک شنبه 15 شهریور 1388, 19:35 عصر
شما می توانید از query که در پست دوم ارسال کردم استفاده کنید! کافی نام ستون ها و جدول را جابجا کنید.در ضمن اگر می خواهید سیستم به طور خود کار این چگ کردن را انجام دهد باید از instead of insert trigger استفاده کنید

اگر واقعا نمی توانید از مثالی که زدم استفاده کنید، بعد افطار در خدمت هستیم :)
اگر ممکن توضیحی درمورد کدتون بدید

محمد سلیم آبادی
یک شنبه 15 شهریور 1388, 20:42 عصر
اینو بری رزرو کردن اتاق های هتل می خوام با توجه به عکس تاریخ نفر بعدی تداخل داره با نفر اول
چون نباید بین 16 تا 22 برای این اتاق رزروی صورت بگیرد ممنون می شم سریع جواب بدین اگر کدی نوشتین یک مقدار هم توضیح بدین
با تشکر

شما یه چیز می گویید، تصویر ضمیمه شده چیز دیگر!!
فکر کنم نفر بعدی نباید در تاریخ بین 17 تا 22 نتواند رزرو کند. و در واقع اصلا شماره اتاق ها متفاوت است!! شماره ی یکی از اتاق ها 100 است و دیگری 200!!

ابتدا بگویید که تاریخ های مد نظر نباید بین کدام تاریخ ها باشند؟ آیا تاریخ های اتاق های با شماره یکسان؟ (که به نظر می رسد همین طور نیز باشد، فرض کنید یک هتل 10 اتاق دارد در یک زمان همه اتاق ها می توانند رزرو شوند پس تداخل نیز ممکن است بوجود بیاید)

akbar_online
یک شنبه 15 شهریور 1388, 20:47 عصر
شما یه چیز می گویید، تصویر ضمیمه شده چیز دیگر!!
فکر کنم نفر بعدی نباید در تاریخ بین 17 تا 22 نتواند رزرو کند. و در واقع اصلا شماره اتاق ها متفاوت است!! شماره ی یکی از اتاق ها 100 است و دیگری 200!!

ابتدا بگویید که تاریخ های مد نظر نباید بین کدام تاریخ ها باشند؟ آیا تاریخ های اتاق های با شماره یکسان؟ (که به نظر می رسد همین طور نیز باشد، فرض کنید یک هتل 10 اتاق دارد در یک زمان همه اتاق ها می توانند رزرو شوند پس تداخل نیز ممکن است بوجود بیاید)

ببخشید درسته رزرو برای یک اتاق :افسرده:

محمد سلیم آبادی
یک شنبه 15 شهریور 1388, 20:52 عصر
این بررسی را می خواهید به یک رویداد (event) بسپارید یا اینکه در یک SP قبل از درج رکورد بررسی صورت بگیرد؟

آیا ممکن است با یک دستور درج بخواهید چندین سطر را در جدول مورد نظر درج کنید؟ (این سوال را می پرسم برای اینکه در نوشتن trigger تاثیر می گذارد اگر تنها یک سطر باشد ساده است و اگر بیش از یک سطر باشد باید از cursor کمک گرفت)

akbar_online
یک شنبه 15 شهریور 1388, 21:09 عصر
این بررسی را می خواهید به یک رویداد (event) بسپارید یا اینکه در یک SP قبل از درج رکورد بررسی صورت بگیرد؟

آیا ممکن است با یک دستور درج بخواهید چندین سطر را در جدول مورد نظر درج کنید؟ (این سوال را می پرسم برای اینکه در نوشتن trigger تاثیر می گذارد اگر تنها یک سطر باشد ساده است و اگر بیش از یک سطر باشد باید از cursor کمک گرفت)

قبل از اینکه درج صورت بگیرد بررسی کنه که اتاق مورد نظر با تاریخ آن تداخل داره

محمد سلیم آبادی
یک شنبه 15 شهریور 1388, 21:12 عصر
حتما باید قبل از درج صورت بگیرد. ولی این جواب سوال من نبود. به هر حال این کار را به Instead of insert trigger خواهم سپرد در صورتی که به جواب های سوالات زیر نیز دست پیدا کنم:

فرض کنید برای یک اتاق چندین رزرو در جدول با تاریخ های زیر درج شده است:
سطر اول: از تاریخ 2 تا 5
سطر دوم: از 6 تا 8
سطر سوم: از 11 تا 14
حالا آیا سطری با تاریخ از 9 تا 15 می تواند در جدول ذخیره شود؟ این تاریخ در بین تاریخ های سه سطر مورد نظر نیستند ولی بر عکس تاریخ سطر سوم بین تاریخ سطر جدید است.

آیا سطری با تاریخ 8 تا 11 می تواند در جدول ذخیره شود؟ اگر دقت کنید این تاریخ تداخلی با تاریخ های سه سطر مورد نظر ندارد ولی مماس است.
آیا زمان رزرو تنها بر اساس روز است یا ساعت نیز ملاک است؟ به طور مثال رزرو اتاق شماره 2 از ساعت 22 شنبه تا تاریخ 8 صبح دوشنبه.

نسخه ی SQL Server شما چند است؟ 2005/200/2008

meysam_pro
یک شنبه 15 شهریور 1388, 21:19 عصر
این سوال را می پرسم برای اینکه در نوشتن trigger تاثیر می گذارد اگر تنها یک سطر باشد ساده است و اگر بیش از یک سطر باشد باید از cursor کمک گرفت
از کرسر استفاده نکنید، Performance رو بدجوری میاره پایین ، مخصوصا اگه تو تریگر باشه. به مثال زیر نگاه کنید:

-- If an Insert occurred
if Exists(Select Number from Inserted) and not Exists(Select Number from Deleted)
Begin
insert into @tempTable (Name, Number) select Name, Number from Inserted
set @count = (select count(Name) from @tempTable)
while @iterator < @count
Begin
if @count > 1
begin
if(@iterator != @count-1)
begin
set @string = @string + Cast((select Number from @tempTable where rowNumber = @iterator) as nvarchar) + ', '
set @string = @string + Cast((select Name from @tempTable where rowNumber = @iterator) as nvarchar) + ',
'
end
else
begin
set @string = @string + Cast((select Number from @tempTable where rowNumber = @iterator) as nvarchar) + ', '
set @string = @string + Cast((select Name from @tempTable where rowNumber = @iterator) as nvarchar) + ' were Inserted.'
end
end
else
begin
set @string = @string + Cast((select Number from @tempTable where rowNumber = @iterator) as nvarchar) + ', '
set @string = @string + Cast((select Name from @tempTable where rowNumber = @iterator) as nvarchar) + ' was inserted.'
end
set @iterator = @iterator + 1
end

set @Message = @string
end

akbar_online
یک شنبه 15 شهریور 1388, 21:25 عصر
حتما باید قبل از درج صورت بگیرد. ولی این جواب سوال من نبود. به هر حال این کار را به Instead of insert trigger خواهم سپرد در صورتی که به جواب های سوالات زیر نیز دست پیدا کنم:

فرض کنید برای یک اتاق چندین رزرو در جدول با تاریخ های زیر درج شده است:
سطر اول: از تاریخ 2 تا 5
سطر دوم: از 6 تا 8
سطر سوم: از 11 تا 14
حالا آیا سطری با تاریخ از 9 تا 15 می تواند در جدول ذخیره شود؟ این تاریخ در بین تاریخ های سه سطر مورد نظر نیستند ولی بر عکس تاریخ سطر سوم بین تاریخ سطر جدید است.

آیا سطری با تاریخ 8 تا 11 می تواند در جدول ذخیره شود؟ اگر دقت کنید این تاریخ تداخلی با تاریخ های سه سطر مورد نظر ندارد ولی مماس است.
آیا زمان رزرو تنها بر اساس روز است یا ساعت نیز ملاک است؟ به طور مثال رزرو اتاق شماره 2 از ساعت 22 شنبه تا تاریخ 8 صبح دوشنبه.

نسخه ی SQL Server شما چند است؟ 2005/200/2008


جواب سوال اول تاریخ 9 تا 15 نباید درج بشود
جواب سوال دوم تاریخ 8 تا 11 هم نباید درج شود
جواب سوال سوم ساعت زیاد مهم نیست اگر خواستی قرار بده
با تشکر

محمد سلیم آبادی
یک شنبه 15 شهریور 1388, 21:36 عصر
خواسته ی آخر:
لطفا script مربوط به کد جدولتان را پست کنید(ضمیمه کنید) تا trigger ای که برایتان می نویسم دقیق دقیق به عمل آید. برای این منظور از روی جدول خود راست کلیک کنید سپس روی create script کلیک کنید..

ممنون از همکاریتان :)


به مثال زیر نگاه کنید
ممنون meysam_pro در فرصت مناسب کد را بررسی خواهم کرد

akbar_online
یک شنبه 15 شهریور 1388, 21:50 عصر
خواسته ی آخر:
لطفا script مربوط به کد جدولتان را پست کنید(ضمیمه کنید) تا trigger ای که برایتان می نویسم دقیق دقیق به عمل آید. برای این منظور از روی جدول خود راست کلیک کنید سپس روی create script کلیک کنید..

ممنون از همکاریتان :)


ممنون meysam_pro در فرصت مناسب کد را بررسی خواهم کرد

یادم رفت از SQL2005 استفاده می کنم

محمد سلیم آبادی
یک شنبه 15 شهریور 1388, 22:29 عصر
این جدول واقعا جدول اصلی بانکتان است؟ پروژه ای که در حال نوشتن آن هستید تجاری است یا برای مقاصد دانشگاهی و... است؟

نه کلید اصلی داشت، نه کلید خارجی نه default نه identity و...

به هر حال فعلا از این استفاده کنید تا اینکه یک trigger توسعه یافته خیلی خوب ایجاد کنم.
برای استفاده از این کد ابتدا آن را در یک پنجره query جدید کپی/پیست کنید سپس execute کنید.


use [Hotel_Management]
go
create trigger trg_I_Guest
on Guest_Rezervi
instead of insert, update
as
begin
declare @Login_Date varchar(10),
@Out_Date varchar(10),
@Number_Room nchar(10)
select @Login_Date=Login_Date,
@Out_Date=Out_Date,
@Number_Room=Number_Room
from inserted
if exists ( select *
from Guest_Rezervi g
where g.Number_Room=@Number_Room and
(
(@Login_Date between g.Login_Date and g.Out_Date) or
(@Out_Date between g.Login_Date and g.Out_Date) or
(Login_Date between @Login_Date and @Out_Date) or
(Out_Date between @Login_Date and @Out_Date)
)
)
raiserror('You Can not insert',1,1);
else
insert into Guest_Rezervi
select * from inserted
end
go

akbar_online
دوشنبه 23 شهریور 1388, 15:30 عصر
من از این تابع استفاده میکنم درست کار می کنه فقط در قسمت else چیکار کنم که یک مقداری به VB برگردونه که پیغام بده تداخل وجود دارد
USE [Hotel_Management]
GO
/****** Object: StoredProcedure [dbo].[USP_InsertGuest_Rezervi2] Script Date: 09/14/2009 14:46:29 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[USP_InsertGuest_Rezervi2]
(
@Id_Cart nchar(10),
@Number_Room nchar(10),
@Login_Date varchar(10),
@Out_Date varchar(10),
@Rezervkonndeh nchar(20),
@Down_payment money
)
AS
if NOT Exists(select Number_Room,Login_Date,Out_Date from Guest_Rezervi
WHERE Number_Room=@Number_Room and (Login_Date between @Login_Date And @Out_Date )or(Out_Date between @Login_Date And @Out_Date )or(@Login_Date between Login_Date And Out_Date ))

INSERT INTO Guest_Rezervi
(Id_Cart,Number_Room,Login_Date,Out_Date,Rezervkon ndeh,Down_payment)
VALUES(@Id_Cart,@Number_Room,@Login_Date,@Out_Date ,@Rezervkonndeh,@Down_payment)

محمد سلیم آبادی
دوشنبه 23 شهریور 1388, 16:49 عصر
اگر از trigger ای که برایتان نوشتم استفاده کرده باشید دیگر نیازی نیست که داخل SP (نه تابع) که نوشته اید دوباره این بررسی (نداشتن تداخل) انجام گیرد!

پس فقط کافی است که در SP خود دستور مربوط به Insert را قرار دهید. و قسمت IF را حذف کنید.(چون این کار را trigger انجام می دهد)
در واقع قبل از درج، trigger به طور اتوماتیک اجرا شده و اگر شرایط درج وجود نداشت، درج صورت نخواهد گرفت.

با کمک یک متغیر از نوع output و تابع @@roucount می توانید به شکل زیر عمل کنید:
(چگونگی استفاده از متغیر خروجی را در VB نمی دانم در این مورد می توانید از تالار مربوطه کمک بگیرید)




USE [Hotel_Management]
GO
/****** Object: StoredProcedure [dbo].[USP_InsertGuest_Rezervi2] Script Date: 09/14/2009 14:46:29 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[USP_InsertGuest_Rezervi2]
(
@Id_Cart nchar(10),
@Number_Room nchar(10),
@Login_Date varchar(10),
@Out_Date varchar(10),
@Rezervkonndeh nchar(20),
@Down_payment money,
@OutPut BIT OUTPUT
)
AS
BEGIN
SET NOCOUNT ON

INSERT INTO Guest_Rezervi
(Id_Cart,Number_Room,Login_Date,Out_Date,Rezervkon ndeh,Down_payment)
VALUES(@Id_Cart,@Number_Room,@Login_Date,@Out_Date ,@Rezervkonndeh,@Down_payment

IF @@ROWCOUNT > 0 SET @OutPut='True'
ELSE SET @OutPut='False'
END

GO

EXECUTE [dbo].[USP_InsertGuest_Rezervi2] .... , @a OUTPUT

akbar_online
دوشنبه 23 شهریور 1388, 17:27 عصر
اگر از trigger ای که برایتان نوشتم استفاده کرده باشید دیگر نیازی نیست که داخل SP (نه تابع) که نوشته اید دوباره این بررسی (نداشتن تداخل) انجام گیرد!

پس فقط کافی است که در SP خود دستور مربوط به Insert را قرار دهید. و قسمت IF را حذف کنید.(چون این کار را trigger انجام می دهد)
در واقع قبل از درج، trigger به طور اتوماتیک اجرا شده و اگر شرایط درج وجود نداشت، درج صورت نخواهد گرفت.

با کمک یک متغیر از نوع output و تابع @@roucount می توانید به شکل زیر عمل کنید:
(چگونگی استفاده از متغیر خروجی را در VB نمی دانم در این مورد می توانید از تالار مربوطه کمک بگیرید)




USE [Hotel_Management]
GO
/****** Object: StoredProcedure [dbo].[USP_InsertGuest_Rezervi2] Script Date: 09/14/2009 14:46:29 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[USP_InsertGuest_Rezervi2]
(
@Id_Cart nchar(10),
@Number_Room nchar(10),
@Login_Date varchar(10),
@Out_Date varchar(10),
@Rezervkonndeh nchar(20),
@Down_payment money,
@OutPut BIT OUTPUT
)
AS
BEGIN
SET NOCOUNT ON

INSERT INTO Guest_Rezervi
(Id_Cart,Number_Room,Login_Date,Out_Date,Rezervkon ndeh,Down_payment)
VALUES(@Id_Cart,@Number_Room,@Login_Date,@Out_Date ,@Rezervkonndeh,@Down_payment

IF @@ROWCOUNT > 0 SET @OutPut='True'
ELSE SET @OutPut='False'
END

GO

EXECUTE [dbo].[USP_InsertGuest_Rezervi2] .... , @a OUTPUT

تو برنامه که نوشتم چطور پیغام بده که تداخل داره

محمد سلیم آبادی
دوشنبه 23 شهریور 1388, 17:40 عصر
فکر کنم درست مطالب آخرین پستم را نخواندید!
گفتم دقیق نمی دانم که چطوری باید در application از مقدار متغیر output استفاده کنید، اگر به این مقدار بتوانید دسترسی داشته باشید یک کدی شبیه به کد زیر باید بنویسید:


IF variable='false'
then messageBox('شما موفق نشدید درج کنید')

fiend_net
چهارشنبه 25 شهریور 1388, 10:20 صبح
واقعا مفيد بود! ممنون!