Oracle'dan SQL Server'a ve SQL Server'dan Oracle'a Geçiş Kılavuzu
Yayınlanan: 2022-03-11“Satıcı bağımlılığı” birçok işletme yöneticisi için korkutucu bir kelimedir. Öte yandan, tam bir “satıcı bağımsızlığının” elde edilemeyeceği sektörde zaten yaygın olarak anlaşılmıştır. Ve bu özellikle veritabanları için geçerlidir.
En yaygın kurumsal RDBMS platformlarından ikisi Oracle Database ve Microsoft SQL Server'dır (kısaca, bu makalenin geri kalanında bunlara sırasıyla “Oracle” ve “SQL Server” diyeceğim). Elbette, IBM Db2, Oracle ile sürekli küçülen - ancak yine de birçok alanda kritik olan - ana bilgisayar platformlarında rekabet ediyor. Ve PostgreSQL gibi hızla gelişen açık kaynak alternatifleri, düşük-orta seviye ticari donanım ve web üzerindeki dinamik ortamlarda sağlam bir zemin kazanıyor.
Ancak Oracle ve SQL Server , kuruluşlarının yeni bir RDBMS'ye ihtiyacı olduğunda birçok işletme yöneticisinin karşılaştığı bir seçimdir. Nihai seçim birden fazla faktöre dayanmaktadır: lisans maliyeti, mevcut dahili uzmanlık ve geçmiş deneyim, mevcut ortamlarla uyumluluk, ortak ilişkileri, gelecekteki iş planları vb. Ancak en kapsamlı ön değerlendirme ve en iyi eğitimli karar verme ile bile, bazen faktörler değişir ve ardından platformun da değişmesi gerekir. Bunu biliyorum çünkü kariyerim boyunca bu tür geçişleri iki kez uyguladım, geçiş fizibilitesinin değerlendirmesini bir kez hazırladım ve şu anda platformlar arası işlevsellik geçişi üzerinde çalışıyorum.
Hem Oracle hem de SQL Server, "eski okul", kısmen ANSI uyumlu RDBMS uygulamalarıdır. Prosedürel uzantıları bir kenara bırakırken (PL/SQL ve Transact-SQL'in farklı sözdizimleri vardır, ancak bunlar arasında çeviri yapmak genellikle basittir) ve daha yeni nesne yönelimli gelecekler, SQL kodu aldatıcı bir şekilde benzer görünebilir. Ve bu tehlikeli bir bal tuzağıdır.
Oracle ve SQL Server arasındaki (her iki yönde) herhangi bir geçiş projesi için en kritik noktalardan ikisi, işlem kapsamını çözmede önemli bir araç olan işlemler ve yakından ilişkili geçici tablolardır . Ayrıca, Oracle'da kullanıcı güvenliği denetiminin uygulanmasının önemli bir parçası olduklarından, başka bir işlemin kapsamında bulunan iç içe işlemleri de ele alacağız. Ancak SQL Server'da, kullanıcı güvenliği denetimi, bu bağlamda COMMIT
davranışı nedeniyle farklı bir yaklaşıma ihtiyaç duyar.
İşlem Yapısını Anlamak: Oracle ile SQL Server'ı On Bin Feet'ten Gözlemlemek
Oracle işlemleri örtüktür. Bu, bir işlem başlatmanıza gerek olmadığı anlamına gelir - her zaman bir işlem içindesiniz. Ve bu işlem, siz bir taahhüt veya geri alma bildirimi yayınlayana kadar açıktır. Evet, açıkça bir işlem başlatabilir, geri alma güvenli noktaları tanımlayabilir ve iç/iç içe işlemleri ayarlayabilirsiniz; ancak önemli olan, asla "bir işlemde bulunmamanız" ve her zaman bir taahhütte bulunmanız veya geri alma yapmanız gerektiğidir. Ayrıca, bir veri tanımlama dili (DDL) deyimi ( CREATE
, ALTER
, vb.; bir işlemde dinamik SQL aracılığıyla yapılabilir) yayınlamanın, verildiği işlemi taahhüt ettiğini unutmayın.
Oracle'dan farklı olarak, SQL Server'ın açık işlemleri vardır. Bu, açıkça bir işlem başlatmadığınız sürece, tüm değişikliklerinizin "otomatik olarak" taahhüt edileceği anlamına gelir - her DML ifadesi ( INSERT
, UPDATE
, DELETE
) kendi başına bir işlem oluşturduğu ve hata yapmadığı sürece taahhüt ettiği için, ifadeniz işlendiği anda hemen dışarı.
Bu, veri depolama uygulamalarındaki - verilerin bir veritabanına nasıl yazıldığı ve veritabanı motorunun onu nasıl okuduğu arasındaki farkın sonucudur.
Oracle'da DML deyimleri, kayıtları doğrudan veri dosyasında değiştirir. Kaydın eski kopyası (veya INSERT
olması durumunda boş kayıt ikamesi) mevcut geri alma dosyasına yazılır ve değişikliğin tam zamanı kayıtta işaretlenir.
Bir SELECT
ifadesi yayınlandığında, yayınlanmadan önce değiştirilmiş verilere dayalı olarak işlenir. SELECT
yayınlandıktan sonra herhangi bir kayıt değiştirilmişse, Oracle geri alma dosyasındaki eski sürümü kullanır.
Oracle, okuma tutarlılığını ve bloke edici olmayan okuma/yazmayı bu şekilde uygulamıştır. Çok aktif işlemsel veritabanlarında uzun süredir devam eden sorguların bazen ORA-01555, snapshot too old: rollback segment ... too small
gibi kötü bir hatayla karşılaşmasının nedeni de budur. (Bu, kaydın eski bir sürümü için sorgunun ihtiyaç duyduğu geri alma dosyasının zaten yeniden kullanıldığı anlamına gelir.) Bu nedenle “Oracle işlemim ne kadar sürmeli?” Sorusuna doğru cevap budur. "Gerektiği kadar ve artık değil."
SQL Server'ın uygulaması farklıdır: Veritabanı motoru yalnızca veri dosyalarına/dosyalardan doğrudan yazar ve okur. Her SQL ifadesi ( SELECT
/ INSERT
/ UPDATE
/ DELETE
), birden çok ifadeyi birlikte gruplandıran ve değişikliklerin geri alınmasına izin veren açık bir işlemin parçası olmadığı sürece bir işlemdir.
Her işlem ihtiyaç duyduğu kaynakları kilitler. Microsoft SQL Server'ın mevcut sürümleri, yalnızca ihtiyaç duyulan kaynakları kilitleme konusunda yüksek düzeyde optimize edilmiştir, ancak ihtiyaç duyulan şey SQL kodu tarafından tanımlanır; bu nedenle sorgularınızı optimize etmek çok önemlidir). Yani, Oracle'dan farklı olarak, SQL Server'daki işlemler mümkün olduğunca kısa olmalıdır ve bu nedenle otomatik taahhütler varsayılan davranıştır.
Ve Oracle ve SQL Server'daki hangi SQL yapısı, işlem uygulamalarındaki farklılıktan etkilenir? Sıcaklık tabloları.
Oracle ve SQL Server'da Geçici Tablolar
ANSI SQL Standard, yerel ve genel geçici tabloları tanımladığında, bunların nasıl uygulanması gerektiğini açıkça belirtmez. Hem Oracle hem de SQL Server, global geçici tablolar uygular. SQL Server ayrıca yerel geçici tablolar da uygular. Oracle 18c aynı zamanda "gerçek" yerel geçici tablolar da uygulamıştır ("özel geçici tablolar" olarak adlandırırlar). otomatik artan kimlik sütunları gibi özellikler.
Ancak saf bir işlevsel analiz perspektifinden bakıldığında, SQL Server'dan Oracle'a geçiş sorunlarının olduğundan daha az görünmesine neden olduğu için özel geçici tabloların eklenmesi karışık bir nimet olabilir. Bu başka bir bal tuzağıdır, çünkü kendi başına bazı yeni zorluklar ortaya çıkarabilir. Örneğin, tasarım zamanı kod doğrulaması özel geçici tablolarda yapılamaz, bu nedenle bunları kullanan herhangi bir kod her zaman daha fazla hataya açık olacaktır. Dinamik SQL kullandıysanız, bunu şöyle açıklayalım: Özel geçici tablolarda hata ayıklamak da aynı derecede karmaşıktır, ancak görünürde benzersiz bir kullanım durumu yoktur. Bu nedenle Oracle neden daha önce değil, yalnızca 18c'de yerel (özel) geçici tablolar ekledi.
Kısacası, Oracle'da aynı veya daha iyi küresel geçici tablolar kullanılarak uygulanamayan özel geçici tablolar için bir kullanım durumu görmüyorum. Dolayısıyla herhangi bir ciddi dönüşüm için Oracle ve SQL Server global geçici tabloları arasındaki farkı anlamamız gerekir.
Oracle ve SQL Server'da Global Geçici Tablolar
Oracle global geçici tablosu, tasarım zamanında bir DDL deyimi tarafından açıkça oluşturulan kalıcı bir veri sözlüğü nesnesidir. Yalnızca veritabanı düzeyinde bir nesne olduğu ve gerekli izinlere sahip herhangi bir veritabanı oturumu tarafından erişilebilir olduğu için “küreseldir”. Ancak, yapısı global olmasına rağmen, global bir geçici tablodaki tüm verilerin kapsamı yalnızca içinde çalıştığı oturuma yöneliktir ve hiçbir koşulda bu oturumun dışında görünmez. Başka bir deyişle, diğer oturumlar, aynı genel geçici tablonun kendi kopyalarında kendi verilerine sahip olabilir. Bu nedenle, Oracle'da, çoğunlukla PL/SQL'de kod basitleştirme ve performans optimizasyonu için kullanılan, yerel oturum verilerini tutan bir küresel geçici tablo.
SQL Server'da, genel bir geçici tablo, bir Transact-SQL kodu bloğunda oluşturulan geçici bir nesnedir. Oluşturma oturumu açık olduğu sürece var olur ve hem yapı hem de veri olarak veritabanındaki diğer oturumlar tarafından görülebilir. Bu nedenle, oturumlar arasında veri paylaşımı için küresel bir geçici nesnedir.
SQL Server'daki yerel bir geçici tablo, yalnızca onu oluşturan oturumda erişilebilir olmasıyla genel olanlardan farklıdır. Ve SQL Server'da yerel geçici tabloların kullanımı, genel geçici tabloların kullanımından çok daha yaygındır (ve veritabanı performansı için daha kritik olduğunu söyleyebilirim).
Peki, SQL Server'da yerel geçici tablolar nasıl kullanılır ve bunlar Oracle'a nasıl çevrilmelidir?
SQL Server'da yerel geçici tabloların kritik (ve doğru) kullanımı, özellikle işlem kaynak kilidini kısaltmak veya kaldırmaktır:
- Bir kayıt kümesinin bazı toplamalar tarafından işlenmesi gerektiğinde
- Veri setinin analiz edilmesi ve değiştirilmesi gerektiğinde
- Aynı veri kümesinin aynı kapsamda birden çok kez kullanılması gerektiğinde
Bu durumlarda, kilidi kaynak tablodan kaldırmak için bu kayıt kümesini yerel bir geçici tabloya seçmek genellikle daha iyi bir çözümdür.
SQL Server'daki yaygın tablo ifadelerinin (CTE'ler, yani WITH <alias> AS (SELECT...)
ifadeleri) yalnızca "sözdizimsel şeker" olduğunu belirtmekte fayda var. SQL yürütmesinden önce satır içi alt sorgulara dönüştürülürler. Oracle CTE'leri (bir /*+ materialize */
ipucu ile) performans açısından optimize edilmiştir ve materyalleştirilmiş bir görünümün geçici bir versiyonunu oluşturur. Oracle'ın yürütme yolunda, CTE'ler kaynak verilere yalnızca bir kez erişir. Bu farka dayalı olarak, SQL Server, bir Oracle sorgusunda yapılabileceği gibi, aynı CTE'ye birden çok referans yerine yerel geçici tablolar kullanarak daha iyi performans gösterebilir.

