Transact-SQL-də kursorların və döngələrin istifadəsi. MySQL-də kursorlar saxlanılan prosedurlar Sql serverində kursorlar

DECLARE CURSOR əmri manipulyasiya üçün cədvəl sətirindən qeydləri əldə etməyə imkan verir. Bu, SQL-in etdiyi ənənəvi verilənlər toplusunun emalı əvəzinə sıra-sətir emal etməyə imkan verir.

İlk yaxınlaşma olaraq, kursorla işləyərkən aşağıdakı addımlardan istifadə olunur.

Kursor DECLARE əmri ilə yaradılır. Kursor OPEN əmri ilə açılır.

Kursorla əməliyyatlar FETCH əmrindən istifadə etməklə həyata keçirilir. Kursor CLOSE əmri ilə bağlanır.

DECLARE CURSOR əmri SELECT ifadəsini təyin edir. SELECT ifadəsi ilə qaytarılan hər bir sıra fərdi olaraq götürülə və işlənə bilər. Aşağıdakı Oracle nümunəsi bir neçə digər dəyişənlərlə birlikdə elan blokunda kursoru elan edir. Bundan sonra sonrakı BEGIN...END blokunda kursor açılır, ondan seçim aparılır və kursor bağlanır.

KURSOR başlıq_qiymət_kursoru SEÇİM başlıqdır, başlıqlardan qiymət

QİYMƏT NULL OLMADIĞINDA; title_price_val title_price_cursor ROWTYPE; yeni_qiymət NUMBER(10.2);

AÇIQ başlıq_qiymət_kursoru;

GƏLİN başlıq_qiyməti_kur-soru başlıq_qiyməti INTO;

new_price:= "title_price_val.price" * 1.25 new_price_price DƏYƏRLƏRİNƏ DAXİL EDİN

(başlıq_qiyməti_dəyər.başlıq, yeni_qiymət) başlıq_qiyməti_kursorunu BAĞLA; END;

Bu nümunə PL/SQL istifadə etdiyi üçün biz bu kitabdakı kodun çoxunu izah etməyəcəyik. Bununla belə, DECLARE bloku kursor bəyannaməsini aydın şəkildə göstərir. İcra edilə bilən PL/SQL blokunda kursor OPEN əmri ilə işə salınır, dəyərlər FETCH əmri ilə götürülür və nəhayət, CLOSE əmri ilə kursor bağlanır.

SELECT ifadəsi kursorun əsasını təşkil edir, ona görə də onu DECLARE CURSOR ifadəsinə daxil etməzdən əvvəl hərtərəfli sınaqdan keçirmək yaxşı təcrübədir. SELECT ifadəsi əsas cədvəldə və ya görünüşdə işləyə bilər. Buna görə də, yalnız oxumaq üçün kursorlar yenilənməyən görünüşlərlə işləyə bilər. SELECT ifadəsində ORDER BY, GROUP BY və HAVING kimi bəndlər ola bilər, çünki bu bəndlər mənbə cədvəlini yeniləməz. Əgər kursor YENİLƏNMƏK ÜÇÜN olaraq təyin olunubsa, o zaman belə bəndləri SELECT ifadəsindən silmək tövsiyə olunur.

Yerli kursorlar çox vaxt saxlanılan prosedurların çıxış parametrləri kimi istifadə olunur. Beləliklə, siz saxlanılan prosedurda kursoru müəyyən edib doldura və onu çağıran toplu iş və ya saxlanılan prosedura ötürə bilərsiniz.

Aşağıdakı sadə DB2 nümunəsində biz "XO1" admin_qrupunda şöbə nömrələrini, şöbə adlarını və menecer nömrələrini axtaran kursor elan edəcəyik.

kursor kursorunu ELAN EDİN

SEÇİM ÜÇÜN dept_nbr, dept_name, mgr_nbr

WHERE admin_group="X01"

SİFARİŞ BY d"ept_name ASC, dept_nbr DESC, mgr_nbr DESC;

Aşağıdakı Microsoft SQL Server nümunəsi nəşriyyatlar cədvəli üçün kursoru elan edir və açır. Kursor nəşriyyatlar cədvəlindən SELECT ifadəsinə uyğun gələn ilk qeydi seçir və onu başqa cədvələ daxil edir. Sonra bütün qeydlər işlənənə qədər növbəti qeydə, sonra növbəti qeydə keçir. Nəhayət, kursor bağlanır və yaddaş boşaldılır (DEALLOCATE əmri yalnız Microsoft SQL Serverində istifadə olunur).

@publisher_name VARCHAR(20) ELAN EDİN

pub_cursor KURSOR ELAN EDİN "ABŞ" ölkəsində nəşriyyatçılardan nəşr_adını SEÇİN

pub_kursordan publisher_name İÇİN NÖVBƏYİ GƏLDİN

WHILE @s>FETCH_STATUS=0

xarici_nəşriyyat VALUES INSERT INTO("j>naşir_adı)

pub_kursoru bağlayın pub_kursoru BOŞALT

Bu nümunədə kursorun bir sıra qeydlər arasında hərəkət etdiyini görə bilərsiniz. (Bu misal yalnız ideyanı nümayiş etdirmək üçün nəzərdə tutulub, çünki əslində var Ən yaxşı yol bu problemin həlli, yəni INSERT, SELECT təlimatı.)

TƏTBİQ EDİLİR: SQL Server (2008-ci ildən)Baza SQL məlumatları Azure SQL Data WarehouseParalel Məlumat Anbarı

Transact-SQL server kursorunun görünüş xassələri və kursorun işlədiyi nəticə dəstini qurmaq üçün istifadə edilən sorğu kimi atributlarını müəyyən edir. DECLARE CURSOR bəyanatı həm ISO standart sintaksisini, həm də Transact-SQL dil genişləndirilməsi dəstindən istifadə edən sintaksisi dəstəkləyir.

ISO sintaksisi kursor_adını ELAN EDİN [ HƏSSİSİZ ] [ KEÇİRİN ] Seçmə ifadəsi ÜÇÜN KURSOR [ ÜÇÜN ( YALNIZ OXUYUN | YENİLƏNİB [ sütun_adı [ ,...n ] ] ) ] [;] Transact-SQL Genişləndirilmiş Sintaksisi kursor_adını ELAN EDİN KURSOR [ YERLİ | QLOBAL ] [ YALNIZ_İLERİ | KEÇİRİN ] [ STATİK | KEYS | DİNAMİK | FAST_İrəli ] [ YALNIZ_OXUMA | SCROLL_LOCKS | OPTİMIST ] [ TİP_XƏBƏRDARLIQ ] seçmə ifadəsi üçün [ YENİLƏNMƏ ÜÇÜN [ sütun_adının [ ,...n ] ] ] [;]

kursor_adı
kursor_adı

HƏSSİSİZ
tempdb; beləliklə, əsas cədvəllərdə edilən dəyişikliklər bu kursorun seçimləri ilə qaytarılan məlumatlarda əks olunmur və bu kursor dəyişdirilə bilməz. İSO sintaksisindən istifadə edərkən, HESABİLSİZ seçim göstərilmədiyi təqdirdə, əsas cədvəllərdə edilmiş yeniliklər və silmələr sonrakı seçimlərdə görünür.

KEÇİRİN
Bütün seçmə seçimlərinin mövcud olduğunu göstərir (İLK, SON, ƏVVƏL, NÖVBƏTİ, NİSİ, MÜTLƏQ). Əgər ISO DECLARE CURSOR bəyanatı SCROLL seçimini göstərmirsə, yalnız NEXT əldə etmə seçimi dəstəklənir. SCROLL seçimi FAST_FORWARD seçimi ilə müəyyən edilə bilməz.

seçim_bəyanatı
Kursorun nəticə dəstini təyin edən standart SELECT ifadəsi. FOR BROWSE və INTO açar sözlərinə icazə verilmir seçim_bəyanatı kursor bəyannaməsi.

seçim_bəyanatı tələb olunan tipli kursorla ziddiyyət.

YALNIZ OXUYUN

Yeniləmə ]
sütun_adı [, .. .n] müəyyən edilir, yalnız sadalanan sütunlar dəyişikliklərə icazə verir. UPDATE bəyanatı sütunların siyahısı olmadan istifadə olunursa, yeniləmə bütün sütunlar üçün mümkündür.

kursor_adı
Xüsusi server kursorunun Transact-SQL adı. kursor_adı identifikatorlar üçün qaydalara əməl etməlidir.

YERLİ
Kursorun yaradıldığı paket, saxlanılan prosedur və ya trigger üçün lokal olduğunu göstərir. Kursor adı yalnız bu sahədə etibarlıdır. Kursor paket yerli dəyişənləri, saxlanılan prosedurlar, tetikleyiciler və ya saxlanılan prosedurun çıxış parametri ilə istinad edilə bilər. OUTPUT parametri yerli kursoru çağıran paketə, saxlanılan prosedura və ya triggerə ötürmək üçün istifadə olunur ki, bu da saxlanılan prosedur başa çatdıqdan sonra kursora sonrakı giriş üçün parametri kursor dəyişəninə təyin edə bilər. Kursor OUTPUT parametrinə ötürülməyibsə, toplu, saxlanılan prosedur və ya trigger icranı tamamlayanda kursor dolayısı ilə buraxılır. Kursor OUTPUT parametrinə ötürülübsə, ona istinad edən bütün dəyişənlər sərbəst buraxıldıqda və ya əhatə dairəsindən çıxdıqda kursor buraxılır.

