Oracle'ın RowID'sinin SQL Server'daki karşılığı nedir?
Oracle'ın RowID'sinin SQL Server'daki karşılığı nedir?
Yanıtlar:
ROWID Sözde Sütun
Veritabanındaki her satır için, ROWID sözde sütun, satırın adresini döndürür. Oracle Database satır kimliği değerleri, bir satırı bulmak için gerekli bilgileri içerir:
- Nesnenin veri nesnesi numarası
- Satırın bulunduğu veri dosyasındaki veri bloğu
- Veri bloğundaki satırın konumu (ilk satır 0'dır)
- Satırın bulunduğu veri dosyası (ilk dosya 1'dir). Dosya numarası tablo alanına bağlıdır.
SQL Server'da buna en yakın eşdeğer rid
, üç bileşene sahip olanıdır File:Page:Slot
.
SQL Server 2008'de bunu %%physloc%%
görmek için belgelenmemiş ve desteklenmeyen sanal sütunu kullanmak mümkündür . Bu binary(8)
, ilk dört baytta Sayfa Kimliği, ardından Dosya Kimliği için 2 bayt ve ardından sayfadaki yuva konumu için 2 bayt olan bir değer döndürür .
Skaler işlevi sys.fn_PhysLocFormatter
veya sys.fn_PhysLocCracker
TVF, bunu daha okunabilir bir forma dönüştürmek için kullanılabilir
CREATE TABLE T(X INT);
INSERT INTO T VALUES(1),(2)
SELECT %%physloc%% AS [%%physloc%%],
sys.fn_PhysLocFormatter(%%physloc%%) AS [File:Page:Slot]
FROM T
Örnek Çıktı
+--------------------+----------------+
| %%physloc%% | File:Page:Slot |
+--------------------+----------------+
| 0x2926020001000000 | (1:140841:0) |
| 0x2926020001000100 | (1:140841:1) |
+--------------------+----------------+
Bunun sorgu işlemcisi tarafından kullanılmadığını unutmayın. Bunu bir cümlede kullanmak mümkün olsa daWHERE
SELECT *
FROM T
WHERE %%physloc%% = 0x2926020001000100
SQL Server olacak değil doğrudan belirtilen satıra ararlar. Bunun yerine tam bir tablo taraması yapacak, değerlendirin%%physloc%%
her satırı ve eşleşen olanı (varsa) döndürecektir.
Daha önce bahsedilen 2 fonksiyon tarafından gerçekleştirilen işlemi tersine çevirmek ve binary(8)
bilinen Dosya, Sayfa, Yuva değerlerine karşılık gelen değeri elde etmek için aşağıdaki kullanılabilir.
DECLARE @FileId int = 1,
@PageId int = 338,
@Slot int = 3
SELECT CAST(REVERSE(CAST(@PageId AS BINARY(4))) AS BINARY(4)) +
CAST(REVERSE(CAST(@FileId AS BINARY(2))) AS BINARY(2)) +
CAST(REVERSE(CAST(@Slot AS BINARY(2))) AS BINARY(2))
Çok sayıda sütun içeren çok büyük bir tabloyu tekilleştirmem gerekiyor ve hız önemli. Bu nedenle, herhangi bir tablo için çalışan bu yöntemi kullanıyorum:
delete T from
(select Row_Number() Over(Partition By BINARY_CHECKSUM(*) order by %%physloc%% ) As RowNumber, * From MyTable) T
Where T.RowNumber > 1
Yeni ROW_NUMBER işlevine göz atın . Şu şekilde çalışır:
SELECT ROW_NUMBER() OVER (ORDER BY EMPID ASC) AS ROWID, * FROM EMPLOYEE
Sonuç kümeniz yerine tablodaki bir satırı benzersiz bir şekilde tanımlamak istiyorsanız, KİMLİK sütunu gibi bir şeye bakmanız gerekir. SQL Server yardımında "IDENTITY özelliği" konusuna bakın. SQL Server, Oracle'ın yaptığı gibi tablodaki her satır için otomatik olarak bir kimlik oluşturmaz, bu nedenle kendi kimlik sütununuzu oluşturma zahmetine girmeniz ve bunu sorgunuza açıkça getirmeniz gerekir.
DÜZENLEME: Sonuç kümesi satırlarının dinamik numaralandırması için aşağıya bakın, ancak bu muhtemelen Oracle'ın ROWNUM için bir eşdeğer olacaktır ve sayfadaki tüm yorumlardan yukarıdaki şeyleri istediğinizi varsayıyorum. SQL Server 2005 ve sonrası için, satırların dinamik numaralandırması için yeni Sıralama İşlevleri işlevini kullanabilirsiniz.
Örneğin bunu bir sorgumda yapıyorum:
select row_number() over (order by rn_execution_date asc) as 'Row Number', rn_execution_date as 'Execution Date', count(*) as 'Count'
from td.run
where rn_execution_date >= '2009-05-19'
group by rn_execution_date
order by rn_execution_date asc
Sana vereceğim:
Row Number Execution Date Count
---------- ----------------- -----
1 2009-05-19 00:00:00.000 280
2 2009-05-20 00:00:00.000 269
3 2009-05-21 00:00:00.000 279
Ayrıca support.microsoft.com'da satırları dinamik olarak numaralandırmakla ilgili bir makale var .
Yukarıdaki yanıtlardan birkaçı, belirli bir satıra doğrudan başvuru olmamasına geçici bir çözüm olacaktır , ancak bir tablodaki diğer satırlarda değişiklik olursa işe yaramayacaktır . Cevapların teknik olarak yetersiz kaldığı kriterlerim budur.
Oracle'ın ROWID'sinin yaygın bir kullanımı, satırları seçmek için (biraz) kararlı bir yöntem sağlamak ve daha sonra onu işlemek için satıra geri dönmektir (örneğin, GÜNCELLEME). Bir satırı bulma yöntemi (karmaşık birleştirmeler, tam metin arama veya satır satır göz atma ve verilere karşı prosedür testleri uygulama) UPDATE ifadesini nitelemek için kolayca veya güvenli bir şekilde yeniden kullanılamayabilir.
SQL Server RID aynı işlevselliği sağlıyor gibi görünüyor, ancak aynı performansı sağlamıyor. Gördüğüm tek sorun bu ve ne yazık ki bir ROWID tutmanın amacı, örneğin çok büyük bir tablodaki satırı bulmak için pahalı bir işlemi tekrar etmekten kaçınmaktır. Bununla birlikte, birçok durumda performans kabul edilebilir. Microsoft, iyileştiriciyi gelecekteki bir sürümde ayarlarsa, performans sorunu çözülebilir.
Yordamsal bir programda FOR UPDATE'ı kullanmak ve CURSOR'u açık tutmak da mümkündür. Bununla birlikte, bu, büyük veya karmaşık toplu işlemede pahalı olabilir.
Uyarı: Örneğin SELECT ve UPDATE arasındaki DBA, fiziksel satır tanımlayıcısı olduğu için veritabanını yeniden oluşturacak olsaydı Oracle'ın ROWID'si bile kararlı olmayacaktır. Bu nedenle, ROWID cihazı yalnızca iyi kapsamlı bir görevde kullanılmalıdır.
Küçük bir veri kümesi için sadece basit satır numaralandırması istiyorsanız, böyle bir şey yapmaya ne dersiniz?
SELECT row_number() OVER (order by getdate()) as ROWID, * FROM Employees
Gönderen http://vyaskn.tripod.com/programming_faq.htm#q17 :
Oracle, satır numarasını veya satır kimliğini kullanarak bir tablonun satırlarına erişmek için bir satıra sahiptir. Bunun SQL Server'da herhangi bir eşdeğeri var mı? Veya SQL Server'da satır numarası ile çıktı nasıl oluşturulur?
Oracle'ın SQL Server'daki satır veya satır kimliğine doğrudan bir eşdeğeri yoktur. Açıkçası, ilişkisel bir veritabanında, bir tablodaki satırlar sıralı değildir ve bir satır kimliği gerçekten bir anlam ifade etmez. Ancak bu işleve ihtiyacınız varsa, aşağıdaki üç alternatifi göz önünde bulundurun:
IDENTITY
Tablonuza bir sütun ekleyin .Her satır için bir satır numarası oluşturmak üzere aşağıdaki sorguyu kullanın. Aşağıdaki sorgu, pubs veritabanının yazarlar tablosundaki her satır için bir satır numarası oluşturur. Bu sorgunun çalışması için tablonun benzersiz bir anahtarı olmalıdır.
SELECT (SELECT COUNT(i.au_id) FROM pubs..authors i WHERE i.au_id >= o.au_id ) AS RowID, au_fname + ' ' + au_lname AS 'Author name' FROM pubs..authors o ORDER BY RowID
Sonuç kümesinin tamamını,
IDENTITY()
işlev tarafından oluşturulan bir satır kimliğiyle birlikte geçici bir tabloda depolamak için geçici bir tablo yaklaşımı kullanın . Geçici bir tablo oluşturmak, özellikle büyük tablolarla çalışırken maliyetli olacaktır. Tablonuzda benzersiz bir anahtar yoksa bu yaklaşımı kullanın.
Tablodaki satırları kalıcı olarak numaralandırmak istiyorsanız, lütfen SQL Server için RID çözümünü kullanmayın. Eski bir 386'daki Access'ten daha kötü performans gösterecektir. SQL Server için basitçe bir IDENTITY sütunu oluşturun ve bu sütunu kümelenmiş birincil anahtar olarak kullanın. Bu, tabloya kalıcı, hızlı bir Tamsayı B-Ağacı yerleştirecek ve daha da önemlisi, kümelenmemiş her indeks, onu satırları bulmak için kullanacaktır. Oracle gibi SQL Server'da geliştirmeye çalışırsanız, düşük performanslı bir veritabanı oluşturursunuz. Motor için optimizasyon yapmanız gerekir, farklı bir motormuş gibi davranmanız gerekmez.
Ayrıca, lütfen Birincil Anahtarı GUID'lerle doldurmak için NewID () kullanmayın, ekleme performansını öldüreceksiniz. GUID'leri kullanmanız gerekiyorsa, sütun varsayılanı olarak NewSequentialID () kullanın. Ancak INT yine de daha hızlı olacak.
Öte yandan, bir sorgudan kaynaklanan satırları numaralandırmak istiyorsanız, sorgu sütunlarından biri olarak SatırNumarası Fazla () işlevini kullanın.
Deneyin lütfen
select NEWID()
Kaynak: https://docs.microsoft.com/en-us/sql/t-sql/data-types/uniqueidentifier-transact-sql
ROWID, Oracle tablolarında gizli bir sütundur, bu nedenle SQL Server için kendinizinkini oluşturun. Varsayılan değeri olan ROWID adlı bir sütun ekleyin NEWID()
.
Nasıl yapılır: SQL Server'daki mevcut tabloya varsayılan değerle sütun ekleyin
Lütfen http://msdn.microsoft.com/en-us/library/aa260631(v=SQL.80).aspx sayfasına bakın SQL sunucusunda bir zaman damgası bir DateTime sütunu ile aynı değildir. Bu, yalnızca bir tablodaki değil, tüm veritabanındaki bir veritabanındaki bir satırı benzersiz şekilde tanımlamak için kullanılır. Bu, iyimser eşzamanlılık için kullanılabilir. örneğin GÜNCELLEME [İş] SET [Ad] = @ Ad, [XCustomData] = @ XCustomData WHERE ([ModifiedTimeStamp] = @ Original_ModifiedTimeStamp AND [GUID] = @ Original_GUID
ModifiedTimeStamp, orijinal verileri güncellemenizi sağlar ve satırda başka bir güncelleme olursa başarısız olur.
Bu örneği MS SQL örneğinden aldım ve @ID'nin tamsayı veya varchar veya her neyse ile değiştirilebileceğini görebilirsiniz. Bu, aradığım çözümün aynısıydı, bu yüzden onu paylaşıyorum. Zevk almak!!
-- UPDATE statement with CTE references that are correctly matched.
DECLARE @x TABLE (ID int, Stad int, Value int, ison bit);
INSERT @x VALUES (1, 0, 10, 0), (2, 1, 20, 0), (6, 0, 40, 0), (4, 1, 50, 0), (5, 3, 60, 0), (9, 6, 20, 0), (7, 5, 10, 0), (8, 8, 220, 0);
DECLARE @Error int;
DECLARE @id int;
WITH cte AS (SELECT top 1 * FROM @x WHERE Stad=6)
UPDATE x -- cte is referenced by the alias.
SET ison=1, @id=x.ID
FROM cte AS x
SELECT *, @id as 'random' from @x
GO
ROWID'yi aşağıda verilen yöntemleri kullanarak alabilirsiniz:
1. İçinde otomatik artış alanı olan yeni bir tablo oluşturun
2. İhtiyaçlarınıza göre sıralamayı elde etmek için Row_Number analitik işlevini kullanın. Bunu tercih ederim çünkü belirli bir alanın veya alanların kombinasyonunun artan veya azalan biçiminde row_id istediğiniz durumlarda yardımcı olur
Örnek: Row_Number () Over (Sal desc ile Deptno sırasına göre bölümleme)
Yukarıdaki örnek size her departmanın en yüksek maaşına göre sıra numarasını verecektir.