কীভাবে একটি এসকিউএল সার্ভার সঞ্চিত পদ্ধতিতে অ্যারে পাস করবেন


293

কীভাবে একটি এসকিউএল সার্ভার সঞ্চিত পদ্ধতিতে অ্যারে পাস করবেন?

উদাহরণস্বরূপ, আমার কর্মীদের একটি তালিকা আছে। আমি এই তালিকাটি একটি টেবিল হিসাবে ব্যবহার করতে এবং এটি অন্য টেবিলের সাথে যুক্ত করতে চাই। তবে কর্মীদের তালিকা সি # থেকে প্যারামিটার হিসাবে পাস করা উচিত।



উত্তর:


437

এসকিউএল সার্ভার ২০০৮ (বা আরও নতুন)

প্রথমে আপনার ডাটাবেসে নিম্নলিখিত দুটি বস্তু তৈরি করুন:

CREATE TYPE dbo.IDList
AS TABLE
(
  ID INT
);
GO

CREATE PROCEDURE dbo.DoSomethingWithEmployees
  @List AS dbo.IDList READONLY
AS
BEGIN
  SET NOCOUNT ON;

  SELECT ID FROM @List; 
END
GO

এখন আপনার সি # কোডে:

// Obtain your list of ids to send, this is just an example call to a helper utility function
int[] employeeIds = GetEmployeeIds();

DataTable tvp = new DataTable();
tvp.Columns.Add(new DataColumn("ID", typeof(int)));

// populate DataTable from your List here
foreach(var id in employeeIds)
    tvp.Rows.Add(id);

using (conn)
{
    SqlCommand cmd = new SqlCommand("dbo.DoSomethingWithEmployees", conn);
    cmd.CommandType = CommandType.StoredProcedure;
    SqlParameter tvparam = cmd.Parameters.AddWithValue("@List", tvp);
    // these next lines are important to map the C# DataTable object to the correct SQL User Defined Type
    tvparam.SqlDbType = SqlDbType.Structured;
    tvparam.TypeName = "dbo.IDList";
    // execute query, consume results, etc. here
}

এসকিউএল সার্ভার 2005

আপনি যদি এসকিউএল সার্ভার 2005 ব্যবহার করেন তবে আমি এক্সএমএল এর পরে একটি বিভক্ত ফাংশনটি সুপারিশ করব। প্রথমে একটি ফাংশন তৈরি করুন:

CREATE FUNCTION dbo.SplitInts
(
   @List      VARCHAR(MAX),
   @Delimiter VARCHAR(255)
)
RETURNS TABLE
AS
  RETURN ( SELECT Item = CONVERT(INT, Item) FROM
      ( SELECT Item = x.i.value('(./text())[1]', 'varchar(max)')
        FROM ( SELECT [XML] = CONVERT(XML, '<i>'
        + REPLACE(@List, @Delimiter, '</i><i>') + '</i>').query('.')
          ) AS a CROSS APPLY [XML].nodes('i') AS x(i) ) AS y
      WHERE Item IS NOT NULL
  );
GO

এখন আপনার সঞ্চিত পদ্ধতিটি কেবল এটি হতে পারে:

CREATE PROCEDURE dbo.DoSomethingWithEmployees
  @List VARCHAR(MAX)
AS
BEGIN
  SET NOCOUNT ON;

  SELECT EmployeeID = Item FROM dbo.SplitInts(@List, ','); 
END
GO

এবং আপনার সি # কোডে আপনাকে কেবল তালিকাটি পাস করতে হবে '1,2,3,12'...


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

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

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

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


3
আমি টেবিলের প্যারামিটার ধারণাটি পছন্দ করি - এটি কখনই ভাবেননি - চিয়ার্স। ডিলিমিটারের জন্য এটি মূল্যবান কিসের জন্য স্প্লিটআইন্টস () ফাংশন কলটিতে যেতে হবে।
ড্রামি

কেবলমাত্র কমা দ্বারা পৃথক স্ট্রিংয়ের অ্যাক্সেস থাকলে আমি টেবিলের প্যারামিটারটি কীভাবে ব্যবহার করতে পারি
বিডউইন

@ বিডওয়াইন উদ্দেশ্যটিকে পরাভূত করবে - টিভিপিতে লাগানোর জন্য আপনাকে একটি বিভক্ত ফাংশন ব্যবহার করতে হবে r আপনার অ্যাপ্লিকেশন কোড এ তা ছিন্ন।
অ্যারন বারট্র্যান্ড