QLOBAL
Kursorun əlaqə üçün qlobal olduğunu göstərir. Kursorun adı əlaqədə işləyən hər hansı saxlanılan prosedur və ya paket tərəfindən istifadə edilə bilər. Kursor yalnız əlaqə pozulduqda açıq şəkildə buraxılır.

YALNIZ_İLERİ
Kursorun yalnız birinci sətirdən sonuncuya kimi baxıla biləcəyini müəyyən edir. Yalnız NÖVBƏTİ GƏLDİR seçimi dəstəklənir. FORWARD_ONLY STATIC, KEYSET və ya DYNAMIC açar sözlər olmadan təyin edilərsə, kursor DYNAMIC kursor kimi davranır. Əgər nə FORWARD_ONLY arqumenti, nə də SCROLL arqumenti göstərilməyibsə, STATIC, KEYSET və ya DYNAMIC açar sözlər mövcud olmadıqda, standart FORWARD_ONLY arqumentidir. STATIC, KEYSET və DYNAMIC kursorlarında SCROLL-un standart dəyəri var. ODBC və ADO kimi verilənlər bazası API-lərindən fərqli olaraq, FORWARD_ONLY rejimi aşağıdakı Transact-SQL kursorları tərəfindən dəstəklənir: STATIC, KEYSET və DYNAMIC.

STATİK
Kursorun istifadəsi üçün məlumatların müvəqqəti surətini yaradan kursoru müəyyən edir. Kursorun bütün sorğuları müəyyən edilmiş müvəqqəti cədvələ daxil olur tempdb; beləliklə, əsas cədvəllərdə edilən dəyişikliklər bu kursorun seçimləri ilə qaytarılan məlumatlarda əks olunmur və bu kursor dəyişdirilə bilməz.

KEYFİYAT
Kursordakı sətirlərin üzvlüyünün və ya sırasının açıldığı zaman dəyişmədiyini göstərir. Cədvəldə sətirləri unikal şəkildə müəyyən edən açarlar dəsti quraşdırılmışdır tempdbçağırdı açarlar.

Kursor sahibi tərəfindən edilən və ya digər istifadəçilər tərəfindən edilən əsas cədvəllərdə əsas olmayan dəyərlərə edilən dəyişikliklər kursor sahibi ona baxdıqda göstərilir. Digər istifadəçilər tərəfindən edilən dəyişikliklər əks olunmur (dəyişikliklər Transact-SQL server kursorundan istifadə etməklə edilə bilməz). Sətir silinərsə, sətirləri əldə etməyə cəhd @@FETCH_STATUS -2 qaytarır. Kursor sərhədlərindən əsas dəyərlərə yeniləmələr köhnə cərgənin silinməsinə və sonra yeni sətirin daxil edilməsinə bənzəyir. Yeni dəyərləri olan cərgə görünmür və köhnə dəyərləri olan cərgəni əldə etməyə cəhdlər @@FETCH_STATUS -2 qaytarır. Yeniləmələr, HARƏCİ CURRENT OF bəndindən istifadə etməklə kursor vasitəsilə edilərsə, dərhal görünür.

DİNAMİK
Bu kursora baxarkən nəticə dəstindəki sətirlərə edilən bütün məlumat dəyişikliklərini göstərən kursoru təyin edir. Hər seçimdə məlumat dəyərləri, sıra və sıra üzvlükləri fərqli ola bilər. ABSOLUTE seçim seçimi dinamik kursorlar tərəfindən dəstəklənmir.

Sürətli_İrəli
Performans optimallaşdırmasının aktivləşdirildiyi YALNIZ İLERİ, YALNIZ READ_ kursorunu göstərir. FAST_FORWARD seçimi SCROLL və ya FOR_UPDATE seçimləri ilə müəyyən edilə bilməz.

YALNIZ_OXUYUN
Bu kursor vasitəsilə edilən dəyişikliklərin qarşısını alır. WHERE CURRENT OF bəndi YENİLƏNİB və ya DELETE bəyanatında kursora istinad edə bilməz. Bu seçim standart kursor yeniləmə funksiyasından üstündür.

SCROLL_LOCKS
Kursordan istifadə edərək yerləşdirilmiş yeniləmələrin və ya silmələrin müvəffəqiyyətli olacağına zəmanət verildiyini göstərir. SQL Server kursora oxunduqca sətirlərin sonrakı dəyişikliklər üçün əlçatan olmasını təmin etmək üçün onları kilidləyir. SCROLL_LOCKS seçimi FAST_FORWARD və ya STATIC seçimi ilə müəyyən edilə bilməz.

OPTİMIST
Müəyyən edir ki, yerləşdirilmiş yeniləmələr və ya kursordan istifadə etməklə edilən silmələr, əgər satır kursorda oxunduqdan sonra yenilənibsə, uğursuz olacaq. SQL Server sətirləri kursora oxuduqca kilidləmir. Bunun əvəzinə müqayisələrdən istifadə olunur vaxt damgası sütun dəyərləri və ya yoxlama məbləğləri, cədvəldə deyilsə vaxt damgası sətrin kursora oxunduqdan sonra dəyişib-dəyişmədiyini müəyyən etmək üçün sütun. Sətir dəyişdirilibsə, yerləşdirilmiş yeniləmə və ya silmə cəhdləri uğursuz olacaq. FAST_FORWARD seçimi ilə OPTİMİSTİC seçimi müəyyən edilə bilməz.

TYPE_XƏBƏRDARLIQ
Kursor gizli olaraq tələb olunan bir növdən digərinə çevrilərsə, müştəriyə xəbərdarlıq göndəriləcəyini müəyyən edir.

seçim_bəyanatı
Kursorun nəticə dəstini təyin edən standart SELECT ifadəsi. COMPUTE, COMPUTE BY, FOR BROWSE və INTO açar sözlərinə icazə verilmir. seçim_bəyanatı kursor bəyannaməsi.

SQL Server bəndlərdə olduğu halda kursoru dolayısı ilə başqa bir növə çevirir seçim_bəyanatı tələb olunan tipli kursorla ziddiyyət. Əlavə məlumat üçün Gizli Kursor Dönüştürmələrinə baxın.

YENİLƏNMƏ ÜÇÜN]
Kursorda yenilənəcək sütunları müəyyənləşdirir. Əgər OF sütun_adı [, ... n] təmin edilir, yalnız sadalanan sütunlar dəyişikliklərə icazə verir. UPDATE bəyanatı sütun siyahısı olmadan istifadə edilərsə, READ_ONLY paralellik seçimi təyin edilmədiyi halda yeniləmə bütün sütunlar üçün mümkündür.

DECLARE CURSOR bəyanatı Transact-SQL server kursorunun baxış xassələri və kursorun işlədiyi nəticə dəstini qurmaq üçün istifadə edilən sorğu kimi atributlarını müəyyən edir. OPEN ifadəsi nəticə dəstini doldurur və FETCH ifadəsi ondan bir sıra qaytarır. CLOSE bəyanatı kursorla əlaqəli cari nəticə dəstini təmizləyir. DEALLOCATE bəyanatı kursorun istifadə etdiyi resursları buraxır.

DECLARE CURSOR ifadəsinin birinci forması kursor parametrlərini təyin etmək üçün ISO sintaksisindən istifadə edir. DECLARE CURSOR bəyanatının ikinci forması Transact-SQL dilinə genişlənmələrdən istifadə edir ki, bu da sizə ODBC və ADO kimi verilənlər bazası API-lərinin kursor funksiyalarında istifadə olunanlarla eyni tiplərdən istifadə edərək kursorları təyin etməyə imkan verir.

Bu iki formanı qarışdırmaq olmaz. CURSOR açar sözündən əvvəl SCROLL və ya açar sözləri buraxsanız, CURSOR arasında və həmçinin, açar sözlərdən istifadə edə bilməzsiniz. seçim_bəyanatı açar sözlər. CURSOR arasında açar sözləri təyin edərkən, həmçinin üçün seçim_bəyanatı açar sözlər üçün, CURSOR açar sözündən əvvəl SCROLL və ya HESABİLİYYƏTİ təyin edə bilməzsiniz.

Əgər siz DECLARE CURSOR bəyanatı üçün Transact-SQL sintaksisindən istifadə edirsinizsə və YALNIZ READ_ONLY, OPTIMISTIC və ya SCROLL_LOCKS seçimlərini təyin etmirsinizsə, aşağıdakı standart dəyər qəbul edilir.

    SELECT ifadəsi yeniləmələri dəstəkləmirsə (və ya qeyri-kafi icazələrə malikdirsə və ya yeniləmələri dəstəkləməyən uzaq cədvəllərə daxil olur və s.), kursor YALNIZ READ_ONLY olaraq təyin edilir.

    STATIC və FAST_FORWARD kursorları defolt olaraq READ_ONLY.

    DYNAMIC və KEYSET kursorları defolt olaraq OPTIMISTIC-dir.

Kursorlara yalnız digər Transact-SQL ifadələri tərəfindən istinad edilə bilər. Database API funksiyaları kursorlara istinad edə bilməz. Məsələn, kursor elan edildikdən sonra OLE DB, ODBC və ya ADO funksiyaları və metodları onun adına istinad edə bilməz. Kursor sıraları müvafiq API funksiyaları və metodlarından istifadə etməklə seçilə bilməz; Bunun üçün siz Transact-SQL FETCH ifadələrindən istifadə etməlisiniz.

Kursor elan edildikdən sonra onun xassələrini təyin etmək üçün aşağıdakı saxlanılan prosedurlardan istifadə edilə bilər.

