Bagikan melalui


Pengetikan XQuery dan Statis

Berlaku untuk:SQL Server

XQuery di SQL Server adalah bahasa yang diketik secara statis. Artinya, ini menimbulkan kesalahan jenis selama kompilasi kueri saat ekspresi mengembalikan nilai yang memiliki jenis atau kardinalitas yang tidak diterima oleh fungsi atau operator tertentu. Selain itu, pemeriksaan tipe statis juga dapat mendeteksi apakah ekspresi jalur pada dokumen XML yang ditik telah salah ketik. Pengkompilasi XQuery pertama-tama menerapkan fase normalisasi yang menambahkan operasi implisit, seperti atomisasi, lalu melakukan inferensi jenis statis dan pemeriksaan jenis statis.

Inferensi Tipe Statis

Inferensi jenis statis menentukan jenis pengembalian ekspresi. Ini menentukan ini dengan mengambil jenis statis parameter input dan semantik statis operasi dan menyimpulkan jenis statis hasilnya. Misalnya, jenis statis ekspresi 1 + 2.3 ditentukan dengan cara berikut:

  • Jenis statis 1 adalah xs:integer dan jenis statis 2.3 adalah xs:desimal. Berdasarkan semantik dinamis, semantik + statis operasi mengonversi bilangan bulat menjadi desimal lalu mengembalikan desimal. Jenis statis yang disimpulkan kemudian akan menjadi xs:desimal.

Untuk instans XML yang tidak dijenis, ada jenis khusus untuk menunjukkan bahwa data tidak ditik. Informasi ini digunakan selama pemeriksaan jenis statis dan untuk melakukan cast implisit tertentu).

Untuk data yang diketik, jenis input disimpulkan dari koleksi skema XML yang membatasi instans jenis data XML. Misalnya, jika skema hanya mengizinkan elemen jenis xs:integer, hasil ekspresi jalur menggunakan elemen tersebut akan menjadi nol atau lebih elemen jenis xs:integer. Ini saat ini dinyatakan dengan menggunakan ekspresi seperti element(age,xs:integer)* di mana tanda bintang (*) menunjukkan kardinalitas jenis yang dihasilkan. Dalam contoh ini, ekspresi dapat mengakibatkan nol atau lebih elemen nama "usia" dan mengetik xs:integer. Kardinalitas lain persis satu dan dinyatakan dengan menggunakan nama jenis saja, nol atau satu dan dinyatakan dengan menggunakan tanda tanya (?), dan 1 atau lebih dan dinyatakan dengan menggunakan tanda plus (+).

Terkadang, inferensi jenis statis dapat menyimpulkan bahwa ekspresi akan selalu mengembalikan urutan kosong. Misalnya, jika ekspresi jalur pada jenis data XML yang diketik mencari <elemen nama> di dalam <elemen pelanggan> (/pelanggan/nama), tetapi skema tidak mengizinkan <nama> di dalam <pelanggan>, inferensi jenis statis akan menyimpulkan bahwa hasilnya akan kosong. Ini akan digunakan untuk mendeteksi kueri yang salah dan akan dilaporkan sebagai kesalahan statis, kecuali ekspresinya () atau data( () ).

Aturan inferensi terperinci disediakan dalam semantik formal spesifikasi XQuery. Microsoft telah memodifikasi ini hanya sedikit untuk bekerja dengan instans jenis data XML yang ditik. Perubahan terpenting dari standar adalah bahwa simpul dokumen implisit tahu tentang jenis instans jenis data XML. Akibatnya, ekspresi jalur formulir /usia akan ditik dengan tepat berdasarkan informasi tersebut.

Dengan menggunakan Templat dan Izin Profiler SQL Server, Anda dapat melihat jenis statis yang dikembalikan sebagai bagian dari kompilasi kueri. Untuk melihat ini, jejak Anda harus menyertakan peristiwa XQuery Static Type dalam kategori peristiwa TSQL.

Pemeriksaan Tipe Statis

Pemeriksaan jenis statis memastikan bahwa eksekusi run-time hanya akan menerima nilai yang merupakan jenis yang sesuai untuk operasi. Karena jenis tidak harus diperiksa pada waktu proses, potensi kesalahan dapat dideteksi di awal kompilasi. Ini membantu meningkatkan performa. Namun, pengetikan statis mengharuskan penulis kueri lebih berhati-hati dalam merumuskan kueri.

Berikut ini adalah jenis yang sesuai yang dapat digunakan:

  • Jenis yang secara eksplisit diizinkan oleh fungsi atau operasi.

  • Subjenis jenis yang diizinkan secara eksplisit.

Subjenis ditentukan, berdasarkan aturan subjenis untuk menggunakan derivasi dengan pembatasan atau ekstensi skema XML. Misalnya, jenis S adalah subjenis jenis T, jika semua nilai yang memiliki jenis S juga merupakan instans dari jenis T.

Selain itu, semua nilai bilangan bulat juga merupakan nilai desimal, berdasarkan hierarki jenis skema XML. Namun, tidak semua nilai desimal adalah bilangan bulat. Oleh karena itu, bilangan bulat adalah subtipe desimal, tetapi bukan sebaliknya. Misalnya, + operasi hanya mengizinkan nilai jenis tertentu, seperti jenis numerik xs:integer, xs:decimal, xs:float, dan xs:double. Jika nilai jenis lain, seperti xs:string, diteruskan, operasi akan menimbulkan kesalahan jenis. Ini disebut sebagai pengetikan yang kuat. Nilai jenis lain, seperti jenis atom yang digunakan untuk menunjukkan XML yang tidak diketik, dapat dikonversi secara implisit ke nilai jenis yang diterima operasi. Ini disebut sebagai pengetikan yang lemah.

