এমএস-এসকিউএলে অবজেক্টের নামগুলি উদ্ধৃত করতে কোনও (লুকানো) বিল্ট-ইন ফাংশন রয়েছে কি?


12

কখনও কখনও আমি আমাদের কিছু ডাটাবেসে অবজেক্টের নাম (সনাক্তকারী) সঞ্চয় করি, উদাহরণস্বরূপ কিছু প্যারামিটার সারণিতে। যেহেতু আমি এই টেবিলগুলি থেকে '=' বা 'লাইক' তুলনা অপারেটরগুলি ব্যবহার করে রেকর্ড নির্বাচন করি, তাই অবশ্যই এই নামগুলি সর্বদা বন্ধনীর সাথে বা ছাড়াই সংরক্ষণ করার জন্য আমাকে যত্নবান হতে হবে ।

IF EXISTS (SELECT 1 FROM MYTABLE WHERE OBJ_NAME = '[TABLE_NAME]';

অথবা

IF EXISTS (SELECT 1 FROM MYTABLE WHERE OBJ_NAME = 'TABLE_NAME';

তবে এমএস-এসকিউএলের কিছু ফাংশন রয়েছে যেখানে আপনি বন্ধনীর সাথে বা ছাড়াই অবজেক্টের নাম ব্যবহার করতে পারেন, উদাহরণস্বরূপ OBJECT_ID () ফাংশন। আমি dbfiddle.uk এ একটি ন্যূনতম উদাহরণ স্থাপন করেছি ।

CREATE TABLE TEST
(
    ID     INT IDENTITY(1,1) PRIMARY KEY,
    OBJECT sysname NOT NULL
);
GO

INSERT INTO TEST VALUES ('[obj1]'),('obj2'),('obj3'),('[obj4]');
GO

টেবিলে TEST এইভাবে উপস্থিত রয়েছে কিনা তা পরীক্ষা করতে আমি এখন OBJECT_ID () ব্যবহার করতে পারি:

IF OBJECT_ID('TEST') IS NOT NULL
BEGIN
    SELECT 'TEST EXISTS.' OBJECT_ID;
END
GO

| OBJECT_ID    |
| :----------- |
| TEST EXISTS. |

IF OBJECT_ID('[TEST]') IS NOT NULL
BEGIN
    SELECT '[TEST] EXISTS.' OBJECT_ID;
END
GO

| OBJECT_ID      |
| :------------- |
| [TEST] EXISTS. |

আমি শনাক্তকারী TEST টি বন্ধনী সহ বা ছাড়াই পাস করি না, পার্সার ব্র্যাকেটগুলি অপসারণ করার জন্য যথেষ্ট স্মার্ট।

ঠিক আছে, আমি এটি একটি স্কেলার ফাংশন যোগ করে তা অনুকরণ করতে পারি যা একটি স্ট্রিং থেকে বন্ধনীগুলি সরিয়ে দেয়:

CREATE FUNCTION UNQUOTENAME(@TXT NVARCHAR(MAX)) 
RETURNS NVARCHAR(MAX)
AS
    BEGIN
        RETURN IIF(LEFT(@TXT, 1) = N'[' AND RIGHT(@TXT, 1) = N']', 
                   SUBSTRING(@TXT, 2, LEN(@TXT) -  2), 
                   @TXT);
    END;
GO

এবং তারপরে এটি ব্যবহার করুন:

SELECT dbo.UNQUOTENAME (N'[FIELD]') NAME1, N'FIELD' NAME2;
GO

NAME1 | NAME2
:---- | :----
FIELD | FIELD

SELECT ID, OBJECT 
FROM   TEST 
WHERE OBJECT LIKE 'obj%';
GO

ID | OBJECT
-: | :-----
 2 | obj2  
 3 | obj3  

SELECT ID, dbo.UNQUOTENAME(OBJECT) 
FROM   TEST 
WHERE  dbo.UNQUOTENAME(OBJECT) LIKE 'obj%';
GO

ID | (No column name)
-: | :---------------
 1 | obj1
 2 | obj2
 3 | obj3
 4 | obj4  

তবে আমার প্রশ্নটি হ'ল:

  • টি-এসকিউএল ব্যবহার করে বন্ধনীগুলি সরিয়ে এমন কোনও লুকানো অন্তর্নির্মিত কার্য রয়েছে?

এখানে ডিবিফিডল

উত্তর:


12

টি-এসকিউএল ব্যবহার করে বন্ধনীগুলি সরিয়ে এমন কোনও লুকানো অন্তর্নির্মিত কার্য রয়েছে?

না , টি-এসকিউএল ব্যবহার করছে না।

OBJECT_IDএকটি অভ্যন্তরীণ ফাংশন। এটি সরাসরি এসকিউএল সার্ভার এক্সিকিউটেবল কোডে প্রয়োগ করা হয়, টি-এসকিউএলে নয়; এবং যখন অনুরোধ করা হয় তখন এটি কোনও টি-এসকিউএল কল করে না।

রানটাইমের সময়, অবজেক্ট আইডিটি এক্সপ্রেশন পরিষেবা কলিংয়ের মাধ্যমে প্রাপ্ত হয় sqlmin!I4ObjIdWstr

এরপরে বাস্তবায়ন সরবরাহিত স্ট্রিং প্যারামিটারগুলি গুলি রেফারেন্সযুক্ত ডাটাবেসের কোনও আইডিতে সমাধান করার জন্য প্রয়োজনীয় সমস্ত পদক্ষেপগুলি অতিক্রম করে।

প্রথম পদক্ষেপের মধ্যে একটি স্ট্রিংয়ের মাধ্যমে কোনও সীমিত চিহ্নিতকারীদের সাথে ডিল করা অন্তর্ভুক্ত sqlmin!CbParseQuotesW। সংকীর্ণ অর্থে, আপনি উল্লেখ করছেন এমন কোড ফাংশন, তবে এটি সরাসরি টি-এসকিউএল থেকে অ্যাক্সেসযোগ্য নয়। এটিতে নিম্নলিখিত কোড রয়েছে:

cmp     r9d,22h
je      sqlmin!CbParseQuotesW+0x185
cmp     r9d,2Eh
je      sqlmin!CbParseQuotesW+0x139
cmp     r9d,5Bh
je      sqlmin!CbParseQuotesW+0xfe
cmp     r9d,5Dh
je      sqlmin!CbParseQuotesW+0xda

... যা চরিত্রগুলি পরিচালনা করার জন্য পরীক্ষা:

  • hex 22 = ডিসেম্বর 34 = "
  • hex 2E = dec 46 = .
  • হেক্স 5 বি = ডিস 91 = [
  • hex 5D = dec 93 = ]

কোনও আইডির পরামিতিগুলি সমাধান করার প্রক্রিয়াটির বাকি অংশগুলি অন্তর্ভুক্ত:

  • একটি স্বয়ংক্রিয় পঠনযোগ্য লেনদেন শুরু হচ্ছে
  • পরীক্ষণে ডাটাবেসের প্রয়োজনীয়তা রয়েছে
  • নামের প্যারামিটারের জন্য সম্ভাব্য মিলগুলির মাধ্যমে আইট্রেট করা (সঠিক কোলেশন ব্যবহার করে)
    • সরবরাহ করা ডাটাবেসের নাম (বা বর্তমান প্রসঙ্গে ডেটাবেস)
    • সরবরাহিত স্কিমা নাম (বা sys , বা ব্যবহারকারীর ডিফল্ট স্কিমা ইত্যাদি)
  • প্রয়োজনীয় মেটাডেটা লক নেওয়া
  • একটি ম্যাচের জন্য মেটাডেটা ক্যাশে পরামর্শ করা
  • প্রয়োজনে ক্যাশে মেটাডেটা আনছে
  • অনুমতি পরীক্ষা করা হচ্ছে (অবজেক্ট আইডি অ্যাক্সেস করতে)
  • প্রথম মিলিত বস্তুর আইডি ফিরিয়ে দেওয়া (যদি থাকে)

পাশের নোটে, প্রশ্নের কোড:

IF OBJECT_ID('TEST') IS NOT NULL

... কেবল টেবিলের জন্য দেখায় না। এটির জন্য দ্বিতীয় ফাংশন প্যারামিটার ব্যবহার করা দরকার। তদ্ব্যতীত , এটি কেবল TEST নামের যেকোন স্কিমা-স্কোপযুক্ত অবজেক্টের সন্ধান করে - সুতরাং বনানচেমা.টিএসটি নামের একটি দৃষ্টিভঙ্গি মিলবে, উদাহরণস্বরূপ। একটি ভাল অভিব্যক্তি হবে:

IF OBJECT_ID(N'dbo.TEST', N'U') IS NOT NULL

সম্পর্কিত প্রশ্নোত্তর:


18

কখনও কখনও আমি আমাদের কিছু ডাটাবেসে বস্তুর নাম সঞ্চয় করি

এই নামগুলি সর্বদা বন্ধনীর সাথে বা ছাড়াই সংরক্ষণ করার জন্য আমাকে অবশ্যই যত্ন নিতে হবে।

একটি "অবজেক্ট নাম" প্রযুক্তিগতভাবে একটি সনাক্তকারী বলা হয় । কিছু প্রসঙ্গে একটি শনাক্তকারী উপস্থিত হবে [এবং] এবং "এবং" দ্বারা বেষ্টিত টিএসকিউএল কোড প্রদর্শিত হবে। এই অক্ষরগুলি শনাক্তকারীর অংশ নয় এবং আপনার এগুলি কখনও সংরক্ষণ করা উচিত নয়।

পরিবর্তে শনাক্তকারীকে একটি nvarchar (128) (বা sysname) হিসাবে সংরক্ষণ করুন, এবং রান সময় সময়োপযোগী যুক্ত করুন QUOTENAME ফাংশন ব্যবহার করে ।

QUOTENAME এর বিপরীতটি হল PARSENAME , যার বহু অংশের নাম নেভিগেট করার অতিরিক্ত ক্ষমতা রয়েছে।

নোট করুন যে QUOTENAME এর একটি alচ্ছিক দ্বিতীয় প্যারামিটার রয়েছে এবং আপনি যদি সেই প্যারামিটারের জন্য একটি একক উদ্ধৃতি অক্ষর নির্দিষ্ট করে থাকেন QUOTENAME একটি বৈধ সীমান্ত সনাক্তকারী অভিব্যক্তি তৈরি করে না। এটি একটি ভারচর আক্ষরিক ভাব প্রকাশ করে।


7

এসকিউএল সার্ভারে স্পষ্টতই অভ্যন্তরীণ কিছু রয়েছে যা [square brackets](বা অন্যান্য শনাক্তকারীদের মতো "double quotes") বাইরে বেরিয়ে আসে ।

যখন তোমার মত একটি সারণি তৈরি [dbo].[foo], তুমি ঠিক আছে, শুধুমাত্র fooসঞ্চিত পরার sys.tablesএবং sys.objectsএবং কোন অভিযোগ যে স্কিমা হয় [dbo](বর্গাকার বন্ধনী সহ) পাওয়া যায়নি।

তবে কোডের ভিতরে এটি ঘটে CREATE TABLE। তারা সম্ভবত ব্যবহার করছে PARSENAME(), যেমন ডেভিড বলেছিল। ডিবাগারকে জড়িয়ে দেওয়া নিশ্চিতভাবে ইঙ্গিত করতে পারে, তবে এটির কী ব্যাপার?

তারা কী করছে তা দেখতে আপনি অন্য কোথাও দেখতে পারেন এবং sys.sp_renameবাস্তবে যে ফলনটি PARSENAME()ব্যবহৃত হয় তা তা পেতে পারেন :

select @UnqualOldName = parsename(@objname, 1),
        @QualName1 = parsename(@objname, 2),
        @QualName2 = parsename(@objname, 3),
        @QualName3 = parsename(@objname, 4)

তবে আবারও, আমি নিশ্চিত না যে আপনি কেন মাঝে মাঝে বর্গাকার বন্ধনীগুলি সরাতে চান তা আমি বুঝতে পেরেছি ।

আমার জন্য, ব্যক্তিগতভাবে, আমার কোডের একটি বৃহত পরিমাণ শতাংশ বিস্তৃত দর্শকের জন্য রচিত, যারা এই কোডটি এমন পরিবেশে ব্যবহার করবেন যেখানে আমার কোনও জ্ঞান নেই বা তারা অনিরাপদ সনাক্তকারী ব্যবহার করছে কিনা তা নিয়ে আমার নিয়ন্ত্রণ নেই। সুতরাং আমি সর্বদা থাকি এবং সর্বদা কোড লিখি (এবং পছন্দ করি) QUOTENAME()যা কোনও স্ক্রিপ্ট তৈরি করতে ব্যবহার করে যা কোনও ধরণের সনাক্তকারীকে অন্তর্ভুক্ত করে।

আমি বরং সমস্ত সময় স্কোয়ার বন্ধনীগুলি রাখি, সেগুলি নেওয়ার চেয়ে এবং একবারে তাদের প্রয়োজনের সময় কামড়ানোর চেয়ে।


2
@ এমসিএনটস - সংক্ষিপ্ত সংখ্যক ক্ষেত্রে যেখানে এটি কার্যকর হতে পারে আমি তার চেয়ে অন্য বিষয়গুলিতে মনোনিবেশ করতাম। আপনি খুব সহজেই সামনের এবং পিছনের বন্ধ স্ট্রিপ বিদ্যমান স্ট্রিং ফাংশন ব্যবহার করতে পারেন [এবং ]এবং কোন প্রতিস্থাপন ]]সঙ্গে]
মার্টিন স্মিথ

-6

যখন বর্গাকার বন্ধনীগুলির প্রয়োজন হয় - এটি কারণ আপনার সনাক্তকারী ইতিমধ্যে একটি সংরক্ষিত কীওয়ার্ড। এগুলি নির্বিচারে ব্যবহার করা কেবল প্রয়োজনীয় নয়, এটি আপনার দেখতে যেমন বিভ্রান্তির দিকে নিয়ে যায়।

আমার মতে, সবচেয়ে ভাল উপায় হ'ল প্রথম স্থানে সংরক্ষিত শনাক্তকারীদের ব্যবহার এড়ানো।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.