Dəyişənlər hissə kimi istifadə edilə bilər seçim_bəyanatı, kursorun elan edildiyi. Kursor dəyişənlərinin dəyərləri elan edildikdən sonra dəyişmir.

Varsayılan olaraq, ELAN KURSOR icazələri kursorun istifadə etdiyi görünüşlər, cədvəllər və sütunlar üzrə SEÇİM icazəsi olan bütün istifadəçilərə verilir.

Kümelənmiş sütun mağazası indeksi olan cədvəldə kursorları və ya tetikleyicileri istifadə edə bilməzsiniz. Bu məhdudiyyət qruplaşdırılmamış indekslərə şamil edilmir; Siz klasterləşdirilməmiş sütun mağazası indeksi olan cədvəldə kursor və tetikleyicilərdən istifadə edə bilərsiniz.

A. Sadə kursor və sintaksisdən istifadə

Bu kursoru açdığınız zaman yaradılan nəticə dəsti cədvəlin bütün sətir və sütunlarını ehtiva edir. Bu kursor yenilənə bilər, bütün yeniləmələr və silinmələr bu kursor üçün seçimdə təmsil olunur. FETCH``NEXT yalnız SCROLL parametri göstərilmədiyi üçün gətirilir.

SEÇMƏK ÜÇÜN vend_kursorunu ELAN EDİN * Satınalma FROM. Satıcı AÇIQ vend_kursoru vend_kursorundan NÖVBƏYİ GƏTİRİN;

B. Hesabatı göstərmək üçün iç-içə kursorlardan istifadə

Aşağıdakı nümunə mürəkkəb hesabatı göstərmək üçün iç-içə kursorlardan istifadə edir. Hər bir provayder üçün daxili kursor elan edilir.

SET NOCOUNT ON ; DECLARE @vendor_id int , @vendor_name nvarchar ( 50 ), @message varchar ( 80 ), @product nvarchar ( 50 );ÇAP" -------- Satıcı Məhsulları Hesabatı --------"; Vendor_kursorunu ELAN EDİN SEÇİLMİŞ VendorID, Adı Purchasing.Vendor HARADA PreferredVendorStatus = 1 VendorID SİFARİŞİ; vendor_cursor AÇIN vendor_cursor-dan NEXT FETCH FROM @vendor_id, @vendor_name WHILE WHILE @FETCH_STATUS = 0 SEÇİN @message = "----- Satıcıdan Məhsullar:"+ @vendor_name PRINT @message -- Əsasən daxili kursoru elan edin -- xarici kursordan vendor_id-də. Purchasing.ProductVendor pv, Production.Product v HARADA pv.ProductID = v.ProductID VƏ pv.VendorID = @vendor_id SEÇMƏK ÜÇÜN məhsul_kursorunu ELAN ET -- Xarici kursordan dəyişən dəyər AÇIQ məhsul_kursoru məhsul_kursorundan NÖVBƏYİ GƏTİRİN @məhsul ƏGƏR @@FETCH_STATUS İÇİN<>0 ÇAP "<>" @@FETCH_STATUS = 0 BAŞLAYAN HAMDA SEÇİN @message = " " + @məhsul ÇAP @message məhsul_kursorundan NÖVBƏYİ GƏTİRİN @məhsulun İÇİNƏ SON BAĞLAYIN məhsul_kursorunu BAŞLAYIN məhsul_kursoru -- Növbəti satıcını əldə edin. NEXT INTO vendor @vendor_id, satıcı_kursorunu SON BAĞLAYIN; vendor_kursoru BOŞALTMA;


Kursor kontekst yaddaş sahəsinə keçiddir. SQL proqramlaşdırma dilinin bəzi tətbiqlərində (Oracle, Microsoft SQL Server) - sorğunun icrası zamanı əldə edilən nəticə dəsti və onunla əlaqəli cari qeyd göstəricisi. Mən deyərdim ki, kursor alternativ məlumat yaddaşını təmsil edən virtual cədvəldir. Bu halda kursor onun məlumatlarına adi massivin verilənləri kimi daxil olmağa imkan verir.
Kursorlar saxlanılan prosedurlarda istifadə olunur. Kifayət qədər nəzəriyyə, bir nümunəyə baxaq:
Verilənlər bazamız var (verilənlər bazası bir az yaxşı deyil, bu mənim laboratoriya işi, amma verilənlər bazası müəllimimiz belə bir quruluşda israr etdi)
/*bank məlumatları*/
CƏDVƏL `bank` YARADIN (

`BankName` VARCHAR (50) COLLATE utf8_bin DEYİL NULL DEFAULT "" ,


İLKİN AÇAR ('BankId')

)ENGINE=InnoDB
XARAKTER DƏSTƏSİ "utf8" COLLATE "utf8_bin" ;
/*depozitlər haqqında məlumat */
CƏDVƏL YARADIN "bank paylanması" (
`BankId` BÜTÜN (11) NULL DEYİL,
`Persent` BÜTÜN (11) DEFAULT NULL,
`Töhfə Miqdarı` DECIMAL (10,0) NULL DEYİL,
`ClientId` BÜTÜN (11) NULL DEYİL,
İLK AÇAR('BankId', 'ClientId'),
KEY `BankId` ('BankId'),
KEY `ClientId` (`ClientId`),
MƏHDUD `bankdistribution_fk` XARİCİ AÇAR (`BankId`) İSTİNADLAR `bank` (`BankId`),
MƏHDUD `bankdistribution_fk1` XARİCİ AÇAR (`ClientId`) REREIGN `client` (`ClientId`)
)ENGINE=InnoDB
/*investorlar haqqında məlumat*/
CƏDVƏL `müştəri` YARADIN (
`ClientId` INTEGER (3) NULL DEYİL AUTO_INCREMENT,
`CreditCardId` BIGINT(10) NULL DEYİL,
`Soyad` VARCHAR (50) COLLATE utf8_bin DEYİL NULL DEFAULT "" ,
`Ad` VARCHAR (50) COLLATE utf8_bin DEYİL NULL DEFAULT "" ,
`FirstName` VARCHAR (50) COLLATE utf8_bin DEYİL NULL DEFAULT "" ,
`Telefon` VARCHAR (50) COLLATE utf8_bin DEYİL NULL DEFAULT "" ,
`Ünvan` VARCHAR (50) COLLATE utf8_bin DEYİL NULL DEFAULT "" ,
`SafeId` BÜTÜN (5) NULL DEYİL,
İLK AÇAR(`Müştəri Kimliyi`, `KreditKartİd`),
KEY `ClientId` (`ClientId`)

)ENGINE=InnoDB
AUTO_INCREMENT=11 XARAKTER SET "utf8" "utf8_bin" KOLLAYIŞ

Tutaq ki, hər bir bankı növbə ilə qəbul etməli və onunla bəzi hərəkətlər etməliyik, aşağıdakı sorğu bizə bu işdə kömək edə bilər.

`bank` seçin.* `bank` LIMIT SAYINDAN LAZIMIZ OLAN_RECORD_1,
. Beləliklə, LIMIT WE NEED_RECORD NUMBER, 1 istifadə edərək, biz dövr ərzində hər bir qeydi bank cədvəlindən növbə ilə çıxarırıq və WE NEED_RECORD NUMBER dəyərini 1 artırarkən onunla lazım olan hərəkətləri yerinə yetiririk. İndi eyni şeyi edəcəyik, lakin kursordan istifadə etməklə
Başlayın
/* verilənləri çıxardığımız dəyişənlər */
vBankId tam ədədini elan edin;
vBankName elan et VARCHAR(50);
vÜnvanı elan et VARCHAR(50);
vPhone VARCHAR elan edin (50);
/* hadler dəyişəni - a*/
Tamamlanmış defolt 0-ı elan edin;
/*Kursor bəyannaməsi*/
`bank`.`BankId`,`bank`.`BankName`,`bank`.`Ünvan`,`bank`.`Telefon`, FROM `bank` üçün BankKursoru elan edin, burada 1;
/*HANDLER məqsədi, aşağıda izah ediləcək*/
SQLSTATE "02000" SET ÜÇÜN DAVAM İŞLƏMƏYİ BİLDİRİN =1;
/* kursoru açın */
Açıq Bank Kursoru;
/*məlumat əldə edin*/
HƏMİYYƏTƏ = 0 EDİN

lazım olan tədbirləri görürük
BİTİRƏK ;
/*kursorun bağlanması*/
Bank Kursorunu bağlayın;
END ;

* Bu mənbə kodu Mənbə Kodu Vurğulayıcı ilə vurğulanıb.

Xəta: 1329 SQLSTATE: 02000 (ER_SP_FETCH_NO_DATA)

Mesaj: Data yoxdur - sıfır sıra götürülüb, seçilib və ya işlənib

SQLSTATE: 02000 kursorun sonuna çatdıqda və ya seçim və ya yeniləmə boş sətir qaytardıqda işə düşür.

Növbəti sətirdə kursoru ELAN ETMƏK kursor_adı CURSOR FOR select_statement;
Kursoru açın Kursorun adını açın;
Sonra kursorun sonuna çatana qədər (WHILE done = 0 DO) məlumatları çıxarıb emal edirik.
Saxlanılan prosedurdan çıxmazdan əvvəl kursoru bağlamalısınız. kursor_adını bağlayın;

Bu mürəkkəb görünmür. Ancaq SQLSTATE "02000" ilə əlaqəli bir çox tələ var.

HƏMİYYƏTƏ = 0 EDİN
BankKursorunu vBankId, vBankName, vAddress, vPhone İÇİNƏ GƏTİRİN;

BankId = vBankId limit 1 olduğu bank paylanmasından vContributeAmountSUM INTO (ContributeAmount) seçin;
bəzi tədbirlər görürük
BİTİRƏK ;

