PDA

View Full Version : جستجوی سندهای ثبت نشده



حمیدرضاصادقیان
جمعه 30 اردیبهشت 1384, 20:28 عصر
سلام خدمت اساتید گرام.
در یک برنامه حسابداری در قسمت جستجو یک آیتمی به نام جستجوی سندهای ثبت نشده وجود دارد.
به فرض کاربری از شماره 1 تا 8 سندمیزنه بعد شماره 9 رو خالی میزاره و بعد 10 رو سند میزنه.
حالا برنامه نویس های قبلی اومدن به این صورت کار کردن که ابتدا مقدار min,max سند رو بدست اوردن بعد با یک for از min به max رفته و با locate دنبال این سندهای خالی میگردن . تقریبا برای 50000 سند یک 5 دقیقه ای طول میکشه . من دنبال یک روشی میگردم که بشه این روش رو از طریق نوشتن یک function در sql درست کرد.

declare @mx varchar(10),@mn varchar(10),@sn varchar(10)

set @mx=(select max(sanad) from f_sanad)
set @mn=(select min(sanad)from f_sanad)
while @mn != @mx
begin
if not (select sanad from f_sanad )=@mn
begin
print @mn
end
end

اینم چیزیه که خودم نوشتم ولی درست جواب نمیده :گیج:

Microsoft.net
جمعه 30 اردیبهشت 1384, 21:51 عصر
چرا این کارو میکنی ؟؟
اول min , max سند هاتو اون سال مالی بدست بیار
بعد یه select بگیر از اون شماره سند هایی که تو این بازه هستند ولی تو database نیستند !!!!

حمیدرضاصادقیان
جمعه 30 اردیبهشت 1384, 22:06 عصر
خوب دوست عزیز چه جوری بفهمم تو دیتابیس نیستند؟؟مشکل همینجاست :گیج:

AminSobati
شنبه 31 اردیبهشت 1384, 00:05 صبح
به نظر کار سختی نمیاد به شرط اینکه درست متوجه صورت مسئله شده باشم:
یعنی اگر بین 1 تا 50000 چند عدد جا افتاده باشه، اونها مد نظر شماست؟

karimh
شنبه 31 اردیبهشت 1384, 01:09 صبح
سلام
من هم دقیقا هین سوال رو دارم .میخوام گزارشی بسازم که این شماره های جا افتاده سند رو به من بده .
چطور میشه این کارو کرد؟ :گیج:

مرسی از راهنمایی هاتون :sunglass:

حمیدرضاصادقیان
شنبه 31 اردیبهشت 1384, 08:06 صبح
دقیقا همین مد نظر منه.حالا من خودم یک راه دیگه به ذهنم رسید
که اول مقدار min,max سند رو بدست بیارم و با یک حلقه مدام عددی که در حلقه بکار میرود را در بازه min,max مقایسه کنم اگر وجود داشت که ادامه دهد اگر وجود نداشت اون عدد رو در یک متغیر ذخیره کند.
حالا نمیدونم این راه درسته یا نه؟
:گیج:

AminSobati
شنبه 31 اردیبهشت 1384, 10:29 صبح
دوست عزیزم روشی که گفتین میتونه جواب بده اما بسیار کنده. بهینه ترین راه استفاده از خاصیت Join هستش. برای مثال، در جدول زیر من چند مقدار بین 1 تا 10 وارد میکنم ولی 4,6,7,9 رو جا میندازم:

create table sanad(
sid int)

insert sanad values(1)
insert sanad values(3)
insert sanad values(2)
insert sanad values(8)
insert sanad values(10)
insert sanad values(5)

create index ix1 on sanad(sid)
توجه کنین که به ایندکس برای سرعت بالاتر نیاز داریم.

به فرض اینکه Min و Max شما 1 و 10 باشن، باید یک جدول مجازی ایجاد کنیم و از 1 تا 10 رو در این جدول وارد کنیم. بعد با یک Join رکوردهای جا افتاده بدست میاد:

declare @Min int
declare @Max int
set @Min=1
set @Max=10

declare @tmp table(tid int primary key)
declare @Counter int
set @Counter=@Min
while @Counter <=@Max
begin
insert @tmp values(@Counter)
set @Counter=@Counter+1
end

select t.tid from @tmp t left outer join sanad s
on t.tid=s.sid
where s.sid is null

ebnsina
شنبه 31 اردیبهشت 1384, 10:54 صبح
فکر کنم مشکل خیلیها بوده.

تشکر از راهنماییتون :flower:

حمیدرضاصادقیان
شنبه 31 اردیبهشت 1384, 11:27 صبح
بسیار عالی بود استاد.
مشکلم حل شد.
فقط یک سوال در دلفی کدوم فیلد رو باید مقدارش رو نمایش بدم.؟
اخه اون فیلد اخری که sanad باشه رو میخوام نمایش بدم میگه field not found

حمیدرضاصادقیان
شنبه 31 اردیبهشت 1384, 14:25 عصر
اقا من این کد رو در دلفی نوشتم ولی تمام مقادیری که بر میکردونه همش صفر هستش.

adst.Active := true;
for i := 0 To adst.RecordCount-1 do
begin

if memSabtNashode.Text=' ' then memSabtNashode.Text:=memSabtNashode.Text+adst.Fiel dbyname('tid').AsString
else
memSabtNashode.Text:=memSabtNashode.Text+' - '+ adst.Fieldbyname('tid').AsString;
end;

حمیدرضاصادقیان
شنبه 31 اردیبهشت 1384, 21:20 عصر
بالاخره مشکل حل شد دست همگی درد نکنه.
آخر حلقه for قبل از اینکه تموم بشه این دستور رو نوشتم و مشکل حل شد.

adst.next;
:flower: :wink:

AminSobati
شنبه 31 اردیبهشت 1384, 22:39 عصر
:) :تشویق:

حمیدرضاصادقیان
یک شنبه 01 خرداد 1384, 20:18 عصر
select t.tid from @tmp t left outer join sanad s
استاد میشه در مورد این خط توضیح بدی که کارش چیه چون اصلا متوجه نشدم. :flower:

AminSobati
دوشنبه 02 خرداد 1384, 00:41 صبح
دوست عزیزم tmp@ نام جدوله که به صورت Variable تعریف شده. درست مثل همه جدولهای دیگه عمل میکنه.
اما در مورد Left Outer Join اگر سوال دارین، میبایست Books Online رو مطالعه بفرمایید. به طور کلی میتونم بگم یعنی: همه رکوردها از سمت چپ یعنی tmp@ انتخاب میشن، ولی از جدول Sanad فقط اونهایی که بر اساس این شرط: on t.tid=s.sid با هم Match میشن انتخاب خواهند شد. طبیعتا ID هایی که در tmp@ هستند ولی در Sanad نیستند، مقدار s.sid براشون Null درمیاد. این همون چیزیه که ما لازم داریم.

حمیدرضاصادقیان
سه شنبه 03 خرداد 1384, 09:49 صبح
استاد ممنون از توضیحتون.
حالا من اومدم یک سند زدم 900000 که وقتی این کد شما رو به user define function تبدیل کردم نزدیک 2:45 ثانیه طول میکشه.حالا میشه با full text کاری کرد که از این هم سریعتر بشه.؟ :kaf:

AminSobati
چهارشنبه 04 خرداد 1384, 14:47 عصر
عزیزم FTS اصلا کارش چیزه دیگست. در روش من، بیشترین زمان صرف تولید اعداد میشه که به جاش میتونین یک جدول همیشگی داشته باشین که اعداد از یک تا هر چقدر که نیازه رو (به همراه ایندکس) داشته باشه و در موقع لزوم، فقط Join رو انجام بدین.
موفق باشید