यूनिकोड पैरामीटर और चर नाम कैसे बनाएं


53

यह सब काम करता है:

CREATE DATABASE [¯\_(ツ)_/¯];
GO
USE [¯\_(ツ)_/¯];
GO
CREATE SCHEMA [¯\_(ツ)_/¯];
GO
CREATE TABLE [¯\_(ツ)_/¯].[¯\_(ツ)_/¯]([¯\_(ツ)_/¯] NVARCHAR(20));
GO
CREATE UNIQUE CLUSTERED INDEX [¯\_(ツ)_/¯] ON [¯\_(ツ)_/¯].[¯\_(ツ)_/¯]([¯\_(ツ)_/¯]);
GO
INSERT INTO [¯\_(ツ)_/¯].[¯\_(ツ)_/¯]([¯\_(ツ)_/¯]) VALUES (N'[¯\_(ツ)_/¯]');
GO
CREATE VIEW [¯\_(ツ)_/¯].[vw_¯\_(ツ)_/¯] AS SELECT [¯\_(ツ)_/¯] FROM [¯\_(ツ)_/¯].[¯\_(ツ)_/¯];
GO
CREATE PROC [¯\_(ツ)_/¯].[sp_¯\_(ツ)_/¯] @Shrug NVARCHAR(20) AS SELECT [¯\_(ツ)_/¯] FROM [¯\_(ツ)_/¯].[vw_¯\_(ツ)_/¯] WHERE [¯\_(ツ)_/¯] = @Shrug;
GO
EXEC [¯\_(ツ)_/¯].[¯\_(ツ)_/¯].[sp_¯\_(ツ)_/¯] @Shrug = N'[¯\_(ツ)_/¯]';
GO

लेकिन आप शायद देख सकते हैं कि मैं कहाँ जा रहा हूँ: मुझे @Srug नहीं चाहिए, मुझे चाहिए @¯\_(ツ)_/¯

2008-2017 से किसी भी संस्करण में न तो ये काम करते हैं:

CREATE PROC [¯\_(ツ)_/¯].[sp_¯\_(ツ)_/¯] @[¯\_(ツ)_/¯] NVARCHAR(20) AS SELECT [¯\_(ツ)_/¯] FROM [¯\_(ツ)_/¯].[vw_¯\_(ツ)_/¯] WHERE [¯\_(ツ)_/¯] = @[¯\_(ツ)_/¯];
GO
CREATE PROC [¯\_(ツ)_/¯].[sp_¯\_(ツ)_/¯] [@¯\_(ツ)_/¯] NVARCHAR(20) AS SELECT [¯\_(ツ)_/¯] FROM [¯\_(ツ)_/¯].[vw_¯\_(ツ)_/¯] WHERE [¯\_(ツ)_/¯] = [@¯\_(ツ)_/¯];
GO

तो, क्या यूनिकोड संग्रहीत कार्यविधि पैरामीटर नामों का उपयोग करने का कोई तरीका है?

जवाबों:


44

खैर, पहचानकर्ता हमेशा यूनिकोड / होते हैं NVARCHAR, इसलिए तकनीकी रूप से आप कुछ भी ऐसा नहीं बना सकते हैं जिसमें यूनिकोड नाम न हो।

