2009-05-26 22 views
62

में ओरेकल के रोविड के समतुल्य SQL सर्वर में ओरेकल के रोविड के बराबर क्या है?SQL सर्वर

+0

स्टेफ़नी: धारणा डेटा में एक अद्वितीय कुंजी है, जो मानता है डेटा सामान्यीकृत है, जो एक गलत है है कि वहाँ है कभी-कभी धारणा। इस प्रकार, SQL सर्वर में ओरेकल के रोविड के बराबर क्या है। –

उत्तर

3

http://vyaskn.tripod.com/programming_faq.htm#q17 से:

ओरेकल पंक्ति नंबर या पंक्ति आईडी का उपयोग कर एक मेज की पंक्तियों तक पहुँचने के लिए ROWNUM है। क्या SQL सर्वर में इसके लिए कोई समतुल्य है? या SQL सर्वर में पंक्ति संख्या के साथ आउटपुट कैसे उत्पन्न करें?

एसक्यूएल सर्वर में ओरेकल के राउनम या पंक्ति आईडी के लिए कोई प्रत्यक्ष समतुल्य नहीं है। एक संबंधपरक डेटाबेस में कड़ाई से बोलते हुए, तालिका के भीतर पंक्तियों का आदेश नहीं दिया जाता है और एक पंक्ति आईडी वास्तव में समझ में नहीं आती है। लेकिन अगर आपको लगता है कि कार्यक्षमता की जरूरत , निम्नलिखित तीन विकल्पों पर विचार:

  • अपनी मेज के लिए एक IDENTITY कॉलम जोड़ें।

  • प्रत्येक पंक्ति के लिए पंक्ति संख्या उत्पन्न करने के लिए निम्न क्वेरी का उपयोग करें। निम्न क्वेरी लेखकों पब डेटाबेस की तालिका में प्रत्येक पंक्ति के लिए एक पंक्ति संख्या उत्पन्न करती है। इस क्वेरी के लिए काम करने के लिए, तालिका में अद्वितीय कुंजी होनी चाहिए।

    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 
    
  • , अस्थायी तालिका में पूरे resultset स्टोर करने के लिए IDENTITY() समारोह द्वारा उत्पन्न एक पंक्ति आईडी के साथ एक अस्थायी तालिका दृष्टिकोण का उपयोग करें। अस्थायी तालिका बनाना महंगा होगा, खासकर जब आप बड़ी तालिकाओं के साथ काम कर रहे हैं। इस दृष्टिकोण के लिए जाएं, अगर आप पर अपनी तालिका में एक अनूठी कुंजी नहीं है।

9

आप अद्वितीय रूप से आपके परिणाम सेट के बजाय टेबल के भीतर एक पंक्ति की पहचान करना चाहते हैं, तो आप एक पहचान स्तंभ की तरह कुछ का उपयोग करने में देखने की जरूरत है। SQL सर्वर सहायता में "पहचान संपत्ति" देखें। SQL सर्वर तालिका में प्रत्येक पंक्ति के लिए ओरेकल के रूप में स्वत: उत्पन्न नहीं करता है, इसलिए आपको अपना स्वयं का आईडी कॉलम बनाने की समस्या पर जाना होगा और इसे स्पष्ट रूप से अपनी क्वेरी में लाएं।

संपादित करें: परिणाम सेट पंक्तियों की गतिशील क्रमांकन के लिए नीचे देखते हैं, लेकिन लगता है कि शायद Oracle की ROWNUM के लिए एक समान होगा और मैं सभी पेज आप ऊपर सामान चाहते हैं कि पर टिप्पणी से मान। SQL सर्वर 2005 के लिए और बाद में आप पंक्तियों की गतिशील संख्या प्राप्त करने के लिए नए Ranking Functions फ़ंक्शन का उपयोग कर सकते हैं।

उदाहरण के लिए मैं मेरा एक प्रश्न पर ऐसा करते हैं:

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 

आप देंगे:

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 

वहाँ भी गतिशील रूप से नंबर पंक्तियों पर support.microsoft.com पर एक लेख है।

+0