1
প্রতিক্রিয়াটির জন্য @ অ্যারনবার্ট্র্যান্ড ধন্যবাদ, আমি আসলে এটি আবিষ্কার করেছি। আমি একটি উপ বন্ধনীর মধ্যে নির্বাচন ব্যবহার করতে হবে: SELECT [colA] FROM [MyTable] WHERE [Id] IN (SELECT [Id] FROM @ListOfIds)
জ্যাকএক্সজেড

3
@ th1rdey3 তারা নিখুঁতভাবে alচ্ছিক। stackoverflow.com/a/18926590/61305
অ্যারন বার্ট্র্যান্ড

44

আমার অভিজ্ঞতার ভিত্তিতে, কর্মচারীদের আইডি থেকে বিস্মৃত অভিব্যক্তি তৈরি করে এই সমস্যার কার্যকর এবং দুর্দান্ত সমাধান রয়েছে। আপনি শুধুমাত্র মতো স্ট্রিং অভিব্যক্তি তৈরি করা উচিত ';123;434;365;'ইন-যা 123, 434এবং 365কিছু employeeIDs হয়। নীচের পদ্ধতিটি কল করে এবং এটিতে এই অভিব্যক্তিটি পাস করার মাধ্যমে আপনি আপনার পছন্দসই রেকর্ডগুলি আনতে পারেন। সহজেই আপনি এই ক্যোয়ারিতে "অন্য টেবিল" এ যোগ দিতে পারেন। এই সমাধানটি এসকিউএল সার্ভারের সমস্ত সংস্করণে উপযুক্ত। এছাড়াও, সারণী ভেরিয়েবল বা টেম্প টেবিল ব্যবহারের তুলনায় এটি খুব দ্রুত এবং অনুকূলিত সমাধান।

CREATE PROCEDURE dbo.DoSomethingOnSomeEmployees  @List AS varchar(max)
AS
BEGIN
  SELECT EmployeeID 
  FROM EmployeesTable
  -- inner join AnotherTable on ...
  where @List like '%;'+cast(employeeID as varchar(20))+';%'
END
GO

নিস! আমি সত্যিই এই পদ্ধতির পছন্দ করি যেখানে আমি ইন কীগুলিতে ফিল্টার করছি! +1
MDV2000

@ MDV2000 ধন্যবাদ :) স্ট্রিং কীগুলিতে, ভারচারে ইন্টি কলামগুলি কাস্ট না করার কারণে এটিরও ভাল পারফরম্যান্স রয়েছে ...
হামেদ নাজক্তবার

আমি খেলায় দেরি করছি, তবে এটি খুব চালাক! আমার সমস্যার জন্য দুর্দান্ত কাজ করে।
ব্যবহারকারী 441058

এটা চমৎকার! আমি অবশ্যই এটি ব্যবহার করব, আপনাকে ধন্যবাদ
ওমর রাডার

26

আপনার সঞ্চিত পদ্ধতির জন্য একটি টেবিল-মূল্যবান পরামিতি ব্যবহার করুন।

আপনি যখন এটি সি # থেকে প্রবেশ করবেন তখন আপনি SqlDb.Structured এর ডেটা টাইপের সাথে পরামিতি যুক্ত করবেন।

এখানে দেখুন: http://msdn.microsoft.com/en-us/library/bb675163.aspx

উদাহরণ:

// Assumes connection is an open SqlConnection object.
using (connection)
{
// Create a DataTable with the modified rows.
DataTable addedCategories =
  CategoriesDataTable.GetChanges(DataRowState.Added);

// Configure the SqlCommand and SqlParameter.
SqlCommand insertCommand = new SqlCommand(
    "usp_InsertCategories", connection);
insertCommand.CommandType = CommandType.StoredProcedure;
SqlParameter tvpParam = insertCommand.Parameters.AddWithValue(
    "@tvpNewCategories", addedCategories);
tvpParam.SqlDbType = SqlDbType.Structured;

// Execute the command.
insertCommand.ExecuteNonQuery();
}

17

আপনাকে এটি এক্সএমএল প্যারামিটার হিসাবে পাস করতে হবে।

সম্পাদনা করুন: আপনাকে ধারণা দেওয়ার জন্য আমার প্রকল্পের দ্রুত কোড:

