2013-05-09 3 views
9

क्या कोई संपूर्ण पंक्ति के md5() या sha1() को प्राप्त करने के लिए "अर्ध-पोर्टेबल" तरीका है? (या बेहतर, अपने सभी क्षेत्रों द्वारा आदेशित पंक्तियों के पूरे समूह का, यानी order by 1,2,3,...,n)? दुर्भाग्यवश सभी डीबी PostgreSQL नहीं हैं ... मुझे कम से कम माइक्रोसॉफ्ट एसक्यूएल सर्वर, साइबेस और ओरेकल से निपटना होगा।एक संपूर्ण पंक्ति के MD5 या SHA1 प्राप्त करने के लिए SQL तरीका

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

मैंने कुछ विकल्प देखे हैं, उदा। Tsql में checksum(*) (डरावनी: यह बहुत टक्कर-प्रवण है, क्योंकि यह एक्सओआरएस और 32-बिट मानों के समूह पर आधारित है), और hashbytes('MD5', field), लेकिन बाद वाले को पूरी पंक्ति पर लागू नहीं किया जा सकता है। और यह मुझे केवल एक एसक्यूएल स्वाद के लिए समाधान प्रदान करेगा जो मुझे सौदा करना है।

कोई विचार? ऊपर वर्णित एसक्यूएल मुहावरों में से केवल एक के लिए, यह बहुत अच्छा होगा।

उत्तर

8

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

Hashbytes varchar, nvarchar, या varbinary डेटाटाइप्स पर काम करता है, और मैं पूर्णांक कुंजी और पाठ फ़ील्ड तुलना करने के लिए, सब कुछ कास्टिंग एक बुरा सपना हो गया होता चाहता था, इसलिए मैं इस प्रकार एसक्यूएल सर्वर में एक्सएमएल खंड के लिए इस्तेमाल किया:

CREATE TRIGGER get_hash_value ON staging_table 
FOR UPDATE, INSERT AS 
UPDATE staging_table 
SET sha1_hash = (SELECT hashbytes('sha1', (SELECT col1, col2, col3 FOR XML RAW))) 
GO 

वैकल्पिक रूप से, आप एक ट्रिगर के बाहर एक ही तरीके से मूल्यों की गणना कर सकते हैं, यदि आप एक्सएमएल क्लॉज के साथ सबक्वायरी का उपयोग करके सभी पंक्तियों पर कई अपडेट करने की योजना बनाते हैं। यदि इस मार्ग पर जा रहे हैं, तो आप इसे एक SELECT * में भी बदल सकते हैं, लेकिन ट्रिगर में नहीं, क्योंकि प्रत्येक बार जब आप इसे चलाते हैं तो आपको एक अलग मूल्य मिल जाएगा क्योंकि sha1_hash कॉलम हर बार अलग होगा।

आप 1 से अधिक पंक्ति पाने के लिए चयन कथन को संशोधित कर सकता है

3

MSSQL में - आप एक्सएमएल का उपयोग करके पूरी पंक्ति भर HashBytes उपयोग कर सकते हैं ..

SELECT MBT.id, 
    hashbytes('MD5', 
       (SELECT MBT.* 
       FROM (
         VALUES(NULL))foo(bar) 
       FOR xml auto)) AS [Hash] 
FROM <Table> AS MBT; 

आप को from (values(null))foo(bar) खंड की जरूरत है एक्सएमएल ऑटो का उपयोग करें, यह कोई अन्य उद्देश्य नहीं देता है ..

संबंधित मुद्दे