आपके द्वारा यहां की जा रही समस्या पूरी तरह से चरित्र के वर्गीकरण के कारण है। नियमित (गैर-सीमांकित) पहचानकर्ताओं के लिए नियम हैं:

  • पहला पत्र होना चाहिए:
    • यूनिकोड मानक 3.2 द्वारा परिभाषित एक पत्र।
    • अंडरस्कोर (_), साइन (@) या नंबर साइन (#) पर
  • इसके बाद के अक्षर हो सकते हैं:
    • यूनिकोड मानक 3.2 में परिभाषित पत्र।
    • दशमलव संख्या बेसिक लैटिन या अन्य राष्ट्रीय लिपियों से।
    • अंडरस्कोर (_), साइन (@), नंबर साइन (#), या डॉलर साइन ($) पर
  • एंबेडेड स्पेस या स्पेशल कैरेक्टर की अनुमति नहीं है।
  • अनुपूरक पात्रों की अनुमति नहीं है।

मैंने इस संदर्भ में केवल वही नियम बोले जो मायने रखते हैं। यहां "प्रथम अक्षर" नियम प्रासंगिक नहीं हैं, इसका कारण यह है कि सभी स्थानीय चर और मापदंडों में पहला अक्षर हमेशा "संकेत पर" होता है @

और स्पष्ट होने के लिए: जिसे "अक्षर" माना जाता है और जिसे "दशमलव अंक" माना जाता है, वह उन गुणों पर आधारित होता है, जिन्हें प्रत्येक चरित्र को यूनिकोड कैरेक्टर डेटाबेस में सौंपा गया है। यूनिकोड प्रत्येक चरित्र को कई गुण प्रदान करता है, जैसे: is_uppercase, is_lowercase, is_digit, is_decimal, is_combining, इत्यादि, आदि यह कोई बात नहीं है कि हम नश्वर लोग अक्षरों या दशमलव अंकों पर विचार करेंगे, लेकिन कौन से वर्ण इन गुणों को सौंपा गया है। इन गुणों को अक्सर "विराम चिह्न" आदि पर मिलान करने के लिए नियमित एक्सप्रेशन में उपयोग किया जाता है, उदाहरण के लिए, \p{Lu}किसी भी ऊपरी मामले के पत्र (सभी भाषाओं / लिपियों में) से \p{IsDingbats}मेल खाता है , और किसी भी "डिंगबैट्स" चरित्र से मेल खाता है।

तो, आपके प्रयास में:

DECLARE @¯\_(ツ)_ INT;

केवल _(अंडरस्कोर या "लो लाइन") और (कटकाना लेटर टू यू + 30 सी 4) अक्षर उन नियमों में फिट होते हैं। अब, सभी अक्षर ¯\_(ツ)_/¯सीमांकित पहचानकर्ताओं के लिए ठीक हैं, लेकिन दुर्भाग्य से ऐसा लगता है कि चर / पैरामीटर नाम और GOTOलेबल को सीमांकित नहीं किया जा सकता है (हालांकि कर्सर के नाम हो सकते हैं)।

इसलिए, चर / पैरामीटर नामों के लिए, चूंकि वे सीमांकित नहीं किए जा सकते हैं, आप केवल उन्हीं वर्णों का उपयोग करने के साथ अटक जाते हैं जो या तो "अक्षर" या "दशमलव अंक" के रूप में अर्हता प्राप्त करते हैं, युनिकोड 3.2 के रूप में (अच्छी तरह से, दस्तावेज के अनुसार; मुझे परीक्षण करने की आवश्यकता है; यदि वर्गीकरण को यूनिकोड के नए संस्करणों के लिए अद्यतन किया गया है क्योंकि वर्गीकरण को वज़न की तुलना में अलग तरीके से नियंत्रित किया जाता है)।

कैसे # 1 , चीजें उतनी सीधी नहीं हैं, जितनी उन्हें होनी चाहिए। मैं अब अपने शोध को पूरा करने में सक्षम हो गया हूं और पाया है कि बताई गई परिभाषा पूरी तरह से सही नहीं है। नियमित पहचानकर्ताओं के लिए कौन से वर्ण मान्य हैं इसकी सटीक (और सत्यापित) परिभाषा है:

  • पहला चरित्र:

    • यूनिकोड 3.2 में "ID_Start" के रूप में वर्गीकृत कुछ भी किया जा सकता है (जिसमें "पत्र" शामिल हैं, लेकिन "अक्षर अक्षर सांख्यिक")
    • हो सकता है _(कम लाइन / अंडरस्कोर) या _(फुलवॉच लो लाइन)
    • हो सकता है @, लेकिन केवल चर / मापदंडों के लिए
    • हो सकता है #, लेकिन अगर स्कीमा-बाउंड ऑब्जेक्ट, तो केवल टेबल्स और स्टोर की गई प्रक्रियाओं के लिए (जिस स्थिति में वे इंगित करते हैं कि ऑब्जेक्ट अस्थायी है)
  • इसके बाद के अक्षर:

    • यूनिकोड 3.2 में "ID_Continue" (जिसमें "दशमलव" संख्याएं शामिल हैं, लेकिन "स्पेसिंग और नॉनस्पैसिंग कॉम्बिनेशन मार्क्स", और "विराम चिह्नों को जोड़ने") के रूप में वर्गीकृत कुछ भी हो सकता है
    • हो सकता है @, #या$
    • प्रारूप नियंत्रण पात्रों के रूप में यूनिकोड 3.2 में वर्गीकृत 26 वर्णों में से कोई भी हो सकता है

(मजेदार तथ्य: "ID_Start" और "ID_Continue" में "ID" का अर्थ "आइडेंटिफ़ायर" है। इमेज ;-);

"यूनिकोड यूटिलिटीज: यूनिकोडसेट" के अनुसार:

  • वैध आरंभिक पात्र

    [: आयु = ३.२:] और [: ID_Start = Yes:]

    -- Test one "Letter" from each of 10+ languages, as of Unicode 3.2
    DECLARE @ᔠᑥᑒᏯשፙᇏᆇᄳᄈლဪඤagೋӁウﺲﶨ   INT;
    -- works
    
    
    -- Test a Supplementary Character that is a "Letter" as of Unicode 3.2
    DECLARE @𝒲 INT;-- Mathematical Script Capital W (U+1D4B2)
    /*
    Msg 102, Level 15, State 1, Line XXXXX
    Incorrect syntax near '0xd835'.
    */
  • वैध निरंतरता के पात्र

    [: आयु = ३.२:] और [: ID_Continue = Yes:]

    -- Test various decimal numbers, but none are Supplementary Characters
    DECLARE @६৮༦൯௫୫9 INT;
    -- works (including some Hebrew and Arabic, which are right-to-left languages)
    
    
    -- Test a Supplementary Character that is a "decimal" number as of Unicode 3.2
    DECLARE @𝟜 INT; -- MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR (U+1D7DC)
    /*
    Msg 102, Level 15, State 1, Line XXXXX
    Incorrect syntax near '0xd835'.
    */
    -- D835 is the first character in the surrogate pair D835 DFDC that makes up U+1D7DC

HOWEVER # 2 , यूनिकोड डेटाबेस को खोजना भी आसान नहीं है। वे दो खोजें उन वर्गीकरणों के लिए मान्य वर्णों की एक सूची तैयार करती हैं, और वे पात्र यूनिकोड 3.2 से हैं, लेकिन यूनिकोड मानक के संस्करणों में विभिन्न वर्गीकरणों की परिवर्तन की परिभाषाएँ हैं। मतलब, यूनिकोड v 10.0 में "ID_Start" की परिभाषा (जो खोज आज का उपयोग कर रहा है, 2018-03-26) वह यूनिकोड v 3.2 में नहीं था। इसलिए, ऑनलाइन खोज एक सटीक सूची प्रदान नहीं कर सकती है। लेकिन आप यूनिकोड 3.2 डेटा फ़ाइलों को पकड़ सकते हैं और "ID_Start" और "ID_Continue" वर्णों की सूची वहां से ले सकते हैं कि SQL सर्वर वास्तव में उपयोग करने के लिए क्या तुलना करता है। और मैंने यह किया है और "HOWEVER # 1" में ऊपर वर्णित नियमों के लिए एक सटीक मिलान की पुष्टि की है।

निम्नलिखित दो ब्लॉग पोस्ट आयात स्क्रिप्ट के लिंक सहित वर्णों की सटीक सूची खोजने के लिए उठाए गए कदमों का विवरण देते हैं:

  1. यूनी-कोड: टी-एसक्यूएल नियमित पहचानकर्ताओं के लिए मान्य वर्णों की सही सूची के लिए खोज, भाग 1
  2. यूनी-कोड: टी-एसक्यूएल नियमित पहचानकर्ताओं के लिए मान्य वर्णों की सही सूची के लिए खोज, भाग 2

अंत में, किसी के लिए भी जो केवल सूची देखना चाहता है और इस बात से चिंतित नहीं है कि उसे खोजने और उसे सत्यापित करने के लिए क्या मिला, आप यहां देख सकते हैं:

पूरी तरह से मान्य टी-एसक्यूएल पहचानकर्ता वर्णों की पूरी सूची
(कृपया पृष्ठ को लोड करने के लिए एक क्षण दें; यह 3.5 एमबी है और लगभग 47% लाइनें है)


"मान्य" ASCII वर्णों के बारे में, जैसे /और -काम नहीं करना: इस मुद्दे का ASCII वर्ण सेट में वर्णों को परिभाषित किया गया है या नहीं, इससे कोई लेना-देना नहीं है। वैध होने के लिए, चरित्र के पास ID_Startया ID_Continueसंपत्ति होना आवश्यक है, या अलग से उल्लेख किए गए कुछ कस्टम वर्णों में से एक होना चाहिए। कुछ "वैध" ASCII वर्ण (कुल 128 में से 62 - अधिकतर विराम चिह्न और नियंत्रण वर्ण) हैं जो "नियमित" पहचानकर्ताओं में मान्य नहीं हैं।

अनुपूरक वर्णों के बारे में: जबकि वे निश्चित रूप से सीमांकित पहचानकर्ताओं में उपयोग किए जा सकते हैं (और दस्तावेज अन्यथा दिखाई नहीं देते हैं), अगर यह सच है कि उनका उपयोग नियमित रूप से पहचानकर्ताओं में नहीं किया जा सकता है, तो उनके कारण पूरी तरह से समर्थित नहीं होने की संभावना है सप्लीमेंट्री कैरेक्टर-अवेयर कोलाज से पहले बिल्ट-इन फ़ंक्शन SQL Server 2012 में पेश किए गए थे (इन्हें दो अलग-अलग "अज्ञात" वर्णों के रूप में माना जाता है), और न ही 100 से पहले गैर-बाइनरी Collations में उन्हें एक दूसरे से अलग भी किया जा सकता है। स्तर Collations (SQL Server 2008 में पेश किया गया)।

ASCII के बारे में: 8-बिट एनकोडिंग का उपयोग यहां नहीं किया जा रहा है क्योंकि सभी पहचानकर्ता यूनिकोड / NVARCHAR/ UTF-16 LE हैं। बयान का SELECT ASCII('ツ');एक मान लौटाता 63है "?" (कोशिश SELECT CHAR(63);:) उस चरित्र के बाद से, भले ही एक ऊपरी-केस "एन" के साथ उपसर्ग किया गया हो, निश्चित रूप से कोड पृष्ठ 1252 में नहीं है। हालांकि, यह चरित्र कोरियाई कोड पेज में है और यह "एन के बिना भी, सही परिणाम प्रस्तुत करता है। "उपसर्ग, एक कोरियाई डिफ़ॉल्ट Collation के साथ डेटाबेस में:

SELECT UNICODE('ツ'); -- 12484

परिणाम को प्रभावित करने वाले पहले पत्र के बारे में: यह संभव नहीं है क्योंकि स्थानीय चर और मापदंडों के लिए पहला पत्र हमेशा होता है @। इन नामों के लिए हमें जो पहला अक्षर मिलता है, वह वास्तव में नाम का दूसरा वर्ण है।

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


बहुत बढ़िया, धन्यवाद। इसने मुझे इस ओर अग्रसर किया, जो एक महान ब्लॉग पोस्ट के लिए बनाने जा रहा है: gist.github.com/BrentOzar/9b08b5ab2b6b817847dbe4aa0297b4cd5b
ब्रेंट

8
@BrentOzar आप हाल ही में एक सीटी स्कैन किया है?
रॉस प्रेसर

वाह, यह काफी प्रभावशाली जवाब है! और मैं दूसरी रॉस प्रेसर की टिप्पणी।
एसक्यूएल नर्ड

22

मुझे नहीं लगता कि यह यूनिकोड है जो समस्या पैदा कर रहा है; स्थानीय चर या पैरामीटर नामों के मामले में, यह है कि चरित्र एक मान्य ASCII / यूनिकोड 3.2 वर्ण नहीं है (और चर / मापदंडों के लिए कोई भागने का क्रम नहीं है जैसे अन्य इकाई प्रकारों के लिए हैं)।

यह बैच ठीक काम करता है, यह एक यूनिकोड वर्ण का उपयोग करता है जो गैर-सीमांकित पहचानकर्ताओं के लिए नियमों का उल्लंघन नहीं करता है:

CREATE OR ALTER PROCEDURE dbo.[💩]
  @ツ int
AS
  CREATE TABLE [#ツ] (ツ int);
  INSERT [#ツ](ツ) SELECT @ツ;
  SELECT +1 FROM [#ツ];
GO
EXEC dbo.[💩] @ツ = 1;

जैसे ही आप स्लैश या डैश का उपयोग करने का प्रयास करते हैं, दोनों ही मान्य ASCII वर्ण हैं, यह बम है:

Msg 102, Level 15, State 1, Procedure 💩 Incorrect syntax near '-'.

दस्तावेज़ीकरण यह नहीं बताता है कि ये पहचानकर्ता अन्य सभी पहचानकर्ताओं की तुलना में थोड़े अलग नियमों के अधीन हैं, या वे दूसरों की तरह क्यों नहीं बच सकते हैं।


हाय हारून। बस यहाँ कुछ बिंदुओं को स्पष्ट करने के लिए: 1) पहला चरित्र एक मुद्दा नहीं है क्योंकि पहला चरित्र वास्तव @में var / param नाम का है। कोई भी वर्ण जो काम नहीं कर रहा है, उसे किसी भी स्थिति में काम नहीं करना चाहिए, भले ही वैध वर्णों से पहले हो। 2) डॉक्टर केवल यह बताता है कि अनुपूरक पात्रों का उपयोग नियमित पहचानकर्ताओं में नहीं किया जा सकता है (जो कि मेरे द्वारा की गई कोशिश के लिए ऐसा ही प्रतीत होता है), लेकिन एम्बेडेड स्थानों के साथ, सीमांकित पहचानकर्ताओं पर कोई प्रतिबंध नहीं रखता है। इसके अलावा, मेरा मानना ​​है कि ये अलग-अलग हैं क्योंकि वे टी-एसक्यूएल भाषा का हिस्सा हैं, डीबी में चीजें नहीं हैं।
सोलोमन रटज़की

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

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

(जब मैंने एक पल पहले उत्तर दिया था तो आपकी टिप्पणी का अद्यतन नहीं देखा था)। हां, यह प्रश्न स्पष्ट है कि ओपी यूनिकोड वर्णों का उपयोग करने में असमर्थ है, लेकिन प्रश्न का मुख्य रूप से तकनीकी रूप से गलत है क्योंकि सभी नाम हमेशा यूनिकोड / NVARCHAR हैं। इसका ASCII से कोई लेना-देना नहीं है क्योंकि यह 8-बिट एन्कोडिंग है जिसका उपयोग यहां नहीं किया जा रहा है। यहां सभी वर्ण यूनिकोड वर्ण हैं, भले ही कुछ विभिन्न 8-बिट कोड पृष्ठों में भी मौजूद हों। जैसा कि मैंने मेरा उत्तर है, जो वर्ण इस्तेमाल किया जा सकता में विस्तार से बताया एक मामले जिनमें से लोगों के साथ या तो टैग किया गया है is_alphabeticया numeric_type=decimal
सोलोमन रटज़की

मैंने संग्रहित प्रोक देखे हैं जो पू से भरे हुए थे लेकिन इसका कभी नाम नहीं लिया!
मिच गेहूं २
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.