تغيير ديناميكي ما يجب الاختيار من خلال بيان حالة SQL

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

  •  20-08-2019
  •  | 
  •  

سؤال

أحاول كتابة إجراء مخزن واعتمادًا على قيمة عمود معينة ، أريد أن أكون قادرًا على تغيير الجدول الذي أختاره. سأحاول إعطاء مثال:

SELECT ItemNumber,
       ItemType, 
       Description
FROM

CASE ItemType
WHEN 'A' THEN TableA
ELSE TableB
END

WHERE 

CASE ItemType
WHEN 'A' THEN ItemNumber = @itemNumber
ELSE PartNumber = @itemNumber
END

كما ترون ، لا أقوم فقط بتغيير الجدول الذي اخترته من خلال ، ولكن نظرًا لأن هذين الجدولين تم صنعهما في مرتين مختلفتين من قبل شخصين مختلفين ، فإن أسماء الأعمدة مختلفة أيضًا.

لذا ، سؤالي هو: ما هي أفضل طريقة لإنجاز هذا ، لأن SQL Server لا يبدو أنه يحب استعلامي الذي قمت ببنائه.

إذا كان أي شخص يرى ما أحاول القيام به يمكن أن يقترح طريقة أفضل للقيام بذلك ، سأكون كل الأذنين :-)

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

المحلول

لا يمكنك استخدام عبارة CASE IN FROM ، ولكن يمكنك استخدام ما يلي بدلاً من ذلك:

SELECT itemnumber, itemtype, description
  FROM tablea
 WHERE itemnumber = @itemnumber AND itemtype = 'A'
UNION ALL
SELECT itemnumber, itemtype, description
  FROM tableb
 WHERE partnumber = @itemnumber AND itemtype <> 'A'

نصائح أخرى

يمكنك محاولة إنشاء عبارة SQL الديناميكية كسلسلة ، ثم استدعاء الإجراء المخزن SP_EXECUTESQL لتنفيذ السلسلة.

نرى هنا لمزيد من المعلومات والأمثلة.

I'm not sure why you want to do things in one SQL Statement .. I'm not a SQL Server person, but in an Oracle stored procedure you could write something like this

If itemtype = 'A' 
Then 
 <statement for table A>
Else
 <statement for Table B>
End if

Something like this should work in SQL Server, too .. maybe someone could expand on this?

You really aren't explaining where ItemType is coming from. As suggested UNION might be applicable if you are simply combining two tables.

Here's another possibility which may relate to your problem:

SELECT ItemNumber,
       ItemType, 
       COALESCE(TableA.Description, TableB.Description) AS Description
FROM Items
LEFT JOIN TableA
    ON Items.ItemType = 'A'
    AND TableA.ItemNumber = Items.ItemNumber
LEFT JOIN TableB
    ON Items.ItemType <> 'A'
    AND TableB.ItemNumber = Items.ItemNumber

You are better of using UNION query to join the tables first, and then SELECT.

Also, you may consider creating a view for one of the tables, so it pulls only the columns you need while renaming them, then UNION, and then select from the UNION.

Or use a temp table to store the result from each query. Put the creation of the temp table in a CASE (pseudocode, not tested):

CASE @itemType
   WHEN 'A'
      SELECT ACol1 AS Col1, ACol2 AS Col2
      FROM TABLE_A
      INTO #tempTable
      WHERE ItemNumber = @itemNumber
   ELSE
      SELECT BCol1 AS Col1, BCol2 AS Col2
      FROM TABLE_B
      INTO #tempTable
      WHERE PartNumber = @itemNumber
END

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