সিএলআর ব্যবহার না করে ডাটাবেস স্তরের ধ্রুবক (গণনা) তৈরি করবেন?


9

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

CREATE PROCEDURE dbo.DoSomeWork(@param1 INTEGER, ..., @EnumValue myEnumType)  AS ...;

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

EXEC doSomeWork 85, ..., (myEnumType.EnumValue1 + myEnumType.EnumValue2);

যেখানে myEnumTypeকয়েকটি গণনার মান থাকবে।

পদ্ধতিতে আমি এটি প্রয়োজনীয় কাজের জন্য @EnumValueমানগুলির সাথে এটি ব্যবহার করতে এবং পরীক্ষা করতে সক্ষম হব myEnumType। আমি myEnumTypeযে ক্ষেত্রে বিবেচনা করছি তার জন্য আমি বিটমাস্কের মানগুলি তৈরি করব।

একটি সাধারণ উদাহরণের জন্য, একটি ব্যয়বহুল প্রক্রিয়া বিবেচনা করুন যা একটি বিশাল ডেটাসেট নেয় এবং এটি একটি ছোট তবে তবুও খুব বড় ডেটাসেটে হ্রাস করে। এই প্রক্রিয়াটিতে আপনাকে সেই প্রক্রিয়াটির মাঝামাঝি কিছু সামঞ্জস্য করা দরকার যা ফলাফলকে প্রভাবিত করবে। বলুন এটি হ্রাসের মধ্যবর্তী গণনার কিছু স্থিতির উপর নির্ভর করে কিছু ধরণের রেকর্ডের (বা বিপক্ষে) ফিল্টার filter @EnumValueধরনের myEnumTypeএই জন্য পরীক্ষা ব্যবহার করা যেতে পারে

SELECT   ...
FROM     ...
WHERE       (@EnumValue & myEnumType.EnumValue1 = myEnumType.EnumValue1 AND ...)
        OR  (@EnumValue & myEnumType.EnumValue2 = myEnumType.EnumValue2 AND ...)
        OR  ...

এসএকিউএল সার্ভারে এই জাতীয় ডাটাবেস স্তরের ধ্রুবকগুলি কি সিএলআর ব্যবহার ছাড়াই সম্ভব?

আমি একটি ডাটাবেস স্তরের গণনা বা ধ্রুবকগুলির সেট চাই যা সঞ্চিত প্রক্রিয়া, ফাংশন ইত্যাদির পরামিতি হিসাবে পাস করা যেতে পারে।

উত্তর:


9

আপনি এক্সএমএল স্কিমা ব্যবহার করে এসকিউএল সার্ভারে একটি গণনার প্রকার তৈরি করতে পারেন।

উদাহরণস্বরূপ রঙ।

create xml schema collection ColorsEnum as '
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="Color">
        <xs:simpleType>
            <xs:restriction base="xs:string"> 
                <xs:enumeration value="Red"/>
                <xs:enumeration value="Green"/>
                <xs:enumeration value="Blue"/>
                <xs:enumeration value="Yellow"/>
            </xs:restriction> 
        </xs:simpleType>
    </xs:element>
</xs:schema>';

এটি আপনাকে টাইপের কোনও ভেরিয়েবল বা প্যারামিটার ব্যবহার করতে দেয় xml(dbo.ColorsEnum)

declare @Colors xml(dbo.ColorsEnum);
set @Colors = '<Color>Red</Color><Color>Green</Color>'

যদি আপনি এমন কোনও রঙ যুক্ত করার চেষ্টা করেন যা কোনও রঙ নয়

set @Colors = '<Color>Red</Color><Color>Ferrari</Color>';

আপনি একটি ত্রুটি পেতে।