* Bu mənbə kodu Mənbə Kodu Vurğulayıcı ilə vurğulanıb.


Sintaksis baxımından hər şey yaxşıdır və düzgündür. Amma məntiqi baxımdan yox. Belə ola bilər ki, əmanətçilər bəzi banklarda hesab açmamışlar, sonra BankId = vBankId limit 1 olduğu bank paylanmasından vContributeAmountSUM INTO (ContributeAmount) seçin; SQLSTATE: 02000 işə düşəcək, yerinə yetirilən dəyişən 1-ə təyin ediləcək və while dövrü gözlədiyimizdən tez bitəcək. Aşağıdakıları etməklə bunun qarşısını almaq olar
HƏMİYYƏTƏ = 0 EDİN
BankKursorunu vBankId, vBankName, vAddress, vPhone İÇİNƏ GƏTİRİN;
/* banka onun hər hansı əmanətinin məbləğini çıxarın */


əgər (vContributeAmountSUM > 0), onda
/* banka onun hər hansı əmanətinin məbləğini çıxarın */

bitərsə;
bəzi tədbirlər görürük
BİTİRƏK ;

* Bu mənbə kodu Mənbə Kodu Vurğulayıcı ilə vurğulanıb.


Birinci sorğu ilə biz töhfələrin olub-olmadığını yoxladıq (əgər yoxdursa, vContributeAmountSUM == 0) və yalnız varsa, məlumatları əldə edirik.

İndi deyək ki, hər bir müştəri üçün müxtəlif banklardakı hesablardakı ümumi məbləği silməliyik
Seçilmiş cəmi üçün ClientSummCursor Kursorunu elan edin

Seçilmiş cəmi (`bankdistribution`.`ContributeAmount`), `bankdistribution`.`ClientId` FROM `bankdistribution` Daxili Qoşulma müştərisi (client.ClientId = bankdistribution.`ClientId`) üçün ClientSummCursor kursorunu elan edin, burada 1 qrup `bankdistribution`. 'Müştəri ID';

ClientSummCursor-u açın;
HƏMİYYƏTƏ = 0 EDİN
BankKursorunu vBankId, vBankName, vAddress, vPhone İÇİNƏ GƏTİRİN;
/* banka onun hər hansı əmanətinin məbləğini çıxarın */
BankId = vBankId limiti 1 olduğu bank paylanmasından vContributeAmountSUM İÇƏ Count(ContributeAmount) seçin;
/* bu bankda həqiqətən əmanətlərin olub olmadığını yoxlayın */
əgər (vContributeAmountSUM > 0), onda
/* banka onun hər hansı əmanətinin məbləğini çıxarın */
BankId = vBankId limit 1;
bitərsə;


bəzi tədbirlər görürük.
BİTİRƏK ;

* Bu mənbə kodu Mənbə Kodu Vurğulayıcı ilə vurğulanıb.

Eyni vəziyyət ClientSummCursor kursorunda verilənlər BankCursor-dakı verilənlərdən tez bitdikdə, SQLSTATE: 02000 işə salındıqda, yerinə yetirilən dəyişən 1-ə təyin olunduqda və while dövrəsi gözlədiyimizdən tez bitdikdə yarana bilər. Aşağıdakıları etməklə bunun qarşısını almaq olar

ClientSummCursor-u açın;
HƏMİYYƏTƏ = 0 EDİN
BankKursorunu vBankId, vBankName, vAddress, vPhone İÇİNƏ GƏTİRİN;
/* banka onun hər hansı əmanətinin məbləğini çıxarın */
BankId = vBankId limiti 1 olduğu bank paylanmasından vContributeAmountSUM İÇƏ Count(ContributeAmount) seçin;
/* bu bankda həqiqətən əmanətlərin olub olmadığını yoxlayın */
əgər (vContributeAmountSUM > 0), onda
/* banka onun hər hansı əmanətinin məbləğini çıxarın */
BankId = vBankId limit 1;
bitərsə;
/* ikinci kursordan məlumat çıxarmazdan əvvəl sqlstate vəziyyətini xatırlayın */
SET old_status = tamamlandı;
/* bizə lazım olan məlumatları çıxarın */
ClientSummCursor-u vSum, vClientId-ə GƏLİN;
/* verilənlərin əldə edilib-edilmədiyini və sqlstate 0200-ün uğursuz olub olmadığını yoxlayın */
əgər (edildi = 0) onda
bəzi tədbirlər görürük.
bitərsə;
/* müddət bitməzdən əvvəl yerinə yetirilən dəyişənin dəyərini bərpa edin */
təyin edildi = köhnə_status;
BİTİRƏK ;

* Bu mənbə kodu Mənbə Kodu Vurğulayıcı ilə vurğulanıb.

Bura qədər oxuyan hər kəsə təşəkkür edirəm, ümid edirəm kiməsə faydalı olacaq.

Kursorun verilənlər bazasında tətbiqi bir sıra verilənlər və onların işlənməsi üsullarına malik olan Java sinfinə bənzəyir. Harada sql kursoru məlumatları müntəzəm massiv kimi istifadə edir. Kursorlar triggerlərdə, saxlanılan prosedurlarda və funksiyalarda istifadə edilə bilər.

SQL standartına uyğun olaraq, kursorlarla işləyərkən aşağıdakı əsas hərəkətlər yerinə yetirilir:

  • kursor bəyannaməsi;
  • oxu məlumatları ilə kursorun açılması;
  • kursordan verilənlərin sətir-sətir seçilməsi;
  • kursordan istifadə edərək sıra məlumatlarının dəyişdirilməsi;
  • kursoru bağlayır, bundan sonra əlçatmaz olur;
  • kursoru buraxmaq, yəni. kursoru yaddaşdan silmək, çünki onun bağlanması onunla əlaqəli yaddaşı mütləq boşaltmır.

Müxtəlif tətbiqlərdə tərif kursor bəzi fərqlər ola bilər. Məsələn, bəzən kursor üçün ayrılmış yaddaşı açıq şəkildə boşaltmaq lazımdır. Kursor azad edildikdən sonra onunla əlaqəli yaddaş da boşaldılır. Bu, kursor adından təkrar istifadə etməyə imkan verir. Digər tətbiqlərdə kursor bağlandıqda yaddaş gizli şəkildə boşaldılır.

Bəzi hallarda kursordan istifadə etmədən edə bilməzsiniz. Bununla belə, mümkünsə, kursordan istifadə etməməli və standart məlumat emal əmrləri ilə işləməlisiniz: SELECT, UPDATE, INSERT, DELETE. Bunun səbəbi, kursorların məlumatların bütün həcmində dəyişiklik əməliyyatlarına icazə verməməsi və kursordan istifadə edərək məlumatların işlənməsi əməliyyatlarının sürətinin nəzərəçarpacaq dərəcədə aşağı olmasıdır. standart vasitələr SQL.

Əgər proqram kursora yüklənmiş məlumatları dəyişdirə bilirsə, o zaman dəyişdirilə bilən adlanır. Kursorlar haqqında danışarkən, əməliyyatın izolyasiyasını unutmamalıyıq. Bir istifadəçi kursordan istifadə edərək qeydi dəyişdirir, digər istifadəçi isə öz kursorundan istifadə edərək həmin qeydi oxuyur. Üstəlik, o, eyni qeydi dəyişə bilər, bu da məlumatların bütövlüyünü qorumağı zəruri edir.

Kursorun elan edilməsi

Kursorlar istifadə edilməzdən əvvəl elan edilməlidir. SQL standartı kursor yaratmaq üçün aşağıdakı sintaksisdən istifadə edir:

Select_statement üçün kursor_adı kursorunu elan edin ])]

Bu ifadə kursoru elan edir kursoru elan edin"kursor_adı" adı ilə.

HƏSSİSİZ dəyişikliklərin edilməsinə imkan verməyən statik kursor yaradılır. Bundan əlavə, digər istifadəçilər tərəfindən edilən dəyişikliklər göstərilmir. INSESSIVE açar sözü yoxdursa, dinamik kursor yaradılır.

Açar sözdən istifadə edərkən KEÇİRİN yaradılmış kursor istənilən istiqamətə sürüşdürülərək istənilən seçim əmrlərini tətbiq etməyə imkan verir. Bu arqument buraxılıbsa, kursor ardıcıl olacaq, yəni. ona baxmaq yalnız bir istiqamətdə mümkün olacaq - əvvəldən axıra.

İfadə seçim_bəyanatı seçin ... -dən ... kimi məlumatı oxumaq üçün strukturu göstərir. O, operatoru ehtiva etməməlidir daxil, çünki kursorun öz operatoru var gətirmək dəyişənləri kursor məlumatları ilə doldurmaq üçün.

Arqument təyin edərkən YALNIZ_OXUMA ÜÇÜN yalnız oxumaq üçün kursor yaradılacaq və məlumatlara heç bir dəyişiklik edilməsinə icazə verilməyəcək. Dinamik kursor başqa istifadəçi tərəfindən edilən dəyişiklikləri göstərməyə imkan verən yalnız oxunan kursor kimi elan edilə bilər.

Arqumentlə kursorun yaradılması YENİLƏNMƏ ÜÇÜN ya müəyyən sütunlarda, ya da arqument olmadıqda kursordakı məlumatlara dəyişiklik etməyə imkan verir OF sütun_adı, bütün sütunlarda.

Alt proqramda birdən çox kursor elan edə bilərsiniz. Lakin hər kursorun özünəməxsus adı olmalıdır. Kursoru açmaq üçün operatordan istifadə etməlisiniz açıqəvvəl elan edilmiş kursoru açır:

Kursor açıqdır

SQL kursoru açmaq üçün aşağıdakı sintaksisi müəyyən edir:

kursor_adını açın;

Kursordan məlumatların alınması, kursorun alınması

Kursordan məlumatları bəzi dəyişənlərə oxumaq üçün sintaksis aşağıdakı kimidir:

Kursor_adını var_name daxil edin [, var_adı] ...;

Operator gətirmək sonra yerləşən dəyişənlərə açıq kursor məlumatlarını seçir daxil və kursoru növbəti mövqeyə keçir.

Kursor bağlanır

Operator yaxın kursoru bağlayır. Əgər operator açıq şəkildə göstərilməyibsə, müvafiq proqram bloku bağlandıqda kursor avtomatik olaraq bağlanır.

kursor_adını bağlayın;

Bağlandıqdan sonra kursor əlçatmaz olur. Bağlanarkən, kursor işləyərkən quraşdırılmış bütün kilidlər buraxılır. Yalnız açıq kursorlar bağlana bilər. Bağlanmış, lakin buraxılmamış kursor yenidən açıla bilər. Açılmamış kursorun bağlanmasına icazə verilmir.

Hər bir DBMS kursordan istifadənin özünəməxsus xüsusiyyətlərinə malikdir.

Oracle-da kursorlardan istifadənin xüsusiyyətləri

PL/SQL-də dörd kursor atributları var %TAPILDI, %TAPILMADI, %ISOPEN%ROWCOUNT. Kursor atributları %TYPE və %ROWTYPE operatorları kimi kursor adının sağında elan edilir.

%FUND atributu

%NOTFOUND atributu

%NOTFOUND atributu %FOUND atributunun tam əksidir.

%ISOPEN atributu

%ISOPEN atributu yalnız kursorun açıq olub olmadığını göstərir.

%ROWCOUNT atribut

Atribut %ROWCOUNT müəyyən bir zamanda kursorun oxuduğu sətirlərin sayını qaytaran rəqəmli atributdur.

Oracle DBMS-də SQL kursorunun nümunəsi

v_id managers.id %TYPE elan edin; v_name managers.name%TYPE; v_comm managers.comm%TYPE; crs kursoru "2014-11-01" və "2014-11-30" arasında olan məlumatların id, adla qruplaşdırıldığı menecerlərdən comm olaraq id, ad, cəmi (comm) seçin; açıq crs başlayın; loop EXIT WHEN crs%NOTFOUND; Crs-ləri v_id, v_name, v_comm daxil edin; bonus dəyərlərinə (id, ad, kom) daxil edin (crs.id, crs.name, crs.comm); son döngə; törətmək; crs bağlayın; son;

SQL serverində kursorlardan istifadənin xüsusiyyətləri

MSSQL-də istifadə olunan kursorlar ardıcıl və ya sürüşdürilə bilər. Ardıcıl məlumatı yalnız bir istiqamətdə - əvvəldən axıra qədər seçməyə imkan verir. Kaydırılan kursorlar hər iki istiqamətdə hərəkət etməyə imkan verir və kursorun nəticə dəstində ixtiyari sıraya keçməyə imkan verir.

SQL Server statik, dinamik, ardıcıl və klaviatura ilə idarə olunan kursorları dəstəkləyir.

Statik kursor dizaynında məlumat müəyyən vaxtda anlıq görüntü kimi saxlanılır. Buna görə də başqa istifadəçi tərəfindən verilənlər bazasına edilən dəyişikliklər görünmür. Kursor açılarkən, server tam nəticə dəstinə daxil olan bütün sətirlərdə kilid qoyur. Statik kursor yaradıldıqdan sonra dəyişmir və həmişə açıldığı anda mövcud olan məlumat dəstini göstərir. Digər istifadəçilər mənbə cədvəlindəki kursora daxil olan məlumatları dəyişdirsələr, bu, statik kursora təsir etməyəcək. Statik kursora dəyişiklik etmək mümkün deyil, ona görə də həmişə yalnız oxumaq rejimində açılır.

Dinamik kursor əlavə şəbəkə yükü və proqram təminatı tələb edir. Dinamik kursorlardan istifadə edərkən verilənlərin tam surəti yaradılmır, lakin mənbə cədvəllərindən seçimlər yalnız istifadəçi müəyyən məlumatlara daxil olduqda həyata keçirilir. Alma zamanı server cərgələri kilidləyir və istifadəçinin kursorun tam nəticə dəstinə etdiyi hər hansı dəyişiklik kursorda görünəcək. Bununla belə, kursor məlumatları əldə etdikdən sonra başqa istifadəçi tərəfindən edilən dəyişikliklər kursorda əks olunmayacaq.

Düymələr dəsti ilə idarə olunan kursor statik və dinamik arasında xüsusiyyətlərə malikdir. Qeydlər nümunə götürmə zamanı müəyyən edilir və beləliklə də dəyişikliklər izlənilir. Bu tip kursor geriyə sürüşməni həyata keçirərkən faydalıdır. Bu halda, məlumat yenilənənə və kursor seçənə qədər məlumatların əlavələri və silinməsi görünmür. yeni versiya onlara dəyişikliklər edildiyi təqdirdə qeydlər.

Statik kursorlar ən yaxşı məlumat emal sistemləri üçün istifadə olunur, yəni. hesabat sistemləri və ya statistik və analitik məqsədlər üçün. Statik kursor böyük həcmdə məlumatların alınmasında daha yaxşıdır. Obyektlərin elektron alışı və ya rezervasiyası sistemlərində (oturacaqlar, biletlər) dəyişikliklər edildikdə, yenilənmiş məlumatları dinamik şəkildə qəbul etmək lazımdır. Belə hallarda dinamik kursor istifadə olunur. Bu proqramlarda ötürülən məlumatların miqdarı adətən kiçik olur və fərdi qeyd səviyyəsində əldə edilir.

Ardıcıl kursorlar məlumatların tərs istiqamətdə alınmasına imkan vermir, yalnız kursorun əvvəlindən sonuna qədər. Ardıcıl kursor bütün məlumat sətirlərinin dəstini saxlamır. Kursorda seçim edilən kimi onlar verilənlər bazasından oxunur ki, bu da INSERT, UPDATE, DELETE komandalarından istifadə etməklə istifadəçilər tərəfindən verilənlər bazasında edilən bütün dəyişiklikləri dinamik şəkildə əks etdirməyə imkan verir. Kursor ən son məlumat vəziyyətini oxuyur.

Kursor bəyannaməsi

SELECT_statement ]] üçün kursor_adı kursorunu elan edin

Açar sözdən istifadə edərkən YERLİ Yalnız blok, trigger, saxlanılan prosedur və ya istifadəçi tərəfindən müəyyən edilmiş funksiya daxilində görünən yerli kursor yaradılacaq. Açar söz QLOBAL, cari əlaqə bağlanana qədər mövcud olan qlobal kursoru müəyyən edir.

Operator YALNIZ_İLERİ verilənlərin yalnız birinci cərgədən axırıncıya qədər olan istiqamətdə alınmasına imkan verən ardıcıl kursoru müəyyən edir. Operatordan istifadə edərkən KEÇİRİN məlumatların istənilən qaydada və istənilən istiqamətdə əldə edilməsinə imkan verən sürüşdürən kursor yaradılır.

Kursor növü operatorlar tərəfindən müəyyən edilir:

  • STATIC - statik kursor yaratmaq;
  • DYNAMIC - dinamik kursor yaratmaq;
  • KEYSET - əsas kursorun yaradılması.

Əgər kursor üçün YALNIZ_OXUYUN arqumenti müəyyənləşdirin Sürətli_İrəli, sonra yaradılmış kursor üçün optimallaşdırılacaq sürətli giriş məlumatlara. Bu arqument arqumentlərlə birlikdə istifadə edilə bilməz YALNIZ_İLERİOPTİMIST.

Əgər kursor operatorla yaradılıbsa OPTİMIST, onda kursor açıldıqdan sonra dəyişdirilmiş sətirləri dəyişdirmək və ya silmək qadağandır.

Arqument təyin edərkən TYPE_XƏBƏRDARLIQ server SELECT sorğusu ilə uyğun gəlmirsə, kursor növü dəyişikliyi barədə məlumat verəcək.

Kursordan məlumatların alınması, gətirilməsi

Kursoru açdıqdan dərhal sonra aşağıdakı əmrdən istifadə edərək onun məzmununu əldə edə bilərsiniz:

Operatordan istifadə edərkən İLK kursorun nəticə dəstinin birinci cərgəsi qaytarılacaq ki, bu da cari sıraya çevrilir. Müəyyən edildikdə SON kursorun son sətri qaytarılacaq. O, həm də cari xəttə çevrilir.

Operatoru təyin edərkən NÖVBƏTİ nəticə dəstindəki caridən dərhal sonrakı sıra geri qaytarılacaq. Bu xətt cari xəttə çevrilir. Defolt əmr FETCH sıraları gətirmək üçün məhz bu üsuldan istifadə edir.

Operatoru təyin edərkən ƏVVƏL caridən əvvəlki xətt qaytarılacaq. Bu xətt cari xəttə çevrilir.