मुझे लगता है कि एक पहचान कॉलम विशिष्ट रूप से एक तालिका में एक पंक्ति की पहचान करता है लेकिन डेटाबेस में नहीं। – tuinstoel

+0

यह सच है, लेकिन यह ROWID की परिभाषा को फिट करता है जो मैं ओरेकल दस्तावेज़ों में देखता हूं: "बाहरी डेटाटाइप ROWID डेटाबेस तालिका में एक विशेष पंक्ति की पहचान करता है" ... लेकिन मुझे लगता है कि आप इसे मेरे टाइपो के कारण कह रहे हैं चोटी। :) यह बात बताने के लिए धन्यवाद। – Xiaofu

+0

यह परिभाषा का एकमात्र हिस्सा है। यह क्वेरी से क्वेरी में नहीं बदलता है ... –

6

नया ROW_NUMBER फ़ंक्शन देखें। यह इस तरह काम करता है:

SELECT ROW_NUMBER() OVER (ORDER BY EMPID ASC) AS ROWID, * FROM EMPLOYEE 
+12

मुझे लगता है कि यह राउनम के लिए एक प्रतिस्थापन है और पंक्तिबद्ध नहीं है। – tuinstoel

2

यदि आप बस एक छोटे डेटासेट के लिए मूल पंक्ति संख्या चाहते हैं, तो इस तरह के बारे में कुछ कैसे?

SELECT row_number() OVER (order by getdate()) as ROWID, * FROM Employees 
+7

कोई पंक्ति नहीं है। –

+0

लेकिन यह त्वरित जोड़ा आईडी के लिए काम करता है जो कुछ दर्शक खोज रहे होंगे, यह नहीं जानते कि ROWID क्या है। – Graeme

1

ROWID ओरेकल टेबल पर एक छुपा स्तंभ है, इसलिए, SQL सर्वर के लिए, अपना स्वयं का निर्माण करें। NEWID() के डिफ़ॉल्ट मान के साथ ROWID नामक एक कॉलम जोड़ें।

कि कैसे करना है: Add column, with default value, to existing table in SQL Server

+1

क्या यह एक टिप्पणी का अधिक नहीं है? –

0

मैं एमएस एसक्यूएल उदाहरण से इस उदाहरण ले लिया और आप देख सकते हैं @ID पूर्णांक या varchar या जो कुछ भी साथ अदला-बदली जा सकती है। यह वही समाधान था जिसे मैं ढूंढ रहा था, इसलिए मैं इसे साझा कर रहा हूं। का आनंद लें!!

-- 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 
102

From the Oracle docs

ROWID Pseudocolumn

डेटाबेस में प्रत्येक पंक्ति के लिए, ROWID pseudocolumn पंक्ति के पता देता है। Oracle डाटाबेस rowid मूल्यों एक पंक्ति का पता लगाने की जानकारी आवश्यक होते हैं:

  • वस्तु का डेटा ऑब्जेक्ट संख्या
  • datafile जिसमें पंक्ति में रहता है
  • पंक्ति की स्थिति में डेटा ब्लॉक डेटा ब्लॉक (पहली पंक्ति 0 है)
  • डेटाफाइल जिसमें पंक्ति रहता है (पहली फ़ाइल 1 है)। फ़ाइल संख्या तालिकास्थान से संबंधित है।

एसक्यूएल सर्वर में इस के सबसे करीब बराबर rid जो तीन घटक File:Page:Slot है।

SQL सर्वर 2008 में यह देखने के लिए अनियंत्रित और असमर्थित %%physloc%% आभासी कॉलम का उपयोग करना संभव है। यह पहले चार बाइट्स में पेज आईडी के साथ binary(8) मान देता है, फिर फ़ाइल आईडी के लिए 2 बाइट्स, पृष्ठ पर स्लॉट स्थान के लिए 2 बाइट्स देता है।

अदिश समारोह sys.fn_PhysLocFormatter या sys.fn_PhysLocCracker TVF एक और अधिक पठनीय रूप

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 

उदाहरण आउटपुट

