2009-01-29 20 views
7

Próbuję napisać procedurę przechowywaną iw zależności od określonej wartości kolumny, chcę móc zmienić wybraną tabelę. Postaram się dać przykład:Dynamicznie Zmienianie tabeli do wybrania za pomocą instrukcji SQL CASE

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 

Jak widać, nie tylko ja dynamicznie zmieniające tabelę I wyboru, ale ponieważ te dwa stoły zostały wykonane w dwóch różnych czasach przez dwóch różnych ludzi, nazwy kolumn również są różne.

Moje pytanie brzmi: Jaki jest najlepszy sposób, aby to osiągnąć, ponieważ SQL Server nie wydaje się podoba mi moje zapytanie, które skonstruowałem.

Jeśli ktoś, kto widzi, co próbuję zrobić, może sugerować lepszy sposób to zrobić, byłbym wszystkie uszy :-)

+0

Podczas gdy ludzie zwykle zakładają "Serwer SQL" == "Serwer MS SQL", lepiej jest wyjaśnić to w pytaniu i znacznikach. Zmieniam tagi, cofnij, jeśli się mylę. –

+4

sqlserver jest tagiem dla Microsoft SQL Server. Obecnie nie ma żadnego innego produktu o tej nazwie i jest to jedyny użyteczny tag na SO. –

Odpowiedz

5

nie można używać instrukcji CASE w klauzuli FROM, ale można użyć następujących zamiast:

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' 
+0

Miałem na myśli klauzulę FROM – user34850

0

Jesteś lepszego wykorzystania zapytania UNION dołączyć tabele pierwszy, a następnie WYBIERZ.

Możesz także rozważyć utworzenie widoku dla jednej z tabel, więc ciągnie ona tylko kolumny, których potrzebujesz podczas zmiany nazwy, a następnie UNION, a następnie wybierz z UNION.

Lub użyj tabeli tymczasowej do przechowywania wyników z każdego zapytania. Umieścić utworzenie tabeli temp w sprawie (Pseudokod, nie testowane):

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 
3

można spróbować budowę dynamicznego SQL jako ciąg znaków, a następnie wywołanie procedury przechowywanej sp_executesql do wykonania łańcucha.

Aby uzyskać więcej informacji i przykładów, zobacz numer here.

+0

Wątpię, czy dynamiczny SQL jest tutaj naprawdę potrzebny, chyba że schemat jest jeszcze bardziej patologiczny. –

+0

Zgadzam się, że SP ma naprawdę zły projekt, ale myślę, że jest to najprostsze rozwiązanie proponowanego problemu. –

+0

Nie sądzę, że problem został określony wystarczająco solidnie, aby stwierdzić, że nie można go rozwiązać za pomocą podstawowego SQL. Dynamiczny SQL nie powinien być traktowany ogólnie, dopóki przeszkoda na drodze zwykłego SQL nie wskaże, że jest to właściwy wybór. –

1

Naprawdę nie wyjaśniasz, skąd pochodzi ItemType. Zgodnie z sugestią UNION może być stosowana, jeśli po prostu łączysz dwie tabele.

Oto inna możliwość, która może odnosić się do problemu:

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 
3

nie jestem Pewnie, dlaczego chcesz robić rzeczy w jednym oświadczeniu SQL. Nie jestem użytkownikiem serwera SQL, ale w procedurze przechowywanej Oracle możesz napisać coś takiego, tak jakbyś mógł napisać coś takiego:

Coś takiego powinno również działać w SQL Server. Może ktoś mógłby rozwinąć to?

+0

To właśnie zrobiłbym – HLGEM

Powiązane problemy