هل يمكن استخدام إجراءات مخزنة معلمات ديناميكية في جملة "في"؟

StackOverflow https://stackoverflow.com/questions/977021

سؤال

أريد تشغيل استعلام مثل هذا:

 SELECT * FROM Studio WHERE Id IN (134, 144, 132, 138, 7432, 7543, 2566)

لكن كمية هوية شخصيةيتم تمرير مرت إلى البند في وقت التشغيل فقط.

هل يجب علي استخدام SQL الديناميكي أو هل يمكن القيام بذلك باستخدام إجراء مخزن؟

تحديث:إذا كان الخيار متاحا، أيهما أفضل؟

شكرًا.

هل كانت مفيدة؟

المحلول

اعتمادا على إصدار SQL Server الخاص بك، يمكنك القيام بهذا بطريقتين مختلفتين.

بالنسبة ل SQL 2000/2005، يمكنك استخدام معلمة (اكتب varchar) التي تحتوي على قائمة محددة من المعرفات. قم بإنشاء UDF الذي من شأنه أن تحليل varchar وإرجاع جدول يحتوي على العناصر. ثم اجعل جملةك في طريقك مقابل الجدول (أي ... في (حدد معرف من ReturnTable)).

إليك مثال على ما يبدو عليه محتويات UDF:http://pietschsoft.com/post/2006/02/03/t-sql-parse-a-delimited-string.aspx.

ل SQL 2008، يمكنك أن تفعل الشيء نفسه؛ ومع ذلك، بدلا من المرور في معلمة varchar، يمكنك فقط قطعها إلى مطاردة وتمرير معلمة جدول. في البند، لا يزال لديه إعالة فرعية، لكنها ستعمل كل نفس. بدلا من ذلك، بمجرد أن يكون لديك الجدول، يمكنك فقط إجراء انضمام داخلي عليه والتحايل على الحاجة إلى البند في.

تحرير: تمت إضافة UDF لتحليل ارتباط سلسلة محدد.

نصائح أخرى

الحل الموصوف هنا:

المصفوفات والقوائم في SQL Server 2005

نص SQL بواسطة Erland Sommarskog، SQL Server MVP

http://www.sommarskog.se/arrays-in-sql-2005.html

يمكنك القيام بذلك تماما في إجراء مخزن.

قم بإنشاء جدول TEMP داخل الإجراء المخزن وإدراج القيم المنقسمة على الفواصل أو أي محدد عند القيام بذلك

SELECT * FROM Studio WHERE Id IN (select id from temptable)

ثم حذف الجدول.

فيما يلي UDF الذي استخدمته منذ MSSQL 2000. لقد وجدت هذا في مكان ما - آسف، لا أستطيع تذكر أين.

في الأساس، يمكنك القيام بالانضمام في UDF، حيث تكون المعلمة الأولى هي السلسلة المحددة، والفارة الثانية هي الحلمين.

حدد t1.somecolumn من sometable t1 inner الانضمام dbo.split (delimitedvar، '،') t2 على t1.id = t2.element

CREATE FUNCTION [dbo].[Split]
(
@vcDelimitedString varchar(max),
@vcDelimiter varchar(100)
)
RETURNS @tblArray TABLE
   (
    ElementID smallint  IDENTITY(1,1), --Array index
    Element varchar(1000) --Array element contents
   )
AS
BEGIN
    DECLARE @siIndex smallint, @siStart smallint, @siDelSize smallint
    SET @siDelSize  = LEN(@vcDelimiter)
    --loop through source string and add elements to destination table array
    WHILE LEN(@vcDelimitedString) > 0
    BEGIN
        SET @siIndex = CHARINDEX(@vcDelimiter, @vcDelimitedString)
        IF @siIndex = 0
        BEGIN
            INSERT INTO @tblArray VALUES(@vcDelimitedString)
            BREAK
        END
        ELSE
        BEGIN
            INSERT INTO @tblArray VALUES(SUBSTRING(@vcDelimitedString, 1,@siIndex - 1))
            SET @siStart = @siIndex + @siDelSize
            SET @vcDelimitedString = SUBSTRING(@vcDelimitedString, @siStart , LEN(@vcDelimitedString) - @siStart + 1)
        END
    END
    RETURN
END

في SQL 2008، يمكنك استخدام الجدول قيمة المعلمة.

في SQL 2005، يجب عليك استخدام SQL Dynamic SQL إلا إذا كنت ترغب في اجتياز القائمة ك XML واستخدم معالجة XML في الإجراء لتمزيق XML مرة أخرى في متغير جدول.

أعلن طاولة تيمب وتقسيم القيم فيه. ثم يمكنك القيام به

حدد * من Studio S Inner انضم إلى TBTRAPTER TB على S.ID =

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top