Msg 6926, Level 16, State 1, Line 43
XML Validation: Invalid simple type value: 'Ferrari'. Location: /*:Color[2]

এর মতো এক্সএমএল তৈরি করা কিছুটা ক্লান্তিকর হতে পারে তাই আপনি উদাহরণস্বরূপ এমন একটি সহায়তা দর্শন তৈরি করতে পারেন যা অনুমোদিত মানগুলিও ধারণ করে।

create view dbo.ColorsConst as
select cast('<Color>Red</Color>' as varchar(100)) as Red,
       cast('<Color>Green</Color>' as varchar(100)) as Green,
       cast('<Color>Blue</Color>' as varchar(100)) as Blue,
       cast('<Color>Yellow</Color>' as varchar(100)) as Yellow;

এবং আলোকায়ন তৈরি করতে এটি ব্যবহার করুন।

set @Colors = (select Red+Blue+Green from dbo.ColorsConst);

আপনি যদি এক্সএমএল স্কিমা থেকে গতিশীলভাবে ভিউ তৈরি করতে চান তবে আপনি এই ক্যোয়ারির সাহায্যে রঙগুলি বের করতে পারেন।

select C.Name
from (select xml_schema_namespace('dbo','ColorsEnum')) as T(X)
  cross apply T.X.nodes('//*:enumeration') as E(X)
  cross apply (select E.X.value('@value', 'varchar(100)')) as C(Name);

অঙ্কটি অবশ্যই কার্যকারিতা এবং পদ্ধতিগুলির পরামিতি হিসাবে ব্যবহার করা যেতে পারে।

create function dbo.ColorsToString(@Colors xml(ColorsEnum))
returns varchar(100)
as
begin
  declare @T table(Color varchar(100));

  insert into @T(Color)
  select C.X.value('.', 'varchar(100)')
  from @Colors.nodes('Color') as C(X);

  return stuff((select ','+T.Color
                from @T as T
                for xml path('')), 1, 1, '');
end
create procedure dbo.GetColors
  @Colors xml(ColorsEnum)
as
select C.X.value('.', 'varchar(100)') as Color
from @Colors.nodes('Color') as C(X);
declare @Colors xml(ColorsEnum) = '
<Color>Red</Color>
<Color>Blue</Color>
';

select dbo.ColorsToString(@Colors);

set @Colors = (select Red+Blue+Green from dbo.ColorsConst);
exec dbo.GetColors @Colors;

6

যেহেতু আপনি দৃশ্যত SQL সার্ভার 2016 ব্যবহার করছেন, আমি অন্য 'বর্জন করতে চাই সম্ভব ' বিকল্পটি - SESSION_CONTEXT

লিওনার্ড লোবেলের নিবন্ধ, এসকিউএল সার্ভারSESSION_CONTEXT ২০১ in-তে ভাগ করে নেওয়ার স্টেটে এসকিউএল সার্ভার ২০১ in এ এই নতুন কার্যকারিতা সম্পর্কে কিছুটা খুব ভাল তথ্য রয়েছে।

কিছু মূল বিষয়গুলি সংক্ষেপে:

আপনি যদি কখনও ডেটাবেস সংযোগের পুরো জীবন জুড়ে সমস্ত সঞ্চিত প্রক্রিয়া এবং ব্যাচগুলিতে সেশন স্টেটটি ভাগ করে নিতে চান তবে আপনি প্রেম করতে চলেছেন SESSION_CONTEXT। আপনি যখন এসকিউএল সার্ভার ২০১ 2016-এ সংযুক্ত হন, আপনি একটি স্টেটফুল ডিকশনারি পান বা প্রায়শই একটি স্টেট ব্যাগ হিসাবে উল্লেখ করা হয়, এমন কোনও জায়গা যেখানে আপনি মানগুলি স্ট্রিং এবং সংখ্যার মতো সঞ্চয় করতে পারেন এবং তারপরে আপনার নির্ধারিত একটি কী দ্বারা এটি পুনরুদ্ধার করুন। এর ক্ষেত্রে SESSION_CONTEXT, কীটি কোনও স্ট্রিং, এবং মানটি একটি sql_variant, যার অর্থ এটি বিভিন্ন ধরণের সংযোজন করতে পারে।

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

আমাদের কাছে এখনও অবধি এরকমই নিকটতম জিনিসটি ছিল CONTEXT_INFOযা আপনাকে 128 বাইট দীর্ঘ একক বাইনারি মান সংরক্ষণ এবং ভাগ করতে দেয় যা আপনি যে অভিধানটি পেয়েছেন তার চেয়ে অনেক কম নমনীয় SESSION_CONTEXT, যা বিভিন্ন ডেটার একাধিক মানকে সমর্থন করে ধরনের।

SESSION_CONTEXTব্যবহার করা সহজ, পছন্দসই কী দ্বারা মান সঞ্চয় করতে কেবল sp_set_session_context কল করুন। আপনি যখন এটি করেন, আপনি অবশ্যই কী এবং মানটি সরবরাহ করেন তবে আপনি পঠন-পরামিতি প্যারামিটারটিকেও সত্যতে সেট করতে পারেন। এটি সেশন প্রসঙ্গে মানটিকে লক করে, যাতে সংযোগের আজীবন এটি পরিবর্তন করা যায় না। সুতরাং, উদাহরণস্বরূপ, ক্লায়েন্ট অ্যাপ্লিকেশনের পক্ষে ডাটাবেস সংযোগ স্থাপনের পরে কিছু সেশন প্রসঙ্গ মান নির্ধারণের জন্য এই সঞ্চিত পদ্ধতিটিকে কল করা সহজ। যদি অ্যাপ্লিকেশনটি রিড_নিলি প্যারামিটার সেট করে থাকে তবে তা সঞ্চিত পদ্ধতি এবং অন্য টি-এসকিউএল কোড যা সার্ভারে চালিত হয় কেবলমাত্র মানটি পড়তে পারে, তারা ক্লায়েন্টের উপর চলমান অ্যাপ্লিকেশন দ্বারা সেট করা কি পরিবর্তন করতে পারে না।

পরীক্ষা হিসাবে, আমি একটি সার্ভার লগইন ট্রিগার তৈরি করেছি যা কিছু CONTEXT_SESSIONতথ্য সেট করে - এর মধ্যে একটিতে SESSION_CONTEXTসেট করা হয়েছিল @read_only

DROP TRIGGER IF EXISTS [InitializeSessionContext] ON ALL SERVER
GO
CREATE TRIGGER InitializeSessionContext ON ALL SERVER
FOR LOGON AS

BEGIN

    --Initialize context information that can be altered in the session
    EXEC sp_set_session_context @key = N'UsRegion'
        ,@value = N'Southeast'

    --Initialize context information that cannot be altered in the session
    EXEC sp_set_session_context @key = N'CannotChange'
        ,@value = N'CannotChangeThisValue'
        ,@read_only = 1

END;

আমি সম্পূর্ণ নতুন ব্যবহারকারী হিসাবে লগ ইন করেছি এবং SESSION_CONTEXTতথ্যটি বের করতে সক্ষম হয়েছি :

DECLARE @UsRegion varchar(20)
SET @UsRegion = CONVERT(varchar(20), SESSION_CONTEXT(N'UsRegion'))
SELECT DoThat = @UsRegion

DECLARE @CannotChange varchar(20)
SET @CannotChange = CONVERT(varchar(20), SESSION_CONTEXT(N'CannotChange'))
SELECT DoThat = @CannotChange

এমনকি 'পঠন_আপনি' প্রসঙ্গে তথ্য পরিবর্তন করার চেষ্টা করেছি:

EXEC sp_set_session_context @key = N'CannotChange'
    ,@value = N'CannotChangeThisValue'

এবং একটি ত্রুটি পেয়েছে:

এমএসজি 15664, স্তর 16, রাজ্য 1, পদ্ধতি sp_set_session_context, লাইন 1 [ব্যাচ শুরুর লাইন 8] সেশন প্রসঙ্গে কী 'CannotChange' সেট করতে পারে না। এই সেশনের জন্য কীটি কেবল পঠনযোগ্য হিসাবে সেট করা হয়েছে।

লগইন ট্রিগার সম্পর্কে একটি গুরুত্বপূর্ণ নোট ( এই পোস্ট থেকে )!

লগন ট্রিগার কার্যকরভাবে সিসাদমিন ফিক্সড সার্ভার রোলের সদস্য সহ সকল ব্যবহারকারীর জন্য ডেটাবেস ইঞ্জিনের সফল সংযোগগুলি কার্যকরভাবে আটকাতে পারে। লগন ট্রিগার যখন সংযোগগুলি আটকাচ্ছে তখন সিসাদমিন স্থির সার্ভার রোলের সদস্যরা ডেডিকেটেড অ্যাডমিনিস্ট্রেটর সংযোগ ব্যবহার করে বা ন্যূনতম কনফিগারেশন মোডে (-f) ডেটাবেস ইঞ্জিন শুরু করে সংযোগ করতে পারবেন role


একটি সম্ভাব্য অপূর্ণতা হ'ল এটি সেশন প্রসঙ্গের ইনস্ট্যান্স প্রশস্ত করে (প্রতিটি ডাটাবেস নয়)। এই মুহুর্তে, আমি কেবলমাত্র বিকল্পগুলি সম্পর্কে ভাবতে পারি তা হ'ল:

  1. আপনার Session_Contextনাম-মান জোড়াটি ডাটাবেসের নামের সাথে উপসর্গ করে তাদের নাম দিন যাতে অন্য কোনও ডাটাবেসে একই ধরণের নামের জন্য সংঘর্ষ না ঘটে। এটি Session_Contextসমস্ত ব্যবহারকারীর জন্য সমস্ত নাম-মানগুলি পূর্বনির্ধারিত করার সমস্যার সমাধান করে না ।
  2. লগইন ট্রিগার জ্বলে EventDataউঠলে আপনার (এক্সএমএল) অ্যাক্সেস থাকে যা আপনি লগইন ব্যবহারকারীকে বের করার জন্য ব্যবহার করতে পারেন এবং তার উপর ভিত্তি করে, আপনি নির্দিষ্ট Session_Contextনাম-মান জোড়া তৈরি করতে পারেন ।

4

এসকিউএল সার্ভারে, না (যদিও আমি ১৯৯৯ সালে আবার ওরাকল প্যাকেজগুলিতে কনস্ট্যান্ট তৈরির কথা মনে করি এবং এসকিউএল সার্ভারে সেগুলি মিস করেছি)।

এবং, আমি সবেমাত্র পরীক্ষা করে দেখেছি যে এসকিউএলসিআরআর দিয়ে আপনি এটিও করতে পারবেন না, অন্তত এই অর্থে নয় যে এটি সমস্ত ক্ষেত্রে কার্যকর হবে। হোল্ড আপ হ'ল সঞ্চিত প্রক্রিয়া পরামিতিগুলির উপর বিধিনিষেধ। দেখে মনে হচ্ছে আপনার একটি .বা ::পরামিতি নাম থাকতে পারে না । আমি চেষ্টা করেছিলাম:

EXEC MyStoredProc @ParamName = SchemaName.UdtName::[StaticField];

-- and:

DECLARE @Var = SchemaName.UdtName = 'something';
EXEC MyStoredProc @ParamName = @Var.[InstanceProperty];

উভয় ক্ষেত্রে এটি পার্সিং পর্বটি (ব্যবহার করে যাচাই করা SET PARSEONLY ON;) পেরিয়ে যায়নি :

এমএসজি 102, স্তর 15, রাজ্য 1, লাইন এক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সক্র্যাক্ট
সিনট্যাক্স '' এর নিকটে।

অন্যদিকে, উভয় পদ্ধতিই ব্যবহারকারী-সংজ্ঞায়িত ফাংশন পরামিতিগুলির জন্য কাজ করে:

SELECT MyUDF(SchemaName.UdtName::[StaticField]);

-- and:

DECLARE @Var = SchemaName.UdtName = N'something';
SELECT MyUDF(@Var.[InstanceProperty]);

সুতরাং, আপনি যা করতে পারেন সর্বোত্তমভাবে হ'ল এসকিউএলসিআরআরকে ইউডিএফ, টিভিএফ, ইউডিএ (আমি ধরে নিই) এবং কোয়েরিগুলির সাথে সরাসরি কাজ করে এবং সঞ্চিত পদ্ধতিগুলির সাথে ব্যবহারের প্রয়োজন হলে স্থানীয় ভেরিয়েবলগুলিকে নির্ধারণ করুন:

DECLARE @VarInt = SchemaName.UdtName::[StaticField];
EXEC MyStoredProc @ParamName = @VarInt;

যখন আমি আসল এনাম মান রাখার সুযোগ পেয়েছি (তখন এর ব্যবহার / অর্থের সাথে সুনির্দিষ্টভাবে দেখার জন্য একটি সারণীর মধ্যে থাকা একটি মূল্যবোধের মানের বিপরীতে) এই পদ্ধতির আমি গ্রহণ করেছি।


"ধ্রুবক" / "এনাম" মানটি ছুঁড়ে ফেলার জন্য ব্যবহারকারী-সংজ্ঞায়িত ফাংশন (ইউডিএফ) দিয়ে এটি চেষ্টা করার ক্ষেত্রে, আমি এটি স্টোরড পদ্ধতি প্যারামিটার হিসাবে পাস করার ক্ষেত্রে এটির কাজ করতে পারি না:

EXEC MyStoredProc @ParamName = FunctionName(N'something');

এসএসএমএসের সাথে প্রথম বন্ধনীর মধ্যে সমস্ত কিছু হাইলাইট করে "ভুল সিনট্যাক্স" ত্রুটি প্রদান করে, এমনকি যদি আমি একটি সংখ্যার সাথে স্ট্রিংটি প্রতিস্থাপন করি তবে বা সেখানে কোনও প্যারামিটার না থাকলে ডান বন্ধনী ব্যবহার করি।

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