sql अंतर - यूनिकोड पाठ को एसक्यूएल में कैसे पहचानें?




का रिलेशनल (3)

टेबल 1 में उर्वर्च कॉलम का नाम उम्ज होता है जिसमें यूनिकोड पाठ होता है और कुछ समय अंग्रेज़ी भी होता है।

मैं umsg स्तंभ में अंग्रेजी पाठ को ढूंढना चाहता हूं।

select * 
from table1 
where 
    RDate >='01/01/2014' and RDate < '09/26/2017' 
    and umsg = convert(varchar(max), umsg)

मैंने उपरोक्त क्वेरी का उपयोग किया है जो क्षेत्रीय भाषा में ठीक काम करता है लेकिन कुछ समय असफल हो जाता है। मान लीजिए कि कर्नल में 'रेफरी नो à © tÃÆ'ÃÆ'Ã। एक € ™ Ã⠀ SA, एक © मुझे लगता है कि उपरोक्त संदेश, युनिकोड है, जैसे पाठ में शामिल है, अगर मैं क्वेरी के ऊपर प्रयोग किया है, तो यह / एसक्यूएल मुझे अंग्रेजी के रूप में यूनिकोड नहीं दिखा रहा है।

Table :
Id  Date                      Umsg
1   2017-09-12 00:00:00.000   The livers detoxification processes.
2   2017-09-11 00:00:00.000   Purposely added 1 
3   2017-09-10 00:00:00.000   फेंगशुई के छोटे-छोटे टिप्स से आप जीवन की विषमताओं से                       स्वयं को बचा सकते
4   2017-09-17 00:00:00.000    तनाव एक लाइलाज बीमारी कतई नहीं है। कुछ लोग तनाव को                                     आसानी से झेल लेते 
5   2017-09-17 00:00:00.000    ref no été

ऊपर मेरी तालिका में डेटा मौजूद है। लेकिन मैं चाहता हूं कि डेटा / आउटपुट की तरह:

    Id      Date                      Umsg
    1   2017-09-12 00:00:00.000   The livers detoxification processes.
    2   2017-09-11 00:00:00.000   Purposely added 1

Answers

यदि आप कुछ यूनिकोड और कुछ आस्की अक्षर एक ही स्ट्रिंग में हैं, तो आप ने क्या जवाब नहीं दिया, इसलिए मैं आपको 1 विचार और 1 समाधान देता हूं यदि आप केवल "शुद्ध अंग्रेजी" या "मिश्रित" पंक्तियों को ढूंढना चाहते हैं

ऐसा करने के लिए आपको प्राकृतिक संख्याओं की एक तालिका की आवश्यकता होती है। अगर आपके पास ऐसी कोई तालिका नहीं है तो आप इसे इस तरह बना सकते हैं:

select top 1000000  row_number() over(order by getdate()) as n
into dbo.nums
from sys.messages m1 cross join sys.messages m2;

alter table dbo.nums alter column n int not null;

alter table dbo.nums add constraint PK_nums_n primary key(n); 

अब जब आपके पास प्राकृतिक संख्याओं की एक तालिका है, तो हम अपने स्ट्रिंग को एकल वर्णों में विघटित करने जा रहे हैं ताकि ascii(character) = unicode(character) :

declare @t table(col Nvarchar(200));
insert into @t values
(N'ref no été'), (N'The livers detoxification processes.'), (N'फेंगशुई के छोटे-छोटे टिप्स से आप जीवन की विषमताओं से')

select t.col, n, substring(t.col, n, 1) as nth_character,
       ascii(substring(t.col, n, 1)) as ascii,
       unicode(substring(t.col, n, 1)) as uni
from @t t join dbo.nums n
       on n.n <= len(t.col); -- this is to give you an idea how to see if it's unicode character or ascii

with cte as
(
select t.col, n, substring(t.col, n, 1) as nth_character,
       ascii(substring(t.col, n, 1)) as ascii,
       unicode(substring(t.col, n, 1)) as uni
from @t t join dbo.nums n
       on n.n <= len(t.col)
)
select col, 
       case
            when sum(case when ascii = uni then 1 else 0 end) = count(*) then 'English only'
            else 'Not only English'
       end as eng_or_not
from cte
group by col -- row level solution

कोड का पहला भाग आपको चरित्र की आस्की और यूनिकोड कोड के साथ चरित्र के आधार पर दिखाता है: जहां वे वैसे ही आस्की वर्ण हैं

दूसरे भाग में जांचें कि सभी पात्रों का एस्सी है।


नीचे जांचें:

;WITH CTE
 AS (
 SELECT ID,
        DATE,
        umsg,
        CASE
            WHEN(CAST(umsg AS VARCHAR(MAX)) COLLATE SQL_Latin1_General_Cp1251_CS_AS) = umsg
            THEN 0
            ELSE 1
        END HasSpecialChars
 FROM <table_name>)
 SELECT ID,
        DATE,
        umsg
 FROM CTE
 WHERE Date >= '01/01/2014'
       AND Date < '09/26/2017'
       AND HasSpecialChars = 0;

वांछित आउटपुट:

ID  DATE                     umsg
1   2017-09-12 00:00:00.000  The livers detoxification processes.                                                                     
2   2017-09-11 00:00:00.000  Purposely added 1      

आशा है इससे आपकी मदद होगी।


यहां हर उत्तर समस्या का केवल एक हिस्सा शामिल है। वास्तव में, चार अलग-अलग क्वेरी पार्ट्स हैं जिन्हें हम गतिशील रूप से इसमें जोड़ सकते हैं:

  • एक स्ट्रिंग
  • एक संख्या
  • एक पहचानकर्ता
  • एक वाक्यविन्यास कीवर्ड।