Jika diperlukan setelah konversi implisit, pemeriksaan jenis statis menjamin bahwa hanya nilai jenis yang diizinkan dengan kardinalitas yang benar yang diteruskan ke operasi. Untuk "string" + 1, ia mengenali bahwa jenis statis "string" adalah xs:string. Karena ini bukan tipe yang diizinkan untuk + operasi, kesalahan jenis dimunculkan.

Dalam kasus menambahkan hasil ekspresi arbitrer E1 ke ekspresi arbitrer E2 (E1 + E2), inferensi jenis statis terlebih dahulu menentukan jenis statis E1 dan E2 lalu memeriksa jenis statisnya dengan jenis yang diizinkan untuk operasi. Misalnya, jika jenis statis E1 dapat berupa xs:string atau xs:integer, pemeriksaan jenis statis menimbulkan kesalahan jenis, meskipun beberapa nilai pada durasi mungkin bilangan bulat. Hal yang sama akan terjadi jika jenis statis E1 adalah xs:integer*. + Karena operasi hanya menerima tepat satu nilai bilangan bulat dan E1 dapat mengembalikan nol atau lebih dari 1, pemeriksaan jenis statis menimbulkan kesalahan.

Seperti disebutkan sebelumnya, inferensi jenis sering menyimpulkan jenis yang lebih luas dari apa yang diketahui pengguna tentang jenis data yang sedang diteruskan. Dalam kasus ini, pengguna harus menulis ulang kueri. Beberapa kasus umum termasuk yang berikut ini:

  • Jenis menyimpulkan jenis yang lebih umum seperti supertype atau persatuan jenis. Jika jenisnya adalah jenis atom, Anda harus menggunakan ekspresi cast atau fungsi konstruktor untuk menunjukkan jenis statis aktual. Misalnya, jika jenis ekspresi E1 yang disimpulkan adalah pilihan antara xs:string atau xs:integer dan penambahan memerlukan xs:integer, Anda harus menulis xs:integer(E1) + E2 alih-alih E1+E2. Ekspresi ini mungkin gagal pada waktu proses jika nilai string ditemukan yang tidak dapat ditransmisikan ke xs:integer. Namun, ekspresi sekarang akan melewati pemeriksaan jenis statis. Ekspresi ini dipetakan ke urutan kosong.

  • Jenis menyimpulkan kardinalitas yang lebih tinggi daripada apa yang sebenarnya dikandung data. Ini sering terjadi, karena tipe data xml dapat berisi lebih dari satu elemen tingkat atas, dan kumpulan skema XML tidak dapat membatasi ini. Untuk mengurangi jenis statis dan menjamin bahwa memang ada paling banyak satu nilai yang diteruskan, Anda harus menggunakan predikat [1]posisional . Misalnya, untuk menambahkan 1 ke nilai atribut c elemen b di bawah elemen tingkat atas, Anda harus write (/a/b/@c)[1]+1. Selain itu, kata kunci DOKUMEN dapat digunakan bersama dengan koleksi skema XML.

  • Beberapa operasi kehilangan informasi jenis selama inferensi. Misalnya, jika jenis node tidak dapat ditentukan, itu menjadi anyType. Ini tidak secara implisit dilemparkan ke jenis lain. Konversi ini paling sering terjadi selama navigasi dengan menggunakan sumbu induk. Anda harus menghindari penggunaan operasi tersebut dan menulis ulang kueri, jika ekspresi akan membuat kesalahan jenis statis.

Pengecekan Jenis Serikat

Jenis serikat memerlukan penanganan yang cermat karena pemeriksaan jenis. Dua masalah diilustrasikan dalam contoh berikut.

Contoh: Fungsi melalui Jenis Union

Pertimbangkan definisi elemen untuk <r> jenis gabungan:

<xs:element name="r">  
<xs:simpleType>  
   <xs:union memberTypes="xs:int xs:float xs:double"/>  
</xs:simpleType>  
</xs:element>  

Dalam konteks XQuery, fungsi fn:avg (//r) "rata-rata" mengembalikan kesalahan statis, karena pengkompilasi XQuery tidak dapat menambahkan nilai dari jenis yang berbeda (xs:int, xs:float atau xs:double) untuk <r> elemen dalam argumen fn:avg(). Untuk mengatasinya, tulis ulang pemanggilan fungsi sebagai fn:avg(for $r in //r return $r cast as xs:double ?).

Contoh: Operator melalui Jenis Union

Operasi penambahan ('+') memerlukan jenis operand yang tepat. Akibatnya, ekspresi (//r)[1] + 1 mengembalikan kesalahan statis yang memiliki definisi jenis yang dijelaskan sebelumnya untuk elemenr<> . Salah satu solusinya adalah menulis ulang sebagai (//r)[1] cast as xs:int? +1, di mana "?" menunjukkan 0 atau 1 kemunculan. SQL Server memerlukan "cast as" dengan "?", karena setiap cast dapat menyebabkan urutan kosong sebagai akibat dari kesalahan run-time.

Lihat Juga

Referensi Bahasa XQuery (SQL Server)