# Native Code > برنامه نویسی در Delphi > بانک های اطلاعاتی در Delphi > سوال: افزایش سرعت ثبت اطلاعات در بانک

## hamedjim

سلام به همه.

لطفا می تونید معادل کد ساده زیر رو با استفاده از SP که برای درج حجم زیادی از اطلاعات در بانک اطلاعاتی استفاده شده، برای من بنویسید؟
در ساده ترین حالت فرض بر این هست که از ADO  استفاده میشه و قرار هست مثلا 10000 رکورد جدید اضافه بشه که فیلد ID اون همین شماره رکورد باشه. هدف هم صرفه جویی در زمان ذخیره سازی هست. ممنونم.

  with Qry do
  begin
    Lo:= 0;
    Hi:= 10000;
    for K := Lo to Hi do
    begin
      Close;
      SQL.Clear;
      SQL.Text := 'SELECT * FROM tblOutput WHERE ID=:P1';
      Parameters.ParamByName('P1').Value := K;
      Open;
      Insert;
      FieldByName('ID').AsInteger:= K;
      Post;
    end;
    Free;
  end;

----------


## یوسف زالی

نیازی به اس پی نیست، کوئری شما مشکل داره و باید اصلاح بشه، تمام این کار ها رو می تونید فقط با یک دستور که تو کوئری می گذارید اجرا کنید.

----------


## hamedjim

> تمام این کار ها رو می تونید فقط با یک دستور که تو کوئری می گذارید اجرا کنید.


آقا یوسف میشه دستورش رو لطف کنید؟

----------


## یوسف زالی

کدش به این تالار مرتبط نیست و باید در تالار اس کیو ال دنبالش باشید.
صرفا جهت اطلاع:
برای چنین مواقعی که اینسرت گروهی دارید دستور زیر کارتون رو راه می ندازه:

insert into TBL
select a
from TBL2
where ..


چنانچه شماره ردیف لازم دارید از توابع ردیف مثل row_number یا rank می تونید استفاده کنید، در بدترین حالت کیس مد نظر شما، کار با یک دستور تمام است و در صورت نداشتن تریگر یا کانسترینت روی جدول، زدن ده هزار ردیف در اون تو کسری از ثانیه انجام می شه.

----------


## hamedjim

ممنونم. من از INSERT INTO استفاده کرده بودم. فکر می کردم روش بهتری هم هست که بشه استفاده کرد.
حالا که مطرح شد، میشه این دو تا کد رو نگاه کنی و نطر بدی؟ چون خودم از زمان اجرای این بخش ها راضی نیستم:


  with Qry do
  begin
    Close;
    SQL.Clear;
    SQL.Text := 'INSERT INTO tblOutput (FTime) VALUES (:FTime)';
    Lo:= 0;
    Hi:= MusicTime;
    for K := Lo to Hi do
    begin
      Parameters.ParamByName('FTime').Value := K;
      ExecSQL;
    end;
    Free;
  end;

و

  with Qry do
  begin
    Lo:= 1020;
    Hi:= 11200;
    FName:= 'F' + IntToStr(I); {Get Field Name}
    Close;
    SQL.Clear;
    SQL.Text := 'UPDATE tblOutput SET ' + FName + '=:P1 WHERE FTime=:P0';
    for K := Lo to Hi do
    begin
      Parameters.ParamByName('P0').Value :=  K;
      Parameters.ParamByName('P1').Value :=  FValue[K] + FColor[K];
      ExecSQL;
    end;
    Free;
  end;

----------


## یوسف زالی

من فرصت بهینه کردن کد رو ندارم متاسفانه، اگر براتون خیلی فورس نیست صبر کنید تا شنبه انشاالله.
همین دو تا پیام رو هم لابلای کارا میام می گذارم.
با احترام -

----------


## hamedjim

> من فرصت بهینه کردن کد رو ندارم متاسفانه، اگر براتون خیلی فورس نیست صبر کنید تا شنبه انشاالله.
> همین دو تا پیام رو هم لابلای کارا میام می گذارم.
> با احترام -


ممنون از لطفتون.
عجله که هست. ولی برای یادگیری، خوشحال میشم هر زمان تونستی کد رو اصلاح کنی. متشکرم

----------


## hamedjim

آقا یوسف عزیز،
هر زمان فرصت کردی ما منتظر نکات آموزشی شما در مورد بهینه کردن این کد ها هستیم.

----------


## یوسف زالی

اول: در خصوص ساخت شمارنده در اس کیو ال،
روش ریکرسیو:
declare @from int = 0
declare @to int = 5


;with CTE as (
  select @from K
  union all
  select K +1
  from CTE
  where K < @to
)
select *
from CTE
option (maxrecursion 0)


روش استفاده از جداول بزرگ:

declare @from int = 0
declare @to int = 5


select top (@to -@from +1) ROW_NUMBER() over(order by (select 1)) +@from -1 K
from sys.objects


یا هر جدول دیگه ای که دارید، یا حتی کراس جوین یه جدول روی خودش، این روش برای تعداد کوچیک خوبه

روش آیدنتیتی:



declare @from int = 0
declare @to int = 5


declare @T table(K int identity(1, 1))
insert into @T DEFAULT VALUES


WHILE SCOPE_IDENTITY() < 100
  INSERT @T DEFAULT VALUES 


select *
from @T


روش های دیگه ای هم هست برای ساخت سکوئنس،
حالا شما سکوئنس رو دارید، مثلا در جدول T
می تونید اگر این کارها رو زیاد انجام می دید، یک جدول تحت همین نام بطور دائم درست کنید و ازش استفاده کنید. البته باز هم بستگی داره به پرفورمنس شما.

INSERT INTO tblOutput (FTime) select K from T

مثلا همین کد با استفاده از روش اول:
declare @from int = 0
declare @to int = 5


;with CTE as (
  select @from K
  union all
  select K +1
  from CTE
  where K < @to
)
INSERT INTO tblOutput (FTime)
select K
from CTE
option (maxrecursion 0)


برای قسمت دوم هم فرض می گیرم که FValue و FColor اسامی فیلد های جدول T2 باشند، که ID فیلدی در اونه که ترتیب ایندکس ها توشه (در حال حاضر فکر کنم آرایه گرفتید)

declare @from int = 0
declare @to int = 5


;with CTE as (
  select @from K
  union all
  select K +1
  from CTE
  where K < @to
)
UPDATE T
SET FName = T2.FValue + T2.FColor
from tblOutput T
  join T2 on T.FTime = T2.ID
  join CTE on T.FTime = K
option (maxrecursion 0)


چیزی شبیه به این می شه.
فیلد ها رو خودتون جایگذاری کنید.

----------


## hamedjim

بسیار عالی :تشویق:  :تشویق:  :تشویق:  :تشویق: 
ممنونم

----------