CREATE PROCEDURE [dbo].[GetArrivalsReport]
    @DateTimeFrom AS DATETIME,
    @DateTimeTo AS DATETIME,
    @HostIds AS XML(xsdArrayOfULong)
AS
BEGIN
    DECLARE @hosts TABLE (HostId BIGINT)

    INSERT INTO @hosts
        SELECT arrayOfUlong.HostId.value('.','bigint') data
        FROM @HostIds.nodes('/arrayOfUlong/u') as arrayOfUlong(HostId)

তারপরে আপনি টেবিলগুলির সাথে যোগ দিতে টেম্প টেবিলটি ব্যবহার করতে পারেন। ডেটা অখণ্ডতা বজায় রাখতে আমরা অ্যারেঅফলংকে এক্সএমএল স্কিমায় একটি বিল্ট হিসাবে সংজ্ঞায়িত করেছি, তবে আপনাকে এটি করতে হবে না to আমি এটি ব্যবহার করার পরামর্শ দিচ্ছি যাতে আপনি সর্বদা দীর্ঘায়ু সহ একটি এক্সএমএল পান তা নিশ্চিত করার জন্য একটি দ্রুত কোড এখানে।

IF NOT EXISTS (SELECT * FROM sys.xml_schema_collections WHERE name = 'xsdArrayOfULong')
BEGIN
    CREATE XML SCHEMA COLLECTION [dbo].[xsdArrayOfULong]
    AS N'<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="arrayOfUlong">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded"
                            name="u"
                            type="xs:unsignedLong" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>';
END
GO