Operator ABSOLUTE (sətir_nömrəsi | @sətir_nömrəsi_dəyişən) kursorun tam nəticə dəstində mütləq sıra nömrəsi ilə bir sıra qaytarır. Sətir nömrəsi sabitdən istifadə etməklə və ya sətir nömrəsinin saxlandığı dəyişənin adı kimi təyin edilə bilər. Dəyişən tam məlumat növü olmalıdır. Həm müsbət, həm də mənfi dəyərlər göstərilir. Müsbət dəyər təyin edilərkən, sətir çoxluğun əvvəlindən, mənfi dəyər isə sonundan sayılır. Seçilmiş xətt cari xəttə çevrilir. Əgər null dəyər göstərilibsə, heç bir sıra qaytarılmır.

Arqument RELATIVE (sətirlərin sayı | @dəyişən sıraların sayı) xətti caridən sonra müəyyən edilmiş sətirlərin ofsetini qaytarır. Sətirlərin mənfi sayını göstərsəniz, caridən əvvəl göstərilən sətir sayı geri qaytarılacaq. Null dəyərinin təyin edilməsi cari sıranı qaytaracaq. Qaytarılan sıra cari cərgəyə çevrilir.

Qlobal kursoru açmaq üçün onun adından əvvəl açar sözü göstərməlisiniz QLOBAL. Kursorun adı dəyişəndən istifadə etməklə də müəyyən edilə bilər.

İfadədə INTO @dəyişən_adı [,...n] qaytarılan sətirin müvafiq sütun dəyərlərinin saxlanacağı dəyişənlərin siyahısı müəyyən edilir. Dəyişənlərin sırası kursordakı sütunların sırasına, dəyişənin məlumat tipi isə kursor sütunundakı məlumat növünə uyğun olmalıdır.

Kursordan istifadə edərək məlumatların dəyişdirilməsi və silinməsi

Kursordan istifadə edərək məlumatları dəyişdirmək üçün aşağıdakı formatda UPDATE əmri verməlisiniz:

Bir əməliyyatda cari kursor sırasının bir neçə sütununun dəyərləri dəyişdirilə bilər, lakin onların hamısı eyni cədvələ aid olmalıdır.

Kursordan istifadə edərək məlumatları silmək üçün aşağıdakı formatda DELETE əmrindən istifadə edin:

Nəticədə kursordakı cari sətir silinəcək.

Yaddaşın boşaldılması, boşaldılması

Kursoru yaddaşdan silmək üçün əmrdən istifadə edin

kursor_adını ayırın;

@@FETCH_STATUS atributu

Kursorda sətirlərin mövcudluğunu müəyyən etmək üçün qlobal dəyişəndən istifadə etməlisiniz @@FETCH_STATUS, kursorda daha çox sətir olmadıqda sıfırdan fərqli qiymət alır. Əgər sətirlər dəsti hələ tükənməyibsə, @@FETCH_STATUS sıfıra bərabərdir.

SQL serverində kursor nümunəsi

Declare @company varchar(50), @manager varchar(50), @message varchar(256); crs_clients kursorunu seçilmiş şirkət üçün yerli elan edin, müştərilərdən menecer harada şəhər = "Moskva" şirkət, menecer tərəfindən sifariş; "Müştərilərin siyahısını" çap edin; crs_clients açın; crs_clients-dən @şirkətə, @manager-ə gətirin; @@FETCH_STATUS = 0 başladıqda @message = "Şirkət" + @şirkət + "menecer" + @manager seçin; @message çap edin; -- crs_clients-dən @şirkətə, @manager-ə növbəti rekord gətirməyə keçin; son; crs_clients-i bağlayın; crs_clientləri boşaldın;

Kursorun tərifi verilmişdir. Onun növlərinin və davranışının təsviri verilmişdir: statik, dinamik, ardıcıl və əsas kursorlar. Kursorun idarə edilməsinin prinsipləri təsvir edilmişdir: kursorun yaradılması və açılması, verilənlərin oxunması, kursorun bağlanması. Kursor proqramlaşdırma nümunələri verilmişdir.

Kursor konsepsiyası

Əlaqəli verilənlər bazasına qarşı sorğu adətən birdən çox məlumat sırasını (qeydlərini) qaytarır, lakin proqram eyni anda yalnız bir qeydi emal edir. Eyni zamanda bir neçə cərgə ilə məşğul olsa belə (məsələn, məlumatların elektron cədvəllər şəklində göstərilməsi), onların sayı hələ də məhduddur. Bundan əlavə, məlumatları dəyişdirərkən, silərkən və ya əlavə edərkən iş vahidi seriyadır. Bu vəziyyətdə kursor anlayışı ön plana çıxır və bu kontekstdə kursor bir sıra üçün göstəricidir.

SQL-də kursor verilənlər bazası yaddaşında sonuncu SQL ifadəsini saxlamaq üçün nəzərdə tutulmuş sahədir. Cari ifadə verilənlər bazası sorğusudursa, cari dəyər və ya cari kursor xətti adlanan sorğu verilənləri cərgəsi də yaddaşda saxlanılır. Yaddaşda göstərilən sahə adlandırılır və tətbiq proqramları üçün əlçatandır.

Tipik olaraq, kursorlar verilənlər bazasından orada saxlanılan məlumatların bir hissəsini seçmək üçün istifadə olunur. İstənilən vaxt bir kursor xətti tətbiq proqramı tərəfindən yoxlana bilər. Kursorlar tez-tez istifadə olunur SQL ifadələri, prosedur dillərində yazılmış tətbiq proqramlarında quraşdırılmışdır. Onların bəziləri gizli şəkildə verilənlər bazası serveri tərəfindən yaradılır, digərləri isə proqramçılar tərəfindən müəyyən edilir.

SQL standartına uyğun olaraq, kursorlarla işləyərkən aşağıdakı əsas hərəkətləri ayırd etmək olar:

  • yaradılması və ya kursor bəyannaməsi;
  • kursoru açın, yəni. onu çoxsəviyyəli yaddaşda saxlanılan məlumatlarla doldurmaq;
  • kursordan seçim və onunla məlumat sətirlərinin dəyişdirilməsi;
  • kursoru bağlamaq, bundan sonra istifadəçi proqramları üçün əlçatmaz olur;
  • kursoru azad edir, yəni. kursorun obyekt kimi silinməsi, çünki onun bağlanması onunla əlaqəli yaddaşı mütləq boşaltmır.

Kursorun tərifi tətbiqlər arasında bir qədər fərqli ola bilər. Məsələn, bəzən tərtibatçı kursor üçün ayrılmış yaddaşı açıq şəkildə boşaltmalıdır. sonra kursoru buraxın onunla əlaqəli yaddaş da azad edilir. Bu, onun adını təkrar istifadə etməyə imkan verir. Digər tətbiqlərdə zaman kursoru bağlamaq yaddaşın boşaldılması dolayısı ilə baş verir. Bərpa edildikdən dərhal sonra digər əməliyyatlar üçün əlçatan olur: başqa kursorun açılması və s.

Bəzi hallarda kursordan istifadə qaçınılmazdır. Bununla belə, mümkünsə, bundan qaçınmalı və standart məlumat emal əmrləri ilə işləməlisiniz: SEÇ, YENİLƏNDİR, INSERT, DELETE. Kursorların məlumatın bütün həcmi üzərində modifikasiya əməliyyatlarına icazə verməməsi ilə yanaşı, kursordan istifadə edərək məlumatların işlənməsi əməliyyatlarının yerinə yetirilməsi sürəti standart SQL alətlərindən nəzərəçarpacaq dərəcədə aşağıdır.

MS SQL Server mühitində kursorların həyata keçirilməsi

SQL Server üç növ kursoru dəstəkləyir:

  • SQL kursorları əsasən triggerlər, saxlanılan prosedurlar və skriptlər daxilində istifadə olunur;
  • server kursorları serverdə işləyir və ODBC, OLE DB, DB_Library üçün proqram proqramlaşdırma interfeysini həyata keçirir;
  • Müştəri kursorları müştərinin özündə həyata keçirilir. Onlar serverdən sətirlərin bütün nəticə dəstini alır və onu yerli olaraq saxlayırlar ki, bu da şəbəkə əməliyyatlarına sərf olunan vaxtı azaltmaqla məlumatların işlənməsini sürətləndirir.

Çox istifadəçi proqramlarının müxtəlif növləri verilənlərə müxtəlif növ paralel giriş tələb edir. Bəzi proqramlar verilənlər bazasında dəyişikliklər haqqında məlumatlara dərhal daxil olmağı tələb edir. Bu, bilet bron sistemləri üçün xarakterikdir. Digər hallarda, məsələn, statistik hesabat sistemlərində məlumatların sabitliyi vacibdir, çünki onlar daim dəyişdirilirsə, proqramlar məlumatı effektiv şəkildə göstərə bilməyəcək. Fərqli proqramlar kursorların müxtəlif tətbiqlərini tələb edir.

SQL Serverdə kursor növləri təmin etdikləri imkanlara görə dəyişir. Kursor növü yaradılma mərhələsində müəyyən edilir və dəyişdirilə bilməz. Bəzi kursor növləri digər istifadəçilər tərəfindən nəticə dəstinə daxil edilmiş sətirlərdə edilən dəyişiklikləri aşkar edə bilər. Bununla belə, SQL Server yalnız cərgəyə giriş zamanı belə sətirlərdə edilən dəyişiklikləri izləyir və sətir artıq oxunduqdan sonra dəyişikliklərin dəyişdirilməsinə icazə vermir.