İşlem uygulamaları arasındaki fark nedeniyle, geçici tablolar da farklı bir işlev görür. Sonuç olarak, SQL Server geçici tablolarını Oracle'a “olduğu gibi” taşımak (Oracle 18c'nin özel geçici tabloları uygulamasıyla bile) yalnızca performansa zarar vermekle kalmaz, aynı zamanda işlevsel olarak da yanlış olabilir.
Öte yandan - Oracle'dan SQL Server'a geçerken - işlem uzunluğuna, global geçici tabloların görünürlük kapsamına ve “materyalize edilmiş” ipucu ile CTE bloklarının performansına dikkat edilmesi gerekir.
Her iki durumda da, taşınan kod geçici tablolar içerdiğinde, kod çevirisinden değil, sistemin yeniden uygulanmasından bahsetmeliyiz.
Tablo Değişkenlerini Girin
Geliştiriciler muhtemelen şunu merak edeceklerdir: Peki ya tablo değişkenleri? Herhangi bir değişiklik yapmamız gerekiyor mu veya Oracle-SQL-Server geçiş adımlarımızda tablo değişkenlerini "olduğu gibi" taşıyabilir miyiz? Bu, kodda neden ve nasıl kullanıldığına bağlıdır.
Hem geçici tabloların hem de tablo değişkenlerinin nasıl kullanılabileceğine bakalım. Microsoft SQL Server ile başlayacağım.
Tablo değişkenlerinin Transact-SQL'de uygulanması, geçici tablolarla bir şekilde eşleşir, ancak kendine ait bazı işlevler ekler. Temel fark, tablo değişkenlerini işlevlere ve saklı yordamlara parametre olarak geçirme yeteneğidir.
Bu teori, ancak pratik kullanım hususları biraz daha ilgili.
Köklü bir Oracle arka planından gelirken ilk olarak ciddi Transact-SQL optimizasyonu ile görevlendirildim, bunun böyle olmasını bekliyordum: geçici tablolar diskteyken tablo değişkenleri bellekte. Ancak 2014'e kadar olan Microsoft SQL Server sürümlerinin tablo değişkenlerini bellekte saklamadığını buldum. Bu nedenle, geçici bir değişken üzerinde tam tablo taraması, gerçekten de diskte tam bir tablo taramasıdır. Neyse ki, SQL Server 2017 ve sonraki sürümler, hem geçici tablolar hem de tablo değişkenleri için bildirimsel bellek optimizasyonunu destekler.
Peki, geçici tablolar kullanılarak her şey iyi veya daha iyi yapılabiliyorsa, Transact-SQL'deki tablo değişkenlerinin kullanım durumu nedir? Bir tablo değişkeninin bir değişken olması ve bu nedenle işlemin geri alınmasından etkilenmemesi ve bir parametre olarak iletilebilmesi anahtar özelliği.
Transact-SQL işlevleri çok kısıtlayıcıdır: Bir işlevin görevi tekil bir dönüş değeri döndürmek olduğundan, tasarımı gereği yan etkileri olamaz . Transact-SQL, SELECT
bile bir yan etki olarak görür, çünkü SQL Server'da bir tabloya herhangi bir erişim, örtük bir işlem ve ilişkili işlem kilidi oluşturur. Bu, bir işlevin içinde, mevcut bir geçici tablodaki verilere erişemeyeceğimiz veya geçici bir tablo oluşturamayacağımız anlamına gelir. Sonuç olarak, herhangi bir kayıt kümesini bir fonksiyona geçirmemiz gerekirse, tablo değişkenlerini kullanmak zorundayız .
Oracle'ın (genel) geçici tabloları ve koleksiyon değişkenlerini (Transact-SQL tablo değişkenlerinin Oracle PL/SQL eşdeğeri) kullanmaya yönelik düşünceleri farklıdır. Oracle koleksiyon değişkenleri bellekteyken, geçici tablolar geçici tablo alanlarında bulunur. Oracle işlevleri, kalıcı veya geçici tablolara salt okunur erişime izin verir; Oracle'daki basit bir SELECT
, kaynaklara asla kilitlenmez.
Oracle'da, geçici tablolara karşı toplama değişkenlerini kullanma seçimi, beklenen veri miktarına, bu verilerin korunması gereken süreye ve belleğe karşı disk tahsisi ve kullanılabilirliğine bağlıdır. Ayrıca, toplama değişkenleri, bir ana bilgisayar programına çıktı olarak bir satır kümesi almanın standart yoludur.
SQL sözdizimi öğelerinin çoğu SQL Server ve Oracle arasında çok benzer göründüğünden, SQL Server Transact-SQL'den tablo değişkenleriyle kod bloklarının Oracle PL/SQL'e dönüştürülmesi daha basit ve sözdizimsel olarak daha bağışlayıcı bir işlemdir. Temel bir doğrulama testini geçebilir, ancak yukarıda belirtildiği gibi geçici tablo yeniden uygulama adımları uygulanmadıkça işlevsel olarak doğru olmayacaktır. Öte yandan, Oracle'dan SQL Server'a taşınan kod, yalnızca sözdizimsel olarak geçerli olması için daha fazla değişiklik adımı içerir. İşlevsel olarak da doğru olması için, geçici tabloların ve CTE'lerin kullanımına ilişkin derinlemesine vakaları ele alması gerekecektir.
İç İşlemler (“İç İçe İşlemler”)
Oracle'dan SQL Server'a geçiş zorlukları açısından bakılacak bir sonraki ana alan iç içe işlemlerdir.
Tıpkı geçici tablolarda olduğu gibi, eğer Transact-SQL kodu iç içe veya iç içe herhangi bir işlem içeriyorsa veya Oracle kodu herhangi bir iç içe işlem içeriyorsa, yalnızca bir düz kod geçişinden değil, işlevsel yeniden uygulamadan bahsediyoruz.
İlk olarak, Oracle iç içe işlemlerin nasıl davrandığına ve bunları nasıl kullanma eğiliminde olduğumuza bakalım.
Oracle'da İç İçe İşlemler
Oracle iç içe işlemler tamamen atomiktir ve dış kapsamdan bağımsızdır. Düz etkileşimli Oracle SQL sorgularında iç içe işlemler için gerçek bir kullanım yoktur. Oracle ile etkileşimli modda çalışırken, bir duruma geldiğinizi gördüğünüzde değişikliklerinizi manuel olarak kabul edersiniz. Geri alınması gerekebilecek son adımı - örneğin sizin için belirsiz olan - yapana kadar henüz taahhüt edemeyeceğiniz bazı değişiklikler yaptıysanız, ancak zaten yapmış olduğunuz işi korumak istiyorsanız, tüm işlemi taahhüt etmeden veya geri almadan geri almak için bir güvenli nokta oluşturacaksınız.
Peki, iç içe işlemler nerede kullanılır? PL/SQL kodunda. Daha spesifik olarak, özerk prosedürlerde— PRAGMA AUTONOMOUS_TRANSACTION
ile beyan edilenler. Bu, bu kod çağrıldığında (adlandırılmış bir saklı yordam olarak veya anonim olarak), işlemin bu kodu çağıran işlemden bağımsız olarak taahhüt edildiği veya geri alındığı anlamına gelir.
İç içe işlemleri kullanmanın amacı, çağrı koduna ne olacağından bağımsız olarak, bağımsız bir iş biriminin taahhüt edilmesini veya geri alınmasını sağlamaktır. Bir iç işlem gerçekleştirilebildiğinde veya geri alınabildiğinde, paylaşılan kaynakların kullanılabilirliğini kontrol etmek (veya rezerve etmek) için kullanılacaktır - örneğin bir oda rezervasyon sisteminin uygulanmasında. Yalnızca taahhütlü dahili işlemler için birincil kullanım, etkinlik izleme, kod izleme ve güvenli erişim denetimidir (yani, bir kullanıcının değişiklik yapmasına izin verilmedi, ancak denendi).
SQL Server Transact-SQL kodundaki iç içe işlemler tamamen farklıdır.
SQL Server'da İç İçe İşlemler
Transact-SQL'de, bir iç işlemin tamamen tamamlanıp tamamlanmadığı, en dıştaki işleme bağlıdır. Bir iç işlem geri alındıysa, sadece geri alınır. Ancak bir iç işlem taahhüt edilmişse, dış kapsam işleminin herhangi bir düzeyi geri alınırsa geri alınabileceğinden, yine de tam olarak taahhüt edilmez.
Öyleyse, dış işlemini geri alarak taahhütleri geri alınabiliyorsa, iç işlemlerin kullanımı nedir? Cevap, yerel geçici tablolar için kullanım durumundakiyle aynıdır: kaynaklar üzerindeki kilidin kaldırılması. Aradaki fark, bunun global bir kilit açma değil, doğrudan dış (doğrudan "üst") işlem kapsamındaki bir kilit olmasıdır. Dış işlem için iç kaynakları serbest bırakmak için karmaşık Transact-SQL kodunda kullanılır. Bir performans optimizasyonu ve kaynak yönetimi aracıdır.
Oracle ve SQL Server iç/iç içe işlemleri farklı (belki de zıt) davranışlara ve tamamen farklı kullanım durumlarına sahip olduğundan, bir platformdan diğerine geçiş yalnızca yeniden yazmayı değil, aynı zamanda iç içe işlem blokları içeren herhangi bir kapsamı tamamen yeniden tasarlamayı gerektirir. .
Diğer Faktörler
Oracle'dan SQL Server'a geçişte ele alınması gereken tek şey bu geçici tablo ve işlem merkezli hususlar mı? En önemlileri olsalar da, kesinlikle başkaları da var, her biri kendi tuhaflıklarını kapsamaya değer. Aşağıda en yanlış anlaşılan konular olarak bulduğum geri kalanlar var:
- SQL Server'da kimlik sütunları
- Oracle'daki diziler
- Oracle'daki eş anlamlılar
- Filtrelenmiş dizinler
- Tutarlılığı okuyun (yalnızca Oracle'dan SQL Server'a)
- Taşıma araçlarının kullanımı
Bu dizinin sonraki bölümü, bunları, özellikle de ilk üçünü keşfederek devam ediyor.
Geçici Tablolar, Tablo/Koleksiyon Değişkenleri ve İç İçe İşlemler: İlk 3 Geçiş Ağrı Noktası
Geçici tablolar, tablo değişkenleri/koleksiyonları ve iç içe işlemlerle başladım çünkü bunlar dönüştürme projelerinde en yaygın ve bariz başarısızlık noktalarıdır. Oracle Database veya Microsoft SQL Server'daki önemsiz olmayan herhangi bir sistem, şüphesiz bunlardan bazılarını kullanacaktır ve bu öğelerin kullanımı, ilgili RDBMS uygulamaları tarafından özel işlem desteği tasarımı ile çok sıkı bir şekilde birleştirilmiştir.
Bölüm 2'de okumaya devam edin!