+--------------------+----------------+ 
| %%physloc%%  | File:Page:Slot | 
+--------------------+----------------+ 
| 0x2926020001000000 | (1:140841:0) | 
| 0x2926020001000100 | (1:140841:1) | 
+--------------------+----------------+ 

ध्यान दें कि यह क्वेरी प्रोसेसर द्वारा आपूर्तित नहीं है में इस कन्वर्ट करने के लिए इस्तेमाल किया जा सकता। जबकि यह संभव एक WHERE खंड में इस का उपयोग करने के लिए है

SELECT * 
FROM T 
WHERE %%physloc%% = 0x2926020001000100 

एसक्यूएल सर्वर नहीं सीधे निर्दिष्ट पंक्ति की तलाश करेंगे। इसके बजाय यह एक पूर्ण टेबल स्कैन करेगा, प्रत्येक पंक्ति के लिए %%physloc%% का मूल्यांकन करें और मेल खाने वाले किसी को वापस लौटाएं (यदि कोई है)।

2 पहले उल्लिखित कार्यों द्वारा की गई प्रक्रिया को उलट करने के लिए और ज्ञात फ़ाइल, पेज, स्लॉट मानों के अनुरूप binary(8) मान प्राप्त करने के लिए नीचे दिए जा सकते हैं।

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)) 
6

ऊपर इच्छा किसी विशिष्ट पंक्ति के लिए एक सीधा संदर्भ की कमी है, लेकिन आसपास काम उत्तरों की कई काम नहीं करेगा यदि परिवर्तन किसी तालिका में अन्य पंक्तियों के होते हैं। यह मेरा मानदंड है जिसके लिए उत्तर तकनीकी रूप से कम हो जाते हैं।

ओरेकल के ROWID का एक सामान्य उपयोग पंक्तियों का चयन करने के लिए (कुछ हद तक) स्थिर विधि प्रदान करना है और बाद में इसे संसाधित करने के लिए पंक्ति पर लौटना है (उदाहरण के लिए, इसे अद्यतन करने के लिए)। एक पंक्ति खोजने (जटिल जुड़ने, पूर्ण-पाठ खोज, या डेटा के विरुद्ध प्रक्रियात्मक परीक्षणों को लागू करने) की विधि को अद्यतन स्थिति को अर्हता प्राप्त करने के लिए आसानी से या सुरक्षित रूप से पुन: उपयोग नहीं किया जा सकता है।

SQL सर्वर RID समान कार्यक्षमता प्रदान करता प्रतीत होता है, लेकिन समान प्रदर्शन प्रदान नहीं करता है। यही एकमात्र मुद्दा है जिसे मैं देखता हूं, और दुर्भाग्य से ROWID को बनाए रखने का उद्देश्य एक बहुत बड़ी तालिका में पंक्ति खोजने के लिए एक महंगे ऑपरेशन को दोहराने से बचाना है। फिर भी, कई मामलों के लिए प्रदर्शन स्वीकार्य है। यदि माइक्रोसॉफ्ट भविष्य में रिलीज में ऑप्टिमाइज़र समायोजित करता है, तो प्रदर्शन समस्या को संबोधित किया जा सकता है।

बस अद्यतन के लिए उपयोग करना और प्रक्रियात्मक कार्यक्रम में CURSOR को खोलना भी संभव है। हालांकि, यह बड़ी या जटिल बैच प्रसंस्करण में महंगा साबित हो सकता है।

चेतावनी: यहां तक ​​कि Oracle की ROWID स्थिर अगर डीबीए, चुनें और अपडेट के बीच, उदाहरण के लिए, डेटाबेस के पुनर्निर्माण के लिए थे नहीं होगा, क्योंकि यह शारीरिक पंक्ति पहचानकर्ता है। तो ROWID डिवाइस का उपयोग केवल एक अच्छी तरह से स्कॉम्ड कार्य के भीतर किया जाना चाहिए।

1