और तैयार बयान उनमें से केवल दो को शामिल करता है।

लेकिन कभी-कभी हमें अपनी क्वेरी को और अधिक गतिशील बनाना पड़ता है, ऑपरेटरों या पहचानकर्ताओं को भी जोड़ना पड़ता है। तो, हमें विभिन्न सुरक्षा तकनीकों की आवश्यकता होगी।

सामान्य रूप से, इस तरह के एक संरक्षण दृष्टिकोण whitelisting पर आधारित है।

इस मामले में, प्रत्येक गतिशील पैरामीटर को आपकी स्क्रिप्ट में हार्डकोड किया जाना चाहिए और उस सेट से चुना जाना चाहिए। उदाहरण के लिए, गतिशील क्रम करने के लिए:

$orders  = array("name", "price", "qty"); // Field names
$key     = array_search($_GET['sort'], $orders)); // See if we have such a name
$orderby = $orders[$key]; // If not, first one will be set automatically. smart enuf :)
$query   = "SELECT * FROM `table` ORDER BY $orderby"; // Value is safe

हालांकि, पहचानने वालों को सुरक्षित करने का एक और तरीका है - भागना। जब तक आपके पास एक पहचानकर्ता उद्धृत किया गया हो, तब तक आप उन्हें दोगुना करके बैकटिक्स से बच सकते हैं।

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

इसलिए, लंबी कहानी को कम करने के लिए: यह प्लेसहोल्डर है , तैयार कथन को चांदी की बुलेट के रूप में नहीं माना जा सकता है।

इसलिए, एक सामान्य सिफारिश को तब तक phrased किया जा सकता है जब तक आप प्लेसहोल्डर (और इन प्लेसहोल्डर्स को सही तरीके से संसाधित) का उपयोग करके क्वेरी में गतिशील भागों को जोड़ रहे हैं, आप सुनिश्चित कर सकते हैं कि आपकी क्वेरी सुरक्षित है

फिर भी, एसक्यूएल सिंटैक्स कीवर्ड (जैसे AND , DESC और ऐसे) के साथ कोई समस्या है, लेकिन इस मामले में श्वेत-सूची एकमात्र दृष्टिकोण प्रतीत होती है।

अद्यतन करें

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

उदाहरण के लिए, there(1) are(2) still(3) many(4) answers(5) , जिसमें share दिए गए share जो आपको मैन्युअल स्ट्रिंग से बचने का सुझाव देते हैं - एक पुराना दृष्टिकोण जो असुरक्षित साबित हुआ है।

या थोड़ा बेहतर जवाब है जो स्ट्रिंग स्वरूपण की एक और विधि का सुझाव देता है और यहां तक ​​कि इसे अंतिम पैनसिया के रूप में भी समझाता है। बेशक, यह नहीं है। यह विधि नियमित स्ट्रिंग स्वरूपण से बेहतर नहीं है, फिर भी यह अपनी सभी कमियों को रखती है: यह केवल स्ट्रिंग पर लागू होती है और, किसी अन्य मैन्युअल स्वरूपण के रूप में, यह अनिवार्य रूप से वैकल्पिक, गैर-अनिवार्य उपाय है, किसी भी प्रकार की मानवीय त्रुटि के लिए प्रवण है।

मुझे लगता है कि यह सब एक बहुत पुरानी अंधविश्वास के कारण, OWASP या पीएचपी मैनुअल जैसे अधिकारियों द्वारा समर्थित है, जो एसक्यूएल इंजेक्शन से "बचने" और सुरक्षा के बीच समानता का प्रचार करता है।

उम्र के लिए PHP मैनुअल ने जो भी कहा, उसके बावजूद, *_escape_string किसी भी माध्यम से डेटा को सुरक्षित बनाता है और इसका इरादा कभी नहीं किया गया है। स्ट्रिंग के अलावा किसी भी एसक्यूएल भाग के लिए बेकार होने के अलावा, मैन्युअल एस्केपिंग गलत है, क्योंकि यह स्वचालित रूप से स्वचालित के विपरीत मैनुअल है।

और ओडब्ल्यूएएसपी इससे भी बदतर हो जाता है, उपयोगकर्ता इनपुट से बचने पर जोर देता है जो एक पूर्ण बकवास है: इंजेक्शन सुरक्षा के संदर्भ में ऐसा कोई शब्द नहीं होना चाहिए। प्रत्येक चर संभावित रूप से खतरनाक है - कोई फर्क नहीं पड़ता स्रोत! या, दूसरे शब्दों में - प्रत्येक चर को एक प्रश्न में डालने के लिए उचित रूप से स्वरूपित किया जाना चाहिए - स्रोत को फिर से कोई फर्क नहीं पड़ता। यह गंतव्य है जो मायने रखता है। जिस क्षण एक डेवलपर बकरियों को बकरियों से अलग करना शुरू कर देता है (सोच रहा है कि कुछ विशेष चर "सुरक्षित" है या नहीं) वह आपदा के प्रति अपना पहला कदम उठाता है। उल्लेख नहीं है कि यहां तक ​​कि शब्द भी प्रवेश बिंदु पर भारी भागने का सुझाव देता है, जैसा कि बहुत ही जादू उद्धरण सुविधा जैसा दिखता है - पहले ही तुच्छ, बहिष्कृत और हटा दिया गया है।

तो, जो भी "भागने" के विपरीत, तैयार बयान वह उपाय है जो वास्तव में एसक्यूएल इंजेक्शन (जब लागू हो) से बचाता है।

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







sql sql-server sql-server-2012