আমি ভেবেছিলাম যখন অনেকগুলি সারি থাকবে তখন টেবিলের ভেরিয়েবলগুলি ব্যবহার করা খারাপ ধারণা? পরিবর্তে কোনও টেম্প (# টেবিল) টেবিল ব্যবহার করা কি ভাল পারফরম্যান্স নয়?
গ্যান্ডার্স

@ গ্যান্ডারস: আমি এর বিপরীতে বলব।
abatishchev

14

প্রসঙ্গটি সর্বদা গুরুত্বপূর্ণ, যেমন অ্যারের আকার এবং জটিলতা । ছোট থেকে মাঝারি আকারের তালিকার জন্য, এখানে পোস্ট করা বেশ কয়েকটি উত্তর ঠিক আছে, যদিও কিছু স্পষ্টতা দেওয়া উচিত:

  • একটি সীমিত তালিকা বিভক্ত করার জন্য, একটি এসকিউএলসিআর-ভিত্তিক স্প্লিটারটি দ্রুততম। আপনি নিজের লেখা লিখতে চাইলে চারপাশে অসংখ্য উদাহরণ রয়েছে বা আপনি কেবল সিএলআর ফাংশনগুলির বিনামূল্যে এসকিউএল # গ্রন্থাগারটি ডাউনলোড করতে পারেন (যা আমি লিখেছি, তবে স্ট্রিং_স্প্লিট ফাংশন এবং আরও অনেকগুলি সম্পূর্ণ নিখরচায়)।
  • এক্সএমএল-ভিত্তিক অ্যারেগুলি বিভক্ত করা দ্রুত হতে পারে, তবে আপনাকে অ্যাট্রিবিউট-ভিত্তিক এক্সএমএল ব্যবহার করতে হবে, এলিমেন্ট-ভিত্তিক এক্সএমএল নয় (যা উত্তরগুলিতে এখানে প্রদর্শিত একমাত্র টাইপ, যদিও @ অ্যারোনবার্ট্র্যান্ডের এক্সএমএল উদাহরণটি সেরা হিসাবে তার কোডটি ব্যবহার করছে text()এক্সএমএল ফাংশন। তালিকাগুলি বিভক্ত করতে এক্সএমএল ব্যবহারের বিষয়ে আরও তথ্যের জন্য (অর্থাত্ পারফরম্যান্স বিশ্লেষণ), ফিল ফ্যাক্টর দ্বারা "এসকিউএল সার্ভারের পরামিতি হিসাবে তালিকাগুলি পাস করার জন্য এক্সএমএল ব্যবহার করে " দেখুন
  • টিভিপি ব্যবহার দুর্দান্ত (ধরে নিলে আপনি কমপক্ষে এসকিউএল সার্ভার ২০০৮ বা আরও নতুন ব্যবহার করছেন) ধরে রাখুন যেহেতু তথ্যটি প্রোকের কাছে প্রবাহিত হয় এবং প্রি-পার্সড এবং দৃ table়ভাবে টাইপযুক্ত ভেরিয়েবল হিসাবে প্রদর্শিত হয়। যাইহোক, বেশিরভাগ ক্ষেত্রে, সমস্ত ডেটা সংরক্ষণ করা DataTableমানে মূল সংগ্রহ থেকে অনুলিপি করা হওয়ায় মেমরিতে নকল করা। অতএব DataTableটিভিপিগুলিতে পাস করার পদ্ধতিটি বৃহত্তর উপাত্তের (যেমন ভাল স্কেল করে না) ভাল কাজ করে না।
  • এক্সএমএল, ইনটস বা স্ট্রিংয়ের সাধারণ সীমিত তালিকাগুলির বিপরীতে, টিভিপিগুলির মতো এক-মাত্রিকের বেশি অ্যারে পরিচালনা করতে পারে। তবে কেবল DataTableটিভিপি পদ্ধতির মতোই , এক্সএমএলও স্কেল করে না কারণ এটি মেমরিতে ডেটাসাইজকে দ্বিগুণ করার চেয়ে বেশি কারণ এটি এক্সএমএল ডকুমেন্টের ওভারহেডের জন্য অ্যাকাউন্ট প্রয়োজন account

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

সঞ্চিত প্রক্রিয়া টি-এসকিউএল তে অভিধান পাস করুন


6

এসকিএল সার্ভারে অ্যারের জন্য কোনও সমর্থন নেই তবে বেশ কয়েকটি উপায় রয়েছে যার মাধ্যমে আপনি সংগ্রহটি কোনও সংগ্রহস্থলের কাছে পাস করতে পারেন।

  1. ডেটাটেবল ব্যবহার করে
  2. এক্সএমএল ব্যবহার করে আপনার সংগ্রহকে একটি এক্সএমএল ফর্ম্যাটে রূপান্তর করার চেষ্টা করুন এবং তারপরে এটি কোনও সঞ্চিত পদ্ধতিতে ইনপুট হিসাবে পাস করুন

নীচের লিঙ্কটি আপনাকে সাহায্য করতে পারে

সঞ্চিত পদ্ধতিতে সংগ্রহ পাস করা


5

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

- নীচের কোডটি প্যারামিটার হিসাবে একটি অ্যারে পেতে যাচ্ছে এবং অন্য টেবিলে সেই অ্যারেটির মানগুলি সন্নিবেশ করতে চলেছে

Create Procedure Proc1 


@UserId int, //just an Id param
@s nvarchar(max)  //this is the array your going to pass from C# code to your Sproc

AS

    declare @xml xml

    set @xml = N'<root><r>' + replace(@s,',','</r><r>') + '</r></root>'

    Insert into UserRole (UserID,RoleID)
    select 
       @UserId [UserId], t.value('.','varchar(max)') as [RoleId]


    from @xml.nodes('//root/r') as a(t)
END 

আপনি এটা উপভোগ করেন


2
@ জাজিটসমান: ক্লিনস্ট মানে সেরা বা সবচেয়ে উপযুক্ত নয় not একটি "ক্লিন" কোড পেতে প্রায়শই নমনীয়তা এবং / অথবা "উপযুক্ত" জটিলতা এবং / অথবা কার্য সম্পাদন ত্যাগ করে। এখানে এই উত্তরটি "ঠিক আছে" তবে কেবলমাত্র ছোট ডেটা সেটগুলির জন্য। যদি আগত অ্যারেটি @sসিএসভি হয় তবে এটি সহজেই বিভক্ত হওয়া আরও দ্রুত হবে (অর্থাত্ INSERT INTO ... SplitFunction থেকে নির্বাচন করুন)। এক্সএমএলে রূপান্তরকরণ সিএলআর থেকে ধীর গতিতে এবং অ্যাট্রিবিউট-ভিত্তিক এক্সএমএল যাইহোক দ্রুততর। এবং এটি একটি সাধারণ তালিকা এখনও এক্সএমএল বা টিভিপিতে পাস করা জটিল অ্যারে পরিচালনা করতে পারে। সহজ, এককালীন এড়িয়ে যা অর্জন করা হয়েছে তা নিশ্চিত নয় CREATE TYPE ... AS TABLE
সলোমন রুটজকি

5

এটি আপনাকে সাহায্য করবে। :) পরবর্তী পদক্ষেপগুলি অনুসরণ করুন,

  1. কোয়েরি ডিজাইনার খুলুন
  2. নিম্নলিখিত কোডটি এটির মতো পেস্ট করুন অনুলিপি করুন, এটি ফাংশন তৈরি করবে যা স্ট্রিংকে ইনটে রূপান্তর করবে

    CREATE FUNCTION dbo.SplitInts
    (
       @List      VARCHAR(MAX),
       @Delimiter VARCHAR(255)
    )
    RETURNS TABLE
    AS
      RETURN ( SELECT Item = CONVERT(INT, Item) FROM
          ( SELECT Item = x.i.value('(./text())[1]', 'varchar(max)')
            FROM ( SELECT [XML] = CONVERT(XML, '<i>'
            + REPLACE(@List, @Delimiter, '</i><i>') + '</i>').query('.')
              ) AS a CROSS APPLY [XML].nodes('i') AS x(i) ) AS y
          WHERE Item IS NOT NULL
      );
    GO
  3. নিম্নলিখিত সঞ্চিত পদ্ধতি তৈরি করুন

     CREATE PROCEDURE dbo.sp_DeleteMultipleId
     @List VARCHAR(MAX)
     AS
     BEGIN
          SET NOCOUNT ON;
          DELETE FROM TableName WHERE Id IN( SELECT Id = Item FROM dbo.SplitInts(@List, ',')); 
     END
     GO
  4. এই এসপিটি কার্যকর করুন এটি ব্যবহার করে exec sp_DeleteId '1,2,3,12'আইডির একটি স্ট্রিং যা আপনি মুছতে চান,

  5. আপনি আপনার অ্যারেটিকে সি # তে স্ট্রিংয়ে রূপান্তর করুন এবং এটি একটি সঞ্চিত পদ্ধতি প্যারামিটার হিসাবে পাস করুন

    int[] intarray = { 1, 2, 3, 4, 5 };  
    string[] result = intarray.Select(x=>x.ToString()).ToArray();

     

    SqlCommand command = new SqlCommand();
    command.Connection = connection;
    command.CommandText = "sp_DeleteMultipleId";
    command.CommandType = CommandType.StoredProcedure;
    command.Parameters.Add("@Id",SqlDbType.VARCHAR).Value=result ;

এটি একাধিক সারি মুছে ফেলবে, সর্বোত্তম


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

2

এটি বের করতে আমার অনেক সময় লেগেছে, তাই যদি কারও এটির প্রয়োজন হয় ...

এটি হারুনের উত্তরের এসকিউএল 2005 পদ্ধতির উপর ভিত্তি করে এবং তার স্প্লিটআইন্টস ফাংশনটি ব্যবহার করে (আমি স্রেফ কমা ব্যবহার করব বলে আমি সীমাবদ্ধ প্যারামটি সরিয়েছি)। আমি এসকিউএল 2008 ব্যবহার করছি তবে আমি এমন কিছু চাইছিলাম যা টাইপ করা ডেটাসেটগুলির সাথে কাজ করে (এক্সএসডি, টেবিলএডাপ্টারস) এবং আমি জানি স্ট্রিং প্যারামগুলি সেগুলির সাথে কাজ করে।

আমি তাঁর ফাংশনটি "যেখানে (1,2,3)" টাইপ ধারাটিতে কাজ করার চেষ্টা করছিলাম, এবং ভাগ্য সোজা-সামনের দিকে নেই। তাই আমি প্রথমে একটি টেম্প টেবিল তৈরি করেছি এবং তারপরে "যেখানে ভিতরে" পরিবর্তে একটি অভ্যন্তরীণ যোগদান করেছি। এখানে আমার উদাহরণ ব্যবহারটি দেওয়া হয়েছে, আমার ক্ষেত্রে আমি এমন কিছু রেসিপিগুলির একটি তালিকা পেতে চেয়েছিলাম যাতে কিছু উপাদান থাকে না:

CREATE PROCEDURE dbo.SOExample1
    (
    @excludeIngredientsString varchar(MAX) = ''
    )
AS
    /* Convert string to table of ints */
    DECLARE @excludeIngredients TABLE (ID int)
    insert into @excludeIngredients
    select ID = Item from dbo.SplitInts(@excludeIngredientsString)

    /* Select recipies that don't contain any ingredients in our excluded table */
   SELECT        r.Name, r.Slug
FROM            Recipes AS r LEFT OUTER JOIN
                         RecipeIngredients as ri inner join
                         @excludeIngredients as ei on ri.IngredientID = ei.ID
                         ON r.ID = ri.RecipeID
WHERE        (ri.RecipeID IS NULL)

সাধারণভাবে বলতে গেলে, কোনও টেবিলের পরিবর্তনশীল সাথে যোগ না দেওয়া ভাল, তবে পরিবর্তে কোনও টেম্প সারণীতে। টেবিল ভেরিয়েবলগুলি ডিফল্টরূপে কেবল একটি সারি থাকে বলে মনে হয়, যদিও এর চারপাশে দু'একটি কৌশল রয়েছে (@ অ্যারোনবার্ট্র্যান্ডের দুর্দান্ত এবং বিস্তারিত নিবন্ধটি দেখুন: sqlperformance.com/2014/06/t-sql-queries/… )।
সলোমন রুটজকি

1

অন্যরা যেমন উপরে উল্লিখিত আছে, এটি করার একটি উপায় হ'ল আপনার অ্যারেটিকে একটি স্ট্রিংয়ে রূপান্তর করা এবং তারপরে এসকিউএল সার্ভারের মধ্যে স্ট্রিংটি বিভক্ত করা।

এসকিউএল সার্ভার ২০১ 2016 হিসাবে, স্ট্রিংগুলিকে বিভক্ত করার একটি অন্তর্নির্মিত উপায় রয়েছে

STRING_SPLIT ()

এটি সারিগুলির একটি সেট প্রদান করে যা আপনি আপনার টেম্প টেবিল (বা আসল টেবিল) এ sertোকাতে পারেন।

DECLARE @str varchar(200)
SET @str = "123;456;789;246;22;33;44;55;66"
SELECT value FROM STRING_SPLIT(@str, ';')

উত্পন্ন হবে:

মান
-----
  123
  456
  789
  246
   22
   33
   44
   55
   66

আপনি যদি ফ্যানসিয়ার পেতে চান:

DECLARE @tt TABLE (
    thenumber int
)
DECLARE @str varchar(200)
SET @str = "123;456;789;246;22;33;44;55;66"

INSERT INTO @tt
SELECT value FROM STRING_SPLIT(@str, ';')

SELECT * FROM @tt
ORDER BY thenumber

আপনাকে উপরের মতো একই ফলাফল দেবে (কলামটির নাম "ততবার" বাদে) তবে সাজানো হয়েছে। আপনি অন্য যে কোনও টেবিলের মতো টেবিলের পরিবর্তনশীল ব্যবহার করতে পারেন, আপনি চাইলে সহজেই ডিবিতে অন্য টেবিলের সাথে এতে যোগ দিতে পারেন।

নোট করুন যে STRING_SPLIT()ফাংশনটি স্বীকৃত হওয়ার জন্য আপনার এসকিউএল সার্ভার ইনস্টলটি সামঞ্জস্যতা স্তরের 130 বা তার বেশি হতে হবে। আপনি নিম্নলিখিত প্রশ্নের সাথে আপনার সামঞ্জস্যের স্তরটি পরীক্ষা করতে পারেন:

SELECT compatibility_level
FROM sys.databases WHERE name = 'yourdatabasename';

বেশিরভাগ ভাষায় (সি # সহ) একটি "যোগদান" ফাংশন থাকে যা আপনি অ্যারে থেকে স্ট্রিং তৈরি করতে ব্যবহার করতে পারেন।

int[] myarray = {22, 33, 44};
string sqlparam = string.Join(";", myarray);

তারপরে আপনি sqlparamউপরের সঞ্চিত পদ্ধতিতে আপনার প্যারামিটার হিসাবে পাস করুন ।


0
CREATE TYPE dumyTable
AS TABLE
(
  RateCodeId int,
  RateLowerRange int,
  RateHigherRange int,
  RateRangeValue int
);
GO
CREATE PROCEDURE spInsertRateRanges
  @dt AS dumyTable READONLY
AS
BEGIN
  SET NOCOUNT ON;

  INSERT  tblRateCodeRange(RateCodeId,RateLowerRange,RateHigherRange,RateRangeValue) 
  SELECT * 
  FROM @dt 
END
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.