Kursorlar iki kateqoriyaya bölünür: ardıcıl və sürüşdürülə bilən. Ardıcıl məlumatları yalnız bir istiqamətdə - əvvəldən sona qədər seçməyə imkan verir. Kaydırılan kursorlar daha böyük hərəkət azadlığını təmin edir - hər iki istiqamətdə hərəkət etmək və kursorun nəticə dəstinin ixtiyari cərgəsinə keçmək mümkündür.Əgər proqram kursorun göstərdiyi verilənləri dəyişdirə bilirsə, ona sürüşdürülən və dəyişdirilə bilən deyilir. Kursorlardan danışarkən, əməliyyatın izolyasiyasını unutmamalıyıq. Bir istifadəçi qeydi dəyişdirəndə, digəri öz kursorundan istifadə edərək onu oxuyur və üstəlik, eyni qeydi dəyişdirə bilər ki, bu da məlumatların bütövlüyünü qorumağı zəruri edir.

SQL Server statik, dinamik, ardıcıl və düymələr dəsti ilə idarə olunur.

ilə sxemdə statik kursor məlumat verilənlər bazasından bir dəfə oxunur və snapshot kimi saxlanılır (müəyyən vaxtda), ona görə də başqa istifadəçi tərəfindən verilənlər bazasına edilən dəyişikliklər görünmür. Bir anlıq kursoru açın server tam nəticə dəstinə daxil olan bütün sətirlərdə kilid qoyur. Statik kursor yaradıldıqdan sonra dəyişmir və həmişə açıldığı anda mövcud olan məlumat dəstini göstərir.

Digər istifadəçilər mənbə cədvəlindəki kursora daxil olan məlumatları dəyişdirsələr, bu, məlumatlara təsir etməyəcək statik kursor.

IN statik kursor Dəyişikliklər etmək mümkün deyil, ona görə də həmişə yalnız oxumaq rejimində açılır.

Dinamik kursor məlumatları "canlı" vəziyyətdə saxlayır, lakin bunun üçün şəbəkə və proqram resursları tələb olunur. İstifadə dinamik kursorlar mənbə məlumatının tam surəti yaradılmır, lakin istifadəçi müəyyən məlumatlara daxil olduqda mənbə cədvəllərindən dinamik seçim həyata keçirilir. Alma zamanı server cərgələri kilidləyir və istifadəçinin kursorun tam nəticə dəstinə etdiyi hər hansı dəyişiklik kursorda görünəcək. Bununla belə, kursor məlumatları götürdükdən sonra başqa istifadəçi dəyişikliklər edibsə, onlar kursorda əks olunmayacaq.

Kursor bir sıra düymələr tərəfindən idarə olunur, bu ifratların arasında ortadadır. Qeydlər nümunə götürmə zamanı müəyyən edilir və beləliklə, dəyişikliklər izlənilir. Bu tip kursor geriyə sürüşməni həyata keçirərkən faydalıdır - sonra məlumat yenilənənə qədər cərgələrin əlavələri və silinməsi görünmür və ona dəyişikliklər edilibsə, sürücü qeydin yeni versiyasını seçir.

Ardıcıl kursorlar məlumatların əks istiqamətdə alınmasına icazə verilmir. İstifadəçi yalnız kursorun əvvəlindən sonuna qədər sətirləri seçə bilər. Serial kursor bütün sətirlərin dəstini saxlamır. Onlar kursorda seçilən kimi verilənlər bazasından oxunur ki, bu da istifadəçilər tərəfindən verilənlər bazasına edilən bütün dəyişikliklərin INSERT, UPDATE, DELETE komandalarından istifadə etməklə dinamik şəkildə əks olunmasına imkan verir. Kursor məlumatların ən son vəziyyətini göstərir.

Statik kursorlar məlumatların sabit görünüşünü təmin edir. Onlar məlumat "anbarı" sistemləri üçün yaxşıdır: hesabat sistemləri və ya statistik və analitik məqsədlər üçün tətbiqlər. Bundan başqa, statik kursor böyük həcmdə məlumatların seçilməsi ilə digərlərindən daha yaxşı öhdəsindən gəlir. Bunun əksinə olaraq, elektron alış və ya bilet bron etmə sistemləri dəyişikliklər edildikdə yenilənmiş məlumatların dinamik qavranılmasını tələb edir. Belə hallarda istifadə olunur dinamik kursor. Bu proqramlarda ötürülən məlumatların miqdarı adətən kiçik olur və sıra (fərdi qeyd) səviyyəsində əldə edilir. Qrup girişi çox nadirdir.

MS SQL Server mühitində kursorun idarə edilməsi

Kursor nəzarəti aşağıdakı əmrləri yerinə yetirməklə həyata keçirilir:

  • DECLARE - yaradılması və ya kursor bəyannaməsi;
  • AÇIQ – kursoru açın, yəni. onu məlumatlarla doldurmaq;
  • FETCH kursordan seçim və kursordan istifadə edərək məlumat sətirlərinin dəyişdirilməsi;
  • YAXIN - kursoru bağlamaq;
  • AYRILMAQ - kursoru azad edir, yəni. kursorun obyekt kimi silinməsi.

Kursor bəyannaməsi

SQL standartı kursor yaratmaq üçün aşağıdakı əmri təmin edir:

INSESITIVE açar sözündən istifadə yaradacaq statik kursor. Data dəyişiklikləri icazə verilmir, əlavə olaraq digər istifadəçilər tərəfindən edilən dəyişikliklər göstərilmir. İNSENSITIV açar sözü yoxdursa, a dinamik kursor.

SCROLL açar sözünü göstərdiyiniz zaman yaradılmış kursor istənilən istiqamətə sürüşdürilə bilər ki, bu da sizə istənilən seçim əmrlərindən istifadə etməyə imkan verir. Bu arqument buraxılıbsa, kursor olacaq ardıcıl, yəni. ona baxmaq yalnız bir istiqamətdə mümkün olacaq - əvvəldən axıra.

SELECT ifadəsi kursor üçün nəticədə sətirlər dəstini təyin edən SELECT sorğusunun gövdəsini təyin edir.

FOR READ_ONLY-in təyin edilməsi yalnız oxumaq üçün kursor yaradır və məlumatlara heç bir dəyişiklik etməyə icazə vermir. Statikdən fərqlənir, baxmayaraq ki, sonuncu da məlumatların dəyişdirilməsinə imkan vermir. Yalnız oxumaq üçün kursor kimi elan edilə bilər dinamik kursor, bu, başqa istifadəçi tərəfindən edilən dəyişiklikləri göstərməyə imkan verəcək.

FOR UPDATE arqumenti ilə kursorun yaradılması kursorda icra etməyə imkan verir məlumat dəyişikliyi ya göstərilən sütunlarda, ya da OF sütun_adı arqumenti olmadıqda, bütün sütunlarda.

MS SQL Server mühitində kursor yaratmaq əmri üçün aşağıdakı sintaksis qəbul edilir:

<создание_курсора>::= SEÇİM_İSTƏMƏSİ ÜÇÜN kursor_adı KURSOR ELAN EDİN ]]

LOCAL açar sözünün istifadəsi yalnız paketin, tetikleyicinin, saxlanılan prosedurun və ya onu yaradan istifadəçi tərəfindən müəyyən edilmiş funksiyanın əhatə dairəsində görünən yerli kursor yaradacaqdır. Paket, trigger, prosedur və ya funksiya başa çatdıqda kursor gizli şəkildə məhv edilir. Kursorun məzmununu onu yaradan konstruksiyadan kənara ötürmək üçün onun parametrinə OUTPUT arqumenti təyin etməlisiniz.

GLOBAL açar sözü təyin olunarsa, qlobal kursor yaradılır; cari əlaqə bağlanana qədər mövcuddur.

FORWARD_ONLY təyin edilməsi yaradır ardıcıl kursor; Məlumatlar yalnız birinci cərgədən sonuncuya qədər olan istiqamətdə nümunə götürülə bilər.

SCROLL-un təyin edilməsi yaradır fırlanan kursor; Məlumatlara istənilən qaydada və istənilən istiqamətdə daxil olmaq olar.

Dəqiqləşdirilməsi STATIC yaradır statik kursor.

KEYSET-in təyin edilməsi əsas kursor yaradır.

DYNAMIC-in təyin edilməsi yaradır dinamik kursor.

YALNIZ READ_FORWARD kursoru üçün FAST_FORWARD arqumentini təyin etsəniz, yaradılmış kursor sürətli məlumat əldə etmək üçün optimallaşdırılacaq. Bu arqument FORWARD_ONLY və ya OPTIMISTIC arqumentləri ilə birlikdə istifadə edilə bilməz.

OPTIMISTIC arqumenti ilə yaradılmış kursor dəyişdirilmiş sətirlərin dəyişdirilməsinin və ya silinməsinin qarşısını alır. kursoru açın.

TYPE_WARNING arqumentini təyin etməklə, server SELECT sorğusu ilə uyğun gəlmirsə, istifadəçiyə kursor növünə gizli dəyişiklik barədə məlumat verəcəkdir.

Kursorun açılması

üçün kursoru açın və onu kursoru yaratarkən göstərilən SELECT sorğusundan verilənlərlə doldurmaq üçün aşağıdakı əmrdən istifadə edin:

sonra kursoru açınƏlaqədar SELECT ifadəsi yerinə yetirilir, onun çıxışı çoxsəviyyəli yaddaşda saxlanılır.

Kursordan məlumatların alınması

Dərhal sonra kursoru açın onun məzmununu (müvafiq sorğunun icrasının nəticəsi) aşağıdakı əmrdən istifadə edərək seçə bilərsiniz:

FIRST-in göstərilməsi kursorun tam nəticə dəstinin ilk cərgəsini qaytaracaq ki, bu da cari sıraya çevrilir.

LAST-ın təyin edilməsi kursorun ən son sırasını qaytarır. O, həm də cari xəttə çevrilir.