कृपया http://msdn.microsoft.com/en-us/library/aa260631(v=SQL.80).aspx SQL सर्वर में एक टाइमस्टैम्प डेटटाइम कॉलम के समान नहीं है। इसका उपयोग डेटाबेस में एक पंक्ति को विशिष्ट रूप से पहचानने के लिए किया जाता है, केवल एक टेबल नहीं बल्कि संपूर्ण डेटाबेस। इसका उपयोग आशावादी समरूपता के लिए किया जा सकता है। के लिए उदाहरण अद्यतन [नौकरी] सेट [नाम] = @ नाम, [XCustomData] = @ XCustomData कहां ([ModifiedTimeStamp] = @ Original_ModifiedTimeStamp और [GUID] = @ Original_GUID

ModifiedTimeStamp सुनिश्चित करता है कि आप मूल डेटा अपडेट कर रहे हैं और यदि कोई अन्य अपडेट पंक्ति में हुआ है तो असफल हो जाएगा।

3

यदि आप तालिका में पंक्तियों को स्थायी रूप से संख्याबद्ध करना चाहते हैं, तो कृपया SQL सर्वर के लिए आरआईडी समाधान का उपयोग न करें। यह पुराने 386 पर एक्सेस से भी बदतर होगा SQL सर्वर के लिए बस एक पहचान कॉलम बनाएं, और क्लस्टर प्राथमिक कुंजी के रूप में उस कॉलम का उपयोग करें। यह तालिका पर एक स्थायी, तेज़ इंटीजर बी-ट्री रखेगा, और अधिक महत्वपूर्ण बात यह है कि प्रत्येक गैर क्लस्टर इंडेक्स इसका उपयोग पंक्तियों का पता लगाने के लिए करेगा। यदि आप SQL सर्वर में विकसित करने का प्रयास करते हैं जैसे कि यह ओरेकल यो है आप एक खराब प्रदर्शन डेटाबेस बनायेंगे। आपको इंजन के लिए ऑप्टिमाइज़ करने की आवश्यकता है, नाटक करें कि यह एक अलग इंजन है।

भी, कृपया GUID के साथ प्राथमिक कुंजी को पॉप्युलेट करने के लिए NewID() का उपयोग न करें, आप सम्मिलित प्रदर्शन को मार देंगे। यदि आपको GUID का उपयोग कॉलम डिफ़ॉल्ट के रूप में NewSequentialID() का उपयोग करना होगा। लेकिन आईएनटी अभी भी तेज होगा।

यदि दूसरी तरफ, आप बस पंक्तियों की संख्या को पंक्ति में रखना चाहते हैं, तो पंक्ति कॉलम ओवर() फ़ंक्शन को क्वेरी कॉलम में से एक के रूप में उपयोग करें।

3

मुझे कई कॉलम के साथ एक बहुत बड़ी तालिका को समर्पित करना है और गति महत्वपूर्ण है।उस में

1. बनाएँ ऑटो वेतन वृद्धि क्षेत्र के साथ एक नई तालिका

:

delete T from 
(select Row_Number() Over(Partition By BINARY_CHECKSUM(*) order by %%physloc%%) As RowNumber, * From MyTable) T 
Where T.RowNumber > 1 
0

आप नीचे दिए गए तरीकों का उपयोग करके ROWID प्राप्त कर सकते हैं: इस प्रकार मैं इस पद्धति है जो किसी भी तालिका के लिए काम करता है का उपयोग करें 2. अपनी आवश्यकता के आधार पर अनुक्रम प्राप्त करने के लिए Row_Number विश्लेषणात्मक फ़ंक्शन का उपयोग करें। मैं इसे पसंद करूंगा क्योंकि यह उन स्थितियों में सहायता करता है जहां आप चाहते हैं कि आप एक विशिष्ट फ़ील्ड के आरोही या अवरोही तरीके पर पंक्ति_आईडी या फ़ील्ड के संयोजन

नमूना: Row_Number() ओवी आर (साल desc द्वारा Deptno आदेश से विभाजन)

नमूना ऊपर आप प्रत्येक department.Partition की सबसे अधिक वेतन के आधार पर क्रम संख्या दे देंगे से वैकल्पिक है और आपको अपनी आवश्यकताओं के अनुसार