هل يمكن استخدام إجراءات مخزنة معلمات ديناميكية في جملة "في"؟
-
13-09-2019 - |
سؤال
أريد تشغيل استعلام مثل هذا:
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
يمكنك القيام بذلك تماما في إجراء مخزن.
قم بإنشاء جدول 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 =