NEXT-in təyin edilməsi tam nəticə dəstində caridən dərhal sonra cərgəni qaytarır. İndi cari olur. Varsayılan olaraq, FETCH əmri satırların alınması üçün bu üsuldan istifadə edir.

PRIOR açar sözü caridən əvvəlki sıranı qaytarır. Cari olur.

Arqument ABSOLUTE (sətir_nömrəsi | @sətir_nömrəsi_dəyişən) kursorun tam nəticə dəstində mütləq sıra nömrəsi ilə bir sıra qaytarır. Sətir nömrəsi sabitdən istifadə etməklə və ya sətir nömrəsinin saxlandığı dəyişənin adı kimi təyin edilə bilər. Dəyişən tam məlumat növü olmalıdır. Həm müsbət, həm də mənfi dəyərlər göstərilir. Müsbət dəyər təyin edilərkən, sətir çoxluğun əvvəlindən, mənfi dəyər isə sonundan sayılır. Seçilmiş xətt cari xəttə çevrilir. Əgər null dəyər göstərilibsə, heç bir sıra qaytarılmır.

Arqument RELATIVE (sətirlərin sayı | @dəyişən sıraların sayı) caridən sonra müəyyən edilmiş sətir sayı olan xətti qaytarır. Sətirlərin mənfi sayını göstərsəniz, caridən əvvəl göstərilən sətir sayı geri qaytarılacaq. Null dəyərinin təyin edilməsi cari sıranı qaytaracaq. Qaytarılan sıra cari cərgəyə çevrilir.

Kimə qlobal kursoru açın, adından əvvəl GLOBAL açar sözünü göstərməlisiniz. Kursorun adı dəyişəndən istifadə etməklə də müəyyən edilə bilər.

Dizaynda INTO @dəyişən_adı [,...n] qaytarılan sətirin müvafiq sütun dəyərlərinin saxlanacağı dəyişənlərin siyahısı müəyyən edilir. Dəyişənlərin təyin edilməsi qaydası kursordakı sütunların sırasına, dəyişənin məlumat tipi isə kursor sütunundakı məlumat növünə uyğun olmalıdır. INTO konstruksiyası göstərilməyibsə, FETCH əmrinin davranışı SELECT əmrinin davranışına bənzəyəcək - məlumatlar ekranda göstərilir.

Məlumatların dəyişdirilməsi və silinməsi

Kursordan istifadə edərək dəyişiklik etmək üçün aşağıdakı formatda UPDATE əmri verməlisiniz:

Cari kursor sırasının bir neçə sütunu bir əməliyyatda dəyişdirilə bilər, lakin onların hamısı eyni cədvələ aid olmalıdır.

Kursordan istifadə edərək məlumatları silmək üçün aşağıdakı formatda DELETE əmrindən istifadə edin:

Nəticədə kursordakı cari xətt dəsti silinəcək.

Kursorun bağlanması

Bağlandıqdan sonra kursor proqram istifadəçiləri üçün əlçatmaz olur. Bağlandıqda, onun istismarı zamanı quraşdırılmış bütün kilidlər çıxarılır. Bağlama yalnız açıq kursorlara tətbiq edilə bilər. Bağlanıb amma yox sərbəst kursor yenidən açıla bilər. Açılmamış kursorun bağlanmasına icazə verilmir.

Kursoru buraxın

Kursorun bağlanması onunla əlaqəli yaddaşı mütləq azad etmir. Bəzi tətbiqlər DEALLOCATE bəyanatından istifadə edərək onu açıq şəkildə ayırmalıdır. sonra kursoru buraxın Yaddaş da boşaldılır ki, bu da kursorun adını təkrar istifadə etməyə imkan verir.

Kursorun sonuna çatılıb-çatılmadığını idarə etmək üçün funksiyadan istifadə etmək tövsiyə olunur: @@FETCH_STATUS

@@FETCH_STATUS funksiyası qaytarır:

0 gətirmə uğurlu olarsa;

1 kursordan kənar bir sətir götürmək cəhdinə görə gətirmə uğursuz olarsa;

2 silinmiş və ya dəyişdirilmiş cərgəyə daxil olmaq cəhdi səbəbindən əldə etmə uğursuz olarsa.

ELAN EDİN @id_kl INT, @firm VARCHAR(50), @fam VARCHAR(50), @message VARCHAR(80), @nam VARCHAR(50), @d DATETIME, @p INT, @s INT SET @s=0 PRINT "Alış-veriş siyahısı" klient_kursorunu SEÇMƏK ÜÇÜN YERLİ ELAN EDİN Müştəri Kodu, Şirkət, Soyadı Müştəridən HARADA Şəhər="Moskva" Şirkət tərəfindən SİFARİŞ OLUNUR, Soyadı AÇIQ klient_kursoru NÖVBƏYİ klient_kursordan @id_kl, @CHHILEST_, @ATST_ DAXİLƏ GETİRİN =0 BAŞLAYIN SEÇİN @message="Müştəri "+@fam+ "Şirkət"+ @firm PRINT @message SELECT @message="Məhsulun adı Satınalma tarixi Xərc" PRINT @message SEÇİLMƏK ÜÇÜN tovar_kursor KURSOR ELAN EDİN Məhsul.Ad, Əməliyyat.Tarix, Məhsul .Qiymət* Əməliyyat.Məhsul DAXİLİNDƏN XƏBƏRLƏR KİMİ Məhsulda Əməliyyata QOŞULUN. Məhsul Kodu=Transaction.Məhsul Kodu HARƏDƏ Tranzaksiya.Müştəri Kodu=@id_kl AÇIQ tovar_cursor tovar_cursor-DAN NÖVBƏYİ GƏTİRİN @nam, @d, @p ƏGƏR @@FETCH_STATUS<>0 @@FETCH_STATUS=0 BAŞLADIĞINDA "Satınalma yoxdur" ÇAP SEÇİN @message=" "+@nam+" "+ YAYIM(@d KİMİ CHAR(12))+" "+ YAYIM(@p KİMİ CHAR(6)) ÇAP @message SET @s=@s+@p tovar_cursorDAN NÖVBƏYİ GƏTİRİN @nam, @d, @p SON YAPIN tovar_cursor SEÇİM @message="Ümumi xərc "+ CHAR(6) KİMİ YAYIM(@s) @message çap edin -- növbəti müştəriyə keçin-- klient_kursorundan NÖVBƏYİ GƏTİRİN @id_kl, @firm, @fam İÇİNƏ SON BAĞLAYIN klient_kursoru BOŞALTIN Misal 13.6. Moskvadan müştərilər tərəfindən alınan malların siyahısını və onların ümumi dəyərini göstərmək üçün kursor.

Misal 13.7. Moskvadan olan müştərilər üçün fırlanan kursor hazırlayın. Telefon nömrəsi 1 ilə başlayırsa, həmin nömrə ilə müştərini silin və ilk kursor girişində telefon nömrəsindəki ilk rəqəmi 4 ilə əvəz edin.

ELAN EDİN @firm VARCHAR(50), @fam VARCHAR(50), @tel VARCHAR(8), @message VARCHAR(80) "Müştərilərin siyahısı" ÇAP EDİN klient_kursoru SEÇMƏK ÜÇÜN KURSOR QLOBAL DÖNDÜŞ DÜŞƏRİ DÜŞÜK SEÇİMİ Firma, Soyad, Telefon F. HARADA Şəhər ="Moskva" Şirkət tərəfindən SİFARİŞ EDİLİR, Soyad YENİLƏNMƏ ÜÇÜN AÇIQ klient_kursoru klient_kursordan NÖVBƏYİ GƏTİRİN @firm, @fam, @tel İÇİNƏ @@FETCH_STATUS=0 BAŞLAYIN SEÇİM @message="Müştəri "+@fam+ " Şirkət "+ @firm " Telefon "+ @tel PRINT @message -- telefon nömrəsi 1 ilə başlayırsa, -- həmin nömrəli müştərini silin ƏGƏR @tel '1%' BƏYƏNDİRƏSƏ, KLİENT_kursorunun CARİ YERİNƏ MÜŞTƏRİNİ SİLİN BAŞQA -- növbətiyə keçin müştəri klient_kursordan @firm, @fam, @tel İÇİN NÖVBƏYİ GƏTİRİN SON MÜTLƏQ 1 klient_kursordan @firm, @fam, @tel-ə GƏLİN -- ilk girişdə telefon nömrəsindəki ilk rəqəmi 4 ilə əvəz edin. ='4' + RIGHT(@ tel,LEN(@tel)-1)) klient_kursorun cari olduğu yerdən SEÇİN @message="Müştəri "+@fam+" Firma "+ @firm "Telefon"+ @tel PRINT @message KLİENT_kursorunu YAPIN klient_kursorunu BOŞALTIN Misal 13.7. Moskvadan olan müştərilər üçün fırlanan kursor.

Misal 13.8.İstifadəsi kursor prosedurun çıxış parametri kimi. Prosedur məlumat dəstini qaytarır - məhsulların siyahısı.

Proseduru çağırmaq və məlumatların çıxış kursorundan çapı aşağıdakı kimi həyata keçirilir:

DECLARE @my_cur KURSOR ELAN EDİN @n VARCHAR(20) EXEC my_proc @cur=@my_cur ÇIXIŞ GƏTİRİN @my_cur FROMDAN SONRAKİ @n SEÇİN @n HƏYDİ (@@FETCH_STATUS=0) @n_curn NONDAN GƏTİRİN @n_curn SON BAXIN @my_cur BÖYÜKLƏRİN @my_cur




Üst